After updating neovim to 0.81 and all plugins to latest release, autocmd to highlight words on cursor hold is not working on certain languages - neovim

I have an auto command highlight words on cursor hold and this autocmd gets attached to buffer when the LSP server has the capability of documentFormattingProvider.
After updating neovim to 0.81 and all the plugins and language servers. The behaviour of this autocmd is buggy.
on svelte files, it does not work and actually outputs error: method textDocument/documentHighlight is not supported by any of the servers registered for the current buffer (lsp:svelte)
on python, no highlighting, no errors, but running lua vim.lsp.buf.document_highlight() on cmd line while cursor on repetitive word, it does highlight (lsp:pyright,black)
on go, it is working! (lsp:gopls)
on typescript files, it is working (lsp:tsserver)
on dart it is working (lsp:dartls)
Here is my dotfiles
local function lsp_highlight_document(client)
-- Set autocommands conditional on server_capabilities
if client.server_capabilities.documentFormattingProvider then
vim.api.nvim_exec(
[[
augroup lsp_document_highlight
autocmd! * <buffer>
autocmd CursorHold <buffer> lua vim.lsp.buf.document_highlight()
autocmd CursorMoved <buffer> lua vim.lsp.buf.clear_references()
augroup END
]],
false
)
end
end
I also tried (also not working):
local function lsp_highlight_document(client)
-- Set autocommands conditional on server_capabilities
if client.server_capabilities.documentFormattingProvider then
vim.api.nvim_create_augroup("lsp_document_highlight", { clear = true })
vim.api.nvim_clear_autocmds({ buffer = bufnr, group = "lsp_document_highlight" })
vim.api.nvim_create_autocmd("CursorHold", {
callback = vim.lsp.buf.document_highlight,
buffer = bufnr,
group = "lsp_document_highlight",
desc = "Document Highlight",
})
vim.api.nvim_create_autocmd("CursorMoved", {
callback = vim.lsp.buf.clear_references,
buffer = bufnr,
group = "lsp_document_highlight",
desc = "Clear All the References",
})
end
end
Both of these functions gets called here
options.on_attach = function(client, bufnr)
if client.name == "tsserver" then
client.server_capabilities.documentFormattingProvider = true
end
if client.name == "sumneko_lua" then
client.server_capabilities.documentFormattingProvider = false
end
lsp_highlight_document(client)
lsp_keymaps(bufnr)
end
local capabilities = vim.lsp.protocol.make_client_capabilities()
local status_ok, cmp_nvim_lsp = pcall(require, "cmp_nvim_lsp")
if not status_ok then
return
end
options.capabilities = cmp_nvim_lsp.default_capabilities(capabilities)
return options
Prior to this update, it was working fine in every language. Not sure what is missing.

Here is my config, which works for pyright, pylsp, lua-language-server etc.:
local api = vim.api
local lsp = vim.lsp
if client.server_capabilities.documentHighlightProvider then
vim.cmd([[
hi! link LspReferenceRead Visual
hi! link LspReferenceText Visual
hi! link LspReferenceWrite Visual
]])
local gid = api.nvim_create_augroup("lsp_document_highlight", { clear = true })
api.nvim_create_autocmd("CursorHold" , {
group = gid,
buffer = bufnr,
callback = function ()
lsp.buf.document_highlight()
end
})
api.nvim_create_autocmd("CursorMoved" , {
group = gid,
buffer = bufnr,
callback = function ()
lsp.buf.clear_references()
end
})
end
Works well on nvim 0.8.1. Try it to see if it works. If it does not work, I think there is something wrong with your config, you need to dig deeper to find why.

Related

Migrating Filetype autocmd setting from vimscript to lua

I'm migrating my vimscript settings to lua, but hit a snag.
I got several of these type of autocmd settings which I don't have a clue how to migrate them
augroup py_fold_custom
autocmd!
autocmd FileType python setlocal foldmethod=indent
augroup END
augroup html_syntax_disable
autocmd!
autocmd Filetype html if getfsize(expand("%")) > 500000 | setlocal syntax=off | endif
augroup END
Can somebody help?
Good choice switching to neovim. I know how it feels overwhelming to translate these sort of commands. While most of my config has been converted, I have one huge monster vim script command that I've yet to be able to translate.
As with everything in neovim you have several options of how to convert these to lua.
First, using autocommands
local generalSettingsGroup = vim.api.nvim_create_augroup('General settings', { clear = true })
vim.api.nvim_create_autocmd('FileType', {
pattern = { '*.py' },
callback = function()
vim.opt.foldmethod = 'indent'
end,
group = generalSettingsGroup,
})
vim.api.nvim_create_autocmd('FileType', {
pattern = { '*.html' },
callback = function()
if vim.api.nvim_buf_line_count(0) > 500000 then
vim.bo.syntax = 'off'
end
end,
group = generalSettingsGroup,
})
But you could also use the ftplugin directory for things like this.
You can still use lua, and upon detection of these file types this code will be run by neovim just by being in this directory.
In a file in your config directory create ftplugin/python.lua with this in the file
vim.opt.foldmethod = 'indent'
And for the html one ftplugin/html.lua
if vim.api.nvim_buf_line_count(0) > 500000 then
vim.bo.syntax = 'off'
end
Those are the main ways that come to mind for me. I hope this helps!

Create a temporary, readonly buffer for test output

