Intro
In this article I will share some of my daily life solutions to make my neovim workflow smoother.
Since posting this article my repository was updated with more elaborate code. here
If I want copy a text and open in neovim (zsh)
I do ...
# Edit content of clipboard on vim
function _edit_clipboard(){
# pbpaste | nvim
termux-clipboard-get | nvim -c 'setlocal bt=nofile bh=wipe nobl noswapfile nu'
}
zle -N edit-clipboard _edit_clipboard
bindkey '^x^v' edit-clipboard
I also have an autoloaded "nvimscratch" do deal with arguments and pipes:
nvscratch() {
local content
if [[ -p /dev/stdin ]]; then
content=$(cat -) # reads from pipes
else
content="$("$@")" # runs with arguments
fi
## now we open the content in a scratch buffer
nvim -c "enew | setlocal buftype=nofile bufhidden=wipe noswapfile" +"0read !echo \"$content\""
}
In termux my pbpaste and pbcopy come from
# for zsh
(( $+commands[termux-clipboard-get] )) && {
alias pbpaste='termux-clipboard-get'
alias pbcopy='termux-clipboard-set'
}
in regular linux use xclip instead of termux-clipboatd. Then I cand run
some_command | pbcopy
or
pbpaste | nvscratch
Blockwise mode made easy
We frequently see articles and videos about visual block mode but sometines
people forget about pressing ctrl-v, and I have found a perfect solution for this:
NOTE: I usually cite the sources but in this case I have to say sorrow,
but the code bellow will make every insert "I", "A", and "gI", become
blockwise. (see my map function bellow)
-- Better block-wise operations on selected area
local blockwise_force = function(key)
local c_v = vim.api.nvim_replace_termcodes('<C-v>', true, false, true)
local keyseq = {
I = { v = '<C-v>I', V = '<C-v>^o^I', [c_v] = 'I' },
A = { v = '<C-v>A', V = '<C-v>0o$A', [c_v] = 'A' },
gI = { v = '<C-v>0I', V = '<C-v>0o$I', [c_v] = '0I' },
}
return function() return keyseq[key][vim.fn.mode()] end
end
map('x', 'I', blockwise_force('I'), { expr = true, noremap = true, desc = 'Blockwise Insert' })
map('x', 'gI', blockwise_force('gI'), { expr = true, noremap = true, desc = 'Blockwise Insert' })
map('x', 'A', blockwise_force('A'), { expr = true, noremap = true, desc = 'Blockwise Append' })
In my utils.lua I have a map function just to make easy creating new mappings (you can use vim.keymap.set instead):
NOTE: For newbies. We have a convetion: lua modules start with local M = {}
and we finish them with return M
. In the code below I am just showing some functions. Those who start whit M.
are inside a module.
-- https://blog.devgenius.io/create-custom-keymaps-in-neovim-with-lua-d1167de0f2c2
-- https://oroques.dev/notes/neovim-init/
M.map = function(mode, lhs, rhs, opts)
local options = { noremap = true, silent = true }
if opts then options = vim.tbl_extend('force', options, opts) end
vim.keymap.set(mode, lhs, rhs, options)
end
Paste the clipboard right away blockwise:
It was been a while I needed this solution, because I am using nvim in termux and the 'termux-clipboard (get and set)' does not allows me to convert the clipboard to blockwise, linewise or characterewise. The idea is:
Using an internal vim register to receive the clipboard content, make it blockwise, paste at cursor position and restore the temporary register content, because in somewere else the temporary register I am using for this process could mess things up.
So, first we creare a function to use a temporary register and run a callback function we will use in our mapping:
-- paste into your utils.lua (as an example)
M.with_temp_register = function(reg, callback)
local content = vim.fn.getreg(reg)
local regtype = vim.fn.getreginfo(reg).regtype
callback()
vim.fn.setreg(reg, content, regtype)
end
Now we are going to use our function in a Alt-2 mapping (just because I have a huge amount of mappings)
local UTILS = require('core.utils')
map("n", "<M-2>", function()
---@type string
local reg_clip_raw = vim.fn.getreg('+')
---@type string[]
local reg_clip = vim.split(reg_clip_raw, "\n", { plain = true })
UTILS.with_temp_register("z", function()
vim.fn.setreg("z", reg_clip, "b")
vim.cmd('normal! "zp')
end)
print("Clipboard colado como blockwise")
end, { desc = "Colar clipboard como blockwise" })
Using only lua api to paste @+ blockwise:
M.paste_blockwise = function(lines)
local row, col = unpack(vim.api.nvim_win_get_cursor(0))
row = row - 1
local buf = 0
local existing_lines = vim.api.nvim_buf_get_lines(buf, row, row + #lines, false)
for i, l in ipairs(lines) do
local target = existing_lines[i] or ""
if #target < col then
target = target .. string.rep(" ", col - #target)
end
existing_lines[i] = target:sub(1, col) .. l .. target:sub(col + 1)
end
vim.api.nvim_buf_set_lines(buf, row, row + #lines, false, existing_lines)
end
The keymap
-- Uso:
map("n", "<M-4>", function()
local block = vim.split(vim.fn.getreg("+"), "\n", { plain = true })
UTILS.paste_blockwise(block)
print("Colado como bloco via API")
end)
Final note: Probably I am going to add more content in this article. Please give us you opinion we appreciate it very much!