irongit

A Neovim plugin enabling you to solve LeetCode problems.

feat(console): testcase virtual text

kawreauthored
parent 2d1de10commit dc0db6af41cf9c3b2633ee1668907766a717601aBrowse files

6 files changed, +93 -10

+2-0lua/leetcode/api/question.lua
@@ -56,6 +56,8 @@ function question.by_title_slug(title_slug)
5656 q.meta_data = select(2, pcall(utils.decode, q.meta_data))
5757 q.stats = select(2, pcall(utils.decode, q.stats))
5858
59+ log.debug(q.meta_data)
60+
5961 return q
6062 end
6163
+1-0lua/leetcode/api/types.lua
@@ -236,6 +236,7 @@
236236 ---@class lc.QuestionResponse.metadata
237237 ---@field manual boolean
238238 ---@field name string
239+---@field database boolean
239240 ---@field params metadata_param[]
240241 ---@field return metadata_return
241242
+2-0lua/leetcode/config/template.lua
@@ -70,6 +70,8 @@ local M = {
7070 },
7171
7272 testcase = {
73+ virt_text = true, ---@type boolean
74+
7375 size = "40%", ---@type string | integer
7476 },
7577 },
+1-0lua/leetcode/ui/console/init.lua
@@ -65,6 +65,7 @@ function console:init(parent)
6565 local keymap = {
6666 ["R"] = function() self:run() end,
6767 ["S"] = function() self:submit() end,
68+ ["r"] = function() self.testcase:reset() end,
6869 [{ "q", "<Esc>" }] = function() self:hide() end,
6970 }
7071
+82-6lua/leetcode/ui/console/testcase.lua
@@ -1,12 +1,12 @@
1-local Layout = require("leetcode-ui.layout")
2-local Text = require("leetcode-ui.component.text")
3-local NuiLine = require("nui.line")
41 local log = require("leetcode.logger")
2+local config = require("leetcode.config")
53 local NuiPopup = require("nui.popup")
64 local console_popup = require("leetcode.ui.console.popup")
75
86 ---@class lc.Testcase: lc.Console.Popup
97 ---@field testcases string[]
8+---@field init_testcases string[]
9+---@field extmarks integer[]
1010 local testcase = {}
1111 testcase.__index = testcase
1212 setmetatable(testcase, console_popup)
@@ -41,9 +41,82 @@ function testcase:draw()
4141
4242 vim.api.nvim_buf_set_lines(self.popup.bufnr, 0, -1, false, t)
4343
44+ self:draw_extmarks()
4445 return self
4546 end
4647
48+function testcase:clear_extmarks()
49+ if not config.user.console.testcase.virt_text then return end
50+
51+ local ns = vim.api.nvim_create_namespace("leetcode_extmarks")
52+ for _, id in ipairs(self.extmarks) do
53+ vim.api.nvim_buf_del_extmark(self.popup.bufnr, ns, id)
54+ end
55+
56+ self.extmarks = {}
57+end
58+
59+function testcase:add_extmark(line, col, opts)
60+ local ns = vim.api.nvim_create_namespace("leetcode_extmarks")
61+
62+ local id = vim.api.nvim_buf_set_extmark(self.popup.bufnr, ns, line, col, opts or {})
63+ table.insert(self.extmarks, id)
64+end
65+
66+function testcase:draw_extmarks()
67+ if not config.user.console.testcase.virt_text then return end
68+
69+ self:clear_extmarks()
70+ local bufnr = self.popup.bufnr
71+
72+ local md = self.parent.parent.q.meta_data
73+ local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
74+
75+ if not md.params then return end
76+
77+ local j = 1
78+ local invalid = false
79+
80+ for i, line in ipairs(lines) do
81+ pcall(function()
82+ if lines[i - 1] == "" and lines[i] == "" then invalid = true end
83+ end)
84+
85+ if line == "" then
86+ j = 1
87+ else
88+ local ok, text = pcall(
89+ function()
90+ return {
91+ { " " },
92+ { "", "Operator" },
93+ { " " },
94+ { md.params[j].name, "Comment" },
95+ { " " },
96+ { md.params[j].type, "Type" },
97+ }
98+ end
99+ )
100+ if not ok or invalid then text = { { " invalid", "leetcode_error" } } end
101+
102+ self:add_extmark(i - 1, -1, { virt_text = text })
103+ j = j + 1
104+ end
105+ end
106+end
107+
108+function testcase:reset()
109+ self:draw()
110+ log.info("Test cases have been reset")
111+end
112+
113+function testcase:autocmds()
114+ self.popup:on(
115+ { "TextChanged", "TextChangedI", "TextChangedP", "TextChangedT" },
116+ function() self:draw_extmarks() end
117+ )
118+end
119+
47120 ---@param parent lc.Console
48121 function testcase:init(parent)
49122 local popup = NuiPopup({
@@ -60,7 +133,7 @@ function testcase:init(parent)
60133 text = {
61134 top = " Console | (q) Hide ",
62135 top_align = "center",
63- bottom = " Testcase ",
136+ bottom = " Testcase | (r) Reset ",
64137 bottom_align = "center",
65138 },
66139 },
@@ -73,13 +146,16 @@ function testcase:init(parent)
73146 },
74147 })
75148
76- local obj = setmetatable({
149+ self = setmetatable({
77150 popup = popup,
78151 testcases = {},
152+ init_testcases = {},
153+ extmarks = {},
79154 parent = parent,
80155 }, self)
81156
82- return obj:draw()
157+ self:autocmds()
158+ return self:draw()
83159 end
84160
85161 return testcase
+5-4lua/leetcode/ui/question.lua
@@ -23,11 +23,12 @@ Question.__index = Question
2323 ---
2424 ---@return boolean
2525 local function is_sql(q)
26- for _, value in ipairs(q.topic_tags or {}) do
27- if value.slug == "database" then return true end
28- end
26+ -- for _, value in ipairs(q.topic_tags or {}) do
27+ -- if value.slug == "database" then return true end
28+ -- end
2929
30- return false
30+ -- return false
31+ return q.meta_data.database
3132 end
3233
3334 function Question:get_snippet()