Getting Emacs ada-mode working

i’ve finally been getting into Ada (although i’ve been programming since the early 80s, using BASICs on 6502-based machines like the TRS-80 and the BBC B). As a result, i’ve created the ‘Ada’ page on the Gentoo wiki, Ada - Gentoo wiki, to try to document what i’ve been learning, in the hope that it might smooth the way for others.

With regards to Irvise’s remark:

He had issues getting Ada working in Emacs. The Ada-mode in Emacs needs to be maintained and refactored to become easier to use. Basically, it has to become “plug & play”.

and Lucretia’s remark:

Other’s said in the chat numerous times that the emacs ada-mode didn’t work and you had to use the older one, I dunno, I gave up on ada-mode and emacs years ago, because I assumed as did he, that once installed, it should just work, which it never did, because you have to compile it yourself, which is a bad move.

Yes, setting up ada-mode in Emacs required more work than i’ve come to expect for setting up language support in Emacs nowadays. A significant part of the above wiki page describes what i learned after some hours of futzing around: Ada - Gentoo wiki

In particular, i found that:

Version 8.1.0 also requires copying the file ada_annex_p_lr1_re2c_parse_table.txt from the top level of the ada-mode-8.1.0 directory to the relevant installation location.

i sent an email to the ada-mode-users list on 20 February about this:

https://lists.nongnu.org/archive/html/ada-mode-users/2024-02/msg00000.html

but have not yet received any response.

2 Likes

@flexibeast welcome to the Ada community!
I regularly use EMACS at work for C and C++. Sadly, I gave up using it for Ada because I ran into issues with the ada-mode. I’ve since switched over to Visual Studio Code and the ada-lang server, but I am not a fan of the indentation style. I probably should consider using GPS.

Unfortunately, the author of ada-mode has retired, which most likely explains why you haven’t received a reply to your message that you submitted back in Feb. I’ll admit, part of me feels the urge to learn how ada-mode works and see how much effort it is to maintain. I dunno…

welcome to the Ada community!

Thank you!

Unfortunately, the author of ada-mode has retired, which most likely explains why you haven’t received a reply to your message that you submitted back in Feb.

Ah okay, that would indeed explain it. :slightly_smiling_face: i’ll note that on the wiki page.

I’ve since switched over to Visual Studio Code and the ada-lang server, but I am not a fan of the indentation style … I’ll admit, part of me feels the urge to learn how ada-mode works and see how much effort it is to maintain. I dunno…

Hmm. i’m not yet that familiar with how the Language Server Protocol works; is the indentation style something permanently determined by each specific server implementation, and not user-configurable? i ask because i’m wondering if you’ve tried using ALS with any or all of Eglot by itself, or Eglot + ada-mode, or the LSP-mode package?

I’m not sure if the indentation is customizable nor have I tried those other combinations you listed.

:+1: Okay, well, i might look into this myself, if i can find some space to do so, unless you end up getting there first. :slightly_smiling_face:

I wonder what build method you used? I just tried with Alire, and (modulo battles between Apple’s git and the “inverted monorepo” which holds the ada-mode source) it seemed OK.

Getting some extra pressure on this would help.

I set indentation to 3 spaces, but for some reason it won’t handle continuation indentation at 2 spaces, as per style guide.

I wonder what build method you used? I just tried with Alire, and (modulo battles between Apple’s git and the “inverted monorepo” which holds the ada-mode source) it seemed OK.

For the purposes of the wiki page, i didn’t use Alire, but the procedure i documented on the wiki page, under “Installation”, “Configuration”, and “Emacs setup”. Although i did put in a note about the end of GNAT Community releases and the transition to Alire, i can imagine a number of Gentoo users not wanting an entire GCC-based toolchain outside of Portage, possibly duplicating at least some things already installed (or installable) via Portage, and not configurable or maintainable through all the standard Portage mechanisms.

Go to the link I posted above.

Go to the link I posted above.

When i wrote my previous post, it was ~3am local, and i was merely out of bed briefly; i took a quick look, but decided to not post further here until after i’d slept. Now that i have, and it’s ~9am:

