irongit

A Neovim plugin enabling you to solve LeetCode problems.

feat: `folke/snacks.nvim` picker support

BYT0723authored
parent db7e1cdcommit 82f96ff91d87433aedc9ae9061dd255a0b3ef0efBrowse files

5 files changed, +203 -3

+1-1lua/leetcode/config/template.lua
@@ -38,7 +38,7 @@
3838
3939 ---@alias lc.storage table<"cache"|"home", string>
4040
41----@alias lc.picker { provider?: "fzf-lua" | "telescope" }
41+---@alias lc.picker { provider?: "fzf-lua" | "telescope" | "snacks-picker" }
4242
4343 ---@class lc.UserConfig
4444 local M = {
+11-2lua/leetcode/picker/init.lua
@@ -1,7 +1,7 @@
11 local log = require("leetcode.logger")
22 local config = require("leetcode.config")
33
4----@return "fzf" | "telescope"
4+---@return "fzf" | "telescope" | "snacks"
55 local function resolve_provider()
66 ---@type string
77 local provider = config.user.picker.provider
@@ -15,9 +15,18 @@ local function resolve_provider()
1515 if telescope_ok then
1616 return "telescope"
1717 end
18+ local snacks_ok = pcall(require, "snacks.picker")
19+ if snacks_ok then
20+ return "snacks"
21+ end
1822 error("no supported picker provider found")
1923 else
20- local provider_ok = pcall(require, provider)
24+ local mod = provider
25+ if provider == "snacks-picker" then
26+ provider = "snacks"
27+ mod = "snacks.picker"
28+ end
29+ local provider_ok = pcall(require, mod)
2130 assert(provider_ok, ("specified picker provider not found: `%s`"):format(provider))
2231 return provider == "fzf-lua" and "fzf" or provider
2332 end
+63-0lua/leetcode/picker/language/snacks.lua
@@ -0,0 +1,63 @@
1+local log = require("leetcode.logger")
2+local t = require("leetcode.translator")
3+local picker = require("snacks.picker")
4+
5+local language_picker = require("leetcode.picker.language")
6+
7+---@param question lc.ui.Question
8+return function(question, cb)
9+ local items = language_picker.items(question.q.code_snippets)
10+ local finder_items = {}
11+ local completed = false
12+
13+ for _, item in ipairs(items) do
14+ local text = language_picker.ordinal(item.value)
15+ table.insert(finder_items, {
16+ text = text,
17+ item = item,
18+ })
19+ end
20+
21+ picker.pick({
22+ source = "select",
23+ items = finder_items,
24+ format = function(item)
25+ local ret = {}
26+ vim.tbl_map(function(col)
27+ if type(col) == "table" then
28+ ret[#ret + 1] = col
29+ else
30+ ret[#ret + 1] = { col }
31+ end
32+ ret[#ret + 1] = { " " }
33+ end, item.item.entry)
34+ return ret
35+ end,
36+ title = t("Available Languages"),
37+ layout = {
38+ preview = false,
39+ layout = {
40+ height = math.floor(math.min(vim.o.lines * 0.8 - 10, #items + 2) + 0.5),
41+ },
42+ },
43+ actions = {
44+ confirm = function(p, item)
45+ if completed then
46+ return
47+ end
48+ completed = true
49+ p:close()
50+ vim.schedule(function()
51+ language_picker.select(item.item.value.t, question, cb)
52+ end)
53+ end,
54+ },
55+ on_close = function()
56+ if completed then
57+ return
58+ end
59+ completed = true
60+ log.warn("No selection")
61+ end,
62+ })
63+end
+63-0lua/leetcode/picker/question/snacks.lua
@@ -0,0 +1,63 @@
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("snacks.picker")
6+
7+---@param questions lc.cache.Question[]
8+return function(questions, opts)
9+ local items = question_picker.items(questions, opts)
10+ local finder_items = {}
11+ local completed = false
12+
13+ for _, item in ipairs(items) do
14+ local text = question_picker.ordinal(item.value)
15+ table.insert(finder_items, {
16+ text = text,
17+ item = item,
18+ })
19+ end
20+
21+ picker.pick({
22+ source = "select",
23+ items = finder_items,
24+ format = function(item)
25+ local ret = {}
26+ vim.tbl_map(function(col)
27+ if type(col) == "table" then
28+ ret[#ret + 1] = col
29+ else
30+ ret[#ret + 1] = { col }
31+ end
32+ ret[#ret + 1] = { " " }
33+ end, item.item.entry)
34+ return ret
35+ end,
36+ title = t("Select a Question"),
37+ layout = {
38+ preview = false,
39+ layout = {
40+ height = math.floor(math.min(vim.o.lines * 0.8 - 10, #items + 2) + 0.5),
41+ },
42+ },
43+ actions = {
44+ confirm = function(p, item)
45+ if completed then
46+ return
47+ end
48+ completed = true
49+ p:close()
50+ vim.schedule(function()
51+ question_picker.select(item.value)
52+ end)
53+ end,
54+ },
55+ on_close = function()
56+ if completed then
57+ return
58+ end
59+ completed = true
60+ log.warn("No selection")
61+ end,
62+ })
63+end
+65-0lua/leetcode/picker/tabs/snacks.lua
@@ -0,0 +1,65 @@
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("snacks.picker")
6+
7+return function(tabs)
8+ local items = tabs_picker.items(tabs)
9+ local finder_items = {}
10+ local completed = false
11+ local items_reflect = {}
12+
13+ for _, item in ipairs(items) do
14+ items_reflect[item.value.question.q.frontend_id] = item.value
15+ local text = tabs_picker.ordinal(item.value.question.q)
16+ table.insert(finder_items, {
17+ entry = item.entry,
18+ item = item.value.question.q.frontend_id,
19+ text = text,
20+ })
21+ end
22+
23+ picker.pick({
24+ source = "select",
25+ items = finder_items,
26+ format = function(item)
27+ local ret = {}
28+ vim.tbl_map(function(col)
29+ if type(col) == "table" then
30+ ret[#ret + 1] = col
31+ else
32+ ret[#ret + 1] = { col }
33+ end
34+ ret[#ret + 1] = { " " }
35+ end, item.entry)
36+ return ret
37+ end,
38+ title = t("Select a Question"),
39+ layout = {
40+ preview = false,
41+ layout = {
42+ height = math.floor(math.min(vim.o.lines * 0.8 - 10, #items + 2) + 0.5),
43+ },
44+ },
45+ actions = {
46+ confirm = function(p, item)
47+ if completed then
48+ return
49+ end
50+ completed = true
51+ p:close()
52+ vim.schedule(function()
53+ tabs_picker.select(items_reflect[item.item])
54+ end)
55+ end,
56+ },
57+ on_close = function()
58+ if completed then
59+ return
60+ end
61+ completed = true
62+ log.warn("No selection")
63+ end,
64+ })
65+end