OmniSharp / omnisharp-roslyn

OmniSharp server (HTTP, STDIO) based on Roslyn workspaces
MIT License
1.77k stars 421 forks source link

Eglot mode silently fails on Emacs 29.1 (windows) #2589

Open johanvts opened 10 months ago

johanvts commented 10 months ago

I unzipped release v1.39.10 omnisharp-win-x64-net6.0.zip to a local path and specified the path in exec-path. eglot-server-programs is already configured to "omnisharp -lsp". One of two things happens when I launch eglot inside a C# file buffer:

  1. Eglot fails to launch with a 30second timeout warning
  2. Eglot appears to launch, but the events buffer is empty and no hints or completions appear. After a while an error is forced.

In both cases I eventually get an eglot events buffer with the content:

[stderr] 
[stderr] 
[stderr] nil
[stderr] nil
[stderr] Process EGLOT (Johan/(csharp-mode csharp-ts-mode)) stderr finished

When I trace-function eglot I see: "1 -> (eglot (csharp-mode csharp-ts-mode) (fsharp . "c:/Users/Johan/") eglot-lsp-server ("c:/Users/Johan/Downloads/omnisharp-win-x64/omnisharp.exe" "-lsp") "csharp" t)" first. The fsharp part makes me wonder if somehow my fsharp settings are messing something up? I'm starting in a file belonging to a new C# project just created via dotnet new but (project-current) returns (fsharp . "c:/Users/Johan/") and I'm not sure how to change that or if it even is part of the reason eglot fails. Any idea how to debug further or other hints appriciated. Thanks in advance.

mcb2003 commented 2 months ago

Also occurs on Linux (same symptoms)

johanvts commented 2 months ago

Hi @mcb2003 If I recall correctly this had something to do with how project.el finds it's projects and C# + F# not playing nicely together. I can't recreate the issue now but I have the following in my dotfiles which solved the issue for me. Hopefully it can also help you:

;; project-find-function supporting both C# and F#:

(defun dotnet-mode/find-sln-or-fsproj (dir-or-file)
  "Search for a solution or F# project file in any enclosing
folders relative to DIR-OR-FILE."
  (dotnet-mode-search-upwards (rx (0+ nonl) (or ".fsproj" ".sln" ".csproj") eol)
                              (file-name-directory dir-or-file)))

(defun dotnet-mode-search-upwards (regex dir)
  (when dir
    (or (car-safe (directory-files dir 'full regex))
        (dotnet-mode-search-upwards regex (dotnet-mode-parent-dir dir)))))

(defun dotnet-mode-parent-dir (dir)
  (let ((p (file-name-directory (directory-file-name dir))))
    (unless (equal p dir)
      p)))

;; Make project.el aware of dotnet projects
(defun dotnet-mode-project-root (dir)
  (when-let (project-file (dotnet-mode/find-sln-or-fsproj dir))
    (cons 'dotnet (file-name-directory project-file))))

(cl-defmethod project-roots ((project (head dotnet)))
  (list (cdr project)))

(add-hook 'project-find-functions #'dotnet-mode-project-root)