Keep your cursor in the middle of the screen in normal mode
:nnoremap j jzz
:nnoremap k kzz
Jump back
As you know, vim has a jump list, and you can access previous jumping with Ctrlo and use Ctrli to go to the newer positions on the jump list.
Normally j
and k
do not change the jumplist but we can change this behavior:
" source: https://www.vi-improved.org/vim-tips/
nnoremap <expr> j v:count ? (v:count > 5 ? "m'" . v:count : '') . 'j' : 'gj'
nnoremap <expr> k v:count ? (v:count > 5 ? "m'" . v:count : '') . 'k' : 'gk'
Now if you type 5j
your jump will be added to the jump list.
Flash Cursorline Function
I am using lua to config my neovim and I have cursorline disabled. I have created a function to flash the cursorline and associate (map) it to some jumps:
-- ~/.config/nvim/lua/core/utils.lua
local M = {} -- M stands for module
-- https://vi.stackexchange.com/questions/31206
-- https://vi.stackexchange.com/a/36950/7339
M.flash_cursorline = function()
local cursorline_state = lua print(vim.opt.cursorline:get())
vim.opt.cursorline = true
vim.cmd([[hi CursorLine guifg=#FFFFFF guibg=#FF9509]])
vim.fn.timer_start(200, function()
vim.cmd([[hi CursorLine guifg=NONE guibg=NONE]])
if cursorline_state == false then
vim.opt.cursorline = false
end
end)
end
-- map helper
M.map = function(mode, lhs, rhs, opts)
local options = { noremap = true }
if opts then
options = vim.tbl_extend("force", options, opts)
end
vim.api.nvim_set_keymap(mode, lhs, rhs, options)
end
map('n', 'n', 'nzz:lua require("core.utils").flash_cursorline()<CR>Nn')
map('n', 'N', 'Nzz:lua require("core.utils").flash_cursorline()Beacon<CR>nN')
-- Why nzzNn: https://vi.stackexchange.com/a/36950/7339
-- zz will remove the count display ([n/nn]) in the statusbar if the view is changed.
-- A quick and dirty solution to show the count again is to hit n or N again, ie.
-- nnoremap n nzzNn
map("n", "<C-o>", '<C-o>zv:lua require("core.utils").flash_cursorline()<CR>')
map("n", "<C-i>", '<C-i>zv:lua require("core.utils").flash_cursorline()<CR>')
return M
Keep your cursor position during some actions:
To call any lua function we need to add our functions to a namespace and return this namespace, this means, at the beginning of the our module use:
M = {}
And at the end of it:
return M
Inside our module we add functions to this namesmapce prepending M.
the the function we are creating.
-- file: ~/.config/nvim/lua/utils.lua
M.preserve = function(arguments)
local arguments = string.format("keepjumps keeppatterns execute %q", arguments)
-- local original_cursor = vim.fn.winsaveview()
local line, col = unpack(vim.api.nvim_win_get_cursor(0))
vim.api.nvim_command(arguments)
local lastline = vim.fn.line("$")
-- vim.fn.winrestview(original_cursor)
if line > lastline then
line = lastline
end
vim.api.nvim_win_set_cursor(0, { line, col })
end
You can use the above function this way:
-- dos2unix
M.dosToUnix = function()
M.preserve("%s/\\%x0D$//e")
vim.bo.fileformat = "unix"
vim.bo.bomb = true
vim.opt.encoding = "utf-8"
vim.opt.fileencoding = "utf-8"
end
vim.cmd([[command! Dos2unix lua require('core.utils').dosToUnix()]])
The command outside the Dos2unix function creates a command that calls the function, of course you also can create mappings to do the same.
Reduce to or more spaces to one keeping the cursor position:
M.squeeze_blank_lines = function()
-- references: https://vi.stackexchange.com/posts/26304/revisions
if vim.bo.binary == false and vim.opt.filetype:get() ~= "diff" then
local old_query = vim.fn.getreg("/") -- save search register
M.preserve("sil! 1,.s/^\\n\\{2,}/\\r/gn") -- set current search count number
local result = vim.fn.searchcount({ maxcount = 1000, timeout = 500 }).current
local line, col = unpack(vim.api.nvim_win_get_cursor(0))
M.preserve("sil! keepp keepj %s/^\\n\\{2,}/\\r/ge")
M.preserve("sil! keepp keepj %s/^\\s\\+$/\\r/ge")
M.preserve("sil! keepp keepj %s/\\v($\\n\\s*)+%$/\\r/e")
if result > 0 then
vim.api.nvim_win_set_cursor(0, { (line - result), col })
end
vim.fn.setreg("/", old_query) -- restore search register
end
end
Change the "Last Change: dd/mm/yy" at the begining of your file each time you save it (it needs an autocommand for it):
--> :lua changeheader()
-- This function is called with the BufWritePre event (autocmd)
-- and when I want to save a file I use ":update" which
-- only writes a buffer if it was modified
M.changeheader = function()
-- We only can run this function if the file is modifiable
if not vim.api.nvim_buf_get_option(vim.api.nvim_get_current_buf(), "modifiable") then
return
end
if vim.fn.line("$") >= 7 then
os.setlocale("en_US.UTF-8") -- show Sun instead of dom (portuguese)
time = os.date("%a, %d %b %Y %H:%M")
M.preserve("sil! keepp keepj 1,7s/\\vlast (modified|change):\\zs.*/ " .. time .. "/ei")
end
end
To see an autocmd.lua file you can follow this link.
We can even reindent the whole file keeping the cursor position:
vim.cmd([[command! Reindent lua require('core.utils').preserve("sil keepj normal! gg=G")]])
Jump to the alternate file:
When you have the buffer list opened it will be like this:
To alternate between the current file and the alternate file, wich is the last one you were on, just press Ctrl-6
Top comments (2)
wow! pretty cool and simple solution the
nnoremap j jzz
I have a suggestion to improve it even more:
It's useful when you have a line bigger than the width of your viewport.
See it in action:
Quickly realized I'm getting a "whole screen movement fatigue" with this.