I want to create a Neovim plugin that automatically runs a test suite whenever a file is saved. Here's an overview:
If I save a Rust file, run cargo test
If there's not a buffer opened for the test output, automatically create the buffer
Mark that buffer as readonly
If I save another file, reuse the existing buffer
If the buffer is quit (e.g., :q), create a new buffer on the next test run
However, I'm currently facing three issues:
I cannot detect if when I quit the buffer
When the test output is longer than the buffer height, the buffer will not scroll down
When I want to quit Neovim, it asks me to save all these temporary buffers (which I don't want to do)
How can I resolve these issues? For reference, here's my code:
local buffer_number = -1
local function log(_, data)
if data then
vim.api.nvim_buf_set_lines(buffer_number, -1, -1, true, data)
end
end
local function open_buffer()
if buffer_number == -1 then
vim.api.nvim_command('botright vnew')
buffer_number = vim.api.nvim_get_current_buf()
end
end
local function autotest(pattern, command)
vim.api.nvim_create_autocmd("BufWritePost", {
group = vim.api.nvim_create_augroup("autotest", { clear = true }),
pattern = pattern,
callback = function()
open_buffer()
vim.api.nvim_buf_set_lines(buffer_number, 0, -1, true, {})
vim.fn.jobstart(command, {
stdout_buffered = true,
on_stdout = log,
on_stderr = log,
})
end
})
end
autotest("*.rs", { "cargo", "test" })
P.S. I know there are several existing plugins for testing. I'm creating my own because I want to learn how to write neovim plugins.
I gave it my best shot. I believe this addresses your questions and does what you're aiming to do.
local buffer_number = -1
local function log(_, data)
if data then
-- Make it temporarily writable so we don't have warnings.
vim.api.nvim_buf_set_option(buffer_number, "readonly", false)
-- Append the data.
vim.api.nvim_buf_set_lines(buffer_number, -1, -1, true, data)
-- Make readonly again.
vim.api.nvim_buf_set_option(buffer_number, "readonly", true)
-- Mark as not modified, otherwise you'll get an error when
-- attempting to exit vim.
vim.api.nvim_buf_set_option(buffer_number, "modified", false)
-- Get the window the buffer is in and set the cursor position to the bottom.
local buffer_window = vim.api.nvim_call_function("bufwinid", { buffer_number })
local buffer_line_count = vim.api.nvim_buf_line_count(buffer_number)
vim.api.nvim_win_set_cursor(buffer_window, { buffer_line_count, 0 })
end
end
local function open_buffer()
-- Get a boolean that tells us if the buffer number is visible anymore.
--
-- :help bufwinnr
local buffer_visible = vim.api.nvim_call_function("bufwinnr", { buffer_number }) ~= -1
if buffer_number == -1 or not buffer_visible then
-- Create a new buffer with the name "AUTOTEST_OUTPUT".
-- Same name will reuse the current buffer.
vim.api.nvim_command("botright vsplit AUTOTEST_OUTPUT")
-- Collect the buffer's number.
buffer_number = vim.api.nvim_get_current_buf()
-- Mark the buffer as readonly.
vim.opt_local.readonly = true
end
end
function autotest(pattern, command)
vim.api.nvim_create_autocmd("BufWritePost", {
pattern = pattern,
callback = function()
-- Open our buffer, if we need to.
open_buffer()
-- Clear the buffer's contents incase it has been used.
vim.api.nvim_buf_set_lines(buffer_number, 0, -1, true, {})
-- Run the command.
vim.fn.jobstart(command, {
stdout_buffered = true,
on_stdout = log,
on_stderr = log,
})
end
})
end
autotest("*.rs", { "cargo", "test" })
I added some comments to help explain each step but specifically for each of your problems:
I cannot detect if when I quit the buffer
Since you already have the buffer number, you can query to see if it's still visible. Just by using the same name when creating the new buffer we an reuse any existing ones.
When the test output is longer than the buffer height, the buffer will not scroll down
This was tricky, and I'm not sure if it's the best way, but I was able to query how many lines the buffer had and set the cursor of the buffer's window to the bottom.
When I want to quit Neovim, it asks me to save all these temporary buffers (which I don't want to do)
This is because the buffers are modified. Neovim by default doesn't want to make it easy to accidentally lose your work if you have active modifications. To get around that we can easily mark that it isn't modified!
Hope that helps.

Issue on attach_mappings with Telescope find_files picker

I try to create a function with the Neovim Telescope plugin and find_files builtin picker to list my configuration files (in ~/.config/nvim/lua directory). But I have an issue to use a specific mapping (here defined with CTRL-e) after selecting an entry via Telescope.
My lua/reload.lua file :
local M = {}
M.reload = function()
local opts = {
prompt_title = 'Configuration files',
cwd = '~/.config/nvim/lua',
attach_mappings = function(_, map)
local action_state = require('telescope.actions.state')
-- Adds a new map to ctrl+e.
map('i', '<C-e>', function(_)
local entry = action_state.get_selected_entry()
local name = get_module_name(entry.value)
print('Name = ' .. name)
return true
end,
}
-- call the builtin method to list files
require('telescope.builtin').find_files(opts)
end
return M
When I call reload method require('reload').reload(), the Telescope find_files picker is open correctly, I can select a file in the list but my CTRL-e mapping does not work => function to print selected filename not called.
Have some clue to help me ?
You will need to press ctr+e before selecting the item in the list.

How to send errors from Neovim LSP to ALE

ALE has an API for sending errors to it from other sources. I'm using this like shown below and it works for the first error. More specifically, if I make one edit that results in an LSP error, the error will be displayed by ALE in the location list. If I make any further keystrokes, the location list is emptied again.
I can also trigger this behavior if I disable LSP, load ALE, manually call ShowResults and then press any other key in insert mode.
My hypothesis is that ALEs linting in insert mode (per default) kicks in. If LSP is disabled and there are no linters registered for the current file type, it doesn't find any errors (obviously, there's nothing that could report any) and so it empties my location list again. So the steps are: open buffer without LSP, call ShowResults, location list opens, press i, press any key, location list is empty
Now I thought that it was because I wasn't implementing the full ALE API. So I added a hook (2nd snippet). I can verify that this hook is called and that it generates valid messages. If I keep the location list open I can even see all the expected errors flickering across the loclist. I can navigate to those errors with :lolder, but I don't know why ALE always adds another, empty location list, after the LSP is done doing its job.
Or maybe I'm doing something wrong here.
vim.lsp.handlers["textDocument/publishDiagnostics"] = function(_, _, params, client_id, _, config)
local uri = params.uri
local bufnr = vim.uri_to_bufnr(uri)
if not bufnr then
return
end
local diagnostics = params.diagnostics
if not diagnostics or vim.tbl_isempty(diagnostics) then
vim.fn['ale#other_source#ShowResults'](bufnr, "nvim-lsp", {})
return
end
-- Important so we can pull diagnostics from this table when ALE asks for
-- them
vim.lsp.diagnostic.save(diagnostics, bufnr, client_id)
local messages = {}
for _, event in ipairs(diagnostics) do
-- :h ale-localist-format
local msg = {}
msg.text = event.message
msg.lnum = event.range.start.line
msg.end_lnum = event.range["end"].line
msg.col = event.range.start.character
msg.end_col = event.range["end"].character
msg.bufnr = bufnr
msg.nr = event.severity
table.insert(messages, msg)
end
vim.fn['ale#other_source#ShowResults'](bufnr, "nvim-lsp", messages)
end
Second snippet which is called from the 'on_attach' function of the Neovim LSP
function ALEHook(bufnr)
vim.fn['ale#other_source#StartChecking'](bufnr, "nvim-lsp")
local diagnostics = vim.lsp.diagnostic.get(bufnr, client.id)
if not diagnostics or vim.tbl_isempty(diagnostics) then
vim.fn['ale#other_source#ShowResults'](bufnr, "nvim-lsp", {})
return
end
local messages = {}
for _, event in ipairs(diagnostics) do
local msg = {}
msg.text = event.message
msg.lnum = event.range.start.line
msg.end_lnum = event.range["end"].line
msg.col = event.range.start.character
msg.end_col = event.range["end"].character
msg.bufnr = bufnr
msg.nr = event.severity
table.insert(messages, msg)
end
vim.fn['ale#other_source#ShowResults'](bufnr, "nvim-lsp", messages)
end
api.nvim_command('augroup ALEHookLSP')
api.nvim_command('autocmd!')
api.nvim_command('autocmd User ALEWantResults call v:lua.ALEHook(g:ale_want_results_buffer)')
api.nvim_command('augroup END')

Blank windows with documentation examples of Gtk(0.17) (julia 1.1)

I got an issue with Gtk.
My code is compiling with no error, but only the windows with its title is appearing.
So I wondered if I made something wrong and tried some examples of the documentation (see below).
And it didn't worked either.
I updated the packages, rm, and add again, no error.
No error in compiling, nothing.
When I ask if the widgets are visible it is saying yes.
I saw that it could be a configuration problem of gtk but with no more explanation.
Thank you for your help !
using Gtk
ls = GtkListStore(String, Int, Bool, Bool)
push!(ls,("Peter",20,false,true))
push!(ls,("Paul",30,false,true))
push!(ls,("Mary",25,true,true))
insert!(ls, 2, ("Susanne",35,true,true))
rTxt = GtkCellRendererText()
rTog = GtkCellRendererToggle()
c1 = GtkTreeViewColumn("Name", rTxt, Dict([("text",0)]), sort_column_id=0)
c2 = GtkTreeViewColumn("Age", rTxt, Dict([("text",1)]), sort_column_id=1)
c3 = GtkTreeViewColumn("Female", rTog, Dict([("active",2)]), sort_column_id=2)
tmFiltered = GtkTreeModelFilter(ls)
GAccessor.visible_column(tmFiltered,3)
tv = GtkTreeView(GtkTreeModel(tmFiltered))
push!(tv, c1, c2, c3)
selection = GAccessor.selection(tv)
signal_connect(selection, "changed") do widget
if hasselection(selection)
currentIt = selected(selection)
println("Name: ", GtkTreeModel(tmFiltered)[currentIt,1],
" Age: ", GtkTreeModel(tmFiltered)[currentIt,1])
end
end
ent = GtkEntry()
signal_connect(ent, "changed") do widget
searchText = get_gtk_property(ent, :text, String)
for l=1:length(ls)
showMe = true
if length(searchText) > 0
showMe = showMe && occursin(lowercase(searchText), lowercase(ls[l,1]))
end
ls[l,4] = showMe
end
end
vbox = GtkBox(:v)
push!(vbox,ent,tv)
win = GtkWindow(vbox, "List View with Filter")
showall(win)
I tried it, but run as a file, your app closes so fast you do not see it display at all. This is covered in the Gtk.jl docs under "Non REPL Usage" ie running as a file, outside the julia REPL command line. Just replace showall(win) with:
condition = Condition()
endit(w) = notify(condition)
signal_connect(endit, win, :destroy)
showall(win)
wait(condition)
The app will then pass control to the internal Gtk runtime event loop and wait for the app to close. I was able to run your app and see the check boxes fine with this. If you cannot, you might have a problem with your local files.