lsp-mode
lsp-mode copied to clipboard
Wrong server selected
Thank you for the bug report
- [X] I am using the latest version of
lsp-moderelated packages. - [X] I checked FAQ and Troubleshooting sections
- [X] You may also try reproduce the issue using clean environment using the following command:
M-x lsp-start-plain
Bug description
Every time I open a JS file lsp-mode selects vue-semantic-server. Even if I remove all emacs.d/ related files (.emacs, .init.el, etc.). There is some configure which is getting loaded somewhere. Where could it be?
Steps to reproduce
- Fresh emacs install
- M-x lsp-start-plain
- open a JS file.
Expected behavior
Open the JS files with ts-ls and not with vue-semantic-server
Which Language Server did you use?
lsp
OS
Linux
Error callstack
In lsp-log I have:
Command "vue-language-server --stdio" is present on the path.
Command "semgrep lsp" is not present on the path.
Command "deno lsp" is not present on the path.
Command "typescript-language-server --stdio" is present on the path.
Command "vue-language-server --stdio" is present on the path.
Command "semgrep lsp" is not present on the path.
Command "deno lsp" is not present on the path.
Command "typescript-language-server --stdio" is present on the path.
Found the following clients for /home/igor/geschichte/web/code/apis/apiatlantocracies/main.js: (server-id vue-semantic-server, priority 0), (server-id ts-ls, priority -2)
The following clients were selected based on priority: (server-id vue-semantic-server, priority 0)
### Anything else?
_No response_
I just came here to mention that I'm having a similar issue.
Given that I opened a graphql file instead of a TSX one when opening the project lsp mode suggested Graphql-lsp server (which is cool for the gql file), but whenever I open a tsx, it doesn't change the selected client, and I can't select it using +lsp/switch-client in doomemacs.
Try to configuring the variable lsp-enabled-clients.
Currently, that variable is empty, however, after manually installing the corresponding clients it apparently worked!
Experiencing the exact same problem as OP here. vue-semantic-server is taking precedence over any other server when opening a file, even non-js-related ones. I noticed it only happens in workspaces where the vue server was used at least once, workspaces where I've not used it work normally. Working in multiple php+vue+typescript projects has made this a very annoying issue.
I'm using emacs-lsp in Doom Emacs on macOS although I was able to replicate the problem in a new emacs installation.
I can switch to the correct server (and/or client, not sure about the correct term here) using +lsp/switch-client in Doom to continue working so it seems that the problem is on file opening only.
I'm having this issue in spacemacs.
Modifying lsp-enabled-clients is a silly solution. Whitelist all servers in order to blacklist one? I want to use vue-semantic-server in vue files. I must modify this variable every time I'm editing a vue app? What about when I'm working on a vue and react app simultaneously?
Is there no other way to manually switch an LSP client? I've been paging through google for about an hour and turned up nothing.
M-x add-dir-local-variable with enabled/disabled clients should work.
I'm also having this issue, but for phpactor and php-ls.
It seems as though the check to ensure that php-language-server exists is not called the first time lsp is run. The check runs as expected if I run lsp a second time.
Here's a snippet from my *lsp-log*:
... (semgrep and serenata are not on path, phpactor is) ...
Found the following clients for [file]: (server-id phpactor, priority -4), (server-id php-ls, priority -3)
The following clients were selected based on priority: (server-id php-ls, priority -3)
... (semgrep and serenata are not on path, phpactor is) ...
[home dir]/.composer/vendor/felixfbecker/language-server/bin/php-language-server.php is not present.
Found the following clients for [file]: (server-id phpactor, priority -4)
The following clients were selected based on priority: (server-id phpactor, priority -4)
Hi, I'm in the same situation here, my project has .vue files, .ts files and .js files, vue-semantic-server always takes over.
Not sure if add-dir-local-variable will be of any use, i have some .vue files in the same directory as others.
Is there a way to set the priority based on the file extension? I don't see why everything is sent to vue-semantic-server. IMO vue-semantic-server should only handle .vue files and nothing else...
I tried to fix this problem and find the code:
(defun lsp-volar--activate-p (filename &optional _)
"Check if the volar-language-server should be enabled base on FILENAME."
(if lsp-volar-take-over-mode
(or (or
(and (lsp-workspace-root) (lsp-volar--vue-project-p (lsp-workspace-root)))
(and (lsp-workspace-root) lsp-volar-activate-file (f-file-p (f-join (lsp-workspace-root) lsp-volar-activate-file))))
(or (or (string-match-p "\\.mjs\\|\\.[jt]sx?\\'" filename)
(and (derived-mode-p 'js-mode 'typescript-mode 'typescript-ts-mode)
(not (derived-mode-p 'json-mode))))
(string= (file-name-extension filename) "vue")))
(string= (file-name-extension filename) "vue")))
So, Try this
(setq lsp-volar-take-over-mode nil)
I'm in the same boat as @AlexanderSeto php-ls tries to starts before phpactor even though php-ls hasn't been installed at all. Then I get the following message:
Server php-ls:290/starting exited (check corresponding stderr buffer for details). Do you want to restart it? (y or no)
Choosing 'yes' starts phpactor on its place instead. Thankfully I found it is possible to black list it with the variable lsp-disabled-clients instead of using lsp-enabled-clients.
(setq lsp-disabled-clients '(php-ls))
Looks like the "Takeover Mode" has been deprecated in 2.0.0... This is honestly a huge mess to know what's suppose to be the proper "vue" lsp config...
Ok so after some digging.
Takeover Mode was an earlier approach where Volar's language server aimed to be the sole provider of language features for both .vue files and regular .ts/.js files within a Vue project.
Hybrid Mode is the current and recommended approach in Volar (v2 and onwards). It adopts a more collaborative strategy by integrating with the existing TypeScript language service.
In essence:
- Takeover Mode (Old): Volar tried to do everything for .vue and .ts/.js files.
- Hybrid Mode (New): Volar handles Vue-specific parts of .vue files and works with the TypeScript server (via a plugin) for all JavaScript/TypeScript code, both in .vue script blocks and regular .ts/.js files.
As lsp-mode still enable Takeover Mode by default. A proper way to configure lsp-mode with vue is to disable Takeover and enable Hybrid. Like so:
;; Doom emacs / config.el
(after! lsp-mode
(setq lsp-volar-take-over-mode nil)
(setq lsp-volar-hybrid-mode t))
Waiting for lsp-mode to be fixed by enabling the Hybrid Mode by default instead.
This ensure that lsp-volar is only loaded on .vue files.