-
Notifications
You must be signed in to change notification settings - Fork 784
Incorrectly sets formatexpr #1131
Comments
Since you already commented on the PR, I imagine you're already aware, but this is default Neovim behavior as of neovim/neovim#19677. Given the way it's set up, I don't really think there's a way for us to opt out of this on our end, but it's pretty easy for users to disable it (the easiest option seems to be in an |
@jose-elias-alvarez Yeah, I'm aware. I'm just very confused on why it's enabling it for The |
That's strange - using your minimal config, running |
@jose-elias-alvarez Sorry, I totally messed up my minimal config. This should be able to reproduce: -- this template is borrowed from nvim-lspconfig
local on_windows = vim.loop.os_uname().version:match("Windows")
local function join_paths(...)
local path_sep = on_windows and "\\" or "/"
local result = table.concat({ ... }, path_sep)
return result
end
vim.g.loaded_remote_plugins = ""
vim.cmd([[set runtimepath=$VIMRUNTIME]])
local temp_dir = vim.loop.os_getenv("TEMP") or "/tmp"
vim.cmd("set packpath=" .. join_paths(temp_dir, "nvim", "site"))
local package_root = join_paths(temp_dir, "nvim", "site", "pack")
local install_path = join_paths(package_root, "packer", "start", "packer.nvim")
local compile_path = join_paths(install_path, "plugin", "packer_compiled.lua")
local null_ls_config = function()
local null_ls = require("null-ls")
-- add only what you need to reproduce your issue
null_ls.setup({
sources = {
null_ls.builtins.diagnostics.vale
},
debug = true,
})
end
local function load_plugins()
-- only add other plugins if they are necessary to reproduce the issue
require("packer").startup({
{
"wbthomason/packer.nvim",
{
"jose-elias-alvarez/null-ls.nvim",
requires = { "nvim-lua/plenary.nvim" },
config = null_ls_config,
},
},
config = {
package_root = package_root,
compile_path = compile_path,
},
})
end
if vim.fn.isdirectory(install_path) == 0 then
vim.fn.system({ "git", "clone", "https://github.com/wbthomason/packer.nvim", install_path })
load_plugins()
require("packer").sync()
else
load_plugins()
require("packer").sync()
end Just adding the |
I see, with this config I can replicate it. The basic issue is that null-ls declares all of its capabilities that it can potentially handle up front, even though its actual capabilities are dependent on which sources a user has actually registered and which sources can run on a given buffer. Since actual LSP servers don't behave this way, there isn't an ideal solution. A similar issue came up in #904, where I mention some potential candidates, but again, I think there's no perfect fix here, since even dynamic registration (which is part of the LSP specification) does not handle each buffer having different capabilities. I think Neovim setting these defaults is generally a good thing, and |
Can you clarify the solution here? I'm finding that |
@danjenson You need to set I went with the latter which you can see here: -- Use internal formatting for bindings like gq.
vim.api.nvim_create_autocmd('LspAttach', {
callback = function(args)
vim.bo[args.buf].formatexpr = nil
end,
}) |
I run into this issue as well and the work around I use is like this: local function is_null_ls_formatting_enabed(bufnr)
local file_type = api.nvim_buf_get_option(bufnr, "filetype")
local generators = require("null-ls.generators").get_available(
file_type,
require("null-ls.methods").internal.FORMATTING
)
return #generators > 0
end
-- In a function that's called in on_attach
function on_attach(client, bufnr)
if server_capabilities.documentFormattingProvider then
if
client.name == "null-ls" and is_null_ls_formatting_enabed(bufnr)
or client.name ~= "null-ls"
then
api.nvim_buf_set_option(bufnr, "formatexpr", "v:lua.vim.lsp.formatexpr()")
map("n", "<leader>gq", "<cmd>lua vim.lsp.buf.format({ async = true })<CR>", opts)
else
api.nvim_buf_set_option(bufnr, "formatexpr", "")
end
end
end |
This is due to default behavior introduced in Neovim v0.8 See: neovim/neovim#19677 jose-elias-alvarez/null-ls.nvim#1131
According to this comment, VSCodeVim/Vim#4523 (comment), |
So this might be the reason 'gq' can't format the comment correctly? |
Solved from the comments of [#1131](jose-elias-alvarez/null-ls.nvim#1131).
* refactor: move from lspinstaller to mason * feat: lsp formatting works alongside gqq - Solved from the comments of [#1131](jose-elias-alvarez/null-ls.nvim#1131). * chore: fill in cmp when traversing list * chore(nvim): add ruff as python diagnostic * feat(nvim): add zen-mode plugin * style(nvim): format file * chore: clean up keymaps * fix(keymap): move accept spelling to <C-M> from <C-L> * fix: spell accept did not work on <c-m>, setting to <c-s> * chore(lsp): add custom settings * chore: clean up old LSP setup * feat(nvim): add treesitter visual select * fix(globals): the mac uname -n has changed..?
@chuan137 yes, here was the fix I committed to my dotfiles to reënable |
In case it helps, here's my packer config to work around this issue use({
"jose-elias-alvarez/null-ls.nvim",
...
config = function()
require("null-ls").setup({
...
on_attach = function(client, bufnr)
vim.api.nvim_buf_set_option(bufnr, "formatexpr", "")
end
})
...
end,
}) |
See jose-elias-alvarez/null-ls.nvim#1131. Signed-off-by: ktsuda <[email protected]>
The issue is that null-ls always announce formatting capabilities and doesn't check if the builtin actually provides it or not. Setting the lines https://github.com/jose-elias-alvarez/null-ls.nvim/blob/main/lua/null-ls/rpc.lua#L33-L34 to false fixes the issue. So they should be set according to what the builtin provides ... |
unset keymap from LazyVim, and use a modified version of the workaround for null-ls to reset vim.bo.formatexpr when there is no formatting generator for the current buffer. Original comment: jose-elias-alvarez/null-ls.nvim#1131 (comment)
I hate to pile on with more "here's how I fixed it" (really, I do), but I think it's worth pointing out that @Furkanzmc's solution above is great because it only clears require("lazyvim.util").on_attach(function(client, buf)
if client.name == "null-ls" then
if not require("null-ls.generators").can_run(vim.bo[buf].filetype, require("null-ls.methods").lsp.FORMATTING) then
vim.bo[buf].formatexpr = nil
end
end
end) |
Can LSPs dynamically report whether they support formatting for the current file-type? If LSP-s can report capabilities dynamically based on what filetype you have open, then this is a null-ls issue and dynamic capability reporting based on filetype should be implemented IMHO. But I have a feeling this might be an LSP spec limitation. Looking at efm-languageserver they also report capabilities as a whole, not per filetype: https://github.com/mattn/efm-langserver/blob/34b8f5bf9c80a361c56245131fa23b197f94b293/langserver/handle_initialize.go#L51 So this really might be an LSP spec limitation (maybe the server does not get asked about capabilities on a file-by-file basis? 🤷 ) |
Yes, that’s what I tried to explain in this comment. Even with dynamic registration support, there is an inherent incompatibility between the spec and what null-ls is doing here, since there are no provisions for a language server that can theoretically handle any filetype but can only actually handle some based on arbitrary conditions. Without a VS Code-style API to for non-LSP request handling (which Neovim maintainers have clarified is not a goal of the project) it’s unlikely that there will ever be a perfect solution here. Since the discussion isn’t really going anywhere and several users have contributed good workarounds, I’m going to close this. |
FAQ
Issues
Neovim Version
NVIM v0.8.0-dev-1132-g37a71d1f28
Operating System
Arch Linux 5.19.10-arch1-1
Minimal config
-- this template is borrowed from nvim-lspconfig
local on_windows = vim.loop.os_uname().version:match("Windows")
local function join_paths(...)
local path_sep = on_windows and "\" or "/"
local result = table.concat({ ... }, path_sep)
return result
end
vim.g.loaded_remote_plugins = ""
vim.cmd([[set runtimepath=$VIMRUNTIME]])
local temp_dir = vim.loop.os_getenv("TEMP") or "/tmp"
vim.cmd("set packpath=" .. join_paths(temp_dir, "nvim", "site"))
local package_root = join_paths(temp_dir, "nvim", "site", "pack")
local install_path = join_paths(package_root, "packer", "start", "packer.nvim")
local compile_path = join_paths(install_path, "plugin", "packer_compiled.lua")
local null_ls_config = function()
local null_ls = require("null-ls")
-- add only what you need to reproduce your issue
null_ls.setup({
sources = {},
debug = true,
})
end
local function load_plugins()
-- only add other plugins if they are necessary to reproduce the issue
require("packer").startup({
{
"wbthomason/packer.nvim",
{
"jose-elias-alvarez/null-ls.nvim",
requires = { "nvim-lua/plenary.nvim" },
config = null_ls_config,
},
},
config = {
package_root = package_root,
compile_path = compile_path,
},
})
end
if vim.fn.isdirectory(install_path) == 0 then
vim.fn.system({ "git", "clone", "https://github.com/wbthomason/packer.nvim", install_path })
load_plugins()
require("packer").sync()
else
load_plugins()
require("packer").sync()
end
Steps to reproduce
null-ls
with the internal LSP.markdown
.:lua =vim.bo.formatexpr
Expected behavior
It should be set to
""
.Actual behavior
It is set to
v:lua.vim.lsp.formatexpr()
Debug log
[TRACE Thu 22 Sep 2022 01:36:51 PM CEST] ...site/pack/packer/opt/null-ls.nvim/lua/null-ls/client.lua:110: starting null-ls client
[TRACE Thu 22 Sep 2022 01:36:51 PM CEST] ...im/site/pack/packer/opt/null-ls.nvim/lua/null-ls/rpc.lua:123: received LSP request for method initialize
[TRACE Thu 22 Sep 2022 01:36:52 PM CEST] ...im/site/pack/packer/opt/null-ls.nvim/lua/null-ls/rpc.lua:148: received LSP notification for method initialized
[TRACE Thu 22 Sep 2022 01:36:52 PM CEST] ...im/site/pack/packer/opt/null-ls.nvim/lua/null-ls/rpc.lua:148: received LSP notification for method textDocument/didOpen
[TRACE Thu 22 Sep 2022 01:36:52 PM CEST] .../pack/packer/opt/null-ls.nvim/lua/null-ls/generators.lua:21: running generators for method NULL_LS_DIAGNOSTICS_ON_OPEN
[DEBUG Thu 22 Sep 2022 01:36:52 PM CEST] .../pack/packer/opt/null-ls.nvim/lua/null-ls/generators.lua:24: no generators available
[TRACE Thu 22 Sep 2022 01:36:53 PM CEST] ...im/site/pack/packer/opt/null-ls.nvim/lua/null-ls/rpc.lua:123: received LSP request for method shutdown
[TRACE Thu 22 Sep 2022 01:36:53 PM CEST] ...im/site/pack/packer/opt/null-ls.nvim/lua/null-ls/rpc.lua:148: received LSP notification for method exit
[TRACE Thu 22 Sep 2022 01:37:01 PM CEST] ...site/pack/packer/opt/null-ls.nvim/lua/null-ls/client.lua:110: starting null-ls client
[TRACE Thu 22 Sep 2022 01:37:01 PM CEST] ...im/site/pack/packer/opt/null-ls.nvim/lua/null-ls/rpc.lua:123: received LSP request for method initialize
[DEBUG Thu 22 Sep 2022 01:37:01 PM CEST] ...site/pack/packer/opt/null-ls.nvim/lua/null-ls/client.lua:165: unable to notify client for method textDocument/didOpen (client not active): {
textDocument = {
uri = "file:///home/sqve/notes/todo.md"
}
}
[TRACE Thu 22 Sep 2022 01:37:01 PM CEST] ...im/site/pack/packer/opt/null-ls.nvim/lua/null-ls/rpc.lua:148: received LSP notification for method initialized
[TRACE Thu 22 Sep 2022 01:37:01 PM CEST] ...im/site/pack/packer/opt/null-ls.nvim/lua/null-ls/rpc.lua:148: received LSP notification for method textDocument/didOpen
[TRACE Thu 22 Sep 2022 01:37:01 PM CEST] .../pack/packer/opt/null-ls.nvim/lua/null-ls/generators.lua:21: running generators for method NULL_LS_DIAGNOSTICS_ON_OPEN
Help
Yes, but I don't know how to start. I would need guidance
Implementation help
No response
Requirements
The text was updated successfully, but these errors were encountered: