From 9fa85bd6be2547e22605b72913558e4a47171a11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chlo=C3=A9=20Vulquin?= Date: Sat, 9 Mar 2024 11:37:33 +0100 Subject: nvim: add markdown quote ftplugin I increase/decrease quote levels a lot, so I figured I'd write a small thing for doing that more easily in visual mode. This isn't without problems. Known bugs: * In normal-mode, it's a bit slow (waiting for more inputs? possible, but if you give it more inputs it just does it twice). * You cannot increase/decrease indentation with <> with this on. This is mostly a bummer for code blocks. * Doesn't work with indentation-based quoting, rather than >. But it's good enough for me, eh? --- dot_config/nvim/ftplugin/markdown_quote.lua | 76 +++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 dot_config/nvim/ftplugin/markdown_quote.lua diff --git a/dot_config/nvim/ftplugin/markdown_quote.lua b/dot_config/nvim/ftplugin/markdown_quote.lua new file mode 100644 index 0000000..3a57c20 --- /dev/null +++ b/dot_config/nvim/ftplugin/markdown_quote.lua @@ -0,0 +1,76 @@ +local api = vim.api +local fn = vim.fn + +local buffer = 0 -- operate on current buffer + +local function location(opts) + -- if called from a command, we don't have event info + if not opts then + opts = { + line1 = fn.line 'v', + line2 = fn.line '.', + } + end + + if opts.line1 > opts.line2 then + opts.line1, opts.line2 = opts.line2, opts.line1 + end + + -- nvim api lines are zero-based end-exclusive + opts.line1 = opts.line1 - 1 + return opts +end + +local function mdquote(opts) + opts = location(opts) + + -- 1. get all of the matching lines + local lines = api.nvim_buf_get_lines(buffer, opts.line1, opts.line2, true) + + -- 2. edit them appropriately + for i, line in ipairs(lines) do + -- prepend a ">" and a " ", + -- unless the first character was already ">" or whitespace + -- so prepend " " first unless the above is true + if line:match '^$' then + elseif line:match '^[%s>]' then + lines[i] = '>' .. line + else + lines[i] = '> ' .. line + end + end + + -- 3. insert them back + api.nvim_buf_set_lines(buffer, opts.line1, opts.line2, true, lines) +end + +local function mddequote(opts) + opts = location(opts) + + -- see mdquote for the steps + local lines = api.nvim_buf_get_lines(buffer, opts.line1, opts.line2, true) + + for i, line in ipairs(lines) do + -- if the line starts with a "> ", remove both + -- elseif the line starts with a ">", remove that + -- TODO: I don't handle \t-based quoting + if line:match '^> ' then + lines[i] = line:sub(3) + elseif line:match '^>' then + lines[i] = line:sub(2) + end + end + + api.nvim_buf_set_lines(buffer, opts.line1, opts.line2, true, lines) +end + +api.nvim_buf_create_user_command(buffer, 'MdQuote', mdquote, { range = true }) +api.nvim_buf_create_user_command(buffer, 'MdDeQuote', mddequote, { range = true }) +vim.keymap.set({'n', 'x'}, '>', mdquote, { + buffer = true, + desc = 'increase quote level of selection', +}) +vim.keymap.set({'n', 'x'}, '<', mddequote, { + buffer = true, + desc = 'decrease quote level of selection', +}) -- cgit v1.2.3