Skip to content

Commit 0b9aebe

Browse files
authored
Merge pull request #1654 from fang2hou/feature/snacks-integration
2 parents dd361c3 + cae3af4 commit 0b9aebe

File tree

4 files changed

+88
-2
lines changed

4 files changed

+88
-2
lines changed

README.md

+6
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ Here's an example spec for [Lazy](https://github.com/folke/lazy.nvim), but you'r
3838
"nvim-telescope/telescope.nvim", -- optional
3939
"ibhagwan/fzf-lua", -- optional
4040
"echasnovski/mini.pick", -- optional
41+
"folke/snacks.nvim", -- optional
4142
},
4243
}
4344
```
@@ -240,6 +241,11 @@ neogit.setup {
240241
-- is also selected then telescope is used instead
241242
-- Requires you to have `echasnovski/mini.pick` installed.
242243
mini_pick = nil,
244+
245+
-- If enabled, uses snacks.picker for menu selection. If the telescope integration
246+
-- is also selected then telescope is used instead
247+
-- Requires you to have `folke/snacks.nvim` installed.
248+
snacks = nil,
243249
},
244250
sections = {
245251
-- Reverting/Cherry Picking

doc/neogit.txt

+5
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,11 @@ to Neovim users.
267267
-- is also selected then telescope is used instead
268268
-- Requires you to have `echasnovski/mini.pick` installed.
269269
mini_pick = nil,
270+
271+
-- If enabled, uses snacks.picker for menu selection. If the telescope integration
272+
-- is also selected then telescope is used instead
273+
-- Requires you to have `folke/snacks.nvim` installed.
274+
snacks = nil,
270275
},
271276
sections = {
272277
-- Reverting/Cherry Picking

lua/neogit/config.lua

+3-2
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ end
362362
---@field preview_buffer? NeogitConfigPopup Preview options
363363
---@field popup? NeogitConfigPopup Set the default way of opening popups
364364
---@field signs? NeogitConfigSigns Signs used for toggled regions
365-
---@field integrations? { diffview: boolean, telescope: boolean, fzf_lua: boolean, mini_pick: boolean } Which integrations to enable
365+
---@field integrations? { diffview: boolean, telescope: boolean, fzf_lua: boolean, mini_pick: boolean, snacks: boolean } Which integrations to enable
366366
---@field sections? NeogitConfigSections
367367
---@field ignored_settings? string[] Settings to never persist, format: "Filetype--cli-value", i.e. "NeogitCommitPopup--author"
368368
---@field mappings? NeogitConfigMappings
@@ -500,6 +500,7 @@ function M.get_default_values()
500500
diffview = nil,
501501
fzf_lua = nil,
502502
mini_pick = nil,
503+
snacks = nil,
503504
},
504505
sections = {
505506
sequencer = {
@@ -803,7 +804,7 @@ function M.validate_config()
803804
end
804805

805806
local function validate_integrations()
806-
local valid_integrations = { "diffview", "telescope", "fzf_lua", "mini_pick" }
807+
local valid_integrations = { "diffview", "telescope", "fzf_lua", "mini_pick", "snacks" }
807808
if not validate_type(config.integrations, "integrations", "table") or #config.integrations == 0 then
808809
return
809810
end

lua/neogit/lib/finder.lua

+74
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,65 @@ local function fzf_actions(on_select, allow_multi, refocus_status)
145145
}
146146
end
147147

148+
---Convert entries to snack picker items
149+
---@param entries any[]
150+
---@return any[]
151+
local function entries_to_snack_items(entries)
152+
local items = {}
153+
for idx, entry in ipairs(entries) do
154+
table.insert(items, { idx = idx, score = 0, text = entry })
155+
end
156+
return items
157+
end
158+
159+
--- Utility function to map actions
160+
---@param on_select fun(item: any|nil)
161+
---@param allow_multi boolean
162+
---@param refocus_status boolean
163+
local function snacks_actions(on_select, allow_multi, refocus_status)
164+
local function refresh(picker)
165+
picker:close()
166+
if refocus_status then
167+
refocus_status_buffer()
168+
end
169+
end
170+
171+
local function confirm(picker, item)
172+
local selection = {}
173+
local picker_selected = picker:selected { fallback = true }
174+
175+
if #picker_selected > 1 then
176+
for _, item in ipairs(picker_selected) do
177+
table.insert(selection, item.text)
178+
end
179+
else
180+
local entry = item.text
181+
local prompt = picker:filter().pattern
182+
183+
local navigate_up_level = entry == ".." and #prompt > 0
184+
local input_git_refspec = prompt:match("%^")
185+
or prompt:match("~")
186+
or prompt:match("@")
187+
or prompt:match(":")
188+
189+
table.insert(selection, (navigate_up_level or input_git_refspec) and prompt or entry)
190+
end
191+
192+
if selection and selection[1] and selection[1] ~= "" then
193+
on_select(allow_multi and selection or selection[1])
194+
end
195+
196+
refresh(picker)
197+
end
198+
199+
local function close(picker)
200+
on_select(nil)
201+
refresh(picker)
202+
end
203+
204+
return { confirm = confirm, close = close }
205+
end
206+
148207
--- Utility function to map finder opts to fzf
149208
---@param opts FinderOpts
150209
---@return table
@@ -274,6 +333,21 @@ function Finder:find(on_select)
274333
elseif config.check_integration("mini_pick") then
275334
local mini_pick = require("mini.pick")
276335
mini_pick.start { source = { items = self.entries, choose = on_select } }
336+
elseif config.check_integration("snacks") then
337+
local snacks_picker = require("snacks.picker")
338+
snacks_picker.pick(nil, {
339+
title = "Neogit",
340+
prompt = string.format("%s > ", self.opts.prompt_prefix),
341+
items = entries_to_snack_items(self.entries),
342+
format = "text",
343+
layout = {
344+
preset = self.opts.theme,
345+
preview = self.opts.previewer,
346+
height = self.opts.layout_config.height,
347+
border = self.opts.border and "rounded" or "none",
348+
},
349+
actions = snacks_actions(on_select, self.opts.allow_multi, self.opts.refocus_status),
350+
})
277351
else
278352
vim.ui.select(self.entries, {
279353
prompt = string.format("%s: ", self.opts.prompt_prefix),

0 commit comments

Comments
 (0)