A Neovim plugin enabling you to solve LeetCode problems.
feat(parser): better highlight
4 files changed, +77 -63
+6-3lua/leetcode/parser/html.lua
| @@ -1,4 +1,5 @@ | ||
| 1 | 1 | ---TODO: 2659 |
| 2 | +---TODO: 1404 | |
| 2 | 3 | ---TODO: https://leetcode.com/problems/make-array-empty/ |
| 3 | 4 | ---TODO: 190 |
| 4 | 5 | |
| @@ -139,10 +140,12 @@ end | ||
| 139 | 140 | ---@private |
| 140 | 141 | --- |
| 141 | 142 | ---@param text string |
| 142 | ----@param tag_data lc.Parser.Tag | |
| 143 | +---@param tag_data lc.Parser.Tag|nil | |
| 143 | 144 | --- |
| 144 | 145 | ---@return NuiLine |
| 145 | 146 | function Html:handle_link(text, tag_data) |
| 147 | + if not tag_data then return NuiLine() end | |
| 148 | + | |
| 146 | 149 | local tag = tag_data.tag |
| 147 | 150 | local link = "" |
| 148 | 151 | |
| @@ -177,8 +180,8 @@ end | ||
| 177 | 180 | ---@private |
| 178 | 181 | --- |
| 179 | 182 | ---@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 | |
| 182 | 185 | function Html:node_hl(node, tags, tag_data) |
| 183 | 186 | local text = self:get_text(node) |
| 184 | 187 | local tag = tags[1] |
+2-53lua/leetcode/parser/utils.lua
| @@ -1,4 +1,5 @@ | ||
| 1 | 1 | local log = require("leetcode.logger") |
| 2 | +local theme = require("leetcode.theme") | |
| 2 | 3 | |
| 3 | 4 | ---@class lc.Parser.Utils |
| 4 | 5 | local utils = {} |
| @@ -37,43 +38,11 @@ local entities = { | ||
| 37 | 38 | ["&lccode;"] = "`", |
| 38 | 39 | } |
| 39 | 40 | |
| 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 | - | |
| 71 | 41 | ---@param entity string |
| 72 | 42 | ---@return string |
| 73 | 43 | function utils.entity(entity) |
| 74 | 44 | if entities[entity] then |
| 75 | 45 | return entities[entity] |
| 76 | - -- return entity | |
| 77 | 46 | else |
| 78 | 47 | log.error("unknown enitity: " .. entity) |
| 79 | 48 | return entity |
| @@ -82,26 +51,6 @@ end | ||
| 82 | 51 | |
| 83 | 52 | ---@param tags string[] |
| 84 | 53 | ---@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 | |
| 106 | 55 | |
| 107 | 56 | return utils |
+3-2lua/leetcode/theme/default.lua
| @@ -35,8 +35,9 @@ M.get = function() | ||
| 35 | 35 | |
| 36 | 36 | normal = { fg = hl("Conceal").fg }, |
| 37 | 37 | 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 }, | |
| 40 | 41 | underline = { underline = true }, |
| 41 | 42 | |
| 42 | 43 | code = { fg = hl("Type").fg, bg = hl("Normal").bg }, |
+66-5lua/leetcode/theme/init.lua
| @@ -1,11 +1,30 @@ | ||
| 1 | 1 | local devicons_ok, devicons = pcall(require, "nvim-web-devicons") |
| 2 | +local log = require("leetcode.logger") | |
| 2 | 3 | local config = require("leetcode.config") |
| 3 | 4 | |
| 4 | 5 | ---@class lc.Theme |
| 5 | 6 | local theme = {} |
| 6 | 7 | |
| 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 | +} | |
| 9 | 28 | |
| 10 | 29 | function theme.load_devicons() |
| 11 | 30 | vim.tbl_map(function(l) |
| @@ -19,10 +38,9 @@ function theme.load_devicons() | ||
| 19 | 38 | end |
| 20 | 39 | |
| 21 | 40 | function theme.load() |
| 22 | - _Lc_dyn_hl = {} | |
| 41 | + local defaults = require("leetcode.theme.default").get() | |
| 23 | 42 | |
| 24 | - local default = require("leetcode.theme.default").get() | |
| 25 | - for key, t in pairs(default) do | |
| 43 | + for key, t in pairs(defaults) do | |
| 26 | 44 | key = "leetcode_" .. key |
| 27 | 45 | vim.api.nvim_set_hl(0, key, t) |
| 28 | 46 | end |
| @@ -32,6 +50,49 @@ function theme.load() | ||
| 32 | 50 | local name = "leetcode_lang_" .. lang.slug |
| 33 | 51 | vim.api.nvim_set_hl(0, name, { fg = lang.color }) |
| 34 | 52 | 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 | |
| 35 | 96 | end |
| 36 | 97 | |
| 37 | 98 | function theme.setup() |