+
Skip to content
Sebastian Lyng Johansen edited this page Aug 17, 2025 · 18 revisions

Tips and tricks

I ideally want this plugin to be pretty minimal, and mostly just a wrapper to start the roslyn server. I am not envisioning some big dev kit like vscode's plugin C# dev kit. I might add some custom handlers for the roslyn server, but I don't want to add everything.

This will be a wiki with some tips and tricks that I will probably update if there is some requests that I don't want to add to this plugin, but instead think the users can add to their config if they want this

Dotnet restore progress notifications

As part of a handler that is implemented in this plugin, the roslyn server will try to restore projects that needs restoring. By default, there are no notifications for this displayed. The reason for this is that there are currently no good way to display progress notifications in neovim. Instead, there are two autocmds fired for each progress event, and also for when it is finished. This can be utilized to integrate with fidget.nvim for example to show progress notifications.

local handles = {}

vim.api.nvim_create_autocmd("User", {
    pattern = "RoslynRestoreProgress",
    callback = function(ev)
        local token = ev.data.params[1]
        local handle = handles[token]
        if handle then
            handle:report({
                title = ev.data.params[2].state,
                message = ev.data.params[2].message,
            })
        else
            handles[token] = require("fidget.progress").handle.create({
                title = ev.data.params[2].state,
                message = ev.data.params[2].message,
                lsp_client = {
                    name = "roslyn",
                },
            })
        end
    end,
})

vim.api.nvim_create_autocmd("User", {
    pattern = "RoslynRestoreResult",
    callback = function(ev)
        local handle = handles[ev.data.token]
        handles[ev.data.token] = nil

        if handle then
            handle.message = ev.data.err and ev.data.err.message or "Restore completed"
            handle:finish()
        end
    end,
})

Diagnostic refresh

Currently, the diagnostics are a bit of a hack, and they might not always update correctly. However, it is possible to retrieve them as often as you would like with something like this:

vim.api.nvim_create_autocmd({ "InsertLeave" }, {
    pattern = "*",
    callback = function()
        local clients = vim.lsp.get_clients({ name = "roslyn" })
        if not clients or #clients == 0 then
            return
        end

        local client = assert(vim.lsp.get_client_by_id(ctx.client_id))
        local buffers = vim.lsp.get_buffers_by_client_id(ctx.client_id)
        for _, buf in ipairs(buffers) do
            local params = { textDocument = vim.lsp.util.make_text_document_params(buf) }
            client:request("textDocument/diagnostic", params, nil, buf)
        end
    end,
})

Just change the InsertLeave event to whichever events you would like

Remove unnecessary using directives

This is already provided with the code actions if you have the cursor over the using statements. I therefore will not add a special command for this. If you however want this, you could do something like this:

vim.api.nvim_create_user_command("CSFixUsings", function()
    local bufnr = vim.api.nvim_get_current_buf()

    local clients = vim.lsp.get_clients({ name = "roslyn" })
    if not clients or vim.tbl_isempty(clients) then
        vim.notify("Couldn't find client", vim.log.levels.ERROR, { title = "Roslyn" })
        return
    end

    local client = clients[1]
    local action = {
        kind = "quickfix",
        data = {
            CustomTags = { "RemoveUnnecessaryImports" },
            TextDocument = { uri = vim.uri_from_bufnr(bufnr) },
            CodeActionPath = { "Remove unnecessary usings" },
            Range = {
                ["start"] = { line = 0, character = 0 },
                ["end"] = { line = 0, character = 0 },
            },
            UniqueIdentifier = "Remove unnecessary usings",
        },
    }

    client:request("codeAction/resolve", action, function(err, resolved_action)
        if err then
            vim.notify("Fix using directives failed", vim.log.levels.ERROR, { title = "Roslyn" })
            return
        end
        vim.lsp.util.apply_workspace_edit(resolved_action.edit, client.offset_encoding)
    end)
end, { desc = "Remove unnecessary using directives" })

textDocument/_vs_onAutoInsert

Image

vim.api.nvim_create_autocmd("LspAttach", {
  callback = function(args)
    local client = vim.lsp.get_client_by_id(args.data.client_id)
    local bufnr = args.buf

    if client and (client.name == "roslyn" or client.name == "roslyn_ls") then
      vim.api.nvim_create_autocmd("InsertCharPre", {
        desc = "Roslyn: Trigger an auto insert on '/'.",
        buffer = bufnr,
        callback = function()
          local char = vim.v.char

          if char ~= "/" then
            return
          end

          local row, col = unpack(vim.api.nvim_win_get_cursor(0))
          row, col = row - 1, col + 1
          local uri = vim.uri_from_bufnr(bufnr)

          local params = {
            _vs_textDocument = { uri = uri },
            _vs_position = { line = row, character = col },
            _vs_ch = char,
            _vs_options = {
              tabSize = vim.bo[bufnr].tabstop,
              insertSpaces = vim.bo[bufnr].expandtab,
            },
          }

          -- NOTE: We should send textDocument/_vs_onAutoInsert request only after
          -- buffer has changed.
          vim.defer_fn(function()
            client:request(
              ---@diagnostic disable-next-line: param-type-mismatch
              "textDocument/_vs_onAutoInsert",
              params,
              function(err, result, _)
                if err or not result then
                  return
                end

                vim.snippet.expand(result._vs_textEdit.newText)
              end,
              bufnr
            )
          end, 1)
        end,
      })
    end
  end,
})
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载