Skip to content

Commit fdd3f91

Browse files
authored
feat: nvim-mini/mini.pick support (#202)
1 parent 10f63d6 commit fdd3f91

File tree

6 files changed

+232
-2
lines changed

6 files changed

+232
-2
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ Supported picker providers are:
288288
- [`snacks-picker`][snacks.nvim]
289289
- [`fzf-lua`][fzf-lua]
290290
- [`telescope`][telescope.nvim]
291+
- [`mini-picker`][mini-picker]
291292

292293
If `provider` is `nil`, [leetcode.nvim] will try to resolve the first
293294
available one in the order above.
@@ -545,3 +546,4 @@ You can then exit [leetcode.nvim] using `:Leet exit` command
545546
[snacks.nvim]: https://github.com/folke/snacks.nvim
546547
[tree-sitter-html]: https://github.com/tree-sitter/tree-sitter-html
547548
[plenary.nvim]: https://github.com/nvim-lua/plenary.nvim
549+
[mini-picker]: https://github.com/nvim-mini/mini.pick

lua/leetcode/picker/init.lua

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
local log = require("leetcode.logger")
22
local config = require("leetcode.config")
33

4-
local provider_order = { "snacks-picker", "fzf-lua", "telescope" }
4+
local provider_order = { "snacks-picker", "fzf-lua", "telescope", "mini-picker" }
55
local providers = {
66
["fzf-lua"] = {
77
name = "fzf",
@@ -23,6 +23,15 @@ local providers = {
2323
return pcall(require, "telescope")
2424
end,
2525
},
26+
["mini-picker"] = {
27+
name = "mini",
28+
is_available = function()
29+
return pcall(function()
30+
-- If MiniPick is set up correctly, :Pick command should be available
31+
return assert(vim.api.nvim_get_commands({})["Pick"])
32+
end)
33+
end,
34+
},
2635
}
2736

2837
local available_pickers = table.concat(
@@ -32,7 +41,7 @@ local available_pickers = table.concat(
3241
", "
3342
)
3443

35-
---@return "fzf" | "telescope" | "snacks"
44+
---@return "fzf" | "telescope" | "snacks" | "mini"
3645
local function resolve_provider()
3746
---@type string
3847
local provider = config.user.picker.provider
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
local log = require("leetcode.logger")
2+
local t = require("leetcode.translator")
3+
local picker = require("mini.pick")
4+
5+
local langage_picker = require("leetcode.picker.language")
6+
7+
---@param question lc.ui.Question
8+
return function(question, cb)
9+
local language_items = langage_picker.items(question.q.code_snippets)
10+
local ns_id = vim.api.nvim_create_namespace("MiniPick LeetCode Language Picker")
11+
local finder_items = {}
12+
local completed = false
13+
14+
for _, item in ipairs(language_items) do
15+
local text = langage_picker.ordinal(item.value)
16+
table.insert(finder_items, {
17+
entry = item.entry,
18+
text = text,
19+
item = item,
20+
})
21+
end
22+
23+
local res = picker.start({
24+
source = {
25+
items = finder_items,
26+
name = t("Available Languages"),
27+
choose = function(item)
28+
if completed then
29+
return
30+
end
31+
completed = true
32+
vim.schedule(function()
33+
langage_picker.select(item.item.value.t, question, cb)
34+
end)
35+
end,
36+
show = function(buf_id, items)
37+
require("leetcode.picker.mini_pick_utils").show_items(buf_id, ns_id, items)
38+
end,
39+
},
40+
window = {
41+
config = {
42+
width = langage_picker.width,
43+
height = langage_picker.height,
44+
},
45+
},
46+
})
47+
48+
if res == nil then
49+
if completed then
50+
return
51+
end
52+
completed = true
53+
log.warn("No selection")
54+
end
55+
end
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
local M = {}
2+
3+
---@class MiniPickItem
4+
---@field entry (string|string[])[]
5+
6+
---Render items to be shown in the `mini.pick` picker menu
7+
---@param buf_id integer Buffer associated with the `mini.pick` picker
8+
---@param ns_id integer Namespace associated with the `mini.pick` picker
9+
---@param items MiniPickItem[] Items to be rendered into the picker menu
10+
M.show_items = function(buf_id, ns_id, items)
11+
local lines, highlights = {}, {}
12+
13+
for _, item in ipairs(items) do
14+
local line, col = {}, 0
15+
local hl_spans = {}
16+
17+
for _, part in ipairs(item.entry) do
18+
if type(part) == "string" then
19+
part = { part }
20+
end
21+
local text, hl = part[1], part[2]
22+
table.insert(line, text)
23+
24+
local start_col, end_col = col, col + #text
25+
if hl then
26+
table.insert(hl_spans, { hl = hl, start_col = start_col, end_col = end_col })
27+
end
28+
29+
col = end_col + 1 -- account for space
30+
table.insert(line, " ")
31+
end
32+
33+
table.insert(lines, table.concat(line))
34+
table.insert(highlights, hl_spans)
35+
end
36+
37+
-- Set lines
38+
vim.api.nvim_buf_set_lines(buf_id, 0, -1, false, lines)
39+
vim.api.nvim_buf_clear_namespace(buf_id, ns_id, 0, -1)
40+
41+
-- Apply highlights on each line chunk
42+
local opts = { hl_mode = "combine", priority = 200 }
43+
for row, hl_spans in ipairs(highlights) do
44+
for _, span in ipairs(hl_spans) do
45+
opts.hl_group = span.hl
46+
opts.end_row, opts.end_col = row - 1, span.end_col
47+
vim.api.nvim_buf_set_extmark(buf_id, ns_id, row - 1, span.start_col, opts)
48+
end
49+
end
50+
end
51+
52+
return M
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
local log = require("leetcode.logger")
2+
local t = require("leetcode.translator")
3+
local question_picker = require("leetcode.picker.question")
4+
5+
local picker = require("mini.pick")
6+
7+
---@param questions lc.cache.Question[]
8+
return function(questions, opts)
9+
local question_items = question_picker.items(questions, opts)
10+
local ns_id = vim.api.nvim_create_namespace("MiniPick LeetCode Questions Picker")
11+
local finder_items = {}
12+
local completed = false
13+
14+
for _, item in ipairs(question_items) do
15+
local text = question_picker.ordinal(item.value)
16+
table.insert(finder_items, {
17+
entry = item.entry,
18+
text = text,
19+
item = item,
20+
})
21+
end
22+
23+
local res = picker.start({
24+
source = {
25+
items = finder_items,
26+
name = t("Select a Question"),
27+
28+
choose = function(item)
29+
if completed then
30+
return
31+
end
32+
completed = true
33+
vim.schedule(function()
34+
question_picker.select(item.item.value)
35+
end)
36+
end,
37+
show = function(buf_id, items)
38+
require("leetcode.picker.mini_pick_utils").show_items(buf_id, ns_id, items)
39+
end,
40+
},
41+
window = {
42+
config = {
43+
width = question_picker.width,
44+
height = math.floor(vim.o.lines * question_picker.height),
45+
},
46+
},
47+
})
48+
49+
if res == nil then
50+
if completed then
51+
return
52+
end
53+
completed = true
54+
log.warn("No selection")
55+
end
56+
end

lua/leetcode/picker/tabs/mini.lua

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
local log = require("leetcode.logger")
2+
local t = require("leetcode.translator")
3+
local tabs_picker = require("leetcode.picker.tabs")
4+
5+
local picker = require("mini.pick")
6+
7+
return function(tabs)
8+
local tab_items = tabs_picker.items(tabs)
9+
local ns_id = vim.api.nvim_create_namespace("MiniPick LeetCode Tabs Picker")
10+
local finder_items = {}
11+
local completed = false
12+
local items_reflect = {}
13+
14+
for _, item in ipairs(tab_items) do
15+
items_reflect[item.value.question.q.frontend_id] = item.value
16+
local text = tabs_picker.ordinal(item.value.question.q)
17+
table.insert(finder_items, {
18+
entry = item.entry,
19+
item = item.value.question.q.frontend_id,
20+
text = text,
21+
})
22+
end
23+
24+
local res = picker.start({
25+
source = {
26+
items = finder_items,
27+
name = t("Select a Question"),
28+
choose = function(item)
29+
if completed then
30+
return
31+
end
32+
completed = true
33+
vim.schedule(function()
34+
tabs_picker.select(items_reflect[item.item])
35+
end)
36+
end,
37+
show = function(buf_id, items)
38+
require("leetcode.picker.mini_pick_utils").show_items(buf_id, ns_id, items)
39+
end,
40+
},
41+
window = {
42+
config = {
43+
width = tabs_picker.width,
44+
height = tabs_picker.height,
45+
},
46+
},
47+
})
48+
49+
if res == nil then
50+
if completed then
51+
return
52+
end
53+
completed = true
54+
log.warn("No selection")
55+
end
56+
end

0 commit comments

Comments
 (0)