autocmds.lua 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. local M = {}
  2. local Log = require "lvim.core.log"
  3. --- Load the default set of autogroups and autocommands.
  4. function M.load_defaults()
  5. local user_config_file = require("lvim.config"):get_user_config_path()
  6. if vim.loop.os_uname().version:match "Windows" then
  7. -- autocmds require forward slashes even on windows
  8. user_config_file = user_config_file:gsub("\\", "/")
  9. end
  10. vim.api.nvim_create_autocmd({ "FileType" }, {
  11. pattern = {
  12. "Jaq",
  13. "qf",
  14. "help",
  15. "man",
  16. "lspinfo",
  17. "spectre_panel",
  18. "lir",
  19. "DressingSelect",
  20. "tsplayground",
  21. },
  22. callback = function()
  23. vim.cmd [[
  24. nnoremap <silent> <buffer> q :close<CR>
  25. set nobuflisted
  26. ]]
  27. end,
  28. })
  29. local definitions = {
  30. {
  31. "TextYankPost",
  32. {
  33. group = "_general_settings",
  34. pattern = "*",
  35. desc = "Highlight text on yank",
  36. callback = function()
  37. require("vim.highlight").on_yank { higroup = "Search", timeout = 100 }
  38. end,
  39. },
  40. },
  41. {
  42. "BufWritePost",
  43. {
  44. group = "_general_settings",
  45. pattern = user_config_file,
  46. desc = "Trigger LvimReload on saving " .. vim.fn.expand "%:~",
  47. callback = function()
  48. require("lvim.config"):reload()
  49. end,
  50. },
  51. },
  52. {
  53. "FileType",
  54. {
  55. group = "_hide_dap_repl",
  56. pattern = "dap-repl",
  57. command = "set nobuflisted",
  58. },
  59. },
  60. {
  61. "FileType",
  62. {
  63. group = "_filetype_settings",
  64. pattern = "qf",
  65. command = "set nobuflisted",
  66. },
  67. },
  68. {
  69. "FileType",
  70. {
  71. group = "_filetype_settings",
  72. pattern = { "gitcommit", "markdown" },
  73. command = "setlocal wrap spell",
  74. },
  75. },
  76. {
  77. "FileType",
  78. {
  79. group = "_buffer_mappings",
  80. pattern = { "qf", "help", "man", "floaterm", "lspinfo", "lsp-installer", "null-ls-info" },
  81. command = "nnoremap <silent> <buffer> q :close<CR>",
  82. },
  83. },
  84. {
  85. { "BufWinEnter", "BufRead", "BufNewFile" },
  86. {
  87. group = "_format_options",
  88. pattern = "*",
  89. command = "setlocal formatoptions-=c formatoptions-=r formatoptions-=o",
  90. },
  91. },
  92. {
  93. "VimResized",
  94. {
  95. group = "_auto_resize",
  96. pattern = "*",
  97. command = "tabdo wincmd =",
  98. },
  99. },
  100. {
  101. "FileType",
  102. {
  103. group = "_filetype_settings",
  104. pattern = "alpha",
  105. callback = function()
  106. vim.cmd [[
  107. nnoremap <silent> <buffer> q :qa<CR>
  108. nnoremap <silent> <buffer> <esc> :qa<CR>
  109. set nobuflisted
  110. ]]
  111. end,
  112. },
  113. },
  114. {
  115. "FileType",
  116. {
  117. group = "_filetype_settings",
  118. pattern = "lir",
  119. callback = function()
  120. vim.opt_local.number = false
  121. vim.opt_local.relativenumber = false
  122. end,
  123. },
  124. },
  125. -- TODO: figure out what keeps overriding laststatus
  126. {
  127. "BufWinEnter",
  128. {
  129. group = "_last_status",
  130. pattern = "*",
  131. callback = function()
  132. vim.opt.laststatus = 3
  133. end,
  134. },
  135. },
  136. }
  137. M.define_autocmds(definitions)
  138. end
  139. local get_format_on_save_opts = function()
  140. local defaults = require("lvim.config.defaults").format_on_save
  141. -- accept a basic boolean `lvim.format_on_save=true`
  142. if type(lvim.format_on_save) ~= "table" then
  143. return defaults
  144. end
  145. return {
  146. pattern = lvim.format_on_save.pattern or defaults.pattern,
  147. timeout = lvim.format_on_save.timeout or defaults.timeout,
  148. }
  149. end
  150. function M.enable_format_on_save()
  151. local opts = get_format_on_save_opts()
  152. vim.api.nvim_create_augroup("lsp_format_on_save", {})
  153. vim.api.nvim_create_autocmd("BufWritePre", {
  154. group = "lsp_format_on_save",
  155. pattern = opts.pattern,
  156. callback = function()
  157. require("lvim.lsp.utils").format { timeout_ms = opts.timeout, filter = opts.filter }
  158. end,
  159. })
  160. Log:debug "enabled format-on-save"
  161. end
  162. function M.disable_format_on_save()
  163. M.clear_augroup "lsp_format_on_save"
  164. Log:debug "disabled format-on-save"
  165. end
  166. function M.configure_format_on_save()
  167. if lvim.format_on_save then
  168. M.enable_format_on_save()
  169. else
  170. M.disable_format_on_save()
  171. end
  172. end
  173. function M.toggle_format_on_save()
  174. local exists, autocmds = pcall(vim.api.nvim_get_autocmds, {
  175. group = "lsp_format_on_save",
  176. event = "BufWritePre",
  177. })
  178. if not exists or #autocmds == 0 then
  179. M.enable_format_on_save()
  180. else
  181. M.disable_format_on_save()
  182. end
  183. end
  184. function M.enable_transparent_mode()
  185. vim.api.nvim_create_autocmd("ColorScheme", {
  186. pattern = "*",
  187. callback = function()
  188. local hl_groups = {
  189. "Normal",
  190. "SignColumn",
  191. "NormalNC",
  192. "TelescopeBorder",
  193. "NvimTreeNormal",
  194. "EndOfBuffer",
  195. "MsgArea",
  196. }
  197. for _, name in ipairs(hl_groups) do
  198. vim.cmd(string.format("highlight %s ctermbg=none guibg=none", name))
  199. end
  200. end,
  201. })
  202. vim.opt.fillchars = "eob: "
  203. end
  204. --- Clean autocommand in a group if it exists
  205. --- This is safer than trying to delete the augroup itself
  206. ---@param name string the augroup name
  207. function M.clear_augroup(name)
  208. -- defer the function in case the autocommand is still in-use
  209. Log:debug("request to clear autocmds " .. name)
  210. vim.schedule(function()
  211. pcall(function()
  212. vim.api.nvim_clear_autocmds { group = name }
  213. end)
  214. end)
  215. end
  216. --- Create autocommand groups based on the passed definitions
  217. --- Also creates the augroup automatically if it doesn't exist
  218. ---@param definitions table contains a tuple of event, opts, see `:h nvim_create_autocmd`
  219. function M.define_autocmds(definitions)
  220. for _, entry in ipairs(definitions) do
  221. local event = entry[1]
  222. local opts = entry[2]
  223. if type(opts.group) == "string" and opts.group ~= "" then
  224. local exists, _ = pcall(vim.api.nvim_get_autocmds, { group = opts.group })
  225. if not exists then
  226. vim.api.nvim_create_augroup(opts.group, {})
  227. end
  228. end
  229. vim.api.nvim_create_autocmd(event, opts)
  230. end
  231. end
  232. return M