A Neovim plugin enabling you to solve LeetCode problems.
README.md
7 files changed, +194 -34
+1-2.neoconf.json
| @@ -6,8 +6,7 @@ | ||
| 6 | 6 | "nvim-notify", |
| 7 | 7 | "telescope.nvim", |
| 8 | 8 | "plenary.nvim", |
| 9 | - "nui.nvim", | |
| 10 | - "alpha-nvim" | |
| 9 | + "nui.nvim" | |
| 11 | 10 | ] |
| 12 | 11 | } |
| 13 | 12 | } |
+121-0README.md
| @@ -0,0 +1,121 @@ | ||
| 1 | +<div align="center"> | |
| 2 | + | |
| 3 | +# leetcode.nvim | |
| 4 | + | |
| 5 | +Solve LeetCode problems within Neovim | |
| 6 | + | |
| 7 | +</div> | |
| 8 | + | |
| 9 | +[leetcode.nvim]: https://github.com/kawre/leetcode.nvim | |
| 10 | + | |
| 11 | +## ✨ Features | |
| 12 | + | |
| 13 | +- 📈 LeetCode statistics withing neovim (Soon) | |
| 14 | + | |
| 15 | +- 🔀 Support for daily and random questions | |
| 16 | + | |
| 17 | +- 💾 Problem list caching | |
| 18 | + | |
| 19 | +## 📬 Dependencies | |
| 20 | + | |
| 21 | +- [nvim-treesitter][nvim-treesitter]: html parser | |
| 22 | + | |
| 23 | +- [telescope.nvim][telescope.nvim]: pickers | |
| 24 | + | |
| 25 | +- [nui.nvim][nui.nvim]: ui provider | |
| 26 | + | |
| 27 | +- [nvim-notify][nvim-notify]: notifications provider | |
| 28 | + | |
| 29 | +[nvim-treesitter]: https://github.com/nvim-treesitter/nvim-treesitter | |
| 30 | +[telescope.nvim]: https://github.com/nvim-telescope/telescope.nvim | |
| 31 | +[nui.nvim]: https://github.com/MunifTanjim/nui.nvim | |
| 32 | +[nvim-notify]: https://github.com/rcarriga/nvim-notify | |
| 33 | + | |
| 34 | +## 📦 Installation | |
| 35 | + | |
| 36 | +- [lazy.nvim][lazy.nvim] | |
| 37 | + | |
| 38 | + ```lua | |
| 39 | + { | |
| 40 | + "kawre/leetcode.nvim", | |
| 41 | + build = ":TSUpdate html", | |
| 42 | + dependencies = { | |
| 43 | + "nvim-treesitter/nvim-treesitter", | |
| 44 | + "nvim-telescope/telescope.nvim", | |
| 45 | + "MunifTanjim/nui.nvim", | |
| 46 | + | |
| 47 | + -- optional dependencies | |
| 48 | + "rcarriga/nvim-notify", | |
| 49 | + "nvim-tree/nvim-web-devicons", | |
| 50 | + }, | |
| 51 | + opts = { | |
| 52 | + -- configuration goes here | |
| 53 | + }, | |
| 54 | + } | |
| 55 | + ``` | |
| 56 | + | |
| 57 | +[lazy.nvim]: https://github.com/folke/lazy.nvim | |
| 58 | +[packer.nvim]: https://github.com/wbthomason/packer.nvim | |
| 59 | + | |
| 60 | +<h2 id="config">⚙️ Default Configuration</h2> | |
| 61 | + | |
| 62 | +```lua | |
| 63 | +{ | |
| 64 | + ---@type string | |
| 65 | + domain = "com", | |
| 66 | + | |
| 67 | + ---@type string | |
| 68 | + arg = "leetcode.nvim", | |
| 69 | + | |
| 70 | + ---@type string | |
| 71 | + lang = "java", | |
| 72 | + | |
| 73 | + ---@type | |
| 74 | + ---| "pythondata" | |
| 75 | + ---| "mysql" | |
| 76 | + ---| "mssql" | |
| 77 | + ---| "oraclesql" | |
| 78 | + sql = "mysql", | |
| 79 | + | |
| 80 | + ---@type string | |
| 81 | + directory = vim.fn.stdpath("data") .. "/leetcode/", | |
| 82 | + | |
| 83 | + ---@type boolean | |
| 84 | + logging = true, | |
| 85 | + | |
| 86 | + menu_tabpage = 1, | |
| 87 | + questions_tabpage = 2, | |
| 88 | + | |
| 89 | + console = { | |
| 90 | + size = { | |
| 91 | + width = "75%", ---@type string | integer | |
| 92 | + height = "75%", ---@type string | integer | |
| 93 | + }, | |
| 94 | + dir = "row", ---@type "col" | "row" | |
| 95 | + | |
| 96 | + result = { | |
| 97 | + max_stdout_length = 200, | |
| 98 | + }, | |
| 99 | + }, | |
| 100 | + | |
| 101 | + description = { | |
| 102 | + width = "40%", ---@type string | integer | |
| 103 | + }, | |
| 104 | +} | |
| 105 | +``` | |
| 106 | + | |
| 107 | +## 🚀 Usage | |
| 108 | + | |
| 109 | +This plugin is meant to be used within a fresh neovim instance. | |
| 110 | +Meaning that to lauch [leetcode.nvim][leetcode.nvim] you have to pass [`arg`](#config) as the neovim argument | |
| 111 | + | |
| 112 | +``` | |
| 113 | +nvim leetcode.nvim | |
| 114 | +``` | |
| 115 | + | |
| 116 | +<!-- NOTE: [leetcode.nvim][leetcode.nvim] launch argument can be changed by modifying `arg` variable --> | |
| 117 | +<!-- inside [config](#config) --> | |
| 118 | + | |
| 119 | +### Sign In | |
| 120 | + | |
| 121 | +It is required to be signed-in to use [leetcode.nvim][leetcode.nvim] |
+33-2lua/leetcode/api/command.lua
| @@ -137,7 +137,38 @@ function cmd.list_questions() | ||
| 137 | 137 | end |
| 138 | 138 | end |
| 139 | 139 | |
| 140 | ----@param lang string | |
| 141 | -function cmd.change_lang(lang) config.lang = lang end | |
| 140 | +function cmd.prompt_lang() | |
| 141 | + local ui = require("leetcode.ui") | |
| 142 | + | |
| 143 | + ui.pick_one( | |
| 144 | + { | |
| 145 | + { lang = "C++", slug = "cpp" }, | |
| 146 | + { lang = "Java", slug = "java" }, | |
| 147 | + { lang = "Python", slug = "python" }, | |
| 148 | + { lang = "Python3", slug = "python3" }, | |
| 149 | + { lang = "C", slug = "c" }, | |
| 150 | + { lang = "C#", slug = "csharp" }, | |
| 151 | + { lang = "JavaScript", slug = "javascript" }, | |
| 152 | + { lang = "TypeScript", slug = "typescript" }, | |
| 153 | + { lang = "PHP", slug = "php" }, | |
| 154 | + { lang = "Swift", slug = "swift" }, | |
| 155 | + { lang = "Kotlin", slug = "kotlin" }, | |
| 156 | + { lang = "Dart", slug = "dart" }, | |
| 157 | + { lang = "Go", slug = "golang" }, | |
| 158 | + { lang = "Ruby", slug = "ruby" }, | |
| 159 | + { lang = "Scala", slug = "scala" }, | |
| 160 | + { lang = "Rust", slug = "rust" }, | |
| 161 | + { lang = "Racket", slug = "racket" }, | |
| 162 | + { lang = "Erlang", slug = "erlang" }, | |
| 163 | + { lang = "Elixir", slug = "elixir" }, | |
| 164 | + }, | |
| 165 | + "Pick a Langauge", | |
| 166 | + function(t) return t.lang end, | |
| 167 | + function(t) | |
| 168 | + config.lang = t.slug | |
| 169 | + log.info("Langauge set to " .. t.lang) | |
| 170 | + end | |
| 171 | + ) | |
| 172 | +end | |
| 142 | 173 | |
| 143 | 174 | return cmd |
+6-23lua/leetcode/init.lua
| @@ -1,6 +1,5 @@ | ||
| 1 | 1 | local config = require("leetcode.config") |
| 2 | 2 | local utils = require("leetcode.utils") |
| 3 | -local cmd = require("leetcode.api.command") | |
| 4 | 3 | |
| 5 | 4 | local log = require("leetcode.logger") |
| 6 | 5 | |
| @@ -22,8 +21,9 @@ end | ||
| 22 | 21 | ---@param cfg? lc.UserConfig |
| 23 | 22 | function leetcode.setup(cfg) |
| 24 | 23 | config.apply(cfg or {}) |
| 25 | - | |
| 26 | 24 | if should_skip() then return end |
| 25 | + | |
| 26 | + local cmd = require("leetcode.api.command") | |
| 27 | 27 | cmd.start() |
| 28 | 28 | |
| 29 | 29 | vim.api.nvim_set_hl(0, "LeetCodeEasy", { fg = "#46c6c2" }) |
| @@ -47,27 +47,10 @@ function leetcode.setup(cfg) | ||
| 47 | 47 | vim.api.nvim_set_hl(0, "LeetCodeList", { link = "Tag" }) |
| 48 | 48 | vim.api.nvim_set_hl(0, "LeetCodeLink", { link = "Function" }) |
| 49 | 49 | |
| 50 | - utils.map("n", "<leader>lc", utils.cmd("console")) | |
| 51 | - utils.map("n", "<leader>lm", utils.cmd("menu")) | |
| 52 | - utils.map("n", "<leader>lq", utils.cmd("list_questions")) | |
| 53 | - | |
| 54 | - -- vim.api.nvim_create_user_command("LcMenu", function() vim.api.nvim_set_current_tabpage(1) end, { | |
| 55 | - -- bang = true, | |
| 56 | - -- desc = "Opens LeetCode Menu", | |
| 57 | - -- nargs = 0, | |
| 58 | - -- bar = true, | |
| 59 | - -- }) | |
| 60 | - -- | |
| 61 | - -- vim.api.nvim_create_user_command( | |
| 62 | - -- "LcQuestion", | |
| 63 | - -- function() vim.api.nvim_set_current_tabpage() end, | |
| 64 | - -- { | |
| 65 | - -- bang = true, | |
| 66 | - -- desc = "Opens last openned LeetCode question", | |
| 67 | - -- nargs = 0, | |
| 68 | - -- bar = true, | |
| 69 | - -- } | |
| 70 | - -- ) | |
| 50 | + vim.api.nvim_create_user_command("LcConsole", function() cmd.console() end, {}) | |
| 51 | + vim.api.nvim_create_user_command("LcMenu", function() cmd.menu() end, {}) | |
| 52 | + vim.api.nvim_create_user_command("LcQuestionTabs", function() cmd.list_questions() end, {}) | |
| 53 | + vim.api.nvim_create_user_command("LcLanguage", function() cmd.prompt_lang() end, {}) | |
| 71 | 54 | end |
| 72 | 55 | |
| 73 | 56 | return leetcode |
+1-6lua/leetcode/logger/init.lua
| @@ -10,12 +10,7 @@ local logger = {} | ||
| 10 | 10 | ---@param lvl? integer |
| 11 | 11 | logger.log = function(msg, lvl) |
| 12 | 12 | if not config.user.logging then return end |
| 13 | - msg = msg or "nil" | |
| 14 | - | |
| 15 | - local mtype = type(msg) | |
| 16 | - if mtype == "number" or mtype == "boolean" then msg = tostring(msg) end | |
| 17 | - if mtype == "table" or mtype == "userdata" then msg = vim.inspect(msg) end | |
| 18 | - vim.notify(msg, lvl or levels.INFO, { title = config.name }) | |
| 13 | + vim.notify(vim.inspect(msg), lvl or levels.INFO, { title = config.name }) | |
| 19 | 14 | end |
| 20 | 15 | |
| 21 | 16 | ---@param msg msg |
+3-1lua/leetcode/ui/question.lua
| @@ -5,6 +5,7 @@ local Description = require("leetcode.ui.description") | ||
| 5 | 5 | local api_question = require("leetcode.api.question") |
| 6 | 6 | local Console = require("leetcode.ui.console") |
| 7 | 7 | local spinner = require("leetcode.logger.spinner") |
| 8 | +local utils = require("leetcode.utils") | |
| 8 | 9 | |
| 9 | 10 | ---@class lc.Question |
| 10 | 11 | ---@field file Path |
| @@ -91,7 +92,8 @@ function question:init(problem) | ||
| 91 | 92 | local q = api_question.by_title_slug(problem.title_slug) |
| 92 | 93 | |
| 93 | 94 | local dir = config.directory |
| 94 | - local fn = string.format("%s.%s.%s", q.frontend_id, q.title_slug, config.lang) | |
| 95 | + local ft = utils.filetype(config.lang) | |
| 96 | + local fn = string.format("%s.%s.%s", q.frontend_id, q.title_slug, ft) | |
| 95 | 97 | |
| 96 | 98 | local obj = setmetatable({ |
| 97 | 99 | file = path:new(dir .. fn), |
+29-0lua/leetcode/utils.lua
| @@ -66,4 +66,33 @@ end | ||
| 66 | 66 | -- |
| 67 | 67 | -- end |
| 68 | 68 | |
| 69 | +---@param lang string | |
| 70 | +function utils.filetype(lang) | |
| 71 | + local filetypes = { | |
| 72 | + cpp = "cpp", | |
| 73 | + java = "java", | |
| 74 | + python = "py", | |
| 75 | + python3 = "py", | |
| 76 | + c = "c", | |
| 77 | + csharp = "cs", | |
| 78 | + javascript = "js", | |
| 79 | + typescript = "ts", | |
| 80 | + php = "php", | |
| 81 | + swift = "swift", | |
| 82 | + kotlin = "kt", | |
| 83 | + dart = "dart", | |
| 84 | + golang = "go", | |
| 85 | + ruby = "rb", | |
| 86 | + scala = "scala", | |
| 87 | + rust = "rs", | |
| 88 | + racket = "rkt", | |
| 89 | + erlang = "erl", | |
| 90 | + elixir = "ex", | |
| 91 | + } | |
| 92 | + | |
| 93 | + local ft = filetypes[lang] | |
| 94 | + assert(ft) | |
| 95 | + return ft | |
| 96 | +end | |
| 97 | + | |
| 69 | 98 | return utils |