Skip to content

cmake: install M2-language-server script#4453

Open
d-torrance wants to merge 3 commits into
Macaulay2:developmentfrom
d-torrance:lsp
Open

cmake: install M2-language-server script#4453
d-torrance wants to merge 3 commits into
Macaulay2:developmentfrom
d-torrance:lsp

Conversation

@d-torrance

Copy link
Copy Markdown
Member

I just installed M2 on my new MacBook and noticed that the language server script was missing!

The homebrew package uses the cmake build, and (as usual), I don't really understand cmake that well and didn't realize we needed an additional install() . I figured that just copying it to usr-dist like we do for the autotools build was sufficient. Nope!

AI Disclosure

Claude figured out what was missing and added the fix.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@mahrud mahrud left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I hadn't seen the this script. Aside from cmake conventions, I don't think this script is the right way to go because it doesn't work if M2 isn't on the path or if you have multiple M2's on different paths, e.g. if I'm running M2 from a build directory I might not want the M2-language-server from brew to be used.

I would suggest one two options:

  1. move this script to the Macaulay2/bin directory and adjust it like the M2 script to run the correct M2-binary or just call ./M2 in the same directory, then move the install call to bin/CMakeFiles.txt and remove the COPY call.
  2. better yet, add this invocation as an argument to M2, e.g. startup.m2 should parse --LSP and just run this, with no extra files involved.

@d-torrance

d-torrance commented Jun 20, 2026

Copy link
Copy Markdown
Member Author

Ooh, yeah, I like option 1. I'm hesitant about option 2. In particular, I foresee adding command-line options to M2-language-server soon and I'd rather not conflate them with M2's command-line options.

@d-torrance d-torrance marked this pull request as draft June 20, 2026 19:01
@mahrud

mahrud commented Jun 20, 2026

Copy link
Copy Markdown
Member

You could have a phase 0 check that if --LSP is present, option processing should stop and pass on to your script instead, similar to --silent which must be used like M2 --script blah.m2.

The M2-language-server script previously called a bare M2, so it relied
entirely on $PATH and broke when M2 wasn't on the path or when multiple
M2 installations existed. Resolve M2 relative to the script's own
location instead: an LSP client launches the server by path (typically
the absolute install path), and the M2 wrapper sits beside the script
in bindir, so $(dirname "$0")/M2 reliably finds the matching M2
regardless of $PATH or cwd.

Sibling resolution via $(dirname "$0") works whenever $0 contains a
slash, which covers the normal installed case. When no sibling M2 is
found -- e.g. running the script from the source directory
(packages/LanguageServer), or invoking it by bare name resolved through
PATH (where dirname yields ".") -- fall back to a bare M2 on PATH.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@d-torrance d-torrance marked this pull request as ready for review June 25, 2026 14:55
@d-torrance

Copy link
Copy Markdown
Member Author

I updated the script to check first for the existence of a "sibling" M2 in the same directory and then if it can't find one, fall back to just calling M2.

I decided to keep everything in the packages directory rather than bin to not spread things out too much and keep bin devoted to just the Macaulay2 binary.

I inadvertently added it when adding the language server. It must have snuck in from an earlier draft!
@mahrud

mahrud commented Jun 25, 2026

Copy link
Copy Markdown
Member

I would like the lines added to packages/CMakeFiles.txt in the previous PR to be removed. Further, since humans would not need to run M2-language-server directly, I don't want it to be on the path. For instance, I use M2- with different postfixes for different versions of M2 compiled on different branches and adding it to path unnecessarily pollutes autocompletion.

You can make this a separate debian package / brew formula which can be selectively installed.

@d-torrance

Copy link
Copy Markdown
Member Author

I thought I removed the stray newline?

I don't understand why this shouldn't be on the PATH. Even if humans won't run it directly, editors certainly will.

Comment on lines 256 to +261
file(COPY LanguageServer/M2-language-server
DESTINATION ${M2_DIST_PREFIX}/${M2_INSTALL_BINDIR})

install(PROGRAMS LanguageServer/M2-language-server
DESTINATION ${CMAKE_INSTALL_BINDIR}
COMPONENT ALL)

@mahrud mahrud Jun 26, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These lines should not be here. This file is for packages only.

I still think adding --language-server option in startup.m2 is the best option, but another alternative is adding a target under Macaulay2/editors/language-server. e.g. prism and generate-symbols.m2 interact with the Style package, but we don't write those targets in packages/CMakeFiles.txt just because Style is in this directory.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But the language server is a package... It's an unusual package in that it has an accompanying script and folks would rarely if ever ever load it by hand, but all the related code is here in the packages directory.

I'd rather avoid touching startup.m2. Keeping the script in the package's auxiliary directory keeps everything close together, and also doesn't require recompiling M2.

I think the comparison to prism actually supports the current proprosal. For prism, the build system targets live in the editors directory since that's where the source code is even though the files get installed alongside the packages. Same idea here -- the source code is in packages but we're installing it alongside the binary.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For prism, the build system targets live in the editors directory since that's where the source code is even though the files get installed alongside the packages.

The template is there but the file is generated by generateSymbols which lives in the Style package, so these two seem contradictory:

  • we should keep the script in the package's aux directory to keep things together
  • we should keep the script in the directory where it gets installed

Either move it to Macaulay2/bin if it needs to be installed on path next to M2 and M2-binary (the main file could live in bin and have a symlink from the aux directory), or to Macaulay2/editors/language-server and put the path in editor configuration.

@mahrud

mahrud commented Jun 26, 2026

Copy link
Copy Markdown
Member

I don't understand why this shouldn't be on the PATH. Even if humans won't run it directly, editors certainly will.

I believe libexec/Macaulay2/bin is meant for this purpose.

@d-torrance

Copy link
Copy Markdown
Member Author

I don't understand why this shouldn't be on the PATH. Even if humans won't run it directly, editors certainly will.

I believe libexec/Macaulay2/bin is meant for this purpose.

That's where binaries that M2 would call should live. A language server should be on PATH so an arbitrary editor can run it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants