Using LanguageServer.jl with eglot in emacs

That’s too bad. On my machine, it takes about a minute to get going and then is pretty much instantaneous with hover and completion after that. Strange that it can vary so much. I wish there was a good standalone testing rig/debugger for language servers; might have more luck in figuring out where the lag is coming from for you, but I’m not aware of any such project. :confused:

The server kept disconnecting and reconnecting also, I even increased the eglot-connect-timeout

Also, offtopic, do you know why variables don’t get syntax highlighted?

Ah. Ya. That will cause it to be slow since it loses its JIT cache each time the server is restarted. I haven’t been able to track down something reproducible for the restarts yet.

Couldn’t tell you; my theme is intentionally very minimal with coloring (only 3 colors), so not much is syntax highlighted on my end. Is your desire to have different highlighting for function symbols, and variable symbols not just at the point of definition but at the point of use? That would require julia-mode to understand the semantics of the code rather than just its syntax, which it certainly doesn’t right now.

On the other hand, if you simply would like a highlighted in e.g. the expression a = 5 that might be possible though I don’t know why it would be helpful.

EDIT: see also My custom theme fails to highlight the variable names · Issue #57 · JuliaEditorSupport/julia-emacs · GitHub

1 Like

Initially I was was just looking for this since Emacs default python-mode does it and I got used to it. But after reading this

I just remembered about Rainbow identifiers mode which does the trick.

I finally managed to get eglot + LanguageServer.jl working, thanks for sharing your config @non-Jedi .

I was wondering about the capabilities of eglot-help-at-point - when I call it on a function defined in the current project I am working on it shows me the function signature but not the docstring, while it seems to provide the docstring when I call it on some function from Base. Is that the expected behavior, or is something wrong with my config?

Nothing wrong with your config. You’re running into:

https://github.com/julia-vscode/LanguageServer.jl/issues/268

2 Likes

Thanks for pointing out the LanguageServer.jl issue!

Are you also experiencing the (relatively) frequent server disconnects and reconnects that were mentioned in a comment above?
If so, do you recall if you also encountered this when using lsp-mode? (I couldn’t get lsp-mode to work with Julia yet)
I wonder whether this is related to eglot or to the LanguageServer.jl side but I am not sure how to debug this (other than trying lsp-mode).

EDIT:
I should have read the other comments more carefully to understand how to debug this.
I just looked at the eglot stderr buffer, and there I see that all the crashes are happening when a textDocument/didChange request is sent to the server (seems that there were several issues in LangauageServer.jl related to this in the past). I also see that there is an issue non-Jedi opened in LangaugeServer.jl about the server crashing on a didSave request.

So I guess this means the problem is on the LangaugeServer.jl side.

lsp-julia should be super simple now, since it comes with all the julia package dependencies in the right versions and is on melpa now:

  • Install lsp-mode and lsp-julia from melpa.
  • If your julia executable is not in the PATH, point lsp-julia-command to the right julia execuatable.
  • Init lsp-mode in a julia-mode buffer (e.g. M-x lsp)
    The first run will take some seconds before it outputs anything
1 Like

Thanks for the instructions and for your contributions to those packages / spacemacs layer @gdkrmr .

I think I already got quite close to making it work (using the spacemacs layer with your contributions), it is just that I managed to get eglot working before lsp-mode. But I’ll get back to trying lsp-mode to check whether it is more stable on my machine.

Do you experience language server crashes when using lsp-mode?

LanguageServer.jl crashes sometimes. If you use lsp-mode you should see the error message in a dedicated buffer (don’t remember the exact name right now, something like *lsp-mode:julia std-err* and lsp-mode should ask you if you want to restart the server.

@orialb @gdkrmr if either of you could capture the stacktrace and the last message sent from the language server client (in the eglot events buffer for eglot, not sure where for lsp-mode) before the crash, I’d appreciate it. It hasn’t been crashing for me lately, so I can’t debug what’s going on at the moment. If it’s crashing on save, please reply to that github issue, and if it’s some other operation, please open a new a github issue and tag me.

Make sure you include in the issue which versions of relevant packages you’re using (LanguageServer.jl, SymbolServer.jl, etc.). Even better if you can include exact reproduction steps with a sample file.

I seem to be able to reproduce it quite consistently with eglot but the same issue doesn’t happen with lsp-mode (as far as I can tell).

I opened an issue in LangaugeServer.jl

1 Like

Opened a PR to fix the issue you filed. If you get a chance to try the PR and see if you still get crashes, that would be awesome.

https://github.com/julia-vscode/LanguageServer.jl/pull/405

2 Likes

Thanks a lot! I will give it a try at some point this week.

Thought I will update here that the fix from @non-Jedi solved the issue I was seeing, and it is now incorporated into the master branch of LanguageServer. Thanks for your fixes @non-Jedi !
As of now I am able to get LanguageServer + eglot running properly using LanguageServer#master SymbolServer#master (no need to pin the other dependencies). Also it seems that there are a lot of updates done at LanguageServer.jl so maybe soon it will not be even necessary to pin SymbolServer to master.

As for the lsp-mode vs. eglot question I managed to get both of them working (@gdkrmr was right it is quite smooth now to get lsp-mode working, thanks for your contributions to lsp-julia!). I decided to continue with eglot in the meantime.
The main reason is that with eglot I can get documentation / code completion of functions from other packages outside of Base which the current module is using while I could not get this information with lsp-mode (see also discussion in this issue ).
A possible reason to use lsp-mode instead would be that it is supposedly possible to make it work with TRAMP (haven’t tried), but I personally find the documentation/completion feature more important.

1 Like

Where did you read this? That sounds really cool, tramp was one of the big reasons for me to switch to emacs entirely!

2 Likes

Originally I saw someone mentioning it in some recent reddit discussion about eglot vs. lsp-mode, but it appears also in the lsp-mode README here.

You will have to have the language server running on the remote server, so I don’t know if it fits your use case. Also I don’t know if it will actually work with LanguageServer.jl, but worth trying.

1 Like

LanguageServer.jl eglot integration is now packaged up at https://github.com/non-Jedi/jleglot and I just created a pending PR to melpa at https://github.com/melpa/melpa/pull/6531. Hope it’s helpful to y’all. :slight_smile:

For anyone wondering how I ended up making sure the project was instantiated, I stole a page from the Revise playbook:

try
    @eval using LanguageServer
catch
    @warn "Unable to import LanguageServer. Instantiating project."
    Pkg.instantiate()
    @eval using LanguageServer
end#try
4 Likes

Thanks everyone for all that great work!

I’ll try it on my home computers.

At work, I have to use Windows. On Windows, the Emacs GUI with Julia has about 1 second of input lag per keystroke. Inside a Cygwin terminal, the lag is livable without the GUI (but still not snappy, like the GUI on Linux). Is this likely to work in that sort of environment?

Anyone also know how to set the executable path in Cygwin?
I’ve just been using emacs as an editor with nice keybindings, but I can’t launch the executable, and copy and paste also does not work well from terminal Emacs on Windows. While it is well integrated on Linux, Windows seems to keep a separate copy paste clipboard for Emacs, as well as a separate “what is highlighted”. Meaning anything copied with M/C + W cannot be pasted externally, and anything highlighted within Emacs (eg, using C+SPACE) cannot be copied with C + INSERT. I can point, click, and drag to copy with C+INSERT, but this does not respect Emacs formatting; it’ll copy line numbers, treat 1 line of text as cutting across all vertically oriented windows, etc.
The fact it isn’t ergonomic to copy/paste, nor can I run code directly within Emacs (I don’t know how / can’t set the executable path), means it is hard to run code within the editor.

Also, a more general emacs question: how does it decide how to split the screen?
I have a relatively square monitor, and emacs always defaults to splitting side by side (equivalent to C-x 3), while with ultra-wide monitors, it splits them one above the other (equivalent to C-x 2). So it seems to be using the screen resolution to always make the opposite choice of what I want.
How can I change this default behavior?

Have you tried the linux subsystem for windows?