Yes, it seems to me - at least as someone new to the Ada ecosystem - that resolving that bug would be helpful for Gentoo Ada users. i can certainly add my voice to that bug - and i’ll try to do so later today - although i’m not a Gentoo dev myself, and i also don’t know how much time and space the members of the Ada Project team currently have.

More generally, i’m getting the impression there might be a developing tension between Linux distros and Alire regarding control and management of the Ada toolchain on the system. Am i correct to say that, even if the referenced bug is resolved, using Alire on Gentoo will still result in Alire pulling in its own copy of the Ada toolchain, regardless of what’s already on the system?

No, alire can use an already installed gnat and gprbuild.

alire can use an already installed gnat and gprbuild.

Ah okay, good! i’ll have to take a closer look then, so that i can wiki-document how to combine use of Alire with a Portage-based toolchain. (And, suggestions as to how i could improve the wiki page are welcome!)

I would start by putting pressure on getting them to add bootstraps for Ada and getting that patch accepted and then removing the old gnat-gpl stuff.

For those interested, i’ve added a comment to that Gentoo bug here.

1 Like

It’s a pity that an Emacs user like you or Tsoding cannot use Ada in your editor. Since there’s Ada code to compile to make the ada-mode work, it is not so easy to install as other pure Elisp packages. Nevertheless, installing the last version for me was mostly straightforward using Alire.

I wanted to try it again from scratch (clean user account) to see which are the rough points, and it failed indeed. The problem is the same already analyzed here: Gprconfig: can't find native toolchain for language 'ada' - #7 by nerd_type

So I’ll write there about this problem.

Hi, I recall the issues I ran into was that the scripts did not work on Windows but worked on Linux. In addition, I think there was a dependency missing (eglot??) which was not obvious. The added step of needing to compile also wasn’t ideal. I am wondering if the recent AppImage creation crate that was recently posted can help avoid the need to compile on Linux, and instead be a simple binary download.

I just tried to install ada-mode 8.1.0 on my Linux box and used Alire 2.0 to build it. It seems to work overall. However, I did run into an issue where a specific line cause the rest of the file to fail to indent properly and there were CONSTRAINT or STORAGE_ERROR exceptions reported which prevented any auto indentation from that point on. Other than that, it seems to work in my small tests.

I haven’t tried installing on Windows though

Eglot support is optional, so not a real problem, in fact.

The AppImage could make things easier under Linux, indeed.

I had the problem about the CONSTRAINT_ERROR in sal. It was discussed in the users mailing list. I think using GNAT 12 as suggested worked for me.

If this can be confirmed, the alire.toml file should state that dependency. It’s currently saying this:

gnat = "(>=11 & <2000) | >=2021"

Maybe we should try to support ada-mode in a community way, until someone volunteers to maintain it more seriously.

There’s also ada-light-mode. I haven’t tested it.

Edit: oh, and we also have old-ada-mode and ada-ts-mode, so I guess there’s a real problem here and different people trying to fix it in different ways.

I built ada-mode using GNAT 13.2.1. Now that you mention it, the CONSTRAINT_ERROR was generated from SAL.

Huh, did not know there are more alternative ada-mode choices

[ Previously incorrectly posted in wrong thread. ]

Finally getting around to trying to use Alire to build ada-mode infrastructure. This is on my Gentoo system, with alr 2.0:

$ ./build.sh
alr is /home/alexis/.local/bin/alr
building ada-mode executables via Alire
warn: Spent 0.14 seconds exploring complete solutions                    
warn:                                                                
warn:    New solution is incomplete.
warn:    +        emacs_wisi          4.3.2   (new)
warn:    +📦      gnat                13.2.1  (new,gnat_native,binary)
warn:    +        gnatcoll            22.0.0  (new,indirect)
warn:    +        libgpr              22.0.0  (new,indirect)
warn:    +        stephes_ada_library 3.7.3   (new)
warn:    +        wisitoken           4.2.1   (new)
warn:    +        xmlada              22.0.0  (new,indirect)
warn:    Missing:
warn:    +❗      re2c                >=2.0.3 (new,missing)
warn: 
warn: Could not find a complete solution for emacs_ada_mode=8.1.0
Build will fail unless externals are made available, do you want to continue?
[Y] Yes  [N] No  (default is No) no

