irongit

A Neovim plugin enabling you to solve LeetCode problems.

183 lines4.8 KBLua
1local Popup = require("leetcode-ui.popup")
2local NuiText = require("nui.text")
3local t = require("leetcode.translator")
4local Line = require("leetcode-ui.line")
5local NuiTree = require("nui.tree")
6local SimilarQuestions = require("leetcode-ui.group.similar-questions")
7local Parser = require("leetcode.parser")
8
9local config = require("leetcode.config")
10local keys = config.user.keys
11
12---@class lc.ui.InfoPopup : lc.ui.Popup
13---@field popup NuiPopup
14---@field question lc.ui.Question
15---@field hints table[]
16local Info = Popup:extend("LeetInfoPopup")
17
18function Info:similar_questions_node()
19 local nodes = SimilarQuestions:to_nodes(self.question.q.similar)
20
21 if not vim.tbl_isempty(nodes) then
22 return NuiTree.Node(
23 { text = NuiText(t("Similar Questions") .. "", "leetcode_ref") },
24 nodes
25 )
26 else
27 return NuiTree.Node({
28 text = NuiText("" .. t("No similar questions available"), "leetcode_error"),
29 })
30 end
31end
32
33function Info:hints_node()
34 local hints = {}
35 for i, hint_txt in ipairs(self.hints) do
36 local line = Line()
37
38 line:append(tostring(i), "leetcode_list")
39 line:append("/" .. #self.hints, "leetcode_alt")
40
41 local hint = NuiTree.Node({ text = line }, { NuiTree.Node({ text = hint_txt }) })
42 table.insert(hints, hint)
43 end
44
45 if not vim.tbl_isempty(hints) then
46 return NuiTree.Node({ text = NuiText(t("Hints") .. " 󰛨", "leetcode_hint") }, hints)
47 else
48 return NuiTree.Node({ text = NuiText("" .. t("No hints available"), "leetcode_error") })
49 end
50end
51
52function Info:topics_node()
53 local topics = {}
54 for _, topic in ipairs(self.question.q.topic_tags) do
55 local line = Line()
56
57 line:append("* ", "leetcode_list")
58 line:append(topic.name)
59
60 table.insert(topics, NuiTree.Node({ text = line }))
61 end
62
63 if not vim.tbl_isempty(topics) then
64 return NuiTree.Node({ text = NuiText(t("Topics") .. "", "Number") }, topics)
65 else
66 return NuiTree.Node({ text = NuiText("" .. t("No topics available"), "leetcode_error") })
67 end
68end
69
70function Info:populate()
71 local nodes = {
72 self:hints_node(),
73 NuiTree.Node({ text = "" }),
74 self:topics_node(),
75 NuiTree.Node({ text = " " }),
76 self:similar_questions_node(),
77 }
78
79 local tree = NuiTree({
80 bufnr = self.bufnr,
81 nodes = nodes,
82 prepare_node = function(node)
83 local line = Line()
84 line:append(string.rep(" ", node:get_depth() - 1))
85
86 if node:has_children() then
87 line:append(node:is_expanded() and "" or "", "leetcode_list")
88 line:append(node.text)
89 else
90 if type(node.text) == "string" then
91 line:append(" ")
92 local txt = Parser:parse(node.text)
93 if txt:lines()[1] then
94 line:append(txt:lines()[1])
95 end
96 else
97 line:append(node.text)
98 end
99 end
100
101 return line
102 end,
103 })
104
105 tree:render()
106
107 self:map("n", keys.confirm, function()
108 local node = tree:get_node()
109 if not node then
110 return
111 end
112
113 if node.text and node.text.press then
114 node.text:press()
115 end
116
117 if not node:is_expanded() then
118 node:expand()
119 else
120 node:collapse()
121 end
122
123 tree:render()
124 end, { noremap = true, nowait = true })
125end
126
127function Info:mount()
128 Info.super.mount(self)
129
130 self:populate()
131
132 local ui_utils = require("leetcode-ui.utils")
133 local winhighlight = "Normal:NormalSB,FloatBorder:FloatBorder"
134
135 ui_utils.win_set_opts(self.winid, {
136 winhighlight = winhighlight,
137 wrap = true,
138 })
139
140 ui_utils.win_set_opts(self.border.winid, {
141 winhighlight = winhighlight,
142 })
143
144 return self
145end
146
147---@param parent lc.ui.Question
148function Info:init(parent)
149 Info.super.init(self, {
150 position = "50%",
151 size = {
152 width = "50%",
153 height = "50%",
154 },
155 enter = true,
156 focusable = true,
157 relative = "editor",
158 border = {
159 padding = {
160 top = 2,
161 bottom = 2,
162 left = 3,
163 right = 3,
164 },
165 style = "rounded",
166 text = {
167 top = (" %s "):format(t("Question Info")),
168 },
169 },
170 buf_options = {
171 modifiable = false,
172 readonly = false,
173 },
174 })
175
176 self.hints = parent.q.hints
177 self.question = parent
178end
179
180---@type fun(parent: lc.ui.Question): lc.ui.InfoPopup
181local LeetInfoPopup = Info
182
183return LeetInfoPopup