Vim and NeoVim can be extended using a problematic language called VimScript, the single best source for which is Learn Vimscript the Hard Way, a book - and website - by Steve Losh. Today I'm going to cover writing functions in VimScript (although probably not as well as Losh did).
To re-indent an entire file, we would do this:
gg=G. Which is great, but ...
gg takes you to the top of the file, so I just lost my place. If you search on Google, you'll see a lot of answers to this problem that look like this:
This is marking your cursor location and your window position, and then returning to it later (note the
gg=G trapped in the middle). Ignore all of these, as Vim introduced a couple wonderful functions to replace all that maneuvering:
winrestview(). So we can write a function:
function! ReindentFile() let l:winview = winsaveview() :normal! gg=G call winrestview(l:winview) endfunction
Saves the current view (both the cursor position and what portion of the file is visible in the window) to local variable
l:winview (where the 'l:' indicates a variable local to the current function - see Vimscript Variable Scoping and Pseudovariables). Invokes Normal Mode, but the "!" forces a state that ignores the user's over-ridden key mappings. (People end up making a lot of mappings - this forces default behaviour in case they overrode any commands we use here. This is also why I called VimScript "problematic" earlier: the behaviour of accepting user modifications to the language as a default is ... perverse and bad.) Then restore the view.
You can enter this at the command line, although I wouldn't particularly recommend it. You can add it to your ~/.vimrc (better) and then call it at the command line with
:call ReindentFile(), but better would be to map it:
nnoremap <leader>r :call ReindentFile()<cr>
See Map Leader and Normal mode mappings if you're not familiar with mapping.
Similarly, let's write another function to delete all trailing white space in a document:
function! DeleteTrailingWhiteSpace() let l:winview = winsaveview() :%s/\s\+$// call winrestview(l:winview) endfunction
As before, save (and restore) the window state, then search the entire file ('%' in the regex) for all whitespace ('s+') at the end of the line ('$') and replace it with nothing ('//'). Then restore your window view.
To make it useful, attach it to a mapped keyset:
nnoremap <leader>dw :call DeleteTrailingWhiteSpace()<CR>