irongit

A Neovim plugin enabling you to solve LeetCode problems.

132 lines3.2 KBLua
1local log = require("leetcode.logger")
2local config = require("leetcode.config")
3
4local provider_order = { "snacks-picker", "fzf-lua", "telescope" }
5local providers = {
6 ["fzf-lua"] = {
7 name = "fzf",
8 is_available = function()
9 return pcall(require, "fzf-lua")
10 end,
11 },
12 ["snacks-picker"] = {
13 name = "snacks",
14 is_available = function()
15 return pcall(function() ---@diagnostic disable-next-line: undefined-field
16 assert(Snacks.config["picker"].enabled)
17 end)
18 end,
19 },
20 ["telescope"] = {
21 name = "telescope",
22 is_available = function()
23 return pcall(require, "telescope")
24 end,
25 },
26}
27
28local available_pickers = table.concat(
29 vim.tbl_map(function(p)
30 return providers[p].name
31 end, provider_order),
32 ", "
33)
34
35---@return "fzf" | "telescope" | "snacks"
36local function resolve_provider()
37 ---@type string
38 local provider = config.user.picker.provider
39
40 if provider == nil then
41 for _, key in ipairs(provider_order) do
42 local picker = providers[key]
43
44 if picker.is_available() then
45 return picker.name
46 end
47 end
48
49 error(("No picker is available. Please install one of the following: `%s`") --
50 :format(available_pickers))
51 end
52
53 local picker = providers[provider]
54 assert(
55 picker,
56 ("Picker `%s` is not supported. Available pickers: `%s`") --
57 :format(provider, available_pickers)
58 )
59
60 local ok = picker.is_available()
61 assert(ok, ("Picker `%s` is not available. Make sure it is installed"):format(provider))
62 return picker.name
63end
64
65---@class leet.Picker
66local P = {}
67P.provider = resolve_provider()
68
69function P.hl_to_ansi(hl_group)
70 local color = vim.api.nvim_get_hl(0, { name = hl_group })
71 if color and color.fg then
72 return string.format(
73 "\x1b[38;2;%d;%d;%dm",
74 bit.rshift(color.fg, 16),
75 bit.band(bit.rshift(color.fg, 8), 0xFF),
76 bit.band(color.fg, 0xFF)
77 )
78 end
79 return ""
80end
81
82function P.apply_hl(text, hl_group)
83 if not hl_group then
84 return text
85 end
86 return P.hl_to_ansi(hl_group) .. text .. "\x1b[0m"
87end
88
89function P.normalize(items)
90 return vim.tbl_map(function(item)
91 return table.concat(
92 vim.tbl_map(function(col)
93 if type(col) == "table" then
94 return P.apply_hl(col[1], col[2])
95 else
96 return col
97 end
98 end, item.entry),
99 " "
100 )
101 end, items)
102end
103
104function P.pick(path, ...)
105 local rpath = table.concat({ "leetcode.picker", path, P.provider }, ".")
106 return require(rpath)(...)
107end
108
109function P.language(...)
110 P.pick("language", ...)
111end
112
113function P.question(...)
114 P.pick("question", ...)
115end
116
117function P.tabs()
118 local utils = require("leetcode.utils")
119 local tabs = utils.question_tabs()
120
121 if vim.tbl_isempty(tabs) then
122 return log.warn("No questions opened")
123 end
124
125 P.pick("tabs", tabs)
126end
127
128function P.hidden_field(text, deli)
129 return text:match(("([^%s]+)$"):format(deli))
130end
131
132return P