Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Getting eglot to work with php-language-server #1

Closed
LeviHarman opened this issue May 14, 2018 · 16 comments
Closed

Getting eglot to work with php-language-server #1

LeviHarman opened this issue May 14, 2018 · 16 comments

Comments

@LeviHarman
Copy link

Is there any way to get eglot to work with other language servers? I'm interested in using https://github.com/felixfbecker/php-language-server and don't mind setting it up myself similar to how is described in lsp-mode.

@joaotavora
Copy link
Owner

joaotavora commented May 14, 2018

Is there any way to get eglot to work with other language servers?

Of course! At least that's Eglot's main point, to work with any language server.

Do you have php-language-server installed and ready to run in your project? If so then it's a matter of evaluating this tiny piece of elisp

(add-to-list 'eglot-server-programs 
  '(php-mode . ("php" "vendor/felixfbecker/language-server/bin/php-language-server.php")))

Then place yourself in a .php file and type M-x eglot. Report here if it works, and I can help you troubleshoot it. If everything goes OK, I can add that piece of elisp to eglot itself, so you won't have to have in your .emacs.

@joaotavora
Copy link
Owner

I have setup a minimal php environment and am trying to get this to work. I'm hitting a problem, but it shouldn't take me long to solve it, I believe...

@LeviHarman
Copy link
Author

Okay, I was trying it out myself and had a problem too. I tried it using XAMPP on windows, so I decided to try using msys2 instead and see if that will make it work.

Thanks a ton for helping me out. Sorry for not replying til now I wanted to bring good news so I wanted to try msys2

@joaotavora
Copy link
Owner

joaotavora commented May 14, 2018

I got it to work using a separately started server

$ cd path/to/your/project
$ php vendor/felixfbecker/language-server/bin/php-language-server.php --tcp-server=localhost:9009
DEBUG     Checking PHPLS_ALLOW_XDEBUG
DEBUG     The xdebug extension is not loaded
DEBUG     Server listening on localhost:9009

Then in Emacs, go to a php-mode file and type M-x eglot. In the prompt, enter localhost:9009.

image

For some reason that I will ask @felixfbecker about tomorrow, when starting with the normal stdio version, I get an error for the :initialize request that I don't get with the network version. This is it, for reference:

-32603: TypeError: Argument 2 passed to LanguageServer\LanguageServer::initialize() must be of the type string or null, integer given, called in /home/capitaomorte/Source/PhP/hello-world/vendor/felixfbecker/advanced-json-rpc/lib/Dispatcher.php on line 164 and defined in /home/capitaomorte/Source/PhP/hello-world/vendor/felixfbecker/language-server/src/LanguageServer.php:168
Stack trace:
#0 /home/capitaomorte/Source/PhP/hello-world/vendor/felixfbecker/advanced-json-rpc/lib/Dispatcher.php(164): LanguageServer\LanguageServer->initialize(Object(LanguageServer\Protocol\ClientCapabilities), 10335)
#1 /home/capitaomorte/Source/PhP/hello-world/vendor/felixfbecker/language-server/src/LanguageServer.php(131): AdvancedJsonRpc\Dispatcher->dispatch(Object(AdvancedJsonRpc\Request))
#2 [internal function]: LanguageServer\LanguageServer->LanguageServer\{closure}()
#3 /home/capitaomorte/Source/PhP/hello-world/vendor/sabre/event/lib/coroutine.php(64): Generator->valid()
#4 /home/capitaomorte/Source/PhP/hello-world/vendor/sabre/event/lib/coroutine.php(118): Sabre\Event\{closure}()
#5 /home/capitaomorte/Source/PhP/hello-world/vendor/felixfbecker/language-server/src/LanguageServer.php(154): Sabre\Event\coroutine(Object(Closure))
#6 /home/capitaomorte/Source/PhP/hello-world/vendor/sabre/event/lib/EmitterTrait.php(88): LanguageServer\LanguageServer->LanguageServer\{closure}(Object(LanguageServer\Protocol\Message))
#7 /home/capitaomorte/Source/PhP/hello-world/vendor/felixfbecker/language-server/src/ProtocolStreamReader.php(56): Sabre\Event\Emitter->emit('message', Array)
#8 /home/capitaomorte/Source/PhP/hello-world/vendor/sabre/event/lib/Loop/Loop.php(311): LanguageServer\ProtocolStreamReader->LanguageServer\{closure}()
#9 /home/capitaomorte/Source/PhP/hello-world/vendor/sabre/event/lib/Loop/Loop.php(233): Sabre\Event\Loop\Loop->runStreams(NULL)
#10 /home/capitaomorte/Source/PhP/hello-world/vendor/sabre/event/lib/Loop/Loop.php(194): Sabre\Event\Loop\Loop->tick(true)
#11 /home/capitaomorte/Source/PhP/hello-world/vendor/sabre/event/lib/Loop/functions.php(122): Sabre\Event\Loop\Loop->run()
#12 /home/capitaomorte/Source/PhP/hello-world/vendor/felixfbecker/language-server/bin/php-language-server.php(109): Sabre\Event\Loop\run()
#13 {main}

And this is what I passed it:

{
  "jsonrpc": "2.0",
  "id": 187,
  "method": "initialize",
  "params": {
    "processId": 10335,
    "capabilities": {
      "workspace": {
        "applyEdit": true,
        "workspaceEdit": {
          "documentChanges": false
        },
        "didChangeWatchesFiles": {
          "dynamicRegistration": true
        },
        "symbol": {
          "dynamicRegistration": false
        }
      },
      "textDocument": {
        "synchronization": {
          "dynamicRegistration": false,
          "willSave": true,
          "willSaveWaitUntil": true,
          "didSave": true
        },
        "completion": {
          "dynamicRegistration": false
        },
        "hover": {
          "dynamicRegistration": false
        },
        "signatureHelp": {
          "dynamicRegistration": false
        },
        "references": {
          "dynamicRegistration": false
        },
        "definition": {
          "dynamicRegistration": false
        },
        "documentSymbol": {
          "dynamicRegistration": false
        },
        "documentHighlight": {
          "dynamicRegistration": false
        },
        "rename": {
          "dynamicRegistration": false
        },
        "publishDiagnostics": {
          "relatedInformation": false
        }
      },
      "experimental": null
    },
    "rootUri": "file:///home/capitaomorte/Source/PhP/hello-world/",
    "initializationOptions": []
  }
}

@joaotavora joaotavora changed the title Getting eglot to work with other Language servers. Getting eglot to work with php-language-server May 14, 2018
@felixfbecker
Copy link

Weird, looks like it is passing the processId as the second parameter instead of the third. Sounds like a bug in https://github.com/felixfbecker/php-advanced-json-rpc. Maybe you can create a failing test case?

@joaotavora
Copy link
Owner

Maybe you can create a failing test case?

Isn't this it already? When that JSON is given as the first input, the failure happens.

@joaotavora
Copy link
Owner

Indeed if I pass null for the processId field, it works!

@joaotavora
Copy link
Owner

@felixfbecker So I also discovered that if you pass it the (deprecated) "rootPath" option, the bug doesn't happen. Because there's nothing wrong in doing so, I have amended eglot to also pass that field.

@LeviHarman Install felix's server according to the instructions and you should be good to go. Let me know if you run into any more problems.

@felixfbecker
Copy link

@joaotavora sorry, I was offering to assist in case you wanted to write a test and potentially a bug fix for the library. Unfortunately I currently don't have time to look into it.

@joaotavora
Copy link
Owner

joaotavora commented May 15, 2018 via email

@LeviHarman
Copy link
Author

LeviHarman commented May 16, 2018

Hi again. I'm getting a timeout problem. I am using the new version of eglot (I tried the one on melpa and cloning the repo here to try out afterwards.) with emacs 26.1.

I am not sure what is the cause right now. In the Warnings buffer I'm getting Warning (eglot): Brutally deleting existing process EGLOT server (~/php-mode)

I'm using Cygwin, since I couldn't build emacs 26.1 with MSYS2 .

P.S. I'd like to say thank you for eglot it is very nice of you to put your time into supporting lsp in emacs.

In *~ stderr* I'm getting

DEBUG     Checking PHPLS_ALLOW_XDEBUG
DEBUG     The xdebug extension is loaded (2.6.0)
DEBUG     No restart (PHPLS_ALLOW_XDEBUG=1)
DEBUG     Listening on STDIN

Process EGLOT server (~/php-mode) stderr finished

In EGLOT server (~/php-mode) events

I'm getting these messages

client-request (id:1):
(:jsonrpc "2.0" :id 1 :method :initialize :params
          (:processId 6644 :capabilities
                      (:workspace
                       (:applyEdit t :workspaceEdit
                                   (:documentChanges :json-false)
                                   :didChangeWatchesFiles
                                   (:dynamicRegistration t)
                                   :symbol
                                   (:dynamicRegistration :json-false))
                       :textDocument
                       (:synchronization
                        (:dynamicRegistration :json-false :willSave t :willSaveWaitUntil t :didSave t)
                        :completion
                        (:dynamicRegistration :json-false)
                        :hover
                        (:dynamicRegistration :json-false)
                        :signatureHelp
                        (:dynamicRegistration :json-false)
                        :references
                        (:dynamicRegistration :json-false)
                        :definition
                        (:dynamicRegistration :json-false)
                        :documentSymbol
                        (:dynamicRegistration :json-false)
                        :documentHighlight
                        (:dynamicRegistration :json-false)
                        :rename
                        (:dynamicRegistration :json-false)
                        :publishDiagnostics
                        (:relatedInformation :json-false))
                       :experimental nil)
                      :rootPath "~/" :rootUri "file:///cygdrive/c/home/" :initializationOptions
                      []))

client-request (id:2):
(:jsonrpc "2.0" :id 2 :method :shutdown :params nil)

:internal-message:
(:message "Process state changed" :change "killed\n")


----------b---y---e---b---y---e----------

@joaotavora
Copy link
Owner

@LeviHarman is your php executable a "cygwin-installed" php, or is it some other php? Check with M-x eval-expression RET (executable-find "php") RET and post the result here.

Then try selecting some part of some buffer, any buffer, and typing M-x shell-command-on-region RET cat RET. What happens?

Also, can you try first with the "host:port" solution as I described above?

I think the problem may lie in the fact that windows doesn't allow stdin/stdout communication the way unix-based operating system do. However, cygwin should emulate this if you work with cygwin-enabled programs (which can be a pain). I don't have access to a cygwin box right now to test.

The network approach is a common solution to this problem. Right now, it is slightly more complicated, since you have the extra step of starting a server, but I am working on ways to simplify that in eglot.el.

@joaotavora
Copy link
Owner

@LeviHarman let's continue this in #2. I finally tested on windows and fixed some serious problems that may have been causing your issues.

@LeviHarman
Copy link
Author

Okay @joaotavora, I'll continue there. I've been rebuilding emacs 26.1. I am getting a few warning which I'm trying to take care of but I should have the information you asked about by today probably in 12 hours since it takes a while to build on my PC.

@joaotavora
Copy link
Owner

joaotavora commented May 17, 2018

You might want to build from scratch, but if you just want to try the Emacs 26.1 Release Candidate 1 on Windows, you can get a pre-built one from here (64 bits) or here (32 bits)

@LeviHarman
Copy link
Author

I think I just got lucky and it's built now. I'll try those in a bit. Thank you. I'll post in issue #2 after I try out what you suggested yesterday.

bhankas pushed a commit to bhankas/emacs that referenced this issue Sep 18, 2022
Closes joaotavora/eglot#1. The problem in that issue is that php-language-server has a
bug when it's not passed it the deprecated ":rootPath" field. The bug
doesn't happen if the ":processId" field is also absent. Eglot was
triggering the bug, because it didn't pass ":rootPath", but there's
nothing wrong in doing so.

* README.md: Add php-language-server to the built-in list.

* eglot.el (eglot-server-programs): Add php-language-server.
(eglot--connect): Also pass (deprecated) rootPath.
bhankas pushed a commit to bhankas/emacs that referenced this issue Sep 19, 2022
Closes joaotavora/eglot#1. The problem in that issue is that php-language-server has a
bug when it's not passed it the deprecated ":rootPath" field. The bug
doesn't happen if the ":processId" field is also absent. Eglot was
triggering the bug, because it didn't pass ":rootPath", but there's
nothing wrong in doing so.

* README.md: Add php-language-server to the built-in list.

* eglot.el (eglot-server-programs): Add php-language-server.
(eglot--connect): Also pass (deprecated) rootPath.
bhankas pushed a commit to bhankas/emacs that referenced this issue Sep 19, 2022
Closes #1. The problem in that issue is that php-language-server has a
bug when it's not passed it the deprecated ":rootPath" field. The bug
doesn't happen if the ":processId" field is also absent. Eglot was
triggering the bug, because it didn't pass ":rootPath", but there's
nothing wrong in doing so.

* README.md: Add php-language-server to the built-in list.

* eglot.el (eglot-server-programs): Add php-language-server.
(eglot--connect): Also pass (deprecated) rootPath.

#1: joaotavora/eglot#1
jollaitbot pushed a commit to sailfishos-mirror/emacs that referenced this issue Oct 12, 2022
Closes joaotavora/eglot#1. The problem in that issue is that php-language-server has a
bug when it's not passed it the deprecated ":rootPath" field. The bug
doesn't happen if the ":processId" field is also absent. Eglot was
triggering the bug, because it didn't pass ":rootPath", but there's
nothing wrong in doing so.

* README.md: Add php-language-server to the built-in list.

* eglot.el (eglot-server-programs): Add php-language-server.
(eglot--connect): Also pass (deprecated) rootPath.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants