Dalius's blog

Wednesday, June 5, 2024

Typescript and Neovim LSP 2024

Typescript development for Neovim is progressing. I found out that the only plugin that remained from the past is nvim-cmp.

You can find my vim configuration here: github.com/daliusd/cfg/blob/master/.vimrc

Configuration

I use following plugins:

Each plugin has detailed documentation so I will cover what might be different in my configuration.

nvim-lspconfig

While it is not strictly TS related but eslint via nvim-lspconfig is what I would recommend to use. No need to install eslint_d and extra plugins.

      require 'lspconfig'.eslint.setup({
        settings = {
          packageManager = 'yarn'
        },
        ---@diagnostic disable-next-line: unused-local
        on_attach = function(client, bufnr)
          vim.api.nvim_create_autocmd("BufWritePre", {
            buffer = bufnr,
            command = "EslintFixAll",
          })
        end,
      })

typescript-tools.nvim

This one might be good out of the box. I disabled formatting by tsserver as I do it using prettier. As well I have enabled jsx_close_tag as this works really well.

  {
    "pmizio/typescript-tools.nvim",
    dependencies = { "nvim-lua/plenary.nvim", "neovim/nvim-lspconfig" },
    opts = {},
    config = function()
      require("typescript-tools").setup {
        on_attach =
            function(client, bufnr)
              client.server_capabilities.documentFormattingProvider = false
              client.server_capabilities.documentRangeFormattingProvider = false
            end,
        settings = {
          jsx_close_tag = {
            enable = true,
            filetypes = { "javascriptreact", "typescriptreact" },
          }
        }
      }
    end
  },

hrsh7th/nvim-cmp

Configure this the way you want. I found out that onsails/lspkind.nvim can make autocomplete to look nicer.

stevearc/conform.nvim

I use this one together with prettierd for formatting my code. Maybe the only relevant thing is that I do enable it conditionally (only if prettier config file is found in path).

  {
    'stevearc/conform.nvim',
    config = function()
      require("conform").setup({
        formatters_by_ft = {
          html = { { "prettierd" } },
          javascript = { { "prettierd" } },
          javascriptreact = { { "prettierd" } },
          markdown = { { "prettierd" } },
          typescript = { { "prettierd" } },
          typescriptreact = { { "prettierd" } },
          ["*"] = { "trim_whitespace" },
        },
        format_on_save = {
          timeout_ms = 500,
          lsp_fallback = true,
        },
        formatters = {
          prettierd = {
            condition = function()
              return vim.loop.fs_realpath(".prettierrc.js") ~= nil or vim.loop.fs_realpath(".prettierrc.mjs") ~= nil
            end,
          },
        },
      })
    end,
  },