diff options
| author | 2024-03-09 11:37:33 +0100 | |
|---|---|---|
| committer | 2024-03-09 11:37:33 +0100 | |
| commit | 9fa85bd6be2547e22605b72913558e4a47171a11 (patch) | |
| tree | 43fe8ec2f383aeab04028099bb3f49fef3619c2e /dot_config/nvim | |
| parent | fish: rework .() (diff) | |
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?
Diffstat (limited to 'dot_config/nvim')
| -rw-r--r-- | dot_config/nvim/ftplugin/markdown_quote.lua | 76 |
1 files changed, 76 insertions, 0 deletions
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', +}) |
