telescope.lua 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. -- file/buffer/etc picker
  2. local telescope = require('telescope')
  3. local telescope_actions = require('telescope.actions')
  4. local telescope_builtin = require('telescope.builtin')
  5. local telescope_pickers = require('telescope.pickers')
  6. local telescope_finders = require('telescope.finders')
  7. local telescope_previewers = require('telescope.previewers')
  8. local telescope_putils = require('telescope.previewers.utils')
  9. local telescope_conf = require('telescope.config').values
  10. local action_state = require('telescope.actions.state')
  11. local util = require('user.util')
  12. local actions = {}
  13. actions.git_show_commit = function(prompt_bufnr)
  14. local selection = action_state.get_selected_entry()
  15. local path = vim.fn.FugitiveFind(selection.value)
  16. telescope_actions.close(prompt_bufnr)
  17. vim.cmd.edit(path)
  18. end
  19. local commit_mappings = {
  20. i = {
  21. ['<CR>'] = actions.git_show_commit,
  22. ['<C-r>c'] = telescope_actions.git_checkout,
  23. }
  24. }
  25. telescope.setup({
  26. defaults = {
  27. mappings = {
  28. i = {
  29. ['<Esc>'] = 'close',
  30. ['<C-e>'] = 'close',
  31. },
  32. },
  33. layout_config = {
  34. prompt_position = 'top',
  35. },
  36. sorting_strategy = 'ascending',
  37. -- use filename as preview window title
  38. dynamic_preview_title = true,
  39. path_display = {
  40. -- shorten directory names of everything but the last 3 parts
  41. -- foo/bar/baz/file.txt -> f/boo/bar/file.txt
  42. shorten = { len = 1, exclude = { -3, -2, -1 } },
  43. -- truncate the beginning of the file name if wider than the window
  44. truncate = true,
  45. },
  46. preview = {
  47. -- don't preview files larger than 1MB
  48. filesize_limit = 1,
  49. timeout = 500,
  50. },
  51. vimgrep_arguments = {
  52. -- defaults
  53. 'rg',
  54. '--color=never',
  55. '--no-heading',
  56. '--with-filename',
  57. '--line-number',
  58. '--column',
  59. '--smart-case',
  60. -- search "hidden" files except git folder
  61. '--hidden',
  62. '--iglob=!.git'
  63. },
  64. -- ignore things we're likely not to edit
  65. file_ignore_patterns = {
  66. '%.zip$',
  67. '%.yarn/releases/',
  68. '%.yarn/plugins/'
  69. },
  70. -- picker history
  71. cache_picker = {
  72. num_pickers = 10,
  73. },
  74. },
  75. pickers = {
  76. buffers = {
  77. sort_lastused = true,
  78. sort_mru = true,
  79. mappings = {
  80. i = {
  81. ['<C-k>'] = 'delete_buffer'
  82. },
  83. },
  84. },
  85. find_files = {
  86. find_command = { 'fd', '--type', 'f', '--strip-cwd-prefix' }
  87. },
  88. git_commits = {
  89. mappings = commit_mappings,
  90. },
  91. git_bcommits = {
  92. mappings = commit_mappings,
  93. },
  94. },
  95. })
  96. -- use native sorter for better performance
  97. telescope.load_extension('fzf')
  98. -- custom picker to fallback to files if no git
  99. local function project_files()
  100. local ok = pcall(telescope_builtin.git_files, { show_untracked = true })
  101. if not ok then telescope_builtin.find_files({}) end
  102. end
  103. -- custom picker for files within a commit
  104. local function commit_files(opts)
  105. local resolved = util.resolve_git_path(0)
  106. if not resolved then
  107. vim.print('current file is not a fugitive path')
  108. return
  109. end
  110. opts = opts or {}
  111. telescope_pickers.new(opts, {
  112. prompt_title = resolved.commit,
  113. finder = telescope_finders.new_oneshot_job({ 'git', 'ls-tree', '--name-only', '-r', resolved.commit }, {
  114. entry_maker = function(entry)
  115. local path = string.format('fugitive://%s//%s/%s', resolved.repo, resolved.commit, entry)
  116. return {
  117. path = path,
  118. value = entry,
  119. display = entry,
  120. ordinal = entry,
  121. }
  122. end,
  123. }),
  124. sorter = telescope_conf.file_sorter(opts),
  125. -- the builtin previewer has fancy async loading which doesn't work for
  126. -- fugitive paths so we have to define our own
  127. previewer = telescope_previewers.new_buffer_previewer({
  128. title = function(self)
  129. return 'Commit Files'
  130. end,
  131. dyn_title = function(self, entry)
  132. return entry.value
  133. end,
  134. define_preview = function(self, entry, status)
  135. -- the builtin previewer does more things like using mime type
  136. -- fallbacks as well as binary file detection which ours doesn't do
  137. local ft = telescope_putils.filetype_detect(entry.value)
  138. vim.api.nvim_buf_call(self.state.bufnr, function()
  139. vim.cmd('Gread ' .. entry.path)
  140. telescope_putils.highlighter(self.state.bufnr, ft, opts)
  141. end)
  142. end,
  143. }),
  144. }):find()
  145. end
  146. vim.keymap.set('n', '<C-P>', project_files)
  147. vim.keymap.set('n', '<C-O>', '<cmd>Telescope buffers<CR>')
  148. vim.keymap.set('n', '<Leader>fg', commit_files)
  149. vim.keymap.set('n', '<Leader>ff', '<cmd>Telescope live_grep<CR>')
  150. vim.keymap.set('n', '<Leader>fr', '<cmd>Telescope resume<CR>')
  151. vim.keymap.set('n', '<Leader>fp', '<cmd>Telescope pickers<CR>')