16

In Vim I used autocmd BufWritePre * :%s/\s\+$//e to delete trailing white space on save. Now, Neovim 0.7 has the new vim.api.nvim_create_autocmd.

What is the correct syntax to adapt this autocmd in Lua?

vim.api.nvim_create_autocmd("BufWritePre", {
  group = "Format",
  buffer = bufnr,
  ...
})

3 Answers 3

24

This should do the trick:

vim.api.nvim_create_autocmd({ "BufWritePre" }, {
  pattern = { "*" },
  command = [[%s/\s\+$//e]],
})

Be sure to read the h:nvim_create_autocmd() for more info!

2
  • It works for me. Try running :checkhealth or seeing if your neovim version is up-to-date with $ nvim -v
    – InsertSON
    Commented May 9, 2022 at 13:38
  • Is there a reason to use surrounding [[ over " for the command?
    – mcp
    Commented Aug 9 at 14:35
10

I agree with the accepted answer.
Something that begins to annoy quickly is that the cursor position is reset to the beginning of the line.
To keep it, one can use getpos/setpos like this:

vim.api.nvim_create_autocmd({ "BufWritePre" }, {
    pattern = {"*"},
    callback = function(ev)
        save_cursor = vim.fn.getpos(".")
        vim.cmd([[%s/\s\+$//e]])
        vim.fn.setpos(".", save_cursor)
    end,
})

To catch errors use pcall()

vim.api.nvim_create_autocmd({ "BufWritePre" }, {
    pattern = {"*"},
    callback = function()
      local save_cursor = vim.fn.getpos(".")
      pcall(function() vim.cmd [[%s/\s\+$//e]] end)
      vim.fn.setpos(".", save_cursor)
    end,
})
1
  • Welcome to Vi and Vim! You might be interested in winsaveview() and its counterpart. To be safe you need try/finally or vim9’s defer, also.
    – D. Ben Knoble
    Commented Mar 2, 2023 at 12:59
2

This could also be setup to only run on a keyboard shortcut.

The following command when executed in n - Normal Mode followed by the Leader key \ + wt.

vim.keymap.set('n', '<Leader>wt', [[:%s/\s\+$//e<cr>]])
-- mode     ----^
-- shortcut ---------^
-- command  ----------------------^

I like to go one step further and wire up the lsp format command like the following example, notice the <bar> symbol allows for multiple commands:

vim.keymap.set('n', '<Leader>wt', [[:lua vim.lsp.buf.format()<cr> <bar> :%s/\s\+$//e<cr>]])
-- mode     ----^
-- shortcut ---------^
-- command1  -----------------------^
-- bar      ------------------------------------------------------^
-- command2  -----------------------------------------------------------^

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.