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

Add volar #1223

Merged
merged 1 commit into from Sep 8, 2021
Merged

Add volar #1223

merged 1 commit into from Sep 8, 2021

Conversation

sethidden
Copy link
Contributor

@sethidden sethidden commented Sep 5, 2021

After the release of Vue 3 there arose a need of a new language server that suppors the new syntax.
We already have vuels in the repo (so that's the one that existed pre-Vue 3) and the new volarvuels I'm adding here that supports the new syntax.

https://github.com/johnsoncodehk/volar

https://github.com/johnsoncodehk/volar#communitys-language-client-implements - it's supported in many vim lsp configuration providing extensions, I'm just adding it also here :P

See vuejs/language-tools#441

Problems:

  • If this is merged we'll have vls, vuels and volarvuels which makes things even more confusing, since vuels is normally vls, but vls is taken by the V language server, so this repo uses vuels instead. But now we have volarvuels. AND there's also https://github.com/vuedx/languagetools/tree/main/packages/vue-languageservice which is a third language server for Vue Decided on just volar
  • It's actually crucial to pass serverPath. I'll need to look at angularls's code to detect it dynamically
  • Improve docs - I assume as long as the nvim set-rtp command from CONTRIBUTING.md has the word 'volar' I'm good. Since it's not modifying the CONFIG.md for me locally
  • bin_name uses volar-server, which I got from the AUR. Better wait for Expose @volar/server/out/index.js as executable in $NPM_PREFIX/bin  vuejs/language-tools#458 - fixed because newest alpha version exposes vue-server binary. Let's still wait for this to stabilize Volar's maitainer's words sound like it's gonna be a while until this changes
  • Run linters, right now it probably has lots of lint errors

@sethidden sethidden changed the title Add volar Add volarvuels Sep 5, 2021
@sethidden
Copy link
Contributor Author

Is the language server in this PR slow for anyone else? I open a .vue file and errors appear after around 12 seconds. Did I enable some resource-heavy options?

@sethidden sethidden changed the title Add volarvuels Add volar Sep 5, 2021
@johnsoncodehk
Copy link
Contributor

johnsoncodehk commented Sep 5, 2021

Is the language server in this PR slow for anyone else? I open a .vue file and errors appear after around 12 seconds. Did I enable some resource-heavy options?

Initialization time is proportional to your project scale, at least need a few seconds, Volar exchanges this for better runtime performance. vuejs/language-tools#455 can improve this problem.

@sethidden sethidden marked this pull request as ready for review September 6, 2021 17:39
local bin_name = 'volar-server'

-- https://github.com/johnsoncodehk/volar/blob/master/packages/shared/src/types.ts
local volar_init_options = {
Copy link
Contributor

@mjlbach mjlbach Sep 7, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do all of these options need to be explicitly set, or are these overriding defaults? General question, not just limited to this section.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, need explicitly set to enable these features. Otherwise features was disabled.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! If you could, since you are the expert, please let me know if anything needs to change in this PR regarding settings or init_options.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The options look good to me! And no need to specifically set false for unsupported features, it will just ignore if unsupported.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wanted to be explicit

local volar_settings = {
volar= {
codeLens= {
references = true,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mjlbach Regarding your comment above about "is it necessary to set those explicitly". init_options need to be explicit, but volar_settings contains some things that basically set some settings to their default value. Here I'm setting references to true, but it's already true by default: https://github.com/johnsoncodehk/volar/blob/26b36fb01a83a68c94fcedd06144041876a7ae69/package.json#L78

I assume you'd like a minimal config that overrides defeaults only when it's necessary to make the LS work with nvim?

On the other hand, I'm worried people won't know about the settings = {} prop in nvim_lsp.volar.setup{}, since most LSs use init_options

Copy link
Contributor Author

@sethidden sethidden Sep 7, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be ok to do something like

init_options = volar_init_options,
-- https://github.com/johnsoncodehk/volar/blob/master/package.json#L42
settings = {} 

?

Copy link
Contributor

@mjlbach mjlbach Sep 7, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would just use the package.json to autogenerate the documentation for these optiosn (see pyright or other servers, it's just one line with the url to the package.json). I find people get extremely confused when we duplicate default settings, so we should only override when nececssary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

86431d9

Done. I also changed the link to package.json in a later commit, since the previous one didn't have a "contributes" property

lua/lspconfig/volar.lua Outdated Show resolved Hide resolved
Do not run `vuels` and `volarvuels` at the same time.
To check which language servers are running, open a `.vue` file and run the `:LspInfo` command.
]],
default_config = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's in default_config should get automatically pulled during docgen, you can test locally but I think it's unnecessary here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked locally. Indeed it gets fetched :)

ce7a7e0

lua/lspconfig/volar.lua Outdated Show resolved Hide resolved
lua/lspconfig/volar.lua Outdated Show resolved Hide resolved
-- https://github.com/johnsoncodehk/volar/blob/master/packages/shared/src/types.ts
local volar_init_options = {
typescript = {
serverPath = get_typescript_server_path(vim.fn.getcwd()),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this vim.fn.getcwd seems brittle, should it not use rootdir? This can be done in on_new_config if necessary.

Copy link
Contributor Author

@sethidden sethidden Sep 7, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is inspired by

local default_probe_dir = get_probe_dir(vim.fn.getcwd())

Perhaps vim.fn.cwd() is warranted in case of angularls's probedir but weird for detecting typescript in this PR

I'll try to fix this with on_new_config, thanks :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done f170b0c

Copy link
Contributor Author

@sethidden sethidden Sep 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if intentionally not providing serverPath in init_options to Volar (eg in volar.setup{init_options={}} is a mistake. Anyhow, I preferred the user to get an error from Volar in that case rather than get some vague lua error about "index is nil".

Hence the if chain check

@johnsoncodehk
Copy link
Contributor

@mjlbach if possible, I hope we can split features to multiple language server, because the DX will be much better. Can nvim-lsp do that?

References:

@mjlbach
Copy link
Contributor

mjlbach commented Sep 7, 2021

Yes, but the API for doing it declaratively is a bit annoying, we basically have a hook after start_client to disable detected server capabilities inon_attach

@sethidden
Copy link
Contributor Author

sethidden commented Sep 8, 2021

Yes, but the API for doing it declaratively is a bit annoying, we basically have a hook after start_client to disable detected server capabilities inon_attach

Is there an example of this somewhere in the repo? I can't wrap my head around what that'd look like.

Do you mean that the implementation would need to:

  1. intercept settings that come to volar in on_attach (after requirelspconfig.volar.setup{})
  2. categorize capabilities and assign them to the 2-3 volar instances
  3. launch them by directly calling built-in vim.lsp methods - so bypassing the nvim-lspconfig abstraction layer

My first reflex when thinking about mapping these lines https://github.com/yaegassy/coc-volar/blob/master/src/index.ts#L82-L86 from the coc-volar implementation to nvim-lspconfig would be

configs['volar-server-1-api'] = {
  init_options = {languageFeatures = { --[[ all languageFeatures ]]--}}
}

configs['volar-server-2-document'] = {
  init_options = {documentFeatures = { --[[ all documentFeatures ]]--}}
}

but that feels naive and probably would add unnecesary entries to CONFIG.md

@mjlbach
Copy link
Contributor

mjlbach commented Sep 8, 2021

When you say "multiple language servers", do you mean mutiple instances of volar? That might be kind of challenging. I'd have to think about it a bit, as it's not something with explicitly support.

Hypothetically you could do something like (contrived example):

vim.lsp.volar.setup{
  on_attach = function(client)
    client.resolved_capabilities.document_formatting = true
  end;
}
vim.lsp.volar.setup{
  on_attach = function(client)
    client.resolved_capabilities.document_formatting = false
  end;
}

In the case of volar, you could just diable these in initOptions as well.

But that shouldn't work with our current autocommands. This isn't a very common pattern, but I'm not opposed to adding support for it.

@mjlbach
Copy link
Contributor

mjlbach commented Sep 8, 2021

Can you address lint/style lint/commit lint issues and then I'll merge? You can just run stylua in the base directory, and then interactive git rebase (or I'll do it for you)

@mergify mergify bot closed this Sep 8, 2021
@mergify
Copy link

mergify bot commented Sep 8, 2021

This pull request has been automatically closed by Mergify.

@mergify
Copy link

mergify bot commented Sep 8, 2021

CONFIG.md is auto-generated: edit the lua source file instead (and re-read the PR template).

@mjlbach mjlbach reopened this Sep 8, 2021
@mjlbach
Copy link
Contributor

mjlbach commented Sep 8, 2021

Seems like a bad rebase :)

@sethidden
Copy link
Contributor Author

@mjlbach do you mean "use git rebase --interactive to drop the merge commits because here we prefer rebases"? :P not sure if I understand correctly

@mjlbach
Copy link
Contributor

mjlbach commented Sep 8, 2021

No, I mean I want you to squash your commits and write a "conventional commits" style commit message haha.

@mjlbach mjlbach merged commit 64700bf into neovim:master Sep 8, 2021
@sethidden
Copy link
Contributor Author

sethidden commented Sep 8, 2021

Thanks for your supervision guys :)

@johnsoncodehk Can you take a look at #1223 (comment) ?

I understood that there should be multiple instances of volar that handle different features (eg. if you open htop/task manger you'd see 2-3 volar processes) - is this correct?

@johnsoncodehk
Copy link
Contributor

johnsoncodehk commented Sep 8, 2021

@johnsoncodehk Can you take a look at #1223 (comment) ?

If my understanding is correct, it means that we cannot simply configure it. We need to wait for nvim-lsp to improve its support.

I understood that there should be multiple instances of volar that handle different features (eg. if you open htop/task manger you'd see 2-3 volar processes) - is this correct?

Yes, it should have 3.

@mjlbach
Copy link
Contributor

mjlbach commented Sep 8, 2021

To clarify, it's an lspconfig limitation not a built-in client thing (they are separate, you don't need to use this repo to use the built-in client)

@sethidden
Copy link
Contributor Author

sethidden commented Oct 17, 2021

@mjlbach Regarding multiple language servers for volar, I came up with this:
vuejs/language-tools#606

Would you say it'd be acceptable to remove the current volar config and have the volar.lua file register three configurations - volar_doc, volar_api and volar_html? Then the user would need to call volar_doc.setup{}, volar_api.setup{}, volar_html.setup{} (if you forget to start one of them you'll get reduced functionality)

Or there could be 4 configs - volar, volar_api, volar_doc, volar_html (all under the same entry in the "supported LSs" in the README.md table)

Or I could just publish a separate neovim plugin that registers those configurations. Though this is suboptimal as I feel as Volar expects multiple LS to be default

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants