A Neovim plugin enabling you to solve LeetCode problems.
stylua indent width=4
21 files changed, +412 -410
+1-1.stylua.toml
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | column_width = 100 |
| 2 | 2 | line_endings = "Unix" |
| 3 | 3 | indent_type = "Spaces" |
| 4 | -indent_width = 2 | |
| 4 | +indent_width = 4 | |
| 5 | 5 | quote_style = "ForceDouble" |
| 6 | 6 | call_parentheses = "Always" |
| 7 | 7 | collapse_simple_statement = "Always" |
+11-11lua/leetcode.lua
| @@ -5,19 +5,19 @@ local M = {} | ||
| 5 | 5 | |
| 6 | 6 | ---@param cfg? lc.Config |
| 7 | 7 | function M.setup(cfg) |
| 8 | - config.apply(cfg or {}) | |
| 8 | + config.apply(cfg or {}) | |
| 9 | 9 | |
| 10 | - vim.cmd([[highlight LcProblemEasy guifg=##00b8a3]]) | |
| 11 | - vim.cmd([[highlight LcProblemMedium guifg=#ffb800]]) | |
| 12 | - vim.cmd([[highlight LcProblemHard guifg=#ef4743]]) | |
| 10 | + vim.cmd([[highlight LcProblemEasy guifg=##00b8a3]]) | |
| 11 | + vim.cmd([[highlight LcProblemMedium guifg=#ffb800]]) | |
| 12 | + vim.cmd([[highlight LcProblemHard guifg=#ef4743]]) | |
| 13 | 13 | |
| 14 | - vim.api.nvim_create_autocmd("VimEnter", { | |
| 15 | - pattern = "*", | |
| 16 | - nested = true, | |
| 17 | - callback = function() | |
| 18 | - if config.user.invoke_name == vim.fn.expand("%") then api.cmd.leetcode() end | |
| 19 | - end, | |
| 20 | - }) | |
| 14 | + vim.api.nvim_create_autocmd("VimEnter", { | |
| 15 | + pattern = "*", | |
| 16 | + nested = true, | |
| 17 | + callback = function() | |
| 18 | + if config.user.invoke_name == vim.fn.expand("%") then api.cmd.leetcode() end | |
| 19 | + end, | |
| 20 | + }) | |
| 21 | 21 | end |
| 22 | 22 | |
| 23 | 23 | return M |
+53-53lua/leetcode/api/command/init.lua
| @@ -12,68 +12,68 @@ local path = require("plenary.path") | ||
| 12 | 12 | local M = {} |
| 13 | 13 | |
| 14 | 14 | function M.lc_problems() |
| 15 | - local _, res = assert(pcall(cache.problems.read)) | |
| 16 | - | |
| 17 | - ui.pick_one( | |
| 18 | - res, | |
| 19 | - "Select a Problem", | |
| 20 | - cache.problems.formatter, | |
| 21 | - | |
| 22 | - ---@param problem lc.Problem | |
| 23 | - function(problem) | |
| 24 | - if not problem then return end | |
| 25 | - | |
| 26 | - local dir = config.user.directory .. "/solutions/" | |
| 27 | - local fn = problem.index .. "." .. problem.title_slug .. ".java" | |
| 28 | - local file = path:new(dir .. fn) | |
| 29 | - | |
| 30 | - if not file:exists() then | |
| 31 | - local editor_data = gql.question.editor_data(problem.title_slug) | |
| 32 | - | |
| 33 | - local code | |
| 34 | - if editor_data.code_snippets ~= vim.NIL then | |
| 35 | - for _, v in ipairs(editor_data.code_snippets) do | |
| 36 | - if v.langSlug == config.user.lang or v.langSlug == config.user.sql then | |
| 37 | - code = v.code | |
| 38 | - break | |
| 15 | + local _, res = assert(pcall(cache.problems.read)) | |
| 16 | + | |
| 17 | + ui.pick_one( | |
| 18 | + res, | |
| 19 | + "Select a Problem", | |
| 20 | + cache.problems.formatter, | |
| 21 | + | |
| 22 | + ---@param problem lc.Problem | |
| 23 | + function(problem) | |
| 24 | + if not problem then return end | |
| 25 | + | |
| 26 | + local dir = config.user.directory .. "/solutions/" | |
| 27 | + local fn = problem.index .. "." .. problem.title_slug .. ".java" | |
| 28 | + local file = path:new(dir .. fn) | |
| 29 | + | |
| 30 | + if not file:exists() then | |
| 31 | + local editor_data = gql.question.editor_data(problem.title_slug) | |
| 32 | + | |
| 33 | + local code | |
| 34 | + if editor_data.code_snippets ~= vim.NIL then | |
| 35 | + for _, v in ipairs(editor_data.code_snippets) do | |
| 36 | + if v.langSlug == config.user.lang or v.langSlug == config.user.sql then | |
| 37 | + code = v.code | |
| 38 | + break | |
| 39 | + end | |
| 40 | + end | |
| 41 | + end | |
| 42 | + | |
| 43 | + if not code then | |
| 44 | + log.error("failed to fetch code snippet") | |
| 45 | + else | |
| 46 | + file:write(code, "w") | |
| 47 | + end | |
| 39 | 48 | end |
| 40 | - end | |
| 41 | - end | |
| 42 | - | |
| 43 | - if not code then | |
| 44 | - log.error("failed to fetch code snippet") | |
| 45 | - else | |
| 46 | - file:write(code, "w") | |
| 47 | - end | |
| 48 | - end | |
| 49 | 49 | |
| 50 | - vim.cmd("cd " .. dir) | |
| 51 | - vim.cmd("e " .. file:absolute()) | |
| 50 | + vim.cmd("cd " .. dir) | |
| 51 | + vim.cmd("e " .. file:absolute()) | |
| 52 | 52 | |
| 53 | - ui.create_leetcode_win(problem) | |
| 54 | - end | |
| 55 | - ) | |
| 53 | + ui.create_leetcode_win(problem) | |
| 54 | + end | |
| 55 | + ) | |
| 56 | 56 | end |
| 57 | 57 | |
| 58 | 58 | function M.leetcode() |
| 59 | - M.authenticate() | |
| 60 | - dashboard.setup() | |
| 61 | - vim.cmd("Alpha | bd#") | |
| 59 | + M.authenticate() | |
| 60 | + dashboard.setup() | |
| 61 | + vim.cmd("Alpha | bd#") | |
| 62 | 62 | end |
| 63 | 63 | |
| 64 | 64 | function M.cookie_prompt() |
| 65 | - local cookie = require("leetcode.cache.cookie") | |
| 66 | - | |
| 67 | - ui.input( | |
| 68 | - "Enter cookie", | |
| 69 | - ---@param cookie_str string | |
| 70 | - function(cookie_str) | |
| 71 | - if not cookie_str then return end | |
| 72 | - | |
| 73 | - cookie.new(cookie_str) | |
| 74 | - require("leetcode.ui.dashboard").update() | |
| 75 | - end | |
| 76 | - ) | |
| 65 | + local cookie = require("leetcode.cache.cookie") | |
| 66 | + | |
| 67 | + ui.input( | |
| 68 | + "Enter cookie", | |
| 69 | + ---@param cookie_str string | |
| 70 | + function(cookie_str) | |
| 71 | + if not cookie_str then return end | |
| 72 | + | |
| 73 | + cookie.new(cookie_str) | |
| 74 | + require("leetcode.ui.dashboard").update() | |
| 75 | + end | |
| 76 | + ) | |
| 77 | 77 | end |
| 78 | 78 | |
| 79 | 79 | ---Merge configurations into default configurations and set it as user configurations. |
+12-12lua/leetcode/api/headers.lua
| @@ -1,19 +1,19 @@ | ||
| 1 | 1 | local M = {} |
| 2 | 2 | |
| 3 | 3 | M.get = function() |
| 4 | - local cookie = require("leetcode.cache.cookie").read() | |
| 4 | + local cookie = require("leetcode.cache.cookie").read() | |
| 5 | 5 | |
| 6 | - return { | |
| 7 | - ["Cookie"] = cookie and string.format( | |
| 8 | - "LEETCODE_SESSION=%s;csrftoken=%s", | |
| 9 | - cookie.leetcode_session, | |
| 10 | - cookie.csrftoken | |
| 11 | - ) or "", | |
| 12 | - ["Content-Type"] = "application/json", | |
| 13 | - ["Accept"] = "application/json", | |
| 14 | - ["x-csrftoken"] = cookie and cookie.csrftoken or nil, | |
| 15 | - ["Referer"] = "https://leetcode.com", | |
| 16 | - } | |
| 6 | + return { | |
| 7 | + ["Cookie"] = cookie and string.format( | |
| 8 | + "LEETCODE_SESSION=%s;csrftoken=%s", | |
| 9 | + cookie.leetcode_session, | |
| 10 | + cookie.csrftoken | |
| 11 | + ) or "", | |
| 12 | + ["Content-Type"] = "application/json", | |
| 13 | + ["Accept"] = "application/json", | |
| 14 | + ["x-csrftoken"] = cookie and cookie.csrftoken or nil, | |
| 15 | + ["Referer"] = "https://leetcode.com", | |
| 16 | + } | |
| 17 | 17 | end |
| 18 | 18 | |
| 19 | 19 | return M |
+1-1lua/leetcode/api/init.lua
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | ---@class lc.Api |
| 2 | 2 | local Api = { |
| 3 | - cmd = require("leetcode.api.command"), | |
| 3 | + cmd = require("leetcode.api.command"), | |
| 4 | 4 | } |
| 5 | 5 | |
| 6 | 6 | return Api |
+17-17lua/leetcode/cache/cookie.lua
| @@ -12,23 +12,23 @@ local M = {} | ||
| 12 | 12 | --- |
| 13 | 13 | ---@return lc.Cookie |
| 14 | 14 | function M.new(cookie_str) |
| 15 | - local _, t = assert(pcall(M.parse, cookie_str)) | |
| 15 | + local _, t = assert(pcall(M.parse, cookie_str)) | |
| 16 | 16 | |
| 17 | - if not file:exists() then file:touch() end | |
| 18 | - file:write(cookie_str, "w") | |
| 17 | + if not file:exists() then file:touch() end | |
| 18 | + file:write(cookie_str, "w") | |
| 19 | 19 | |
| 20 | - return t | |
| 20 | + return t | |
| 21 | 21 | end |
| 22 | 22 | |
| 23 | 23 | ---@return lc.Cookie | nil |
| 24 | 24 | function M.read() |
| 25 | - local r_ok, contents = pcall(path.read, file) | |
| 26 | - if not r_ok then return end | |
| 25 | + local r_ok, contents = pcall(path.read, file) | |
| 26 | + if not r_ok then return end | |
| 27 | 27 | |
| 28 | - local n_ok, cookie = pcall(M.new, contents) | |
| 29 | - if not n_ok then return end | |
| 28 | + local n_ok, cookie = pcall(M.new, contents) | |
| 29 | + if not n_ok then return end | |
| 30 | 30 | |
| 31 | - return cookie | |
| 31 | + return cookie | |
| 32 | 32 | end |
| 33 | 33 | |
| 34 | 34 | function M.delete() file:rm() end |
| @@ -36,17 +36,17 @@ function M.delete() file:rm() end | ||
| 36 | 36 | ---@param cookie_str string |
| 37 | 37 | --- |
| 38 | 38 | function M.parse(cookie_str) |
| 39 | - local cookie = {} | |
| 39 | + local cookie = {} | |
| 40 | 40 | |
| 41 | - local csrf_ok, csrf = pcall(string.match, cookie_str, "csrftoken=[^;]+") | |
| 42 | - assert(csrf_ok and csrf, "Bad csrf token format") | |
| 43 | - cookie.csrftoken = csrf:sub(11) | |
| 41 | + local csrf_ok, csrf = pcall(string.match, cookie_str, "csrftoken=[^;]+") | |
| 42 | + assert(csrf_ok and csrf, "Bad csrf token format") | |
| 43 | + cookie.csrftoken = csrf:sub(11) | |
| 44 | 44 | |
| 45 | - local ls_ok, ls = pcall(string.match, cookie_str, "LEETCODE_SESSION=[^;]+") | |
| 46 | - assert(ls_ok and ls, "Bad leetcode session token format") | |
| 47 | - cookie.leetcode_session = ls:sub(18) | |
| 45 | + local ls_ok, ls = pcall(string.match, cookie_str, "LEETCODE_SESSION=[^;]+") | |
| 46 | + assert(ls_ok and ls, "Bad leetcode session token format") | |
| 47 | + cookie.leetcode_session = ls:sub(18) | |
| 48 | 48 | |
| 49 | - return cookie | |
| 49 | + return cookie | |
| 50 | 50 | end |
| 51 | 51 | |
| 52 | 52 | return M |
+3-3lua/leetcode/cache/init.lua
| @@ -1,8 +1,8 @@ | ||
| 1 | 1 | ---@class lc.Cache |
| 2 | 2 | local Cache = { |
| 3 | - cookie = require("leetcode.cache.cookie"), | |
| 4 | - problems = require("leetcode.cache.problems"), | |
| 5 | - -- solutions = require("leetcode.cache.solutions"), | |
| 3 | + cookie = require("leetcode.cache.cookie"), | |
| 4 | + problems = require("leetcode.cache.problems"), | |
| 5 | + -- solutions = require("leetcode.cache.solutions"), | |
| 6 | 6 | } |
| 7 | 7 | |
| 8 | 8 | return Cache |
+30-30lua/leetcode/cache/problems.lua
| @@ -16,62 +16,62 @@ local file = path:new(config.user.directory .. "/.problems") | ||
| 16 | 16 | local M = {} |
| 17 | 17 | |
| 18 | 18 | local function populate() |
| 19 | - file:touch() | |
| 20 | - local problems = assert(gql.problems.all()) | |
| 21 | - file:write(vim.json.encode(problems), "w") | |
| 19 | + file:touch() | |
| 20 | + local problems = assert(gql.problems.all()) | |
| 21 | + file:write(vim.json.encode(problems), "w") | |
| 22 | 22 | end |
| 23 | 23 | |
| 24 | 24 | ---@return lc.Problem[] | nil |
| 25 | 25 | function M.read() |
| 26 | - async.run(M.update) | |
| 26 | + async.run(M.update) | |
| 27 | 27 | |
| 28 | - local contents = file:read() | |
| 28 | + local contents = file:read() | |
| 29 | 29 | |
| 30 | - local ok, problems = pcall(M.parse, contents) | |
| 31 | - if not ok then return end | |
| 30 | + local ok, problems = pcall(M.parse, contents) | |
| 31 | + if not ok then return end | |
| 32 | 32 | |
| 33 | - return problems | |
| 33 | + return problems | |
| 34 | 34 | end |
| 35 | 35 | |
| 36 | 36 | function M.update() |
| 37 | - local stats = file:_stat() | |
| 37 | + local stats = file:_stat() | |
| 38 | 38 | |
| 39 | - if vim.tbl_isempty(stats) then | |
| 40 | - assert(populate()) | |
| 41 | - return | |
| 42 | - end | |
| 39 | + if vim.tbl_isempty(stats) then | |
| 40 | + assert(populate()) | |
| 41 | + return | |
| 42 | + end | |
| 43 | 43 | |
| 44 | - local mod_time = stats.mtime.sec | |
| 45 | - local curr_time = os.time() | |
| 44 | + local mod_time = stats.mtime.sec | |
| 45 | + local curr_time = os.time() | |
| 46 | 46 | |
| 47 | - if (curr_time - mod_time) > 60 * 60 * 24 * 7 then | |
| 48 | - -- logger.info("Updating cache. This way take a while...") | |
| 49 | - assert(populate()) | |
| 50 | - end | |
| 47 | + if (curr_time - mod_time) > 60 * 60 * 24 * 7 then | |
| 48 | + -- logger.info("Updating cache. This way take a while...") | |
| 49 | + assert(populate()) | |
| 50 | + end | |
| 51 | 51 | end |
| 52 | 52 | |
| 53 | 53 | ---@param problem lc.Problem |
| 54 | 54 | --- |
| 55 | 55 | ---@return string |
| 56 | 56 | M.formatter = function(problem) |
| 57 | - return string.format( | |
| 58 | - "%d. %s (%d%%, %s)", | |
| 59 | - problem.index, | |
| 60 | - problem.title, | |
| 61 | - problem.ac_rate, | |
| 62 | - problem.difficulty | |
| 63 | - ) | |
| 57 | + return string.format( | |
| 58 | + "%d. %s (%d%%, %s)", | |
| 59 | + problem.index, | |
| 60 | + problem.title, | |
| 61 | + problem.ac_rate, | |
| 62 | + problem.difficulty | |
| 63 | + ) | |
| 64 | 64 | end |
| 65 | 65 | |
| 66 | 66 | ---@param problems_str string |
| 67 | 67 | --- |
| 68 | 68 | ---@return lc.Problem[] |
| 69 | 69 | function M.parse(problems_str) |
| 70 | - ---@type boolean, lc.Problem[] | |
| 71 | - local ok, problems = pcall(vim.json.decode, problems_str) | |
| 72 | - assert(ok) | |
| 70 | + ---@type boolean, lc.Problem[] | |
| 71 | + local ok, problems = pcall(vim.json.decode, problems_str) | |
| 72 | + assert(ok) | |
| 73 | 73 | |
| 74 | - return problems | |
| 74 | + return problems | |
| 75 | 75 | end |
| 76 | 76 | |
| 77 | 77 | return M |
+5-5lua/leetcode/config/init.lua
| @@ -2,8 +2,8 @@ local template = require("leetcode.config.template") | ||
| 2 | 2 | |
| 3 | 3 | ---@class lc.Settings |
| 4 | 4 | local Config = { |
| 5 | - name = "leetcode.nvim", | |
| 6 | - debug = true, | |
| 5 | + name = "leetcode.nvim", | |
| 6 | + debug = true, | |
| 7 | 7 | } |
| 8 | 8 | |
| 9 | 9 | ---Default configurations. |
| @@ -23,10 +23,10 @@ Config.auth = nil | ||
| 23 | 23 | --- |
| 24 | 24 | ---@param cfg lc.Config Configurations to be merged. |
| 25 | 25 | function Config.apply(cfg) |
| 26 | - Config.user = vim.tbl_deep_extend("force", template, cfg) | |
| 26 | + Config.user = vim.tbl_deep_extend("force", template, cfg) | |
| 27 | 27 | |
| 28 | - local ok, notify = pcall(require, "notify") | |
| 29 | - if ok then vim.notify = notify end | |
| 28 | + local ok, notify = pcall(require, "notify") | |
| 29 | + if ok then vim.notify = notify end | |
| 30 | 30 | end |
| 31 | 31 | |
| 32 | 32 | ---Merge configurations into default configurations and set it as user configurations. |
+16-16lua/leetcode/config/template.lua
| @@ -1,26 +1,26 @@ | ||
| 1 | 1 | ---@class lc.Config |
| 2 | 2 | local M = { |
| 3 | - ---@type string | |
| 4 | - domain = "com", | |
| 3 | + ---@type string | |
| 4 | + domain = "com", | |
| 5 | 5 | |
| 6 | - ---@type string | |
| 7 | - invoke_name = "leetcode.nvim", | |
| 6 | + ---@type string | |
| 7 | + invoke_name = "leetcode.nvim", | |
| 8 | 8 | |
| 9 | - ---@type string | |
| 10 | - lang = "java", | |
| 9 | + ---@type string | |
| 10 | + lang = "java", | |
| 11 | 11 | |
| 12 | - ---@type | |
| 13 | - ---| "pythondata" | |
| 14 | - ---| "mysql" | |
| 15 | - ---| "mssql" | |
| 16 | - ---| "oraclesql" | |
| 17 | - sql = "mysql", | |
| 12 | + ---@type | |
| 13 | + ---| "pythondata" | |
| 14 | + ---| "mysql" | |
| 15 | + ---| "mssql" | |
| 16 | + ---| "oraclesql" | |
| 17 | + sql = "mysql", | |
| 18 | 18 | |
| 19 | - ---@type string | |
| 20 | - directory = vim.fn.stdpath("data") .. "/leetcode", | |
| 19 | + ---@type string | |
| 20 | + directory = vim.fn.stdpath("data") .. "/leetcode", | |
| 21 | 21 | |
| 22 | - ---@type boolean | |
| 23 | - logging = true, | |
| 22 | + ---@type boolean | |
| 23 | + logging = true, | |
| 24 | 24 | } |
| 25 | 25 | |
| 26 | 26 | return M |
+6-6lua/leetcode/graphql/auth.lua
| @@ -12,7 +12,7 @@ local M = {} | ||
| 12 | 12 | |
| 13 | 13 | ---@return lc.UserStatus | nil |
| 14 | 14 | function M.user_status() |
| 15 | - local query = [[ | |
| 15 | + local query = [[ | |
| 16 | 16 | query globalData { |
| 17 | 17 | userStatus { |
| 18 | 18 | userId |
| @@ -26,13 +26,13 @@ function M.user_status() | ||
| 26 | 26 | } |
| 27 | 27 | ]] |
| 28 | 28 | |
| 29 | - local ok, res = pcall(gql.query, query) | |
| 30 | - if not ok then return end | |
| 29 | + local ok, res = pcall(gql.query, query) | |
| 30 | + if not ok then return end | |
| 31 | 31 | |
| 32 | - local status = res["userStatus"] | |
| 33 | - config.authenticate(status) | |
| 32 | + local status = res["userStatus"] | |
| 33 | + config.authenticate(status) | |
| 34 | 34 | |
| 35 | - return res["userStatus"] | |
| 35 | + return res["userStatus"] | |
| 36 | 36 | end |
| 37 | 37 | |
| 38 | 38 | return M |
+3-3lua/leetcode/graphql/init.lua
| @@ -1,8 +1,8 @@ | ||
| 1 | 1 | ---@class lc.Graphql |
| 2 | 2 | local Gql = { |
| 3 | - problems = require("leetcode.graphql.problems"), | |
| 4 | - question = require("leetcode.graphql.question"), | |
| 5 | - auth = require("leetcode.graphql.auth"), | |
| 3 | + problems = require("leetcode.graphql.problems"), | |
| 4 | + question = require("leetcode.graphql.question"), | |
| 5 | + auth = require("leetcode.graphql.auth"), | |
| 6 | 6 | } |
| 7 | 7 | |
| 8 | 8 | return Gql |
+15-15lua/leetcode/graphql/problems.lua
| @@ -6,7 +6,7 @@ local M = {} | ||
| 6 | 6 | |
| 7 | 7 | ---@return integer |
| 8 | 8 | function M.total_num() |
| 9 | - local query = [[ | |
| 9 | + local query = [[ | |
| 10 | 10 | query problemsetQuestionList { |
| 11 | 11 | problemsetQuestionList: questionList( |
| 12 | 12 | categorySlug: "" |
| @@ -17,18 +17,18 @@ function M.total_num() | ||
| 17 | 17 | } |
| 18 | 18 | ]] |
| 19 | 19 | |
| 20 | - local total = gql.query(query)["problemsetQuestionList"]["total"] | |
| 20 | + local total = gql.query(query)["problemsetQuestionList"]["total"] | |
| 21 | 21 | |
| 22 | - return total | |
| 22 | + return total | |
| 23 | 23 | end |
| 24 | 24 | |
| 25 | 25 | ---@return lc.Problem[] |
| 26 | 26 | function M.all() |
| 27 | - local variables = { | |
| 28 | - limit = 3000, | |
| 29 | - } | |
| 27 | + local variables = { | |
| 28 | + limit = 3000, | |
| 29 | + } | |
| 30 | 30 | |
| 31 | - local query = [[ | |
| 31 | + local query = [[ | |
| 32 | 32 | query problemsetQuestionList($limit: Int) { |
| 33 | 33 | problemsetQuestionList: questionList( |
| 34 | 34 | categorySlug: "" |
| @@ -46,14 +46,14 @@ function M.all() | ||
| 46 | 46 | } |
| 47 | 47 | ]] |
| 48 | 48 | |
| 49 | - local ok, res = pcall(gql.query, query, variables) | |
| 50 | - assert(ok) | |
| 49 | + local ok, res = pcall(gql.query, query, variables) | |
| 50 | + assert(ok) | |
| 51 | 51 | |
| 52 | - return res["problemsetQuestionList"]["questions"] | |
| 52 | + return res["problemsetQuestionList"]["questions"] | |
| 53 | 53 | end |
| 54 | 54 | |
| 55 | 55 | function M.question_of_today() |
| 56 | - local query = [[ | |
| 56 | + local query = [[ | |
| 57 | 57 | query questionOfToday { |
| 58 | 58 | activeDailyCodingChallengeQuestion { |
| 59 | 59 | userStatus |
| @@ -73,12 +73,12 @@ function M.question_of_today() | ||
| 73 | 73 | } |
| 74 | 74 | ]] |
| 75 | 75 | |
| 76 | - local ok, res = pcall(gql.query, query) | |
| 77 | - assert(ok) | |
| 76 | + local ok, res = pcall(gql.query, query) | |
| 77 | + assert(ok) | |
| 78 | 78 | |
| 79 | - logger.inspect(res) | |
| 79 | + logger.inspect(res) | |
| 80 | 80 | |
| 81 | - return res["activeDailyCodingChallengeQuestion"] | |
| 81 | + return res["activeDailyCodingChallengeQuestion"] | |
| 82 | 82 | end |
| 83 | 83 | |
| 84 | 84 | return M |
+19-19lua/leetcode/graphql/question.lua
| @@ -10,11 +10,11 @@ local M = {} | ||
| 10 | 10 | --- |
| 11 | 11 | ---@return lc.Question.Content |
| 12 | 12 | function M.content(title_slug) |
| 13 | - local variables = { | |
| 14 | - titleSlug = title_slug, | |
| 15 | - } | |
| 13 | + local variables = { | |
| 14 | + titleSlug = title_slug, | |
| 15 | + } | |
| 16 | 16 | |
| 17 | - local query = [[ | |
| 17 | + local query = [[ | |
| 18 | 18 | query questionContent($titleSlug: String!) { |
| 19 | 19 | question(titleSlug: $titleSlug) { |
| 20 | 20 | content |
| @@ -24,19 +24,19 @@ function M.content(title_slug) | ||
| 24 | 24 | } |
| 25 | 25 | ]] |
| 26 | 26 | |
| 27 | - local ok, res = pcall(gql.query, query, variables) | |
| 28 | - assert(ok) | |
| 27 | + local ok, res = pcall(gql.query, query, variables) | |
| 28 | + assert(ok) | |
| 29 | 29 | |
| 30 | - return res["question"] | |
| 30 | + return res["question"] | |
| 31 | 31 | end |
| 32 | 32 | |
| 33 | 33 | ---@param title_slug string |
| 34 | 34 | function M.editor_data(title_slug) |
| 35 | - local variables = { | |
| 36 | - titleSlug = title_slug, | |
| 37 | - } | |
| 35 | + local variables = { | |
| 36 | + titleSlug = title_slug, | |
| 37 | + } | |
| 38 | 38 | |
| 39 | - local query = [[ | |
| 39 | + local query = [[ | |
| 40 | 40 | query questionEditorData($titleSlug: String!) { |
| 41 | 41 | question(titleSlug: $titleSlug) { |
| 42 | 42 | questionId |
| @@ -54,19 +54,19 @@ function M.editor_data(title_slug) | ||
| 54 | 54 | } |
| 55 | 55 | ]] |
| 56 | 56 | |
| 57 | - local ok, res = pcall(gql.query, query, variables) | |
| 58 | - assert(ok) | |
| 57 | + local ok, res = pcall(gql.query, query, variables) | |
| 58 | + assert(ok) | |
| 59 | 59 | |
| 60 | - return res["question"] | |
| 60 | + return res["question"] | |
| 61 | 61 | end |
| 62 | 62 | |
| 63 | 63 | ---@param title_slug string |
| 64 | 64 | function M.title(title_slug) |
| 65 | - local variables = { | |
| 66 | - titleSlug = title_slug, | |
| 67 | - } | |
| 65 | + local variables = { | |
| 66 | + titleSlug = title_slug, | |
| 67 | + } | |
| 68 | 68 | |
| 69 | - local query = [[ | |
| 69 | + local query = [[ | |
| 70 | 70 | query questionTitle($titleSlug: String!) { |
| 71 | 71 | question(titleSlug: $titleSlug) { |
| 72 | 72 | questionId |
| @@ -82,7 +82,7 @@ function M.title(title_slug) | ||
| 82 | 82 | } |
| 83 | 83 | ]] |
| 84 | 84 | |
| 85 | - return gql.query(query, variables)["question"] | |
| 85 | + return gql.query(query, variables)["question"] | |
| 86 | 86 | end |
| 87 | 87 | |
| 88 | 88 | return M |
+10-10lua/leetcode/graphql/utils.lua
| @@ -13,18 +13,18 @@ local M = {} | ||
| 13 | 13 | --- |
| 14 | 14 | ---@return table |
| 15 | 15 | function M.query(query, variables) |
| 16 | - local response = curl.post(endpoint, { | |
| 17 | - headers = headers.get(), | |
| 18 | - body = vim.json.encode({ | |
| 19 | - query = query, | |
| 20 | - variables = variables or {}, | |
| 21 | - }), | |
| 22 | - }) | |
| 16 | + local response = curl.post(endpoint, { | |
| 17 | + headers = headers.get(), | |
| 18 | + body = vim.json.encode({ | |
| 19 | + query = query, | |
| 20 | + variables = variables or {}, | |
| 21 | + }), | |
| 22 | + }) | |
| 23 | 23 | |
| 24 | - local ok, data = pcall(vim.json.decode, response["body"]) | |
| 25 | - assert(ok and data and data["data"], "Failed to query data") | |
| 24 | + local ok, data = pcall(vim.json.decode, response["body"]) | |
| 25 | + assert(ok and data and data["data"], "Failed to query data") | |
| 26 | 26 | |
| 27 | - return data["data"] | |
| 27 | + return data["data"] | |
| 28 | 28 | end |
| 29 | 29 | |
| 30 | 30 | return M |
+4-4lua/leetcode/logger/init.lua
| @@ -7,8 +7,8 @@ local Logger = {} | ||
| 7 | 7 | ---@param msg string |
| 8 | 8 | ---@param lvl? integer |
| 9 | 9 | Logger.log = function(msg, lvl) |
| 10 | - if not config.user.logging then return end | |
| 11 | - vim.notify(msg, lvl or levels.INFO, { title = config.name }) | |
| 10 | + if not config.user.logging then return end | |
| 11 | + vim.notify(msg, lvl or levels.INFO, { title = config.name }) | |
| 12 | 12 | end |
| 13 | 13 | |
| 14 | 14 | ---@param msg string |
| @@ -25,8 +25,8 @@ Logger.error = function(msg) Logger.log(msg, levels.ERROR) end | ||
| 25 | 25 | |
| 26 | 26 | ---@param msg string |
| 27 | 27 | Logger.debug = function(msg) |
| 28 | - if not config.debug then return end | |
| 29 | - Logger.log(msg, levels.DEBUG) | |
| 28 | + if not config.debug then return end | |
| 29 | + Logger.log(msg, levels.DEBUG) | |
| 30 | 30 | end |
| 31 | 31 | |
| 32 | 32 | return Logger |
+1-1lua/leetcode/ui/components/init.lua
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | ---@class lc.Ui.Components |
| 2 | 2 | local Components = { |
| 3 | - problem = require("leetcode.ui.components.problem"), | |
| 3 | + problem = require("leetcode.ui.components.problem"), | |
| 4 | 4 | } |
| 5 | 5 | |
| 6 | 6 | return Components |
+54-52lua/leetcode/ui/components/problem.lua
| @@ -11,89 +11,91 @@ local M = {} | ||
| 11 | 11 | |
| 12 | 12 | ---@param title any |
| 13 | 13 | function M.title(title) |
| 14 | - local line = Line() | |
| 14 | + local line = Line() | |
| 15 | 15 | |
| 16 | - line:append(title.questionFrontendId .. ". " .. title.title) | |
| 16 | + line:append(title.questionFrontendId .. ". " .. title.title) | |
| 17 | 17 | |
| 18 | - return line | |
| 18 | + return line | |
| 19 | 19 | end |
| 20 | 20 | |
| 21 | 21 | ---@param title_slug string |
| 22 | 22 | function M.link(title_slug) |
| 23 | - local line = Line() | |
| 23 | + local line = Line() | |
| 24 | 24 | |
| 25 | - line:append("https://leetcode.com/problems/" .. title_slug .. "/", "Comment") | |
| 26 | - line:append("") | |
| 25 | + line:append("https://leetcode.com/problems/" .. title_slug .. "/", "Comment") | |
| 26 | + line:append("") | |
| 27 | 27 | |
| 28 | - return line | |
| 28 | + return line | |
| 29 | 29 | end |
| 30 | 30 | |
| 31 | 31 | ---@param title any |
| 32 | 32 | function M.stats(title) |
| 33 | - local line = Line() | |
| 34 | - | |
| 35 | - line:append( | |
| 36 | - title.difficulty, | |
| 37 | - title.difficulty == "Easy" and "DiagnosticOk" | |
| 38 | - or title.difficulty == "Medium" and "DiagnosticWarn" | |
| 39 | - or "DiagnosticError" | |
| 40 | - ) | |
| 41 | - line:append(" | ") | |
| 42 | - line:append(title.likes .. " ", "Comment") | |
| 43 | - line:append(title.dislikes .. " ", "Comment") | |
| 44 | - | |
| 45 | - return line | |
| 33 | + local line = Line() | |
| 34 | + | |
| 35 | + line:append( | |
| 36 | + title.difficulty, | |
| 37 | + title.difficulty == "Easy" and "DiagnosticOk" | |
| 38 | + or title.difficulty == "Medium" and "DiagnosticWarn" | |
| 39 | + or "DiagnosticError" | |
| 40 | + ) | |
| 41 | + line:append(" | ") | |
| 42 | + line:append(title.likes .. " ", "Comment") | |
| 43 | + line:append(title.dislikes .. " ", "Comment") | |
| 44 | + | |
| 45 | + return line | |
| 46 | 46 | end |
| 47 | 47 | |
| 48 | 48 | ---@param content any |
| 49 | 49 | function M.content(content) |
| 50 | - local line = Line() | |
| 50 | + local line = Line() | |
| 51 | 51 | |
| 52 | - local s = vim.split(content.content, "\n\n<p> </p>\n", { trimempty = true }) | |
| 52 | + local s = vim.split(content.content, "\n\n", { trimempty = true }) | |
| 53 | 53 | |
| 54 | - local desc = M.description(s[1]) | |
| 55 | - local exam = M.examples(s[2]) | |
| 56 | - local cons = M.constrains(s[3]) | |
| 57 | - local foll = M.follow_up(s[4]) | |
| 54 | + for _, v in ipairs(s) do | |
| 55 | + log.info(v) | |
| 56 | + end | |
| 57 | + | |
| 58 | + -- local desc = M.description(s[1]) | |
| 59 | + -- line:append(desc) | |
| 60 | + | |
| 61 | + -- local exam = M.examples(s[2]) | |
| 62 | + -- local cons = M.constrains(s[3]) | |
| 63 | + -- local foll = M.follow_up(s[4]) | |
| 58 | 64 | |
| 59 | - line:append({ desc, exam, cons, foll }) | |
| 65 | + -- line:append({ desc, exam, cons, foll }) | |
| 60 | 66 | |
| 61 | - return line | |
| 67 | + return line | |
| 62 | 68 | end |
| 63 | 69 | |
| 64 | 70 | ---@param p string |
| 65 | 71 | local parse_paragraph = function(p) |
| 66 | - -- for s in vim.gsplit(p, " ", { trimempty = true }) do | |
| 67 | - -- log.info(s) | |
| 68 | - -- end | |
| 69 | - | |
| 70 | - local ts = vim.treesitter | |
| 71 | - local parser = ts.get_string_parser(p, "html") | |
| 72 | - | |
| 73 | - local tree = parser:parse()[1] | |
| 74 | - local function get_text(node) | |
| 75 | - local text = {} | |
| 76 | - for _, child in ipairs(node) do | |
| 77 | - if child:type() == "text" then | |
| 78 | - table.insert(text, child:subtree_text()) | |
| 79 | - elseif child:named() then | |
| 80 | - table.insert(text, get_text(child)) | |
| 81 | - end | |
| 72 | + local ts = vim.treesitter | |
| 73 | + local parser = ts.get_string_parser(p, "html") | |
| 74 | + local tree = parser:parse()[1] | |
| 75 | + | |
| 76 | + local t = {} | |
| 77 | + local function get_text(node, text) | |
| 78 | + for child in node:iter_children() do | |
| 79 | + if child:type() == "text" then | |
| 80 | + local txt = ts.get_node_text(child, p) | |
| 81 | + table.insert(text, txt) | |
| 82 | + elseif child:named() then | |
| 83 | + get_text(child, text) | |
| 84 | + end | |
| 85 | + end | |
| 82 | 86 | end |
| 83 | - return table.concat(text) | |
| 84 | - end | |
| 85 | - local text = get_text(tree:root()) | |
| 87 | + get_text(tree:root(), t) | |
| 86 | 88 | |
| 87 | - log.info(text) | |
| 89 | + return table.concat(t, " ") | |
| 88 | 90 | end |
| 89 | 91 | |
| 90 | 92 | ---@param description string |
| 91 | 93 | function M.description(description) |
| 92 | - local lines = { "Description:" } | |
| 94 | + local lines = { "Description:" } | |
| 93 | 95 | |
| 94 | - for v in vim.gsplit(description, "\n\n", { trimempty = true }) do | |
| 95 | - parse_paragraph(utils.strip_html_tag(v, "p")) | |
| 96 | - end | |
| 96 | + -- for v in vim.gsplit(description, "\n\n", { trimempty = true }) do | |
| 97 | + return parse_paragraph(description) | |
| 98 | + -- end | |
| 97 | 99 | end |
| 98 | 100 | |
| 99 | 101 | ---@param examples string |
+106-106lua/leetcode/ui/dashboard.lua
| @@ -6,130 +6,130 @@ local log = require("leetcode.logger") | ||
| 6 | 6 | local M = {} |
| 7 | 7 | |
| 8 | 8 | local header = { |
| 9 | - type = "text", | |
| 10 | - val = { | |
| 11 | - [[ /$$ /$$ /$$$$$$ /$$ ]], | |
| 12 | - [[| $$ | $$ /$$__ $$ | $$ ]], | |
| 13 | - [[| $$ /$$$$$$ /$$$$$$ /$$$$$$ | $$ \__/ /$$$$$$ /$$$$$$$ /$$$$$$ ]], | |
| 14 | - [[| $$ /$$__ $$/$$__ $|_ $$_/ | $$ /$$__ $$/$$__ $$/$$__ $$]], | |
| 15 | - [[| $$ | $$$$$$$| $$$$$$$$ | $$ | $$ | $$ \ $| $$ | $| $$$$$$$$]], | |
| 16 | - [[| $$ | $$_____| $$_____/ | $$ /$| $$ $| $$ | $| $$ | $| $$_____/]], | |
| 17 | - [[| $$$$$$$| $$$$$$| $$$$$$$ | $$$$| $$$$$$| $$$$$$| $$$$$$| $$$$$$$]], | |
| 18 | - [[|________/\_______/\_______/ \___/ \______/ \______/ \_______/\_______/]], | |
| 19 | - }, | |
| 20 | - opts = { | |
| 21 | - position = "center", | |
| 22 | - hl = "Keyword", | |
| 23 | - }, | |
| 9 | + type = "text", | |
| 10 | + val = { | |
| 11 | + [[ /$$ /$$ /$$$$$$ /$$ ]], | |
| 12 | + [[| $$ | $$ /$$__ $$ | $$ ]], | |
| 13 | + [[| $$ /$$$$$$ /$$$$$$ /$$$$$$ | $$ \__/ /$$$$$$ /$$$$$$$ /$$$$$$ ]], | |
| 14 | + [[| $$ /$$__ $$/$$__ $|_ $$_/ | $$ /$$__ $$/$$__ $$/$$__ $$]], | |
| 15 | + [[| $$ | $$$$$$$| $$$$$$$$ | $$ | $$ | $$ \ $| $$ | $| $$$$$$$$]], | |
| 16 | + [[| $$ | $$_____| $$_____/ | $$ /$| $$ $| $$ | $| $$ | $| $$_____/]], | |
| 17 | + [[| $$$$$$$| $$$$$$| $$$$$$$ | $$$$| $$$$$$| $$$$$$| $$$$$$| $$$$$$$]], | |
| 18 | + [[|________/\_______/\_______/ \___/ \______/ \______/ \_______/\_______/]], | |
| 19 | + }, | |
| 20 | + opts = { | |
| 21 | + position = "center", | |
| 22 | + hl = "Keyword", | |
| 23 | + }, | |
| 24 | 24 | } |
| 25 | 25 | |
| 26 | 26 | local notifications = { |
| 27 | - type = "text", | |
| 28 | - val = {}, | |
| 29 | - opts = { | |
| 30 | - position = "center", | |
| 31 | - hl = "DiagnosticInfo", | |
| 32 | - }, | |
| 27 | + type = "text", | |
| 28 | + val = {}, | |
| 29 | + opts = { | |
| 30 | + position = "center", | |
| 31 | + hl = "DiagnosticInfo", | |
| 32 | + }, | |
| 33 | 33 | } |
| 34 | 34 | |
| 35 | 35 | local buttons = { |
| 36 | - type = "group", | |
| 37 | - val = {}, | |
| 38 | - opts = { | |
| 39 | - spacing = 1, | |
| 40 | - }, | |
| 36 | + type = "group", | |
| 37 | + val = {}, | |
| 38 | + opts = { | |
| 39 | + spacing = 1, | |
| 40 | + }, | |
| 41 | 41 | } |
| 42 | 42 | |
| 43 | 43 | local footer = { |
| 44 | - type = "text", | |
| 45 | - val = {}, | |
| 46 | - opts = { | |
| 47 | - position = "center", | |
| 48 | - hl = "Number", | |
| 49 | - }, | |
| 44 | + type = "text", | |
| 45 | + val = {}, | |
| 46 | + opts = { | |
| 47 | + position = "center", | |
| 48 | + hl = "Number", | |
| 49 | + }, | |
| 50 | 50 | } |
| 51 | 51 | |
| 52 | 52 | function M.setup() |
| 53 | - local auth = config.auth | |
| 54 | - local is_signed_in = auth and auth.is_signed_in | |
| 55 | - | |
| 56 | - local alpha = require("alpha") | |
| 57 | - local dashboard = require("alpha.themes.dashboard") | |
| 58 | - | |
| 59 | - notifications.val = not is_signed_in and { " Sign in to use LeetCode.nvim" } or {} | |
| 60 | - | |
| 61 | - buttons.val = is_signed_in | |
| 62 | - and { | |
| 63 | - dashboard.button( | |
| 64 | - "p", | |
| 65 | - " " .. " All Problems", | |
| 66 | - "<cmd>lua require('leetcode.api').cmd.lc_problems()<CR>" | |
| 67 | - ), | |
| 68 | - dashboard.button( | |
| 69 | - "t", | |
| 70 | - " " .. " Question of today", | |
| 71 | - "<cmd>lua require('leetcode.api').gql.problems.question_of_today()<CR>" | |
| 72 | - ), | |
| 73 | - dashboard.button("r", " " .. " Recent problems", ""), | |
| 74 | - dashboard.button( | |
| 75 | - "c", | |
| 76 | - " " .. " Update cookie", | |
| 77 | - "<cmd>lua require('leetcode.api').cmd.cookie_prompt()<cr>" | |
| 78 | - ), | |
| 79 | - dashboard.button( | |
| 80 | - "s", | |
| 81 | - " " .. " Sign out", | |
| 82 | - "<cmd>lua require('leetcode.utils').remove_cookie()<cr>" | |
| 83 | - ), | |
| 84 | - dashboard.button("q", " " .. " Exit LeetCode", "<cmd>qa<CR>"), | |
| 85 | - } | |
| 86 | - or { | |
| 87 | - dashboard.button( | |
| 88 | - "s", | |
| 89 | - " " .. " Sign in (By Cookie)", | |
| 90 | - "<cmd>lua require('leetcode.api').cmd.cookie_prompt()<cr>" | |
| 91 | - ), | |
| 92 | - dashboard.button("q", " " .. " Exit LeetCode", "<cmd>qa!<CR>"), | |
| 53 | + local auth = config.auth | |
| 54 | + local is_signed_in = auth and auth.is_signed_in | |
| 55 | + | |
| 56 | + local alpha = require("alpha") | |
| 57 | + local dashboard = require("alpha.themes.dashboard") | |
| 58 | + | |
| 59 | + notifications.val = not is_signed_in and { " Sign in to use LeetCode.nvim" } or {} | |
| 60 | + | |
| 61 | + buttons.val = is_signed_in | |
| 62 | + and { | |
| 63 | + dashboard.button( | |
| 64 | + "p", | |
| 65 | + " " .. " All Problems", | |
| 66 | + "<cmd>lua require('leetcode.api').cmd.lc_problems()<CR>" | |
| 67 | + ), | |
| 68 | + dashboard.button( | |
| 69 | + "t", | |
| 70 | + " " .. " Question of today", | |
| 71 | + "<cmd>lua require('leetcode.api').gql.problems.question_of_today()<CR>" | |
| 72 | + ), | |
| 73 | + dashboard.button("r", " " .. " Recent problems", ""), | |
| 74 | + dashboard.button( | |
| 75 | + "c", | |
| 76 | + " " .. " Update cookie", | |
| 77 | + "<cmd>lua require('leetcode.api').cmd.cookie_prompt()<cr>" | |
| 78 | + ), | |
| 79 | + dashboard.button( | |
| 80 | + "s", | |
| 81 | + " " .. " Sign out", | |
| 82 | + "<cmd>lua require('leetcode.utils').remove_cookie()<cr>" | |
| 83 | + ), | |
| 84 | + dashboard.button("q", " " .. " Exit LeetCode", "<cmd>qa<CR>"), | |
| 85 | + } | |
| 86 | + or { | |
| 87 | + dashboard.button( | |
| 88 | + "s", | |
| 89 | + " " .. " Sign in (By Cookie)", | |
| 90 | + "<cmd>lua require('leetcode.api').cmd.cookie_prompt()<cr>" | |
| 91 | + ), | |
| 92 | + dashboard.button("q", " " .. " Exit LeetCode", "<cmd>qa!<CR>"), | |
| 93 | + } | |
| 94 | + | |
| 95 | + footer.val = is_signed_in and "Signed in as: " .. auth.username or "" | |
| 96 | + | |
| 97 | + local section = { | |
| 98 | + header = header, | |
| 99 | + notifications = notifications, | |
| 100 | + buttons = buttons, | |
| 101 | + footer = footer, | |
| 93 | 102 | } |
| 94 | 103 | |
| 95 | - footer.val = is_signed_in and "Signed in as: " .. auth.username or "" | |
| 96 | - | |
| 97 | - local section = { | |
| 98 | - header = header, | |
| 99 | - notifications = notifications, | |
| 100 | - buttons = buttons, | |
| 101 | - footer = footer, | |
| 102 | - } | |
| 103 | - | |
| 104 | - local cfg = { | |
| 105 | - layout = { | |
| 106 | - -- header | |
| 107 | - { type = "padding", val = 2 }, | |
| 108 | - section.header, | |
| 109 | - | |
| 110 | - -- notifications | |
| 111 | - { type = "padding", val = 2 }, | |
| 112 | - section.notifications, | |
| 113 | - { type = "padding", val = 2 }, | |
| 114 | - | |
| 115 | - -- buttons | |
| 116 | - section.buttons, | |
| 117 | - | |
| 118 | - --footer | |
| 119 | - section.footer, | |
| 120 | - }, | |
| 121 | - opts = { | |
| 122 | - margin = 5, | |
| 123 | - }, | |
| 124 | - } | |
| 104 | + local cfg = { | |
| 105 | + layout = { | |
| 106 | + -- header | |
| 107 | + { type = "padding", val = 2 }, | |
| 108 | + section.header, | |
| 109 | + | |
| 110 | + -- notifications | |
| 111 | + { type = "padding", val = 2 }, | |
| 112 | + section.notifications, | |
| 113 | + { type = "padding", val = 2 }, | |
| 114 | + | |
| 115 | + -- buttons | |
| 116 | + section.buttons, | |
| 117 | + | |
| 118 | + --footer | |
| 119 | + section.footer, | |
| 120 | + }, | |
| 121 | + opts = { | |
| 122 | + margin = 5, | |
| 123 | + }, | |
| 124 | + } | |
| 125 | 125 | |
| 126 | - alpha.setup(cfg) | |
| 126 | + alpha.setup(cfg) | |
| 127 | 127 | end |
| 128 | 128 | |
| 129 | 129 | function M.update() |
| 130 | - utils.alpha_move_cursor_top() | |
| 131 | - M.setup() | |
| 132 | - pcall(vim.cmd, "AlphaRedraw") | |
| 130 | + utils.alpha_move_cursor_top() | |
| 131 | + M.setup() | |
| 132 | + pcall(vim.cmd, "AlphaRedraw") | |
| 133 | 133 | end |
| 134 | 134 | |
| 135 | 135 | return M |
+36-36lua/leetcode/ui/init.lua
| @@ -10,59 +10,59 @@ local Ui = {} | ||
| 10 | 10 | ---@param fn? fun(table) |
| 11 | 11 | ---@param callback fun(table) |
| 12 | 12 | function Ui.pick_one(items, prompt, fn, callback) |
| 13 | - vim.ui.select(items, { | |
| 14 | - prompt = prompt or "", | |
| 15 | - format_item = fn or function(item) return item end, | |
| 16 | - telescope = require("telescope.themes").get_dropdown(), | |
| 17 | - }, callback) | |
| 13 | + vim.ui.select(items, { | |
| 14 | + prompt = prompt or "", | |
| 15 | + format_item = fn or function(item) return item end, | |
| 16 | + telescope = require("telescope.themes").get_dropdown(), | |
| 17 | + }, callback) | |
| 18 | 18 | end |
| 19 | 19 | |
| 20 | 20 | function Ui.input(opts, callback) vim.ui.input(opts, callback) end |
| 21 | 21 | |
| 22 | 22 | ---@param problem lc.Problem |
| 23 | 23 | function Ui.create_leetcode_win(problem) |
| 24 | - local start_win = vim.api.nvim_get_current_win() | |
| 24 | + local start_win = vim.api.nvim_get_current_win() | |
| 25 | 25 | |
| 26 | - local Split = require("nui.split") | |
| 27 | - local split = Split({ | |
| 28 | - relative = "win", | |
| 29 | - position = "left", | |
| 30 | - size = "30%", | |
| 31 | - }) | |
| 32 | - split:mount() | |
| 26 | + local Split = require("nui.split") | |
| 27 | + local split = Split({ | |
| 28 | + relative = "win", | |
| 29 | + position = "left", | |
| 30 | + size = "30%", | |
| 31 | + }) | |
| 32 | + split:mount() | |
| 33 | 33 | |
| 34 | - local title = gql.question.title(problem.title_slug) | |
| 35 | - local content = gql.question.content(problem.title_slug) | |
| 34 | + local title = gql.question.title(problem.title_slug) | |
| 35 | + local content = gql.question.content(problem.title_slug) | |
| 36 | 36 | |
| 37 | - local win = vim.api.nvim_get_current_win() -- We save our navigation window handle... | |
| 38 | - local buf = vim.api.nvim_get_current_buf() -- ...and it's buffer handle. | |
| 37 | + local win = vim.api.nvim_get_current_win() -- We save our navigation window handle... | |
| 38 | + local buf = vim.api.nvim_get_current_buf() -- ...and it's buffer handle. | |
| 39 | 39 | |
| 40 | - vim.api.nvim_buf_set_name(buf, "LeetCode") | |
| 40 | + vim.api.nvim_buf_set_name(buf, "LeetCode") | |
| 41 | 41 | |
| 42 | - vim.api.nvim_buf_set_option(buf, "filetype", "leetcode.nvim") | |
| 43 | - vim.api.nvim_buf_set_option(buf, "swapfile", false) | |
| 44 | - vim.api.nvim_buf_set_option(buf, "buftype", "nofile") | |
| 45 | - vim.api.nvim_buf_set_option(buf, "buflisted", false) | |
| 46 | - -- vim.api.nvim_buf_set_option(buf, "modifiable", true) | |
| 42 | + vim.api.nvim_buf_set_option(buf, "filetype", "leetcode.nvim") | |
| 43 | + vim.api.nvim_buf_set_option(buf, "swapfile", false) | |
| 44 | + vim.api.nvim_buf_set_option(buf, "buftype", "nofile") | |
| 45 | + vim.api.nvim_buf_set_option(buf, "buflisted", false) | |
| 46 | + -- vim.api.nvim_buf_set_option(buf, "modifiable", true) | |
| 47 | 47 | |
| 48 | - vim.api.nvim_win_set_option(win, "wrap", true) | |
| 49 | - vim.api.nvim_win_set_option(win, "number", false) | |
| 50 | - vim.api.nvim_win_set_option(win, "signcolumn", "no") | |
| 48 | + vim.api.nvim_win_set_option(win, "wrap", true) | |
| 49 | + vim.api.nvim_win_set_option(win, "number", false) | |
| 50 | + vim.api.nvim_win_set_option(win, "signcolumn", "no") | |
| 51 | 51 | |
| 52 | - vim.api.nvim_buf_set_keymap(buf, "n", "<esc>", "<cmd>hide<CR>", { noremap = true }) | |
| 53 | - vim.api.nvim_buf_set_keymap(buf, "n", "q", "<cmd>hide<CR>", { noremap = true }) | |
| 52 | + vim.api.nvim_buf_set_keymap(buf, "n", "<esc>", "<cmd>hide<CR>", { noremap = true }) | |
| 53 | + vim.api.nvim_buf_set_keymap(buf, "n", "q", "<cmd>hide<CR>", { noremap = true }) | |
| 54 | 54 | |
| 55 | - local line = require("nui.line")() | |
| 56 | - line:append("") | |
| 55 | + local line = require("nui.line")() | |
| 56 | + line:append("") | |
| 57 | 57 | |
| 58 | - components.problem.link(problem.title_slug):render(buf, -1, 1) | |
| 59 | - line:render(buf, -1, 2) | |
| 58 | + components.problem.link(problem.title_slug):render(buf, -1, 1) | |
| 59 | + line:render(buf, -1, 2) | |
| 60 | 60 | |
| 61 | - components.problem.title(title):render(buf, -1, 3) | |
| 62 | - components.problem.stats(title):render(buf, -1, 4) | |
| 63 | - line:render(buf, -1, 5) | |
| 61 | + components.problem.title(title):render(buf, -1, 3) | |
| 62 | + components.problem.stats(title):render(buf, -1, 4) | |
| 63 | + line:render(buf, -1, 5) | |
| 64 | 64 | |
| 65 | - components.problem.content(content):render(buf, -1, 6) | |
| 65 | + components.problem.content(content):render(buf, -1, 6) | |
| 66 | 66 | end |
| 67 | 67 | |
| 68 | 68 | return Ui |
+9-9lua/leetcode/utils.lua
| @@ -2,14 +2,14 @@ | ||
| 2 | 2 | local Utils = {} |
| 3 | 3 | |
| 4 | 4 | function Utils.remove_cookie() |
| 5 | - require("leetcode.cache.cookie").delete() | |
| 6 | - require("leetcode.ui.dashboard").update() | |
| 5 | + require("leetcode.cache.cookie").delete() | |
| 6 | + require("leetcode.ui.dashboard").update() | |
| 7 | 7 | end |
| 8 | 8 | |
| 9 | 9 | function Utils.alpha_move_cursor_top() |
| 10 | - local curr_win = vim.api.nvim_get_current_win() | |
| 11 | - vim.api.nvim_win_set_cursor(curr_win, { 1, 0 }) | |
| 12 | - require("alpha").move_cursor(curr_win) | |
| 10 | + local curr_win = vim.api.nvim_get_current_win() | |
| 11 | + vim.api.nvim_win_set_cursor(curr_win, { 1, 0 }) | |
| 12 | + require("alpha").move_cursor(curr_win) | |
| 13 | 13 | end |
| 14 | 14 | |
| 15 | 15 | ---Extracts an HTML tag from a string. |
| @@ -23,11 +23,11 @@ function Utils.get_html_tag(str) return str:match("^<(.-)>") end | ||
| 23 | 23 | --- |
| 24 | 24 | ---@return string |
| 25 | 25 | function Utils.strip_html_tag(str, tag) |
| 26 | - local regex = string.format("^<%s>(.*)</%s>$", tag, tag) | |
| 27 | - assert(str:match(regex)) | |
| 26 | + local regex = string.format("^<%s>(.*)</%s>$", tag, tag) | |
| 27 | + assert(str:match(regex)) | |
| 28 | 28 | |
| 29 | - local offset = 3 + tag:len() | |
| 30 | - return str:sub(offset, str:len() - offset) | |
| 29 | + local offset = 3 + tag:len() | |
| 30 | + return str:sub(offset, str:len() - offset) | |
| 31 | 31 | end |
| 32 | 32 | |
| 33 | 33 | return Utils |