But re2c 2.2 is installed:

$ eix re2c
[I] dev-util/re2c (2.2@13/06/23): Tool for generating C-based recognizers from regular expressions

with the specific files installed by that package being:

$ equery f re2c
 * Searching for re2c ...
 * Contents of dev-util/re2c-2.2:
/usr
/usr/bin
/usr/bin/re2c
/usr/bin/re2go
/usr/share
/usr/share/doc
/usr/share/doc/re2c-2.2
/usr/share/doc/re2c-2.2/CHANGELOG.bz2
/usr/share/doc/re2c-2.2/README.md.bz2
/usr/share/doc/re2c-2.2/examples
/usr/share/doc/re2c-2.2/examples/c
/usr/share/doc/re2c-2.2/examples/c/01_basic.c
/usr/share/doc/re2c-2.2/examples/c/01_basic.re
/usr/share/doc/re2c-2.2/examples/c/__run_all.sh
/usr/share/doc/re2c-2.2/examples/c/conditions
/usr/share/doc/re2c-2.2/examples/c/conditions/parse_u32_blocks.c
/usr/share/doc/re2c-2.2/examples/c/conditions/parse_u32_blocks.re
/usr/share/doc/re2c-2.2/examples/c/conditions/parse_u32_conditions.c
/usr/share/doc/re2c-2.2/examples/c/conditions/parse_u32_conditions.re
/usr/share/doc/re2c-2.2/examples/c/encodings
/usr/share/doc/re2c-2.2/examples/c/encodings/unicode_identifier.c
/usr/share/doc/re2c-2.2/examples/c/encodings/unicode_identifier.re
/usr/share/doc/re2c-2.2/examples/c/eof
/usr/share/doc/re2c-2.2/examples/c/eof/01_sentinel.c
/usr/share/doc/re2c-2.2/examples/c/eof/01_sentinel.re
/usr/share/doc/re2c-2.2/examples/c/eof/02_bounds_checking.c
/usr/share/doc/re2c-2.2/examples/c/eof/02_bounds_checking.re
/usr/share/doc/re2c-2.2/examples/c/eof/03_eof_rule.c
/usr/share/doc/re2c-2.2/examples/c/eof/03_eof_rule.re
/usr/share/doc/re2c-2.2/examples/c/eof/04_generic_api_sentinel.c
/usr/share/doc/re2c-2.2/examples/c/eof/04_generic_api_sentinel.re
/usr/share/doc/re2c-2.2/examples/c/eof/05_generic_api_eof_rule.c
/usr/share/doc/re2c-2.2/examples/c/eof/05_generic_api_eof_rule.re
/usr/share/doc/re2c-2.2/examples/c/fill
/usr/share/doc/re2c-2.2/examples/c/fill/01_fill.c
/usr/share/doc/re2c-2.2/examples/c/fill/01_fill.re
/usr/share/doc/re2c-2.2/examples/c/fill/02_fill.c
/usr/share/doc/re2c-2.2/examples/c/fill/02_fill.re
/usr/share/doc/re2c-2.2/examples/c/generic_api
/usr/share/doc/re2c-2.2/examples/c/generic_api/ifstream.c
/usr/share/doc/re2c-2.2/examples/c/generic_api/ifstream.re
/usr/share/doc/re2c-2.2/examples/c/headers
/usr/share/doc/re2c-2.2/examples/c/headers/header.c
/usr/share/doc/re2c-2.2/examples/c/headers/header.re
/usr/share/doc/re2c-2.2/examples/c/headers/src
/usr/share/doc/re2c-2.2/examples/c/headers/src/lexer
/usr/share/doc/re2c-2.2/examples/c/headers/src/lexer/lexer.h
/usr/share/doc/re2c-2.2/examples/c/includes
/usr/share/doc/re2c-2.2/examples/c/includes/definitions.h
/usr/share/doc/re2c-2.2/examples/c/includes/extra_rules.re.inc
/usr/share/doc/re2c-2.2/examples/c/includes/include.c
/usr/share/doc/re2c-2.2/examples/c/includes/include.re
/usr/share/doc/re2c-2.2/examples/c/real_world
/usr/share/doc/re2c-2.2/examples/c/real_world/cxx98.c
/usr/share/doc/re2c-2.2/examples/c/real_world/cxx98.re
/usr/share/doc/re2c-2.2/examples/c/reuse
/usr/share/doc/re2c-2.2/examples/c/reuse/braille.c
/usr/share/doc/re2c-2.2/examples/c/reuse/braille.re
/usr/share/doc/re2c-2.2/examples/c/reuse/braille.ucs2.txt
/usr/share/doc/re2c-2.2/examples/c/reuse/braille.utf16.txt
/usr/share/doc/re2c-2.2/examples/c/reuse/braille.utf32.txt
/usr/share/doc/re2c-2.2/examples/c/reuse/braille.utf8.txt
/usr/share/doc/re2c-2.2/examples/c/reuse/reuse.c
/usr/share/doc/re2c-2.2/examples/c/reuse/reuse.re
/usr/share/doc/re2c-2.2/examples/c/reuse/usedir.c
/usr/share/doc/re2c-2.2/examples/c/reuse/usedir.re
/usr/share/doc/re2c-2.2/examples/c/state
/usr/share/doc/re2c-2.2/examples/c/state/push.c
/usr/share/doc/re2c-2.2/examples/c/state/push.re
/usr/share/doc/re2c-2.2/examples/c/submatch
/usr/share/doc/re2c-2.2/examples/c/submatch/01_stags.c
/usr/share/doc/re2c-2.2/examples/c/submatch/01_stags.re
/usr/share/doc/re2c-2.2/examples/c/submatch/01_stags_fill.c
/usr/share/doc/re2c-2.2/examples/c/submatch/01_stags_fill.re
/usr/share/doc/re2c-2.2/examples/c/submatch/02_mtags.c
/usr/share/doc/re2c-2.2/examples/c/submatch/02_mtags.re
/usr/share/doc/re2c-2.2/examples/c/submatch/03_posix.c
/usr/share/doc/re2c-2.2/examples/c/submatch/03_posix.re
/usr/share/doc/re2c-2.2/examples/c/submatch/http_rfc7230.c
/usr/share/doc/re2c-2.2/examples/c/submatch/http_rfc7230.re
/usr/share/doc/re2c-2.2/examples/c/submatch/parse_etc_passwd.c
/usr/share/doc/re2c-2.2/examples/c/submatch/parse_etc_passwd.re
/usr/share/doc/re2c-2.2/examples/c/submatch/parse_options.c
/usr/share/doc/re2c-2.2/examples/c/submatch/parse_options.re
/usr/share/doc/re2c-2.2/examples/c/submatch/parse_records.c
/usr/share/doc/re2c-2.2/examples/c/submatch/parse_records.re
/usr/share/doc/re2c-2.2/examples/c/submatch/uri_rfc3986.c
/usr/share/doc/re2c-2.2/examples/c/submatch/uri_rfc3986.re
/usr/share/doc/re2c-2.2/examples/go
/usr/share/doc/re2c-2.2/examples/go/01_basic.go
/usr/share/doc/re2c-2.2/examples/go/01_basic.re
/usr/share/doc/re2c-2.2/examples/go/__run_all.sh
/usr/share/doc/re2c-2.2/examples/go/conditions
/usr/share/doc/re2c-2.2/examples/go/conditions/parse_u32_blocks.go
/usr/share/doc/re2c-2.2/examples/go/conditions/parse_u32_blocks.re
/usr/share/doc/re2c-2.2/examples/go/conditions/parse_u32_conditions.go
/usr/share/doc/re2c-2.2/examples/go/conditions/parse_u32_conditions.re
/usr/share/doc/re2c-2.2/examples/go/encodings
/usr/share/doc/re2c-2.2/examples/go/encodings/unicode_identifier.go
/usr/share/doc/re2c-2.2/examples/go/encodings/unicode_identifier.re
/usr/share/doc/re2c-2.2/examples/go/eof
/usr/share/doc/re2c-2.2/examples/go/eof/01_sentinel.go
/usr/share/doc/re2c-2.2/examples/go/eof/01_sentinel.re
/usr/share/doc/re2c-2.2/examples/go/eof/02_bounds_checking.go
/usr/share/doc/re2c-2.2/examples/go/eof/02_bounds_checking.re
/usr/share/doc/re2c-2.2/examples/go/eof/03_eof_rule.go
/usr/share/doc/re2c-2.2/examples/go/eof/03_eof_rule.re
/usr/share/doc/re2c-2.2/examples/go/eof/04_generic_api_sentinel.go
/usr/share/doc/re2c-2.2/examples/go/eof/04_generic_api_sentinel.re
/usr/share/doc/re2c-2.2/examples/go/eof/05_generic_api_eof_rule.go
/usr/share/doc/re2c-2.2/examples/go/eof/05_generic_api_eof_rule.re
/usr/share/doc/re2c-2.2/examples/go/fill
/usr/share/doc/re2c-2.2/examples/go/fill/01_fill.go
/usr/share/doc/re2c-2.2/examples/go/fill/01_fill.re
/usr/share/doc/re2c-2.2/examples/go/fill/02_fill.go
/usr/share/doc/re2c-2.2/examples/go/fill/02_fill.re
/usr/share/doc/re2c-2.2/examples/go/headers
/usr/share/doc/re2c-2.2/examples/go/headers/header.go
/usr/share/doc/re2c-2.2/examples/go/headers/header.re
/usr/share/doc/re2c-2.2/examples/go/headers/src
/usr/share/doc/re2c-2.2/examples/go/headers/src/lexer
/usr/share/doc/re2c-2.2/examples/go/headers/src/lexer/lexer.go
/usr/share/doc/re2c-2.2/examples/go/includes
/usr/share/doc/re2c-2.2/examples/go/includes/definitions.go
/usr/share/doc/re2c-2.2/examples/go/includes/extra_rules.re.inc
/usr/share/doc/re2c-2.2/examples/go/includes/include.go
/usr/share/doc/re2c-2.2/examples/go/includes/include.re
/usr/share/doc/re2c-2.2/examples/go/reuse
/usr/share/doc/re2c-2.2/examples/go/reuse/reuse.go
/usr/share/doc/re2c-2.2/examples/go/reuse/reuse.re
/usr/share/doc/re2c-2.2/examples/go/reuse/usedir.go
/usr/share/doc/re2c-2.2/examples/go/reuse/usedir.re
/usr/share/doc/re2c-2.2/examples/go/state
/usr/share/doc/re2c-2.2/examples/go/state/push.go
/usr/share/doc/re2c-2.2/examples/go/state/push.re
/usr/share/doc/re2c-2.2/examples/go/submatch
/usr/share/doc/re2c-2.2/examples/go/submatch/01_stags.go
/usr/share/doc/re2c-2.2/examples/go/submatch/01_stags.re
/usr/share/doc/re2c-2.2/examples/go/submatch/01_stags_fill.go
/usr/share/doc/re2c-2.2/examples/go/submatch/01_stags_fill.re
/usr/share/doc/re2c-2.2/examples/go/submatch/02_mtags.go
/usr/share/doc/re2c-2.2/examples/go/submatch/02_mtags.re
/usr/share/doc/re2c-2.2/examples/go/submatch/03_posix.go
/usr/share/doc/re2c-2.2/examples/go/submatch/03_posix.re
/usr/share/man
/usr/share/man/man1
/usr/share/man/man1/re2c.1
/usr/share/man/man1/re2go.1
/usr/share/re2c
/usr/share/re2c/stdlib
/usr/share/re2c/stdlib/unicode_categories.re