Skip to content

implementing snack picker #823

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ The only **required** plugin dependency is [plenary.nvim](https://github.com/nvi
- **[recommended]** [nvim-telescope/telescope.nvim](https://github.com/nvim-telescope/telescope.nvim): for search and quick-switch functionality.
- [Mini.Pick](https://github.com/echasnovski/mini.pick) from the mini.nvim library: an alternative to telescope for search and quick-switch functionality.
- [ibhagwan/fzf-lua](https://github.com/ibhagwan/fzf-lua): another alternative to telescope for search and quick-switch functionality.
- [Snacks.Picker](https://github.com/folke/snacks.nvim/blob/main/docs/picker.md) from the snacks.nvim library: an alternative to mini and telescope for search and quick-switch functionality.

**Syntax highlighting:**

Expand Down Expand Up @@ -412,7 +413,7 @@ This is a complete list of all of the options that can be passed to `require("ob
open_app_foreground = false,

picker = {
-- Set your preferred picker. Can be one of 'telescope.nvim', 'fzf-lua', or 'mini.pick'.
-- Set your preferred picker. Can be one of 'telescope.nvim', 'fzf-lua', 'mini.pick' or 'snacks.pick'.
name = "telescope.nvim",
-- Optional, configure key mappings for the picker. These are the defaults.
-- Not all pickers support all mappings.
Expand Down
3 changes: 2 additions & 1 deletion doc/obsidian.txt
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ dependencies that enhance the obsidian.nvim experience.
- **[recommended]** nvim-telescope/telescope.nvim <https://github.com/nvim-telescope/telescope.nvim>: for search and quick-switch functionality.
- Mini.Pick <https://github.com/echasnovski/mini.pick> from the mini.nvim library: an alternative to telescope for search and quick-switch functionality.
- ibhagwan/fzf-lua <https://github.com/ibhagwan/fzf-lua>: another alternative to telescope for search and quick-switch functionality.
- Snacks.Pick <https://github.com/folke/snacks.nvim/blob/main/docs/picker.md>: another alternative to telescope for search and quick-switch functionality.

**Syntax highlighting:**

Expand Down Expand Up @@ -468,7 +469,7 @@ carefully and customize it to your needs:
open_app_foreground = false,

picker = {
-- Set your preferred picker. Can be one of 'telescope.nvim', 'fzf-lua', or 'mini.pick'.
-- Set your preferred picker. Can be one of 'telescope.nvim', 'fzf-lua', 'mini.pick' or 'snacks.pick'.
name = "telescope.nvim",
-- Optional, configure key mappings for the picker. These are the defaults.
-- Not all pickers support all mappings.
Expand Down
2 changes: 1 addition & 1 deletion lua/obsidian/commands/debug.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ return function(client, data)
end

log.lazy_info "Dependencies:"
for _, plugin in ipairs { "plenary.nvim", "nvim-cmp", "telescope.nvim", "fzf-lua", "mini.pick" } do
for _, plugin in ipairs { "plenary.nvim", "nvim-cmp", "telescope.nvim", "fzf-lua", "mini.pick", "snacks.pick" } do
local plugin_info = util.get_plugin_info(plugin)
if plugin_info ~= nil then
log.lazy_info(" ✓ %s: %s", plugin, plugin_info.commit or "unknown")
Expand Down
1 change: 1 addition & 0 deletions lua/obsidian/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ config.Picker = {
telescope = "telescope.nvim",
fzf_lua = "fzf-lua",
mini = "mini.pick",
snacks = "snacks.pick",
}

---@class obsidian.config.PickerOpts
Expand Down
162 changes: 162 additions & 0 deletions lua/obsidian/pickers/_snacks.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
local snacks_picker = require "snacks.picker"

local Path = require "obsidian.path"
local abc = require "obsidian.abc"
local Picker = require "obsidian.pickers.picker"

local function debug_once(msg, ...)
-- vim.notify(msg .. vim.inspect(...))
end

---@param mapping table
---@return table
local function notes_mappings(mapping)
if type(mapping) == "table" then
opts = { win = { input = { keys = {} } }, actions = {} };
for k, v in pairs(mapping) do
local name = string.gsub(v.desc, " ", "_")
opts.win.input.keys = {
[k] = { name, mode = { "n", "i" }, desc = v.desc }
}
opts.actions[name] = function(picker, item)
debug_once("mappings :", item)
picker:close()
vim.schedule(function()
v.callback(item.value or item._path)
end)
end
end
return opts
end
return {}
end

---@class obsidian.pickers.SnacksPicker : obsidian.Picker
local SnacksPicker = abc.new_class({
---@diagnostic disable-next-line: unused-local
__tostring = function(self)
return "SnacksPicker()"
end,
}, Picker)

---@param opts obsidian.PickerFindOpts|? Options.
SnacksPicker.find_files = function(self, opts)
opts = opts or {}

---@type obsidian.Path
local dir = opts.dir.filename and Path:new(opts.dir.filename) or self.client.dir

local map = vim.tbl_deep_extend("force", {},
notes_mappings(opts.selection_mappings))

local pick_opts = vim.tbl_extend("force", map or {}, {
source = "files",
title = opts.prompt_title,
cwd = tostring(dir),
confirm = function(picker, item, action)
picker:close()
if item then
if opts.callback then
debug_once("find files callback: ", item)
opts.callback(item._path)
else
debug_once("find files jump: ", item)
snacks_picker.actions.jump(picker, item, action)
end
end
end,
})
local t = snacks_picker.pick(pick_opts)
end

---@param opts obsidian.PickerGrepOpts|? Options.
SnacksPicker.grep = function(self, opts)
opts = opts or {}

debug_once("grep opts : ", opts)

---@type obsidian.Path
local dir = opts.dir.filename and Path:new(opts.dir.filename) or self.client.dir

local map = vim.tbl_deep_extend("force", {},
notes_mappings(opts.selection_mappings))

local pick_opts = vim.tbl_extend("force", map or {}, {
source = "grep",
title = opts.prompt_title,
cwd = tostring(dir),
confirm = function(picker, item, action)
picker:close()
if item then
if opts.callback then
debug_once("grep callback: ", item)
opts.callback(item._path or item.filename)
else
debug_once("grep jump: ", item)
snacks_picker.actions.jump(picker, item, action)
end
end
end,
})
snacks_picker.pick(pick_opts)
end

---@param values string[]|obsidian.PickerEntry[]
---@param opts obsidian.PickerPickOpts|? Options.
---@diagnostic disable-next-line: unused-local
SnacksPicker.pick = function(self, values, opts)
self.calling_bufnr = vim.api.nvim_get_current_buf()

opts = opts or {}

debug_once("pick opts: ", opts)

local buf = opts.buf or vim.api.nvim_get_current_buf()

local entries = {}
for _, value in ipairs(values) do
if type(value) == "string" then
table.insert(entries, {
text = value,
value = value,
})
elseif value.valid ~= false then
local name = self:_make_display(value)
table.insert(entries, {
text = name,
buf = buf,
filename = value.filename,
value = value.value,
pos = { value.lnum, value.col or 0 },
})
end
end

local map = vim.tbl_deep_extend("force", {},
notes_mappings(opts.selection_mappings))

local pick_opts = vim.tbl_extend("force", map or {}, {
tilte = opts.prompt_title,
items = entries,
layout = {
preview = false
},
format = "text",
confirm = function(picker, item, action)
picker:close()
if item then
if opts.callback then
debug_once("pick callback: ", item)
opts.callback(item.value)
else
debug_once("pick jump: ", item)
snacks_picker.actions.jump(picker, item, action)
end
end
end,
})

local entry = snacks_picker.pick(pick_opts)
end

return SnacksPicker
4 changes: 3 additions & 1 deletion lua/obsidian/pickers/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ M.get = function(client, picker_name)
if picker_name then
picker_name = string.lower(picker_name)
else
for _, name in ipairs { PickerName.telescope, PickerName.fzf_lua, PickerName.mini } do
for _, name in ipairs { PickerName.telescope, PickerName.fzf_lua, PickerName.mini, PickerName.snacks } do
local ok, res = pcall(M.get, client, name)
if ok then
return res
Expand All @@ -28,6 +28,8 @@ M.get = function(client, picker_name)
return require("obsidian.pickers._mini").new(client)
elseif picker_name == string.lower(PickerName.fzf_lua) then
return require("obsidian.pickers._fzf").new(client)
elseif picker_name == string.lower(PickerName.snacks) then
return require("obsidian.pickers._snacks").new(client)
elseif picker_name then
error("not implemented for " .. picker_name)
end
Expand Down
Loading