Open TysonAndre opened 6 years ago
hey @TysonAndre i wanted to try this out. I've hardcoded the value of lsp-phan-language-server-command
for now just to see if I can get it working.
I am able to see that phan does indeed start up as a sub process, but I still get the following error:
File mode specification error: (lsp-timed-out-error)
Any ideas on what might be the issue? I assume you have been able to get this running?
Here is how I am using it:
(use-package lsp-mode :ensure t)
(defvar phan-project-location "/Users/tam/Code/test-app"
"The location of the project for phan to analyze. TODO
this needs to be dynamic somehow.")
(defvar lsp-phan-language-server-command
(list
"docker"
"run"
"-v" (concat phan-project-location ":/mnt/src")
"-v" "/Users/tam/Code/phan:/opt/phan"
"--rm"
"cloudflare/phan:edge"
"--daemonize-tcp-host" "0.0.0.0"
"--quick"
"--language-server-allow-missing-pcntl"
"--allow-polyfill-parser"
"--use-fallback-parser"
"--memory-limit" "1G"
"--language-server-enable-go-to-definition"
"--project-root-directory" "/mnt/src"
"--language-server-on-stdin"))
(use-package lsp-ui :ensure t)
(use-package lsp-phan)
(add-hook 'lsp-mode-hook 'lsp-ui-mode)
(add-hook 'php-mode-hook 'flycheck-mode)
(add-hook 'php-mode-hook 'lsp-mode)
(add-hook 'php-mode-hook #'lsp-phan-enable)
cloudflare/docker-phan is outdated, and I think it's still running 0.9.
I was able to get it working, but did not make any attempts to run it in docker.
-v
. The language server protocol is passing absolute paths (file:///absolute/path/to/), not relative paths.I'm assuming /Users/tam/Code/phan is Phan 1.x.
https://hub.docker.com/r/cloudflare/phan/tags/ https://github.com/cloudflare/docker-phan
It could be that the language server crashed. Does the docker run command work in batch mode (i.e. without the daemonize flags?)
Also, you can't use both --language-server-on-stdin
and --daemonize-tcp-host 0.0.0.0
- Those are two completely different transports (TCP and stdin) - Remove the --daemonize-tcp-host setting.
Emacs opens buffers with the errors reported by language servers. Those may tell you more about errors.
If you're going with stdin (the only method Phan supports), you also need -i
so that it can actually read the stdin from emacs. By default, docker run
doesn't read stdin.
# man docker-run
-i, --interactive=true|false
Keep STDIN open even if not attached. The default is false.
When set to true, keep stdin open even if not attached.
e.g.
» docker run alpine cat
# terminates without reading stdin
» docker run -i alpine cat
test
test
other line
other line
# the process can read from stdin
If you are going with TCP, you would have to manually patch lsp-phan to use lsp-define-tcp-client or something similar. See https://github.com/emacs-lsp/lsp-mode/blob/master/lsp-mode.el
; the only client defined in lsp-phan.el
(lsp-define-stdio-client lsp-phan "php"
'lsp-phan-get-root
(lsp-phan-get-language-server-command))
Also, you can use --language-server-allow-missing-pcntl
if pcntl is unavailable, if that was the only reason you needed docker.
» ./phan --extended-help|grep -i pcntl 1 ↵
--language-server-allow-missing-pcntl
Allow the fallback that doesn't use pcntl (New and experimental) to be used if the pcntl extension is not installed.
wow, thanks for the quick and detailed info @TysonAndre!
Based on your feedback I learned a few things, and also noticed that the version of phan I was using was my own checked out version that had some issues.
I was able to get it running (i think properly) without docker for now.
The only thing left is i still do not see feedback from the server, but it could be i am missing something else.
I see there is a buffer for stderr, is there a way I can view the other communication with the lsp-phan server? Such as what requests I am actually making, and what the responses are?
There's two ways
tee
stdin and stdout to files that you can inspect later.--language-server-verbose
may also help (Documented in ./phan --extended-help
). I'm not sure if emacs will render that or if it's of use:A rough example of the first one:
#!/bin/bash
# Put this in /path/to/phan-wrapper.sh and change your program
# to run /path/to/phan-wrapper.sh instead of phan
# "$@" will expand to the arguments passed to phan-wrapper.sh
tee /tmp/stdin-log | /path/to/phan/phan "$@" | tee /tmp/stdout-log
Well, that works pretty awesomely thanks!
You seem to have answers for everything so I'll just keep going:
It looks like I am making requests just fine to the server, but the responses after the first look like they are all null
:
Content-Type: application/vscode-jsonrpc; charset=utf8
Content-Length: 248
{"result":{"capabilities":{"textDocumentSync":{"openClose":true,"change":1,"willSave":null,"willSaveWaitUntil":null,"save":{"includeText":true}},"definitionProvider":true,"typeDefinitionProvider":true,"hoverProvider":false}},"id":1,"jsonrpc":"2.0"}Content-Type: application/vscode-jsonrpc; charset=utf8
Content-Length: 38
{"result":null,"id":2,"jsonrpc":"2.0"}Content-Type: application/vscode-jsonrpc; charset=utf8
Content-Length: 38
{"result":null,"id":3,"jsonrpc":"2.0"}Content-Type: application/vscode-jsonrpc; charset=utf8
Content-Length: 38
I generated .phan
by doing phan --init
.
Any ideas?
There are two types of communication in JSON-RPC: Requests and notifications.
Requests have id
s (e.g. "id":3
), and always require a response with the same id. This response's "result"
is null when Phan has nothing to respond with (e.g. didOpen).
Notifications don't have an id, and don't have a response
Make sure that the file you are editing exists on disk - Phan won't report errors for files that don't exist due to the way file listing is implemented
Make sure that the file you are editing exists in directory_list or file_list of .phan/config.php
, and is not excluded
Again, --language-server-verbose
may help with seeing what phan is doing
I had a typo in my path. It's working now, thanks for your help!
lsp-phan-*
have booleans and strings that can be set to modify the CLI settings.