nvim-lua / kickstart.nvim

A launch point for your personal nvim configuration
MIT License
18.43k stars 20.56k forks source link

How to implement format on save #158

Closed ners10100100 closed 1 year ago

ners10100100 commented 1 year ago

Can anyone give me some advice on how to implement format on save with prettier and eslint for typescript?

jvthuijl commented 1 year ago

I use null-ls for this purpose. You could add the following lines in the require('packer').startup scope (e.g. on line 62) to automatically format the file on saving using prettier.

 use 'jose-elias-alvarez/null-ls.nvim'
  local null_ls = require("null-ls")
  local augroup = vim.api.nvim_create_augroup("LspFormatting", {})
  null_ls.setup({
    sources = {
       null_ls.builtins.formatting.prettier
    },
    -- you can reuse a shared lspconfig on_attach callback here
    on_attach = function(client, bufnr)
      if client.supports_method("textDocument/formatting") then
        vim.api.nvim_clear_autocmds({ group = augroup, buffer = bufnr })
        vim.api.nvim_create_autocmd("BufWritePre", {
          group = augroup,
          buffer = bufnr,
          callback = function()
            vim.lsp.buf.format({ bufnr = bufnr }) 
          end,
        })
      end
    end,
  })

See the BUILTINS for other options!

porfur commented 1 year ago

Total noob here but I have absolutely no idea how to get this to work.

jvthuijl commented 1 year ago

No worries. You can paste previous code on line 62 of the init.lua file. Save the file, and then type :PackerInstall. The null-ls package will then be installed. After restarting nvim, supported files will automatically be formatted using prettier.

porfur commented 1 year ago

Thanks. seems to work on a work project but not in the init.lua. do I have to install prettier globally for that to work?

Also this may not be the correct place to ask so please ignore but where does eslint fit in all this ?

vimode commented 1 year ago

@porfur

Thanks. seems to work on a work project but not in the init.lua.

The builtins work for specific file types. Check the info on prettier, its very well documented.

To enable formatting for lua filetype, add to the list of source from @jvthuijl's null-ls setup null_ls.builtins.formatting.stylua,

where does eslint fit in all this ?

Similarly you can add eslint if you want to, just refer this BUILTINS doc at null-ls eslint will not do the formatting for you but only code actions.

I am not completely sure if you need to install prettierd and eslint from LSPInstaller/Mason to get these working but its a simple thing to try.

As you go through the BUILTINS page, you will get the idea of what to do when you stumble upon a new filetype that you will need help with.

Hope this helps.

cbrake commented 1 year ago

here is what I ended up with to pull in multiple formatters/diags. Not sure if this is all correct as I don't understand this very well yet, but it is working pretty well.

-- null-ls is used for formatters/diagnostics not provided by the language
-- server
local null_ls = require("null-ls")
local augroup = vim.api.nvim_create_augroup("LspFormatting", {})
null_ls.setup({
  sources = {
    null_ls.builtins.formatting.prettier,
    null_ls.builtins.formatting.goimports,
    null_ls.builtins.formatting.elm_format,
    null_ls.builtins.formatting.shfmt,
    null_ls.builtins.diagnostics.shellcheck,
  },
  -- you can reuse a shared lspconfig on_attach callback here
  on_attach = function(client, bufnr)
    if client.supports_method("textDocument/formatting") then
      vim.api.nvim_clear_autocmds({ group = augroup, buffer = bufnr })
      vim.api.nvim_create_autocmd("BufWritePre", {
        group = augroup,
        buffer = bufnr,
        callback = function()
          vim.lsp.buf.format({ bufnr = bufnr })
        end,
      })
    end
  end,
})
JoachimR commented 1 year ago

if you run prettier via eslint then it should be enough to set it up like this:

  1. Write :LspInstall eslint
  2. in after/plugin/defaults.lua enter the following and save:
    -- format on save
    require('lspconfig').eslint.setup({
    on_attach = function(_, bufnr)
    vim.api.nvim_create_autocmd("BufWritePre", {
      buffer = bufnr,
      command = "EslintFixAll",
    })
    end,
    })
  3. Restart neovim
cbrake commented 1 year ago

@tjdevries have you given thought to opening up discussions on this repo for questions like this? Or is there a better place to to discuss?

tjdevries commented 1 year ago

I have an example that works in #178, which should hopefully be merged soon. Feel free to leave some comments there if you have problems (i'll check out this disucssion more after I'm all done with that stuff)

cjstock commented 11 months ago

To anyone wanting to use Prettier for autoformatting:

  1. Add 'prettier/vim-prettier' plugin to init.lua
  2. Handle the Prettier formatting when the LSP client is 'tsserver'

lua/kickstart/plugins/autoformat.lua

 vim.api.nvim_create_autocmd('LspAttach', {
      group = vim.api.nvim_create_augroup('kickstart-lsp-attach-format', { clear = true }),
      -- This is where we attach the autoformatting for reasonable clients
      callback = function(args)
        local client_id = args.data.client_id
        local client = vim.lsp.get_client_by_id(client_id)
        local bufnr = args.buf

        -- Only attach to clients that support document formatting
        if not client.server_capabilities.documentFormattingProvider then
          return
        end

        -- Tsserver usually works poorly. Sorry you work with bad languages
        -- Use prettier for formatting
        if client.name == 'tsserver' then
          vim.api.nvim_create_autocmd('BufWritePre', {
            buffer = bufnr,
            command = "Prettier",
          })
        end

        -- Create an autocmd that will run *before* we save the buffer.
        --  Run the formatting command for the LSP that has just attached.
        vim.api.nvim_create_autocmd('BufWritePre', {
          group = get_augroup(client),
          buffer = bufnr,
          callback = function()
            if not format_is_enabled then
              return
            end

            vim.lsp.buf.format {
              async = false,
              filter = function(c)
                return c.id == client.id
              end,
            }
          end,
        })
      end,
    })