irongit

A Neovim plugin enabling you to solve LeetCode problems.

feat(parser): better highlight

kawreauthored
parent 3d1238ccommit 2d685b50330ee117022eb8aa25ca8a1d93d06651Browse files

4 files changed, +77 -63

+6-3lua/leetcode/parser/html.lua
@@ -1,4 +1,5 @@
11 ---TODO: 2659
2+---TODO: 1404
23 ---TODO: https://leetcode.com/problems/make-array-empty/
34 ---TODO: 190
45
@@ -139,10 +140,12 @@ end
139140 ---@private
140141 ---
141142 ---@param text string
142----@param tag_data lc.Parser.Tag
143+---@param tag_data lc.Parser.Tag|nil
143144 ---
144145 ---@return NuiLine
145146 function Html:handle_link(text, tag_data)
147+ if not tag_data then return NuiLine() end
148+
146149 local tag = tag_data.tag
147150 local link = ""
148151
@@ -177,8 +180,8 @@ end
177180 ---@private
178181 ---
179182 ---@param node TSNode
180----@param tags lc.Parser.Tag
181---@param tag_data lc.Parser.Tag
183+---@param tags string[]
184+---@param tag_data lc.Parser.Tag|nil
182185 function Html:node_hl(node, tags, tag_data)
183186 local text = self:get_text(node)
184187 local tag = tags[1]
+2-53lua/leetcode/parser/utils.lua
@@ -1,4 +1,5 @@
11 local log = require("leetcode.logger")
2+local theme = require("leetcode.theme")
23
34 ---@class lc.Parser.Utils
45 local utils = {}
@@ -37,43 +38,11 @@ local entities = {
3738 ["&lccode;"] = "`",
3839 }
3940
40-local xd = "header"
41-
42-local highlights = {
43- strong = "bold",
44- b = "bold",
45- em = "italic",
46- i = "italic",
47- code = "code",
48- a = "link",
49- u = "underline",
50-
51- example = "example",
52- constraints = "constraints",
53-
54- input = xd,
55- output = xd,
56- explanation = xd,
57-
58- -- pre = "",
59- -- span = "",
60- -- p = "",
61- -- ul = "",
62- -- ol = "",
63- -- li = "",
64- -- font = "",
65- -- sup = "",
66- -- sub = "",
67- -- small = "",
68- -- div = "",
69-}
70-
7141 ---@param entity string
7242 ---@return string
7343 function utils.entity(entity)
7444 if entities[entity] then
7545 return entities[entity]
76- -- return entity
7746 else
7847 log.error("unknown enitity: " .. entity)
7948 return entity
@@ -82,26 +51,6 @@ end
8251
8352 ---@param tags string[]
8453 ---@return string
85-function utils.hl(tags)
86- if vim.tbl_isempty(tags) then return "" end
87-
88- local name = "leetcode_dyn_" .. table.concat(tags, "_")
89- if _Lc_dyn_hl[name] then return name end
90-
91- local default = require("leetcode.theme.default").get()
92-
93- local theme = default["normal"]
94- for _, tag in ipairs(tags) do
95- local hl = highlights[tag]
96- if hl then theme = vim.tbl_deep_extend("force", theme, default[hl]) end
97- end
98-
99- if pcall(vim.api.nvim_set_hl, 0, name, theme) then
100- _Lc_dyn_hl[name] = theme
101- return name
102- else
103- return "leetcode_normal"
104- end
105-end
54+function utils.hl(tags) return theme.get_dynamic(vim.deepcopy(tags)) end
10655
10756 return utils
+3-2lua/leetcode/theme/default.lua
@@ -35,8 +35,9 @@ M.get = function()
3535
3636 normal = { fg = hl("Conceal").fg },
3737 alt = { fg = hl("Comment").fg },
38- italic = { fg = hl("Normal").fg, italic = true },
39- bold = { fg = hl("Normal").fg, bold = true },
38+
39+ italic = { italic = true },
40+ bold = { bold = true },
4041 underline = { underline = true },
4142
4243 code = { fg = hl("Type").fg, bg = hl("Normal").bg },
+66-5lua/leetcode/theme/init.lua
@@ -1,11 +1,30 @@
11 local devicons_ok, devicons = pcall(require, "nvim-web-devicons")
2+local log = require("leetcode.logger")
23 local config = require("leetcode.config")
34
45 ---@class lc.Theme
56 local theme = {}
67
7----@type table<string, table>
8-_Lc_dyn_hl = {}
8+---@type table<string, string[]>
9+local dynamic_hls = {}
10+
11+local highlights = {
12+ strong = "bold",
13+ b = "bold",
14+
15+ em = "italic",
16+ i = "italic",
17+
18+ u = "underline",
19+
20+ a = "link",
21+ example = "example",
22+ constraints = "constraints",
23+ code = "code",
24+ input = "header",
25+ output = "header",
26+ explanation = "header",
27+}
928
1029 function theme.load_devicons()
1130 vim.tbl_map(function(l)
@@ -19,10 +38,9 @@ function theme.load_devicons()
1938 end
2039
2140 function theme.load()
22- _Lc_dyn_hl = {}
41+ local defaults = require("leetcode.theme.default").get()
2342
24- local default = require("leetcode.theme.default").get()
25- for key, t in pairs(default) do
43+ for key, t in pairs(defaults) do
2644 key = "leetcode_" .. key
2745 vim.api.nvim_set_hl(0, key, t)
2846 end
@@ -32,6 +50,49 @@ function theme.load()
3250 local name = "leetcode_lang_" .. lang.slug
3351 vim.api.nvim_set_hl(0, name, { fg = lang.color })
3452 end
53+
54+ theme.load_dynamic(defaults)
55+end
56+
57+function theme.load_dynamic(defaults)
58+ log.debug(dynamic_hls)
59+ for name, tags in pairs(dynamic_hls) do
60+ theme.create_dynamic(name, tags, defaults)
61+ end
62+end
63+
64+---@param tags string[]
65+function theme.get_dynamic(tags)
66+ if vim.tbl_isempty(tags) then return "leetcode_normal" end
67+
68+ local name = "leetcode_dyn_" .. table.concat(tags, "_")
69+ if dynamic_hls[name] then return name end
70+
71+ return theme.create_dynamic(name, tags)
72+end
73+
74+---@param name string
75+---@param tags string[]
76+---@param defaults? table
77+function theme.create_dynamic(name, tags, defaults)
78+ defaults = defaults or require("leetcode.theme.default").get()
79+
80+ local t = defaults["normal"]
81+ for _, tag in ipairs(tags) do
82+ local hl = highlights[tag]
83+ if hl then t = vim.tbl_extend("force", t, defaults[hl]) end
84+ end
85+
86+ if t.italic or t.bold then
87+ if t.fg == defaults["normal"].fg then t.fg = defaults[""].fg end
88+ end
89+
90+ if pcall(vim.api.nvim_set_hl, 0, name, t) then
91+ dynamic_hls[name] = tags
92+ return name
93+ else
94+ return "leetcode_normal"
95+ end
3596 end
3697
3798 function theme.setup()