telescope.lua 4.6 KB

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