elixir-tools / elixir-tools.nvim

Neovim plugin for Elixir
MIT License
395 stars 29 forks source link

Performance tips? #185

Open igorgue opened 7 months ago

igorgue commented 7 months ago

Hi,

I wonder if anyone can help me make ElixirLS or NextLS perform faster on my very big project, ideally I would like to use ElixirLS only for autocomplete and NextLS for everything else. Here's my config (that works on LazyVim):

  {
    "elixir-tools/elixir-tools.nvim",
    dependencies = {
      "elixir-editors/vim-elixir",
      "nvim-lua/plenary.nvim",
    },
    ft = { "elixir", "eex", "heex", "surface" },
    -- stylua: ignore
    enabled = not vim.o.diff,
    config = function()
      local elixir = require("elixir")
      local elixirls = require("elixir.elixirls")

      local register_keys = function()
        local wk = require("which-key")
        local bufnr = vim.api.nvim_get_current_buf()

        wk.register({
          p = { "<cmd>ElixirToPipe<cr>", "To Pipe" },
          P = { "<cmd>ElixirFromPipe<cr>", "From Pipe" },
          m = { "<cmd>ElixirExpandMacro<cr>", "Expand Macro" },
          r = { "<cmd>ElixirRestart<cr>", "Restart" },
          o = { "<cmd>ElixirOutputPanel<cr>", "Output Panel" },
        }, {
          prefix = "<leader>cE",
          name = "+elixir",
          buffer = bufnr,
        })
      end

      vim.api.nvim_create_autocmd(
        "FileType",
        { pattern = { "elixir", "eex", "heex", "surface" }, callback = register_keys }
      )

      elixir.setup({
        nextls = {
          enable = true,
          -- {
          --   experimental = {
          --     completions = {
          --       enable = true,
          --     },
          --   },
          -- },
        },
        credo = { enable = false },
        elixirls = {
          enable = true,
          settings = {
            elixirls.settings({
              dialyzerEnabled = false,
              -- dialyzerFormat = "dialyxir_long",
              -- dialyzerWarnOpts = []
              enableTestLenses = false,
              -- envVariables =
              fetchDeps = false,
              -- languageServerOverridePath =
              mixEnv = "dev",
              -- mixTarget = "host",
              -- projectDir = "",
              signatureAfterComplete = false,
              suggestSpecs = false,
              log_level = vim.lsp.protocol.MessageType.Log,
              message_level = vim.lsp.protocol.MessageType.Log,
              trace = {
                server = "off",
              },
            }),
          },
        },
      })
    end,
  },

It's unbearably slow in my system (a 2021 16GB laptop), for some reason moving from insert mode to normal mode when ElixirLS is enabled is very slow, after save is understandable since mix itself is slow on big projects. Sometimes it also takes a fairly long time to open any file...

I'm on neovim NVIM v0.10.0-dev-582d7f4 but it's also very slow on NVIM v0.9.4

I also have treesitter disabled to help this work faster.

mhanberg commented 7 months ago

I don't think its possible to disable all ElixirLS features except for completion, so if you plan to use both, you will get double diagnostics.

or some reason moving from insert mode to normal mode when ElixirLS is enabled is very slow

this seems strange, and i would not expect this to happen. Can you reproduce with a clean config and only elixir-tools.nvim?

igorgue commented 7 months ago

@mhanberg I do this with my Python

  {
    "neovim/nvim-lspconfig",
    opts = {
      setup = {
        ruff_lsp = function()
          require("lazyvim.util").lsp.on_attach(function(client, _)
            if client.name == "ruff_lsp" then
              -- Disable hover in favor of pyright
              client.server_capabilities.hoverProvider = false
            end
          end)
        end,
      },
    },
  },

Is that the way I can disable the diagnostics only for elixirls?

I see if I can do the simple reproduction, but sadly this only happens in the project I work on when the file is over 500 lines of code in this big project I cannot share...

mhanberg commented 7 months ago

hmm, that might work actually. I originally thought you might want to disable the client capabilities, but that relies on the server respecting them. but if you trick neovim into thinking the server doesn't support them, that could work.

I see if I can do the simple reproduction, but sadly this only happens in the project I work on when the file is over 500 lines of code in this big project I cannot share...

this tends to be the case, and unfortunately if you can't reproduce it without sharing your code (not that i expect you to!), the chances of me being able to reproduce are low haha