lua-language-server
lua-language-server copied to clipboard
When workspace folders are specified, two workspaces are loaded.
https://github.com/sumneko/lua-language-server/blob/25acc18ff5ec25d5cf4a052dfba11c777847f86e/script/provider/provider.lua#L55
Shouldn't the fallback config only be loaded when #scope.folders == 0?
Related to #1089
Can be improved to lazyload
@carsakiller I once wrote a wiki explaining why there are multiple progress bars, but I can't find it now
I think that got combined into the Why is the Server Scanning the Wrong Folder? FAQ answer.
I don't really remember seeing a progress bar section, but I'll take a look through the history
I found this section from the old How-to-improve-startup-speed.md file. Is this what you are referring to?
Excerpt
多进度条/单文件模式|Multi progress bar/Single file mode
在阅读接下来的内容之前,请先看一下 https://github.com/sumneko/lua-language-server/wiki/Multi-workspace-supports
当你以单文件模式启动服务器时,服务器只会创建 <fallback> Scope,所有的Lua文件都在此处理。
当你以工作区模式启动服务器时,服务器实际上会创建2个Scope,一个是你的工作区,另一个则是 <fallback> 。当你打开一个不属于工作区的Lua文件时,该文件会被放置到 <fallback> 中,以免该文件的全局变量污染你的工作区环境。
由于我的开发环境是VSCode,而VSCode可以简单的为不同的工作区进行不同的设置,因此我做出了以下假设:
- 用户会给工作区单独设置
workspace.library,因为Lua的能力主要由宿主提供,而不同的工作区一般会对应不同的宿主 - 用户不会给全局设置
workspace.library,因为它的主要目的是快速的看一下某个环境未知/不需要环境的Lua代码。
但最近的用户反馈让我发现了一个问题,在非VSCode环境中用户不方便给每个工作区进行单独设置(虽然我也提供了 .luarc.json 的方式),很多人直接会在全局设置中设置 workspace.library,当 library 较大时导致了一些问题:
- 以单文件模式启动服务器时,启动速度会被 library 影响,导致你明明只是想快速的看一下某一段Lua代码,却需要等待漫长的加载时间。
- 以工作区模式启动服务器时,会看到多个进度条。如果
<fallback>只需要加载基础的Lua API通常可以在0.5秒内完成(进度条有0.5秒的显示延迟),这使得你不会看到<fallback>的加载进度条。但<fallback>受到 library 影响后也需要加载很多文件,这导致你会看到多个进度条。不过这不会影响实际的加载速度,因为同一个文件只会被加载一次。
介于这个情况,我在考虑添加一个默认开启的设置,使得 <fallback> 可以忽略 workspace.library 。
Please take a look before reading the following content: https://github.com/sumneko/lua-language-server/wiki/Multi-workspace-supports
When you start the server in single file mode, the server will only create a <fallback> scope, and all Lua files will be processed here.
When you start the server in workspace mode, the server will actually create two scopes, one is your workspace, and the other is the <fallback>. When you open a Lua file that does not belong to the workspace, the file will be placed in <fallback> to prevent the global variables of the file from polluting your workspace environment.
Since my development environment is VSCode, and VSCode can simply set different settings for different workspaces, I make the following assumptions:
- The user will set the
workspace.libraryseparately for workspaces, because Lua's capabilities are mainly provided by the host, and different workspaces generally correspond to different hosts. - The user will not set global
workspace.library, because its main purpose is to quickly look at the Lua code of an unknown/unnecessary environment.
However, I found a problem in the recent user feedback. In the non VSCode client, it is not convenient for users to set each workspace separately (although I provided .luarc.json), many people directly set workspace.library in the global setting, which causes some problems when the library is very large:
- When you start the server in single file mode, the startup speed will be affected by the library, so you just want to take a quick look at Lua code, but you need to wait for a long loading time.
- When you start the server in workspace mode, you will see multiple progress bars. If
<fallback>only needs to load the basic Lua API, it can usually be completed in 0.5 sec (the progress bar has a display delay of 0.5 sec), so you won't see the loading progress bar of<fallback>at all. But<fallback>also need to load many files after affecting by the library, which leads you to see multiple progress bars. Fortunately this will not affect the actual loading speed, because the same file will only be loaded once.
In this case, I'm considering adding a setting enabled by default, witch makes <fallback> ignore workspace.library.
It looks like I forgot to include the progress bar part. This could be its own FAQ question.
Yes
Added as a new FAQ question 🙂
Awesome, thank you for the FAQ :)
I'm looking to see how I can fix this in Neovim/lspconfig.
It seems that the fallback (single file) config still indexes all files in the rootDir.
But reading the FAQ, this is likely not a problem, since it will actually index every file only once?
But reading the FAQ, this is likely not a problem, since it will actually index every file only once?
Yes, but I can consider changing into lazy loading or loading in turn, try not to show multiple progress bars.
I'm looking to see how I can fix this in Neovim/lspconfig.
It seems that the fallback (single file) config still indexes all files in the rootDir.
My understanding is that lua-language-server sends two workspace/configuration requests to the LSP client: one with scopeUri being the workspace folder, and another with scopeUri being absent (or nil). The latter is for settings of the fallback scope. Unfortunately neovim's LSP implementation completely ignores scopeUri and responds with the same settings to both, and this is what causes lua-l-s to show two progress bars.
A possible workaround is to teach neovim to look at scopeUri:
local lspconfig = require 'lspconfig'
lspconfig.util.on_setup = lspconfig.util.add_hook_after(lspconfig.util.on_setup, function(config)
if config.name == 'lua_ls' then
-- workaround for nvim's incorrect handling of scopes in the workspace/configuration handler
-- https://github.com/folke/neodev.nvim/issues/41
-- https://github.com/LuaLS/lua-language-server/issues/1089
-- https://github.com/LuaLS/lua-language-server/issues/1596
config.handlers = vim.tbl_extend('error', {}, config.handlers)
config.handlers['workspace/configuration'] = function(...)
local _, result, ctx = ...
local client_id = ctx.client_id
local client = vim.lsp.get_client_by_id(client_id)
if client and client.workspace_folders and #client.workspace_folders then
if result.items and #result.items > 0 then
if not result.items[1].scopeUri then
return vim.tbl_map(function(_) return nil end, result.items)
end
end
end
return vim.lsp.handlers['workspace/configuration'](...)
end
end
end)
But yeah, if lua-l-s could optionally ignore workspace.library for the fallback scope if there's at least one workspace folder, that would greatly improve compatibility with non VS Code clients 🙂
But yeah, if lua-l-s could optionally ignore
workspace.libraryfor the fallback scope if there's at least one workspace folder, that would greatly improve compatibility with non VS Code clients 🙂
@liskin thank you for this workaround! In your opinion is this something we should apply for performance (or any other) reasons? Or is the only problem with the double loader the fact that the loader is shown twice in UI? as opposed to any actual performance impact?
@liskin thank you for this workaround!
I just updated the workaround to a better version that only overrides the handlers for lua_ls to avoid interfering with other language servers.
In your opinion is this something we should apply for performance (or any other) reasons? Or is the only problem with the double loader the fact that the loader is shown twice in UI? as opposed to any actual performance impact?
Hm, I just tested this and it seems that there isn't actually any performance difference. I wouldn't have expected that :-) So it's probably more of a confusion than an actual performance/behaviour issue.
I just added something based on this to neodev: https://github.com/folke/neodev.nvim/commit/c6be05aab078827e51aabdc64cc9fba7c06d27b7
But indeed it probably doesn't make a difference performance wise, since luals won't index files multiple times.
Either way, it will at least stop people reporting this issue for LazyVim, neodev etc....
@folke I still am having the problem with losing some of the global vim references after peeking a different file. I opened a new issue as requested here: https://github.com/folke/neodev.nvim/issues/178 (repeating this message here as I find it hard sometimes to find comments within commits which is where I pinged you a few minutes ago here: https://github.com/folke/neodev.nvim/commit/c6be05aab078827e51aabdc64cc9fba7c06d27b7#r137715953).
the same issue . I think this need to solve