NeoVim: Normalize and Copy Code Block
Published: Jan 29, 2025
Let's say I wanted to copy this block of code so that I can paste it into a github comment:
If I just press y
to yank the block and paste it into a lua
block on
github, it will look like this:
If I use my function (see below), it looks like this when pasted:
Much better!
Here's the function:
local function copy_normalized_block()
local mode = vim.fn.mode()
if mode ~= "v" and mode ~= "V" then
return
end
vim.cmd([[silent normal! "xy]])
local text = vim.fn.getreg("x")
local lines = vim.split(text, "\n", { plain = true })
local converted = {}
for _, line in ipairs(lines) do
local l = line:gsub("\t", " ")
table.insert(converted, l)
end
local min_indent = math.huge
for _, line in ipairs(converted) do
if line:match("[^%s]") then
local indent = #(line:match("^%s*"))
min_indent = math.min(min_indent, indent)
end
end
min_indent = min_indent == math.huge and 0 or min_indent
local result = {}
for _, line in ipairs(converted) do
if line:match("^%s*$") then
table.insert(result, "")
else
local processed = line:sub(min_indent + 1)
processed = processed:gsub("^%s+", function(spaces)
return string.rep(" ", math.floor(#spaces / 2))
end)
table.insert(result, processed)
end
end
local normalized = table.concat(result, "\n")
vim.fn.setreg("+", normalized)
vim.notify("Copied normalized text to clipboard")
end
And then I bind it to a key like so:
vim.keymap.set(
"v",
"<leader>y",
copy_normalized_block,
{ desc = "Copy normalized" },
)
Filed Under: