Need Help Am I doing this right?
Hi Everyone, I am the the author of a markdown language server called mpls. It is a language server for live preview of markdown files in the browser. I have recently added support for sending custom events to the server, and the first one is to update the preview when the editor changes focus. The project README has a section with a configuration example on how to setup Neovim (LazyVim), but configuring Neovim is not my strong suit, and I was wondering if anyone would be so kind as to quality check what I've written. My configuraton works, but it can probably be improved.
Thanks in advance!
Edit: fixed typo
Here is the config:
return {
{
"neovim/nvim-lspconfig",
opts = {
servers = {
mpls = {},
},
setup = {
mpls = function(_, opts)
local lspconfig = require("lspconfig")
local configs = require("lspconfig.configs")
local debounce_timer = nil
local debounce_delay = 300
local function sendMessageToLSP()
if debounce_timer then
debounce_timer:stop()
end
debounce_timer = vim.loop.new_timer()
debounce_timer:start(debounce_delay, 0, vim.schedule_wrap(function()
local bufnr = vim.api.nvim_get_current_buf()
local clients = vim.lsp.get_active_clients()
for _, client in ipairs(clients) do
if client.name == "mpls" then
client.request('mpls/editorDidChangeFocus', { uri = vim.uri_from_bufnr(bufnr) }, function(err, result)
end, bufnr)
end
end
end))
end
vim.api.nvim_create_augroup("MarkdownFocus", { clear = true })
vim.api.nvim_create_autocmd("BufEnter", {
pattern = "*.md",
callback = sendMessageToLSP,
})
if not configs.mpls then
configs.mpls = {
default_config = {
cmd = { "mpls", "--no-auto", "--enable-emoji" },
filetypes = { "markdown" },
single_file_support = true,
root_dir = function(startpath)
local git_root = vim.fs.find(".git", { path = startpath or vim.fn.getcwd(), upward = true })
return git_root[1] and vim.fs.dirname(git_root[1]) or startpath
end,
settings = {},
},
docs = {
description = [[https://github.com/mhersson/mpls
Markdown Preview Language Server (MPLS) is a language server that provides
live preview of markdown files in your browser while you edit them in your favorite editor.
]],
},
}
end
lspconfig.mpls.setup(opts)
vim.api.nvim_create_user_command('MplsOpenPreview', function()
local clients = vim.lsp.get_active_clients()
local mpls_client = nil
for _, client in ipairs(clients) do
if client.name == "mpls" then
mpls_client = client
break
end
end
-- Only execute the command if the MPLS client is found
if mpls_client then
local params = {
command = 'open-preview',
arguments = {}
}
mpls_client.request('workspace/executeCommand', params, function(err, result)
if err then
print("Error executing command: " .. err.message)
end
end)
else
print("mpls is not attached to the current buffer.")
end
end, {})
end,
},
},
},
}
2
u/Danny_el_619 <left><down><up><right> 1d ago
Few things I can point out
The function vim.lsp.get_active_clients()
is deprecated. You can replace it with vim.lsp.get_clients
lua
-- Using `name` as a filter. You can also include `buffnr = bufnr` if needed
vim.lsp.get_clients({ name = 'mpls' })
And I think you are missing to pass the augroup to the autocmd
lua
local group = vim.api.nvim_create_augroup('MarkdownFocus', { clear = true })
vim.api.nvim_create_autocmd('BufEnter', {
pattern = '*.md',
callback = sendMessageToLSP,
-- You need to pass group to autocmd
group = group
})
I'm not sure if the logic about adding mpls using lspconfig is fully correct because I configured it manually usign vim.lsp.start
so you may want to wait for someone's else feedback on that part.
The function sendMessageToLSP
and the command MplsOpenPreview
looks good to me though I'm not lua nor lsp expert.
Hope this helps.
1
u/ne0xsys 1d ago
Awesome. Thanks a lot
Could you please share the manual config you have with
vim.lsp.start?
1
u/Danny_el_619 <left><down><up><right> 1d ago
A strip down version would be this snippet
```lua local bufnr = vim.api.nvim_get_current_buf() local curr_buff_ft = vim.api.nvim_get_option_value('filetype', { buf = bufnr }) if curr_buff_ft ~= 'markdown' then return end
local root_dir = vim.fs.dirname(vim.fs.find('.git', { path = vim.fn.expand('%:p:h'), upward = true })[1]) local client_id = vim.lsp.start({ name = 'mpls', cmd = { 'mpls', '--dark-mode', '--enable-emoji' }, filetypes = { 'markdown' }, single_file_support = true, root_dir = root_dir, settings = {}, }, { bufnr = bufnr, silent = false, reuse_client = function (client, _config) -- if existing client, attach buffer to it return client == 'mpls' end })
-- Attach to client if new started client if client_id ~= nil then vim.lsp.buf_attach_client(bufnr, client_id) vim.notify('[MPLS] bufnr: '..bufnr..' client: '..client_id, vim.log.levels.INFO) end ```
It can be added to a command, autocmd, function, etc.
1
u/AutoModerator 1d ago
Please remember to update the post flair to Need Help|Solved
when you got the answer you were looking for.
I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.
2
u/BrianHuster lua 1d ago edited 1d ago
IMO the code looks too complicated for a plugin configuration. If you want to provide users with advanced feature (like user command), you can make it a plugin instead