autocmds.lua 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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. local definitions = {
  11. {
  12. "TextYankPost",
  13. {
  14. group = "_general_settings",
  15. pattern = "*",
  16. desc = "Highlight text on yank",
  17. callback = function()
  18. require("vim.highlight").on_yank { higroup = "Search", timeout = 200 }
  19. end,
  20. },
  21. },
  22. {
  23. "BufWritePost",
  24. {
  25. group = "_general_settings",
  26. pattern = user_config_file,
  27. desc = "Trigger LvimReload on saving " .. vim.fn.expand "%:~",
  28. callback = function()
  29. require("lvim.config"):reload()
  30. end,
  31. },
  32. },
  33. {
  34. "FileType",
  35. {
  36. group = "_filetype_settings",
  37. pattern = "qf",
  38. command = "set nobuflisted",
  39. },
  40. },
  41. {
  42. "FileType",
  43. {
  44. group = "_filetype_settings",
  45. pattern = { "gitcommit", "markdown" },
  46. command = "setlocal wrap spell",
  47. },
  48. },
  49. {
  50. "FileType",
  51. {
  52. group = "_buffer_mappings",
  53. pattern = { "qf", "help", "man", "floaterm", "lspinfo", "lsp-installer", "null-ls-info" },
  54. command = "nnoremap <silent> <buffer> q :close<CR>",
  55. },
  56. },
  57. {
  58. { "BufWinEnter", "BufRead", "BufNewFile" },
  59. {
  60. group = "_format_options",
  61. pattern = "*",
  62. command = "setlocal formatoptions-=c formatoptions-=r formatoptions-=o",
  63. },
  64. },
  65. {
  66. "VimResized",
  67. {
  68. group = "_auto_resize",
  69. pattern = "*",
  70. command = "tabdo wincmd =",
  71. },
  72. },
  73. }
  74. M.define_autocmds(definitions)
  75. end
  76. local get_format_on_save_opts = function()
  77. local defaults = require("lvim.config.defaults").format_on_save
  78. -- accept a basic boolean `lvim.format_on_save=true`
  79. if type(lvim.format_on_save) ~= "table" then
  80. return defaults
  81. end
  82. return {
  83. pattern = lvim.format_on_save.pattern or defaults.pattern,
  84. timeout = lvim.format_on_save.timeout or defaults.timeout,
  85. }
  86. end
  87. function M.enable_format_on_save()
  88. local opts = get_format_on_save_opts()
  89. vim.api.nvim_create_augroup("lsp_format_on_save", {})
  90. vim.api.nvim_create_autocmd("BufWritePre", {
  91. group = "lsp_format_on_save",
  92. pattern = opts.pattern,
  93. callback = function()
  94. require("lvim.lsp.utils").format { timeout_ms = opts.timeout, filter = opts.filter }
  95. end,
  96. })
  97. Log:debug "enabled format-on-save"
  98. end
  99. function M.disable_format_on_save()
  100. M.clear_augroup "lsp_format_on_save"
  101. Log:debug "disabled format-on-save"
  102. end
  103. function M.configure_format_on_save()
  104. if lvim.format_on_save then
  105. M.enable_format_on_save()
  106. else
  107. M.disable_format_on_save()
  108. end
  109. end
  110. function M.toggle_format_on_save()
  111. local exists, _ = pcall(vim.api.nvim_get_autocmds, {
  112. group = "lsp_format_on_save",
  113. event = "BufWritePre",
  114. })
  115. if not exists then
  116. M.enable_format_on_save()
  117. else
  118. M.disable_format_on_save()
  119. end
  120. end
  121. function M.enable_transparent_mode()
  122. vim.api.nvim_create_autocmd("ColorScheme", {
  123. pattern = "*",
  124. callback = function()
  125. local hl_groups = {
  126. "Normal",
  127. "SignColumn",
  128. "NormalNC",
  129. "TelescopeBorder",
  130. "NvimTreeNormal",
  131. "EndOfBuffer",
  132. "MsgArea",
  133. }
  134. for _, name in ipairs(hl_groups) do
  135. vim.cmd(string.format("highlight %s ctermbg=none guibg=none", name))
  136. end
  137. end,
  138. })
  139. vim.opt.fillchars = "eob: "
  140. end
  141. --- Clean autocommand in a group if it exists
  142. --- This is safer than trying to delete the augroup itself
  143. ---@param name string the augroup name
  144. function M.clear_augroup(name)
  145. -- defer the function in case the autocommand is still in-use
  146. local exists, _ = pcall(vim.api.nvim_get_autocmds, { group = name })
  147. if not exists then
  148. Log:debug("ignoring request to clear autocmds from non-existent group " .. name)
  149. return
  150. end
  151. vim.schedule(function()
  152. local status_ok, _ = xpcall(function()
  153. vim.api.nvim_clear_autocmds { group = name }
  154. end, debug.traceback)
  155. if not status_ok then
  156. Log:warn("problems detected while clearing autocmds from " .. name)
  157. Log:debug(debug.traceback())
  158. end
  159. end)
  160. end
  161. --- Create autocommand groups based on the passed definitions
  162. --- Also creates the augroup automatically if it doesn't exist
  163. ---@param definitions table contains a tuple of event, opts, see `:h nvim_create_autocmd`
  164. function M.define_autocmds(definitions)
  165. for _, entry in ipairs(definitions) do
  166. local event = entry[1]
  167. local opts = entry[2]
  168. if type(opts.group) == "string" and opts.group ~= "" then
  169. local exists, _ = pcall(vim.api.nvim_get_autocmds, { group = opts.group })
  170. if not exists then
  171. vim.api.nvim_create_augroup(opts.group, {})
  172. end
  173. end
  174. vim.api.nvim_create_autocmd(event, opts)
  175. end
  176. end
  177. return M