nvim/.config/nvim/lua/config/autocmds.lua

-- nvim/.config/nvim/lua/config/autocmds.lua

local function augroup(name)
  return vim.api.nvim_create_augroup("user_" .. name, { clear = true })
end

-- Highlight yanked text briefly.
vim.api.nvim_create_autocmd("TextYankPost", {
  group = augroup("yank_flash"),
  callback = function()
    vim.highlight.on_yank({ higroup = "IncSearch", timeout = 150 })
  end,
})

-- Strip trailing whitespace on save, except in a few filetypes.
local skip_trim = { markdown = true, diff = true, gitcommit = true }
vim.api.nvim_create_autocmd("BufWritePre", {
  group = augroup("trim_ws"),
  callback = function(ev)
    if skip_trim[vim.bo[ev.buf].filetype] then return end
    local view = vim.fn.winsaveview()
    vim.cmd([[%s/\s\+$//e]])
    vim.fn.winrestview(view)
  end,
})

-- Return to last edit position when opening a file.
vim.api.nvim_create_autocmd("BufReadPost", {
  group = augroup("last_pos"),
  callback = function(ev)
    local mark = vim.api.nvim_buf_get_mark(ev.buf, '"')
    local lcount = vim.api.nvim_buf_line_count(ev.buf)
    if mark[1] > 0 and mark[1] <= lcount then
      pcall(vim.api.nvim_win_set_cursor, 0, mark)
    end
  end,
})

-- Auto-reload files changed outside of nvim.
vim.api.nvim_create_autocmd({ "FocusGained", "BufEnter", "CursorHold" }, {
  group = augroup("auto_read"),
  callback = function()
    if vim.fn.mode() ~= "c" then vim.cmd("checktime") end
  end,
})

-- Close some filetypes with `q` only.
vim.api.nvim_create_autocmd("FileType", {
  group = augroup("close_with_q"),
  pattern = { "help", "lspinfo", "qf", "notify", "checkhealth", "man" },
  callback = function(ev)
    vim.bo[ev.buf].buflisted = false
    vim.keymap.set("n", "q", "<cmd>close<cr>", { buffer = ev.buf, silent = true })
  end,
})

-- Create parent dirs on save. :e foo/bar/new.lua just works.
vim.api.nvim_create_autocmd("BufWritePre", {
  group = augroup("mkdir_on_save"),
  callback = function(ev)
    if ev.match:match("^%w+://") then return end
    local dir = vim.fn.fnamemodify(ev.file, ":p:h")
    if vim.fn.isdirectory(dir) == 0 then
      vim.fn.mkdir(dir, "p")
    end
  end,
})