Browse Source

nixpkgs/neovim: add picker for files within the same commit

Thomas Dy 6 months ago
parent
commit
22447640ae
2 changed files with 69 additions and 1 deletions
  1. 1 0
      .config/nixpkgs/neovim/mappings.lua
  2. 68 1
      .config/nixpkgs/neovim/plugins.lua

+ 1 - 0
.config/nixpkgs/neovim/mappings.lua

@@ -19,6 +19,7 @@ vim.keymap.set('n', 'gp', '`[v`]', opts)
 -- pickers
 vim.keymap.set('n', '<C-P>', '<cmd>lua project_files()<CR>', opts)
 vim.keymap.set('n', '<C-O>', '<cmd>Telescope buffers<CR>', opts)
+vim.keymap.set('n', '<Leader>fg', '<cmd>lua commit_files()<CR>', opts)
 vim.keymap.set('n', '<Leader>ff', '<cmd>Telescope live_grep<CR>', opts)
 
 -- jumplist navigation

+ 68 - 1
.config/nixpkgs/neovim/plugins.lua

@@ -5,6 +5,13 @@ require('plenary.filetype').add_table({
   }
 })
 
+-- add extra builtin filetypes
+vim.filetype.add({
+  pattern = {
+    ['.*%.ts$'] = 'typescript'
+  },
+})
+
 -- file/buffer/etc picker
 require('telescope').setup({
   defaults = {
@@ -52,13 +59,73 @@ require('telescope').setup({
 -- use native sorter for better performance
 require('telescope').load_extension('fzf')
 
--- custom picker to fallback to files if no git
 local telescope_builtin = require('telescope.builtin')
+local telescope_pickers = require('telescope.pickers')
+local telescope_finders = require('telescope.finders')
+local telescope_previewers = require('telescope.previewers')
+local telescope_putils = require('telescope.previewers.utils')
+local telescope_conf = require('telescope.config').values
+
+-- custom picker to fallback to files if no git
 _G.project_files = function()
   local ok = pcall(telescope_builtin.git_files, { show_untracked = true })
   if not ok then telescope_builtin.find_files({}) end
 end
 
+-- custom picker for files within a commit
+_G.commit_files = function(opts)
+  local current_path = vim.api.nvim_buf_get_name(0)
+  local parsed = vim.fn.FugitiveParse(current_path)
+  local resolved_path = parsed[1]
+  local repo = parsed[2]
+
+  if resolved_path == "" then
+    vim.print("current file is not a fugitive path")
+    return
+  end
+
+  local parts = vim.split(resolved_path, ':')
+  local commit = parts[1]
+
+  opts = opts or {}
+  telescope_pickers.new(opts, {
+    prompt_title = commit,
+    finder = telescope_finders.new_oneshot_job({ "git", "ls-tree", "--name-only", "-r", commit }, {
+      entry_maker = function(entry)
+        local path = string.format("fugitive://%s//%s/%s", repo, commit, entry)
+        return {
+          path = path,
+          value = entry,
+          display = entry,
+          ordinal = entry,
+        }
+      end,
+    }),
+    sorter = telescope_conf.file_sorter(opts),
+
+    -- the builtin previewer has fancy async loading which doesn't work for
+    -- fugitive paths so we have to define our own
+    previewer = telescope_previewers.new_buffer_previewer({
+      title = function(self)
+        return 'Commit Files'
+      end,
+      dyn_title = function(self, entry)
+        return entry.value
+      end,
+      define_preview = function(self, entry, status)
+        -- the builtin previewer does more things like using mime type
+        -- fallbacks as well as binary file detection which ours doesn't do
+        local ft = telescope_putils.filetype_detect(entry.value)
+
+        vim.api.nvim_buf_call(self.state.bufnr, function()
+          vim.cmd('Gread ' .. entry.path)
+          telescope_putils.highlighter(self.state.bufnr, ft, opts)
+        end)
+      end,
+    }),
+  }):find()
+end
+
 -- shows added/removed/changed lines
 require('gitsigns').setup()