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

Custom command name may not conform user command naming rules #3087

Open
blmarket opened this issue Mar 22, 2024 · 8 comments
Open

Custom command name may not conform user command naming rules #3087

blmarket opened this issue Mar 22, 2024 · 8 comments
Labels
bug Something isn't working

Comments

@blmarket
Copy link

blmarket commented Mar 22, 2024

Description

TLDR

I have a use case to register commands which is not actually user commands. In short, I wanna execute lsp.start_client without calling nvim_create_user_command.

Minimal reproduction

note that I have my own LSP implementation, which is a part of the issue.

vim.cmd('packadd nvim-lspconfig')

local lspconfig = require('lspconfig')
local configs = require('lspconfig.configs')
local util = require("lspconfig.util")

-- My own lsp server for markdown
if not configs.blah then
  configs.blah = {
    default_config = {
      cmd = { 'blahblah' },
      filetypes = { 'markdown' },
      single_file_support = true,
      commands = {
        ['my_app/command1'] = { function(args, client_info)
        end },
        ['my_app/command2'] = { function(args, client_info)
        end },
      }
    },
  }
end

lspconfig.blah.setup({})

-- Codelens actions include `my_app/command1` which will be handled by custom commands
vim.api.nvim_create_autocmd('LspAttach', {
  callback = function(_)
    vim.api.nvim_create_autocmd({'TextChanged', 'InsertLeave'}, {
      callback = function(_)
        vim.lsp.codelens.refresh()
      end
    })
    vim.lsp.codelens.refresh()
  end
})

The problem

With 0.9.5 it works fine, but with 0.10-dev it fails as it tries to register my_app/command1 as user command and fail because of the command name. I don't know why 0.9.5 is working fine though...

Context

I need a client-side integration to implement codelens action properly. (e.g. I'd like to use telescope to show the result etc...), and relying on this neovim lsp client impl. So those commands are only to be run by codelens actions, not by user commands. I'm also fine if there's another way to add such custom command handlers without breaking neovim's user command name rules.

@blmarket blmarket added the bug Something isn't working label Mar 22, 2024
@glepnir
Copy link
Member

glepnir commented Mar 22, 2024

use vim.lsp.start instead

@blmarket
Copy link
Author

blmarket commented Mar 22, 2024

use vim.lsp.start instead

Are there no LSP providing codelens with custom commands? Wondering this is something we can consider support in the future or never will be.

And other stuff I'm missing:

  • In order to run vim.lsp.start within lazy.nvim but without using nvim-lspconfig, I might need to create a plugin (unless I call the code from init.vim).
  • I need to setup my own filetype handler to run the LSP (e.g. I only want to run my LSP for markdown files)

@glepnir
Copy link
Member

glepnir commented Mar 22, 2024

actually lspconfig just wrapper of vim.lsp.start . i don't know lazy nvim. if you want create a server config with some custom you can just use vim.lsp.start.

@blmarket
Copy link
Author

Yeah I do need that wrapper part - at least autocmd to launch lsp. Just asking whether it's possible to disable nvim-lspconfig doing something with commands config.

@blmarket
Copy link
Author

Let me put it in this way - would you consider if I create a PR to skip registration of commands as user commands? like setting commands_created but maybe with different config name.

@glepnir
Copy link
Member

glepnir commented Mar 22, 2024

could you explain what's your custom commands do in codelens ?

@blmarket
Copy link
Author

blmarket commented Mar 22, 2024

could you explain what's your custom commands do in codelens ?

Not something standard LSP functionality. Here they are:

  1. LSP provides a sorted reference list with score, and client(nvim) show it for navigation.
  2. LSP provides a list of keywords, client use telescope to let user choose, and do keyword based search for the sections.

Just for reference, here is the real configuration:

commands = {
  ['lsp_md/searchSimilar'] = function(args, client_info)
    local client = vim.lsp.get_active_clients()[client_info.client_id]
    client.request('workspace/executeCommand',
      args,
      function(_, resp, ctx, _)
        local items = {}
        for _, it in ipairs(resp) do
          table.insert(items, {
            filename = vim.uri_to_fname(it.location.uri),
            lnum = it.location.range.start.line + 1,
            col = it.location.range.start.character + 1,
            text = string.format("%.3f: %s", it.score, it.title),
            user_data = it,
          })
        end
        vim.fn.setloclist(client_info.bufnr, {}, ' ', { title = "title", items = items, context = ctx })
        vim.api.nvim_command("lopen")
      end
    )
  end,
  ['lsp_md/keywords'] = function(args, client_info)
    local client = vim.lsp.get_active_clients()[client_info.client_id]
    client.request('workspace/executeCommand',
      args,
      function(_, resp, _, _)
        local items = {}
        for _, it in ipairs(resp) do
          table.insert(items, it) -- it has text and score
        end

        local opts = {}
        pickers.new(opts, {
          prompt_title = "Keywords",
          finder = finders.new_table {
            results = items,
            entry_maker = function(entry)
              return {
                value = entry,
                display = entry.text,
                ordinal = entry.score,
              }
            end,
          },
          sorter = conf.generic_sorter(opts),
          attach_mappings = function(prompt_bufnr, _)
            actions.select_default:replace(function()
              actions.close(prompt_bufnr)
              local selected = action_state.get_selected_entry()
              SearchByKeyword(selected.value.text)
            end)
            return true
          end,
        }):find()
      end
    )
  end
}

@blmarket
Copy link
Author

blmarket commented Mar 22, 2024

What I just realized is my commands is actually for https://neovim.io/doc/user/lsp.html#vim.lsp.ClientConfig struct, where nvim-lspconfig has its own definition of commands which is described at https://github.com/neovim/nvim-lspconfig/blob/master/doc/lspconfig.txt#L281

And seems I need a way to pass commands table as-is to the vim.lsp.start API. I'm wondering this is something we can create a PR to add, or no plan to fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants