plugins.lua 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. -- add extra filetypes for plenary
  2. require('plenary.filetype').add_table({
  3. extension = {
  4. ['elv'] = [[elvish]]
  5. }
  6. })
  7. -- add extra builtin filetypes
  8. vim.filetype.add({
  9. pattern = {
  10. ['.*%.ts$'] = 'typescript'
  11. },
  12. })
  13. -- file/buffer/etc picker
  14. require('telescope').setup({
  15. defaults = {
  16. mappings = {
  17. i = {
  18. ['jj'] = 'close',
  19. },
  20. },
  21. layout_config = {
  22. prompt_position = 'top',
  23. },
  24. sorting_strategy = 'ascending',
  25. -- use filename as preview window title
  26. dynamic_preview_title = true,
  27. path_display = {
  28. -- shorten directory names of everything but the last 3 parts
  29. -- foo/bar/baz/file.txt -> f/boo/bar/file.txt
  30. shorten = { len = 1, exclude = { -3, -2, -1 } },
  31. -- truncate the beginning of the file name if wider than the window
  32. truncate = true,
  33. },
  34. preview = {
  35. -- don't preview files larger than 1MB
  36. filesize_limit = 1,
  37. timeout = 500,
  38. },
  39. vimgrep_arguments = {
  40. -- defaults
  41. "rg",
  42. "--color=never",
  43. "--no-heading",
  44. "--with-filename",
  45. "--line-number",
  46. "--column",
  47. "--smart-case",
  48. -- search "hidden" files except git folder
  49. "--hidden",
  50. "--iglob=!.git"
  51. },
  52. -- ignore things we're likely not to edit
  53. file_ignore_patterns = {
  54. "%.zip$",
  55. "%.yarn/releases/",
  56. "%.yarn/plugins/"
  57. },
  58. -- picker history
  59. cache_picker = {
  60. num_pickers = 10,
  61. },
  62. },
  63. pickers = {
  64. buffers = {
  65. sort_lastused = true,
  66. sort_mru = true,
  67. mappings = {
  68. i = {
  69. ['<C-k>'] = 'delete_buffer'
  70. },
  71. },
  72. },
  73. find_files = {
  74. find_command = { "fd", "--type", "f", "--strip-cwd-prefix" }
  75. },
  76. },
  77. })
  78. -- use native sorter for better performance
  79. require('telescope').load_extension('fzf')
  80. local telescope_builtin = require('telescope.builtin')
  81. local telescope_pickers = require('telescope.pickers')
  82. local telescope_finders = require('telescope.finders')
  83. local telescope_previewers = require('telescope.previewers')
  84. local telescope_putils = require('telescope.previewers.utils')
  85. local telescope_conf = require('telescope.config').values
  86. -- custom picker to fallback to files if no git
  87. _G.project_files = function()
  88. local ok = pcall(telescope_builtin.git_files, { show_untracked = true })
  89. if not ok then telescope_builtin.find_files({}) end
  90. end
  91. -- custom picker for files within a commit
  92. _G.commit_files = function(opts)
  93. local current_path = vim.api.nvim_buf_get_name(0)
  94. local parsed = vim.fn.FugitiveParse(current_path)
  95. local resolved_path = parsed[1]
  96. local repo = parsed[2]
  97. if resolved_path == "" then
  98. vim.print("current file is not a fugitive path")
  99. return
  100. end
  101. local parts = vim.split(resolved_path, ':')
  102. local commit = parts[1]
  103. opts = opts or {}
  104. telescope_pickers.new(opts, {
  105. prompt_title = commit,
  106. finder = telescope_finders.new_oneshot_job({ "git", "ls-tree", "--name-only", "-r", commit }, {
  107. entry_maker = function(entry)
  108. local path = string.format("fugitive://%s//%s/%s", repo, commit, entry)
  109. return {
  110. path = path,
  111. value = entry,
  112. display = entry,
  113. ordinal = entry,
  114. }
  115. end,
  116. }),
  117. sorter = telescope_conf.file_sorter(opts),
  118. -- the builtin previewer has fancy async loading which doesn't work for
  119. -- fugitive paths so we have to define our own
  120. previewer = telescope_previewers.new_buffer_previewer({
  121. title = function(self)
  122. return 'Commit Files'
  123. end,
  124. dyn_title = function(self, entry)
  125. return entry.value
  126. end,
  127. define_preview = function(self, entry, status)
  128. -- the builtin previewer does more things like using mime type
  129. -- fallbacks as well as binary file detection which ours doesn't do
  130. local ft = telescope_putils.filetype_detect(entry.value)
  131. vim.api.nvim_buf_call(self.state.bufnr, function()
  132. vim.cmd('Gread ' .. entry.path)
  133. telescope_putils.highlighter(self.state.bufnr, ft, opts)
  134. end)
  135. end,
  136. }),
  137. }):find()
  138. end
  139. -- shows added/removed/changed lines
  140. require('gitsigns').setup()
  141. require('mini.statusline').setup({
  142. content = {
  143. -- copy-pasted from default, we just want to remove the icon
  144. active = function()
  145. local mode, mode_hl = MiniStatusline.section_mode({ trunc_width = 120 })
  146. local git = MiniStatusline.section_git({ trunc_width = 75, icon = '' })
  147. local diagnostics = MiniStatusline.section_diagnostics({ trunc_width = 75, icon = '' })
  148. local filename = MiniStatusline.section_filename({ trunc_width = 140 })
  149. local fileinfo = MiniStatusline.section_fileinfo({ trunc_width = 120 })
  150. local location = MiniStatusline.section_location({ trunc_width = 75 })
  151. return MiniStatusline.combine_groups({
  152. { hl = mode_hl, strings = { mode } },
  153. { hl = 'MiniStatuslineDevinfo', strings = { git, diagnostics } },
  154. '%<', -- Mark general truncate point
  155. { hl = 'MiniStatuslineFilename', strings = { filename } },
  156. '%=', -- End left alignment
  157. { hl = 'MiniStatuslineFileinfo', strings = { fileinfo } },
  158. { hl = mode_hl, strings = { location } },
  159. })
  160. end
  161. },
  162. })
  163. -- delete buffer while preserving layout
  164. require('mini.bufremove').setup()
  165. -- shows a line indicating the current indentation scope
  166. require('mini.indentscope').setup()
  167. -- comment actions
  168. require('mini.comment').setup()
  169. -- surround actions
  170. require('mini.surround').setup()
  171. local spec_treesitter = require('mini.ai').gen_spec.treesitter
  172. require('mini.ai').setup({
  173. custom_textobjects = {
  174. [','] = spec_treesitter({
  175. a = '@parameter.outer',
  176. i = '@parameter.inner',
  177. }),
  178. },
  179. });
  180. -- align actions
  181. require('mini.align').setup()
  182. -- repeatable f/t
  183. require('mini.jump').setup({
  184. mappings = {
  185. repeat_jump = '',
  186. },
  187. delay = {
  188. highlight = 10000000,
  189. },
  190. })
  191. -- autopair brackets
  192. require('mini.pairs').setup({
  193. mappings = {
  194. -- default config includes (, [ and {
  195. -- autopair <> if preceded by a character, otherwise it might be a regular
  196. -- comparison operation
  197. ['<'] = { action = 'open', pair = '<>', neigh_pattern = '%w.' },
  198. ['>'] = { action = 'close', pair = '<>', neigh_pattern = '%w.' },
  199. },
  200. })
  201. -- notifications
  202. require('mini.notify').setup()
  203. vim.notify = require('mini.notify').make_notify()
  204. -- rest client
  205. require('rest-nvim').setup({})
  206. -- Use Treesitter for syntax highlighting
  207. require('nvim-treesitter.configs').setup({
  208. highlight = {
  209. enable = true,
  210. },
  211. indent = {
  212. enable = true,
  213. },
  214. incremental_selection = {
  215. enable = true,
  216. keymaps = {
  217. init_selection = "]t",
  218. node_incremental = "]t",
  219. node_decremental = "[t",
  220. },
  221. },
  222. textobjects = {
  223. swap = {
  224. enable = true,
  225. swap_next = {
  226. ['>,'] = '@parameter.inner',
  227. },
  228. swap_previous = {
  229. ['<,'] = '@parameter.inner',
  230. },
  231. },
  232. },
  233. })
  234. local tsj_utils = require('treesj.langs.utils')
  235. -- Treesitter-aware split/join
  236. require('treesj').setup({
  237. use_default_keymaps = false,
  238. })
  239. -- Treesitter context
  240. require('treesitter-context').setup({
  241. enable = true,
  242. multiline_threshold = 5,
  243. })
  244. -- completion
  245. local cmp = require('cmp')
  246. local cmp_types = require('cmp.types')
  247. function sort_label(entry1, entry2)
  248. local diff = vim.stricmp(entry1.completion_item.label, entry2.completion_item.label)
  249. if diff < 0 then
  250. return true
  251. elseif diff > 0 then
  252. return false
  253. end
  254. end
  255. cmp.setup({
  256. snippet = {
  257. expand = function(args)
  258. vim.fn['vsnip#anonymous'](args.body)
  259. end,
  260. },
  261. mapping = cmp.mapping.preset.insert({
  262. ['<C-u>'] = cmp.mapping.scroll_docs(-4),
  263. ['<C-d>'] = cmp.mapping.scroll_docs(4),
  264. ['<C-Space>'] = cmp.mapping.complete(),
  265. ['<C-e>'] = cmp.mapping.abort(),
  266. ['<CR>'] = cmp.mapping.confirm({ select = true }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items.
  267. }),
  268. sources = cmp.config.sources({
  269. {
  270. name = "nvim_lsp",
  271. entry_filter = function(entry, ctx)
  272. -- don't autocomplete keywords
  273. return cmp_types.lsp.CompletionItemKind[entry:get_kind()] ~= 'Keyword'
  274. end
  275. },
  276. { name = "vsnip" },
  277. }),
  278. completion = {
  279. autocomplete = false,
  280. },
  281. matching = {
  282. -- disable non-prefix matching
  283. disallow_fuzzy_matching = true,
  284. disallow_partial_matching = true,
  285. disallow_prefix_unmatching = true,
  286. },
  287. sorting = {
  288. comparators = {
  289. -- since we only have prefix matches, just sort the results
  290. sort_label,
  291. },
  292. },
  293. })
  294. -- typescript-vim compiler options
  295. vim.g.typescript_compiler_options = '--incremental --noEmit'