init.lua (4002B)
1 local state = { 2 buf = nil, 3 win = nil, 4 cards = {}, 5 index = 1, 6 showing_back = false, 7 } 8 9 local function shuffle(t) 10 for i = #t, 2, -1 do 11 local j = math.random(i) 12 t[i], t[j] = t[j], t[i] 13 end 14 return t 15 end 16 17 local function formatCard(strArr) 18 19 local result = {} 20 local firstNonBlank = false 21 22 for i = 2, #strArr do 23 if strArr[i] == "" and firstNonBlank == false then 24 goto continue 25 end 26 27 firstNonBlank = true 28 table.insert(result, strArr[i]) 29 30 ::continue:: 31 end 32 33 return result 34 end 35 36 local function formatH1(str) 37 if not str then 38 return "" 39 end 40 41 if #str >= 3 then 42 return str:sub(3) 43 end 44 45 return "" 46 end 47 48 local function load_cards() 49 50 -- clear state 51 state.cards = {} 52 state.index = 1 53 state.showing_back = false 54 55 local cwd = vim.fs.dirname(vim.api.nvim_buf_get_name(0)) 56 local files = vim.split(vim.fn.glob(cwd .. "/*.md"), "\n") 57 files = shuffle(files) 58 59 for index, _ in ipairs(files) do 60 if files[index] ~= "" then 61 local file = vim.fn.readfile(files[index]) 62 -- add card to state 63 table.insert(state.cards, { 64 formatH1(file[1]), formatCard(file) 65 }) 66 end 67 end 68 end 69 70 local function render() 71 72 if state.cards[state.index] == nil then 73 print("Unable to find card.") 74 return 75 end 76 77 vim.bo[state.buf].modifiable = true 78 vim.api.nvim_buf_set_lines(state.buf, 0, -1, false, {}) 79 if state.showing_back then 80 vim.api.nvim_buf_set_lines(state.buf, 0, 10, false, state.cards[state.index][2]) 81 else 82 vim.api.nvim_buf_set_lines(state.buf, 0, 10, false, {state.cards[state.index][1]}) 83 end 84 vim.bo[state.buf].modifiable = false 85 end 86 87 88 local function previous_card() 89 state.index = state.index - 1 90 state.showing_back = false 91 92 if state.index < 1 then 93 state.index = #state.cards 94 end 95 96 render() 97 end 98 99 local function next_card() 100 state.index = state.index + 1 101 state.showing_back = false 102 103 if state.index > #state.cards then 104 state.index = 1 105 end 106 107 render() 108 end 109 110 local function flip_card() 111 state.showing_back = not state.showing_back 112 render() 113 end 114 115 local function flash() 116 117 load_cards() 118 119 if state.cards[1] == nil then 120 print("No cards found in the cwd.") 121 return 122 end 123 124 if state.buf ~= nil then 125 vim.api.nvim_buf_delete(state.buf, { force = true }) 126 state.buf = nil 127 state.win = nil 128 end 129 130 state.win = vim.api.nvim_get_current_win() 131 state.buf = vim.api.nvim_create_buf(false, true) 132 133 vim.api.nvim_buf_set_keymap(state.buf, "n", "<Left>", "<Cmd>PreviousCard<CR>", {}) 134 vim.api.nvim_buf_set_keymap(state.buf, "n", "<Right>", "<Cmd>NextCard<CR>", {}) 135 vim.api.nvim_buf_set_keymap(state.buf, "n", "<Up>", "<Cmd>Flip<CR>", {}) 136 vim.api.nvim_buf_set_keymap(state.buf, "n", "<Down>", "<Cmd>Flip<CR>", {}) 137 138 vim.api.nvim_buf_set_keymap(state.buf, "n", "h", "<Cmd>PreviousCard<CR>", {}) 139 vim.api.nvim_buf_set_keymap(state.buf, "n", "l", "<Cmd>NextCard<CR>", {}) 140 vim.api.nvim_buf_set_keymap(state.buf, "n", "k", "<Cmd>Flip<CR>", {}) 141 vim.api.nvim_buf_set_keymap(state.buf, "n", "j", "<Cmd>Flip<CR>", {}) 142 143 local row = 0 144 local col = 0 145 146 local width = vim.fn.winwidth(state.win) 147 local height = vim.fn.winheight(state.win) 148 149 local opts = { 150 width = width, 151 height = height, 152 row = row, 153 col = col, 154 border = "rounded", 155 relative = "win", 156 title = "Flashcards", 157 title_pos = "center" 158 } 159 160 local _ = vim.api.nvim_open_win(state.buf, true, opts) 161 162 render() 163 164 165 end 166 167 vim.api.nvim_create_user_command('Flash', flash, {}) 168 vim.api.nvim_create_user_command('Flip', flip_card, {}) 169 vim.api.nvim_create_user_command('NextCard', next_card, {}) -- defaults first side 170 vim.api.nvim_create_user_command('PreviousCard', previous_card, {}) -- defaults first side