A Neovim plugin enabling you to solve LeetCode problems.
feat: `non_standalone` plugin (#51)
18 files changed, +248 -30
+1-0.stylua.toml
| @@ -4,4 +4,5 @@ indent_type = "Spaces" | ||
| 4 | 4 | indent_width = 4 |
| 5 | 5 | quote_style = "ForceDouble" |
| 6 | 6 | call_parentheses = "Always" |
| 7 | +# collapse_simple_statement = "FunctionOnly" | |
| 7 | 8 | collapse_simple_statement = "Always" |
+39-0README.md
| @@ -93,6 +93,11 @@ To see full configuration types see [template.lua](./lua/leetcode/config/templat | ||
| 93 | 93 | cache = vim.fn.stdpath("cache") .. "/leetcode", |
| 94 | 94 | }, |
| 95 | 95 | |
| 96 | + ---@type table<string, boolean> | |
| 97 | + plugins = { | |
| 98 | + non_standalone = false, | |
| 99 | + }, | |
| 100 | + | |
| 96 | 101 | ---@type boolean |
| 97 | 102 | logging = true, |
| 98 | 103 | |
| @@ -137,6 +142,9 @@ To see full configuration types see [template.lua](./lua/leetcode/config/templat | ||
| 137 | 142 | |
| 138 | 143 | ---@type fun(question: lc.ui.Question)[] |
| 139 | 144 | ["question_enter"] = {}, |
| 145 | + | |
| 146 | + ---@type fun()[] | |
| 147 | + ["leave"] = {}, | |
| 140 | 148 | }, |
| 141 | 149 | |
| 142 | 150 | keys = { |
| @@ -226,6 +234,17 @@ storage = { | ||
| 226 | 234 | }, |
| 227 | 235 | ``` |
| 228 | 236 | |
| 237 | +### plugins | |
| 238 | + | |
| 239 | +[plugins list](#-plugins) | |
| 240 | + | |
| 241 | +```lua | |
| 242 | +---@type table<string, boolean> | |
| 243 | +plugins = { | |
| 244 | + non_standalone = false, | |
| 245 | +}, | |
| 246 | +``` | |
| 247 | + | |
| 229 | 248 | ### logging |
| 230 | 249 | |
| 231 | 250 | Whether to log [leetcode.nvim] status notifications |
| @@ -272,6 +291,9 @@ hooks = { | ||
| 272 | 291 | |
| 273 | 292 | ---@type fun(question: lc.ui.Question)[] |
| 274 | 293 | ["question_enter"] = {}, |
| 294 | + | |
| 295 | + ---@type fun()[] | |
| 296 | + ["leave"] = {}, | |
| 275 | 297 | }, |
| 276 | 298 | ``` |
| 277 | 299 | |
| @@ -294,6 +316,8 @@ image_support = false, | ||
| 294 | 316 | |
| 295 | 317 | - `menu` same as `Leet` |
| 296 | 318 | |
| 319 | +- `exit` close [leetcode.nvim] | |
| 320 | + | |
| 297 | 321 | - `console` opens console pop-up for currently opened question |
| 298 | 322 | |
| 299 | 323 | - `info` opens a pop-up containing information about the currently opened question |
| @@ -419,6 +443,21 @@ https://github.com/kawre/leetcode.nvim/assets/69250723/b7be8b95-5e2c-4153-8845-4 | ||
| 419 | 443 | } |
| 420 | 444 | ``` |
| 421 | 445 | |
| 446 | +## 🧩 Plugins | |
| 447 | + | |
| 448 | +### Non-Standalone mode | |
| 449 | + | |
| 450 | +To run [leetcode.nvim] in a non-standalone mode (i.e. not with argument or an empty Neovim session), | |
| 451 | +enable the `non_standalone` plugin in your config: | |
| 452 | + | |
| 453 | +```lua | |
| 454 | +plugins = { | |
| 455 | + non_standalone = true, | |
| 456 | +} | |
| 457 | +``` | |
| 458 | + | |
| 459 | +You can then exit [leetcode.nvim] using `:Leet exit` command | |
| 460 | + | |
| 422 | 461 | ## 🙌 Credits |
| 423 | 462 | |
| 424 | 463 | - [Leetbuddy.nvim](https://github.com/Dhanus3133/Leetbuddy.nvim) |
+39-0README.zh.md
| @@ -95,6 +95,11 @@ https://github.com/kawre/leetcode.nvim/assets/69250723/aee6584c-e099-4409-b114-1 | ||
| 95 | 95 | cache = vim.fn.stdpath("cache") .. "/leetcode", |
| 96 | 96 | }, |
| 97 | 97 | |
| 98 | + ---@type table<string, boolean> | |
| 99 | + plugins = { | |
| 100 | + non_standalone = false, | |
| 101 | + }, | |
| 102 | + | |
| 98 | 103 | ---@type boolean |
| 99 | 104 | logging = true, |
| 100 | 105 | |
| @@ -139,6 +144,9 @@ https://github.com/kawre/leetcode.nvim/assets/69250723/aee6584c-e099-4409-b114-1 | ||
| 139 | 144 | |
| 140 | 145 | ---@type fun(question: lc.ui.Question)[] |
| 141 | 146 | ["question_enter"] = {}, |
| 147 | + | |
| 148 | + ---@type fun()[] | |
| 149 | + ["leave"] = {}, | |
| 142 | 150 | }, |
| 143 | 151 | |
| 144 | 152 | keys = { |
| @@ -228,6 +236,17 @@ storage = { | ||
| 228 | 236 | }, |
| 229 | 237 | ``` |
| 230 | 238 | |
| 239 | +### plugins | |
| 240 | + | |
| 241 | +[插件列表](#-plugins) | |
| 242 | + | |
| 243 | +```lua | |
| 244 | +---@type table<string, boolean> | |
| 245 | +plugins = { | |
| 246 | + non_standalone = false, | |
| 247 | +}, | |
| 248 | +``` | |
| 249 | + | |
| 231 | 250 | ### logging |
| 232 | 251 | |
| 233 | 252 | 是否记录 [leetcode.nvim] 状态通知 |
| @@ -271,6 +290,9 @@ hooks = { | ||
| 271 | 290 | |
| 272 | 291 | ---@type fun(question: lc.ui.Question)[] |
| 273 | 292 | ["question_enter"] = {}, |
| 293 | + | |
| 294 | + ---@type fun()[] | |
| 295 | + ["leave"] = {}, | |
| 274 | 296 | }, |
| 275 | 297 | ``` |
| 276 | 298 | |
| @@ -293,6 +315,8 @@ image_support = false, -- 将此设置为 `true` 将禁用问题描述的换行 | ||
| 293 | 315 | |
| 294 | 316 | - `menu` 与 `Leet` 相同 |
| 295 | 317 | |
| 318 | +- `exit` 关闭 [leetcode.nvim] | |
| 319 | + | |
| 296 | 320 | - `console` 打开当前打开问题的控制台弹出窗口 |
| 297 | 321 | |
| 298 | 322 | - `info` 打开包含当前打开问题信息的弹出窗口 |
| @@ -417,6 +441,21 @@ https://github.com/kawre/leetcode.nvim/assets/69250723/b7be8b95-5e2c-4153-8845-4 | ||
| 417 | 441 | } |
| 418 | 442 | ``` |
| 419 | 443 | |
| 444 | +## 🧩 Plugins | |
| 445 | + | |
| 446 | +### Non-Standalone mode | |
| 447 | + | |
| 448 | +要在非独立模式下运行 [leetcode.nvim](即不带参数或在空的 Neovim 会话中运行), | |
| 449 | +请在您的配置中启用 `non_standalone` 插件: | |
| 450 | + | |
| 451 | +```lua | |
| 452 | +plugins = { | |
| 453 | + non_standalone = true, | |
| 454 | +} | |
| 455 | +``` | |
| 456 | + | |
| 457 | +你可以使用 `:Leet exit` 命令退出 [leetcode.nvim] | |
| 458 | + | |
| 420 | 459 | ## 🙌 鸣谢 |
| 421 | 460 | |
| 422 | 461 | - [Leetbuddy.nvim](https://github.com/Dhanus3133/Leetbuddy.nvim) |
+12-0lua/leetcode-plugins/non_standalone/init.lua
| @@ -0,0 +1,12 @@ | ||
| 1 | +---@class lc.plugins.non_standalone | |
| 2 | +local non_standalone = {} | |
| 3 | + | |
| 4 | +non_standalone.opts = { | |
| 5 | + lazy = false, | |
| 6 | +} | |
| 7 | + | |
| 8 | +function non_standalone.load() -- | |
| 9 | + require("leetcode-plugins.non_standalone.leetcode") | |
| 10 | +end | |
| 11 | + | |
| 12 | +return non_standalone |
+87-0lua/leetcode-plugins/non_standalone/leetcode.lua
| @@ -0,0 +1,87 @@ | ||
| 1 | +local leetcode = require("leetcode") | |
| 2 | +local config = require("leetcode.config") | |
| 3 | + | |
| 4 | +local standalone = true | |
| 5 | +local prev_cwd = nil | |
| 6 | + | |
| 7 | +---@param on_vimenter boolean | |
| 8 | +leetcode.should_skip = function(on_vimenter) | |
| 9 | + if on_vimenter then | |
| 10 | + if vim.fn.argc() ~= 1 then return true end | |
| 11 | + | |
| 12 | + local usr_arg, arg = vim.fn.argv()[1], config.user.arg | |
| 13 | + if usr_arg ~= arg then return true end | |
| 14 | + | |
| 15 | + local lines = vim.api.nvim_buf_get_lines(0, 0, -1, true) | |
| 16 | + if #lines > 1 or (#lines == 1 and lines[1]:len() > 0) then | |
| 17 | + local log = require("leetcode.logger") | |
| 18 | + log.warn(("Failed to initialize: `%s` is not an empty buffer"):format(usr_arg)) | |
| 19 | + return true | |
| 20 | + end | |
| 21 | + else | |
| 22 | + for _, buf_id in pairs(vim.api.nvim_list_bufs()) do | |
| 23 | + local bufinfo = vim.fn.getbufinfo(buf_id)[1] | |
| 24 | + if bufinfo and (bufinfo.listed == 1 and #bufinfo.windows > 0) then -- | |
| 25 | + return false, true | |
| 26 | + end | |
| 27 | + end | |
| 28 | + end | |
| 29 | + | |
| 30 | + return false | |
| 31 | +end | |
| 32 | + | |
| 33 | +---@param on_vimenter boolean | |
| 34 | +leetcode.start = function(on_vimenter) | |
| 35 | + local skip, buflisted = leetcode.should_skip(on_vimenter) | |
| 36 | + if skip then -- | |
| 37 | + return false | |
| 38 | + end | |
| 39 | + | |
| 40 | + config.setup() | |
| 41 | + | |
| 42 | + leetcode.setup_cmds() | |
| 43 | + | |
| 44 | + local theme = require("leetcode.theme") | |
| 45 | + theme.setup() | |
| 46 | + | |
| 47 | + if not on_vimenter then -- | |
| 48 | + if buflisted then | |
| 49 | + prev_cwd = vim.fn.getcwd() | |
| 50 | + vim.cmd.tabe() | |
| 51 | + else | |
| 52 | + vim.cmd.enew() | |
| 53 | + end | |
| 54 | + | |
| 55 | + standalone = not buflisted | |
| 56 | + end | |
| 57 | + | |
| 58 | + vim.api.nvim_set_current_dir(config.storage.home:absolute()) | |
| 59 | + | |
| 60 | + local Menu = require("leetcode-ui.renderer.menu") | |
| 61 | + Menu():mount() | |
| 62 | + | |
| 63 | + local utils = require("leetcode.utils") | |
| 64 | + utils.exec_hooks("enter") | |
| 65 | + | |
| 66 | + return true | |
| 67 | +end | |
| 68 | + | |
| 69 | +leetcode.stop = vim.schedule_wrap(function() | |
| 70 | + if standalone then return vim.cmd("qa!") end | |
| 71 | + | |
| 72 | + _Lc_state.menu:unmount() | |
| 73 | + | |
| 74 | + vim.api.nvim_create_user_command("Leet", require("leetcode.command").start_with_cmd, { | |
| 75 | + bar = true, | |
| 76 | + bang = true, | |
| 77 | + desc = "Open leetcode.nvim", | |
| 78 | + }) | |
| 79 | + | |
| 80 | + local utils = require("leetcode.utils") | |
| 81 | + utils.exec_hooks("leave") | |
| 82 | + | |
| 83 | + if prev_cwd then | |
| 84 | + vim.api.nvim_set_current_dir(prev_cwd) | |
| 85 | + prev_cwd = nil | |
| 86 | + end | |
| 87 | +end) |
+1-1lua/leetcode-ui/lines/calendar.lua
| @@ -83,7 +83,7 @@ function Calendar:handle_res(res) | ||
| 83 | 83 | self:append(line):endl() |
| 84 | 84 | end |
| 85 | 85 | |
| 86 | - _Lc_menu:draw() | |
| 86 | + _Lc_state.menu:draw() | |
| 87 | 87 | end |
| 88 | 88 | |
| 89 | 89 | function Calendar:handle_submissions() |
+1-1lua/leetcode-ui/lines/solved.lua
| @@ -76,7 +76,7 @@ function Solved:handle_res(res) | ||
| 76 | 76 | self:endl() |
| 77 | 77 | end |
| 78 | 78 | |
| 79 | - _Lc_menu:draw() | |
| 79 | + _Lc_state.menu:draw() | |
| 80 | 80 | end |
| 81 | 81 | |
| 82 | 82 | function Solved:update() |
+8-7lua/leetcode-ui/question.lua
| @@ -152,7 +152,7 @@ function Question:injector(code) | ||
| 152 | 152 | return table.concat(parts, "\n") |
| 153 | 153 | end |
| 154 | 154 | |
| 155 | -function Question:unmount() | |
| 155 | +function Question:_unmount() | |
| 156 | 156 | if vim.v.dying ~= 0 then -- |
| 157 | 157 | return |
| 158 | 158 | end |
| @@ -166,15 +166,16 @@ function Question:unmount() | ||
| 166 | 166 | vim.api.nvim_buf_delete(self.bufnr, { force = true, unload = false }) |
| 167 | 167 | end |
| 168 | 168 | |
| 169 | - _Lc_questions = vim.tbl_filter(function(q) -- | |
| 170 | - return q.bufnr ~= self.bufnr | |
| 171 | - end, _Lc_questions) | |
| 169 | + _Lc_state.questions = vim.tbl_filter( | |
| 170 | + function(q) return q.bufnr ~= self.bufnr end, | |
| 171 | + _Lc_state.questions | |
| 172 | + ) | |
| 172 | 173 | |
| 173 | 174 | self = nil |
| 174 | 175 | end) |
| 175 | 176 | end |
| 176 | 177 | |
| 177 | -function Question:_unmount() | |
| 178 | +function Question:unmount() | |
| 178 | 179 | if vim.api.nvim_win_is_valid(self.winid) then vim.api.nvim_win_close(self.winid, true) end |
| 179 | 180 | end |
| 180 | 181 | |
| @@ -183,14 +184,14 @@ function Question:autocmds() | ||
| 183 | 184 | vim.api.nvim_create_autocmd("WinClosed", { |
| 184 | 185 | group = group, |
| 185 | 186 | pattern = tostring(self.winid), |
| 186 | - callback = function() self:unmount() end, | |
| 187 | + callback = function() self:_unmount() end, | |
| 187 | 188 | }) |
| 188 | 189 | end |
| 189 | 190 | |
| 190 | 191 | function Question:handle_mount() |
| 191 | 192 | self:create_buffer() |
| 192 | 193 | |
| 193 | - table.insert(_Lc_questions, self) | |
| 194 | + table.insert(_Lc_state.questions, self) | |
| 194 | 195 | |
| 195 | 196 | self.description = Description(self):mount() |
| 196 | 197 | self.console = Console(self) |
+2-0lua/leetcode-ui/renderer/init.lua
| @@ -24,6 +24,8 @@ function Renderer:draw(component) | ||
| 24 | 24 | self.bufnr = component.bufnr |
| 25 | 25 | self.winid = component.winid |
| 26 | 26 | |
| 27 | + if not vim.api.nvim_buf_is_valid(self.bufnr) then return end | |
| 28 | + | |
| 27 | 29 | self:map("n", keys.confirm, function() self:handle_press() end) |
| 28 | 30 | |
| 29 | 31 | self:clear_keymaps() |
+3-3lua/leetcode.lua
| @@ -37,9 +37,7 @@ function leetcode.setup_cmds() require("leetcode.command").setup() end | ||
| 37 | 37 | |
| 38 | 38 | ---@param on_vimenter boolean |
| 39 | 39 | function leetcode.start(on_vimenter) |
| 40 | - if leetcode.should_skip(on_vimenter) then -- | |
| 41 | - return false | |
| 42 | - end | |
| 40 | + if leetcode.should_skip(on_vimenter) then return false end | |
| 43 | 41 | |
| 44 | 42 | config.setup() |
| 45 | 43 | |
| @@ -63,6 +61,8 @@ function leetcode.start(on_vimenter) | ||
| 63 | 61 | return true |
| 64 | 62 | end |
| 65 | 63 | |
| 64 | +function leetcode.stop() vim.cmd("qa!") end | |
| 65 | + | |
| 66 | 66 | ---@param cfg? lc.UserConfig |
| 67 | 67 | function leetcode.setup(cfg) |
| 68 | 68 | config.apply(cfg or {}) |
+12-4lua/leetcode/command/init.lua
| @@ -95,10 +95,15 @@ cmd.q_close_all = function() | ||
| 95 | 95 | local qs = utils.question_tabs() |
| 96 | 96 | |
| 97 | 97 | for _, tabp in ipairs(qs) do |
| 98 | - tabp.question:_unmount() | |
| 98 | + tabp.question:unmount() | |
| 99 | 99 | end |
| 100 | 100 | end |
| 101 | 101 | |
| 102 | +function cmd.exit() | |
| 103 | + local leetcode = require("leetcode") | |
| 104 | + leetcode.stop() | |
| 105 | +end | |
| 106 | + | |
| 102 | 107 | cmd.expire = vim.schedule_wrap(function() |
| 103 | 108 | local tabp = api.nvim_get_current_tabpage() |
| 104 | 109 | cmd.menu() |
| @@ -160,12 +165,14 @@ function cmd.start_with_cmd() | ||
| 160 | 165 | end |
| 161 | 166 | |
| 162 | 167 | function cmd.menu() |
| 163 | - local ok, tabp = pcall(api.nvim_win_get_tabpage, _Lc_menu.winid) | |
| 168 | + local winid, bufnr = _Lc_state.menu.winid, _Lc_state.menu.bufnr | |
| 169 | + local ok, tabp = pcall(api.nvim_win_get_tabpage, winid) | |
| 164 | 170 | |
| 165 | 171 | if ok then |
| 166 | 172 | api.nvim_set_current_tabpage(tabp) |
| 173 | + api.nvim_win_set_buf(winid, bufnr) | |
| 167 | 174 | else |
| 168 | - _Lc_menu:remount() | |
| 175 | + _Lc_state.menu:remount() | |
| 169 | 176 | end |
| 170 | 177 | end |
| 171 | 178 | |
| @@ -184,7 +191,7 @@ function cmd.yank() | ||
| 184 | 191 | end |
| 185 | 192 | |
| 186 | 193 | ---@param page lc-menu.page |
| 187 | -function cmd.set_menu_page(page) _Lc_menu:set_page(page) end | |
| 194 | +function cmd.set_menu_page(page) _Lc_state.menu:set_page(page) end | |
| 188 | 195 | |
| 189 | 196 | function cmd.start_user_session() -- |
| 190 | 197 | cmd.set_menu_page("menu") |
| @@ -525,6 +532,7 @@ cmd.commands = { | ||
| 525 | 532 | cmd.menu, |
| 526 | 533 | |
| 527 | 534 | menu = { cmd.menu }, |
| 535 | + exit = { cmd.exit }, | |
| 528 | 536 | console = { cmd.console }, |
| 529 | 537 | info = { cmd.info }, |
| 530 | 538 | hints = { cmd.hints }, |
+4-5lua/leetcode/config/init.lua
| @@ -1,11 +1,10 @@ | ||
| 1 | 1 | local template = require("leetcode.config.template") |
| 2 | 2 | local P = require("plenary.path") |
| 3 | 3 | |
| 4 | ----@type lc.ui.Question[] | |
| 5 | -_Lc_questions = {} | |
| 6 | - | |
| 7 | ----@type lc.ui.Menu | |
| 8 | -_Lc_menu = {} ---@diagnostic disable-line | |
| 4 | +_Lc_state = { | |
| 5 | + menu = nil, ---@type lc.ui.Menu | |
| 6 | + questions = {}, ---@type lc.ui.Question[] | |
| 7 | +} | |
| 9 | 8 | |
| 10 | 9 | local lazy_plugs = {} |
| 11 | 10 |
+5-4lua/leetcode/config/stats.lua
| @@ -14,7 +14,7 @@ function Stats.update_streak() | ||
| 14 | 14 | Stats.daily.streak = res.streakCount |
| 15 | 15 | Stats.daily.today_completed = res.todayCompleted |
| 16 | 16 | |
| 17 | - if _Lc_menu then _Lc_menu:draw() end | |
| 17 | + _Lc_state.menu:draw() | |
| 18 | 18 | end) |
| 19 | 19 | end |
| 20 | 20 | |
| @@ -26,7 +26,8 @@ function Stats.update_sessions() | ||
| 26 | 26 | |
| 27 | 27 | stats_api.sessions(function(_, err) |
| 28 | 28 | if err then return log.err(err) end |
| 29 | - if _Lc_menu then _Lc_menu:draw() end | |
| 29 | + | |
| 30 | + _Lc_state.menu:draw() | |
| 30 | 31 | end) |
| 31 | 32 | |
| 32 | 33 | stats_api.session_progress(function(res, err) |
| @@ -39,7 +40,7 @@ function Stats.update_sessions() | ||
| 39 | 40 | Stats.progress[p.difficulty:lower()] = p |
| 40 | 41 | end |
| 41 | 42 | |
| 42 | - if _Lc_menu then _Lc_menu:draw() end | |
| 43 | + _Lc_state.menu:draw() | |
| 43 | 44 | end) |
| 44 | 45 | end |
| 45 | 46 | |
| @@ -47,7 +48,7 @@ function Stats.update() | ||
| 47 | 48 | Stats.update_streak() |
| 48 | 49 | Stats.update_sessions() |
| 49 | 50 | |
| 50 | - if _Lc_menu then _Lc_menu:draw() end | |
| 51 | + _Lc_state.menu:draw() | |
| 51 | 52 | end |
| 52 | 53 | |
| 53 | 54 | return Stats |
+8-1lua/leetcode/config/template.lua
| @@ -23,6 +23,7 @@ | ||
| 23 | 23 | ---@alias lc.hook |
| 24 | 24 | ---| "enter" |
| 25 | 25 | ---| "question_enter" |
| 26 | +---| "leave" | |
| 26 | 27 | |
| 27 | 28 | ---@alias lc.size |
| 28 | 29 | ---| string |
| @@ -57,7 +58,10 @@ local M = { | ||
| 57 | 58 | cache = vim.fn.stdpath("cache") .. "/leetcode", |
| 58 | 59 | }, |
| 59 | 60 | |
| 60 | - plugins = {}, | |
| 61 | + ---@type table<string, boolean> | |
| 62 | + plugins = { | |
| 63 | + non_standalone = false, | |
| 64 | + }, | |
| 61 | 65 | |
| 62 | 66 | ---@type boolean |
| 63 | 67 | logging = true, |
| @@ -103,6 +107,9 @@ local M = { | ||
| 103 | 107 | |
| 104 | 108 | ---@type fun(question: lc.ui.Question)[] |
| 105 | 109 | ["question_enter"] = {}, |
| 110 | + | |
| 111 | + ---@type fun()[] | |
| 112 | + ["leave"] = {}, | |
| 106 | 113 | }, |
| 107 | 114 | |
| 108 | 115 | keys = { |
+4-1lua/leetcode/logger/init.lua
| @@ -36,7 +36,10 @@ logger.info = function(msg) logger.log(msg) end | ||
| 36 | 36 | logger.warn = function(msg) logger.log(msg, lvls.WARN) end |
| 37 | 37 | |
| 38 | 38 | ---@param msg any |
| 39 | -logger.error = function(msg) logger.log(msg, lvls.ERROR) end | |
| 39 | +logger.error = function(msg) | |
| 40 | + logger.log(msg, lvls.ERROR) | |
| 41 | + logger.debug(msg) | |
| 42 | +end | |
| 40 | 43 | |
| 41 | 44 | ---@param err lc.err |
| 42 | 45 | logger.err = function(err) |
+1-1lua/leetcode/utils.lua
| @@ -31,7 +31,7 @@ end | ||
| 31 | 31 | function utils.question_tabs() |
| 32 | 32 | local questions = {} |
| 33 | 33 | |
| 34 | - for _, q in ipairs(_Lc_questions) do | |
| 34 | + for _, q in ipairs(_Lc_state.questions) do | |
| 35 | 35 | local tabp = utils.question_tabp(q) |
| 36 | 36 | if tabp then table.insert(questions, { tabpage = tabp, question = q }) end |
| 37 | 37 | end |