DEV Community

Cover image for neovim: Wrap selection into clipboard
Sérgio Araújo
Sérgio Araújo

Posted on • Edited on

neovim: Wrap selection into clipboard

Intro

NOTE: The proposed solutions here have evolved a little bit, my utils.lua was modularized becomming a folder. If you want to see the differences follow this link.

Sharing code using markdown is way common these days. What about having those backticks and the language of the code (our fenced code) wrapped around the selection and placed into the clipboard at the distance of a keyboard map?

First we define a lua function to get the visual selection

get_clipboard_selection

--- @return string # selected text M.get_visual_selection = function() local mode = vim.fn.mode() if not vim.tbl_contains({ 'v', 'V', '\22' }, mode) then return '' end -- visual selection margins local s_pos = vim.fn.getpos('v') local e_pos = vim.fn.getpos('.') -- cursor atual local s_row, s_col = s_pos[2], s_pos[3] local e_row, e_col = e_pos[2], e_pos[3] -- if selection is backwards if s_row > e_row or (s_row == e_row and s_col > e_col) then s_row, e_row = e_row, s_row s_col, e_col = e_col, s_col end local lines = vim.api.nvim_buf_get_lines(0, s_row - 1, e_row, false) if #lines == 0 then return '' end lines[1] = string.sub(lines[1], s_col) if #lines == 1 then lines[1] = string.sub(lines[1], 1, e_col - s_col + 1) else lines[#lines] = string.sub(lines[#lines], 1, e_col) end return table.concat(lines, '\n') end 
Enter fullscreen mode Exit fullscreen mode

Wrap visual selected text with fenced code

Now a helper wrapper function that adds backtics and the language name around the selected text

function M.wrap_in_markdown_codeblock(text, lang) if not text or text == '' then return '' end lang = lang or '' return string.format('```%s\n%s\n```', lang, text) end 
Enter fullscreen mode Exit fullscreen mode

The keymap

The functions of sections above are in text_manipulation.lua module.

local text_utils = require('core.utils.text_manipulation') map('v', '<M-s>', function() local wrap_in_markdown_codeblock = text_utils.wrap_in_markdown_codeblock local ft = vim.bo.filetype local text = text_utils.get_visual_selection() if text == '' then vim.notify('No selection found', vim.log.levels.WARN) return end local wrapped = wrap_in_markdown_codeblock(text, ft) vim.fn.setreg('+', wrapped) vim.notify('markdown block copied into reg +', vim.log.levels.INFO) end, { desc = 'Copy selection as markdown fenced code' }) 
Enter fullscreen mode Exit fullscreen mode

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.