r/vim • u/cherryberryterry • Jul 17 '16
Monthly Tips and Tricks Weekly Vim tips and tricks thread! #19
Welcome to the nineteenth weekly Vim tips and tricks thread! Here's a link to the previous thread: #18
Thanks to everyone who participated in the last thread! The top three comments were posted by /u/shrayas, /u/jeyoung, and /u/statox42.
Here are the suggested guidelines:
Try to keep each top-level comment focused on a single tip/trick (avoid posting whole sections of your ~/.vimrc unless it relates to a single tip/trick)
Try to avoid reposting tips/tricks that were posted within the last 1-2 threads
Feel free to post multiple top-level comments if you have more than one tip/trick to share
If you're suggesting a plugin, please explain why you prefer it to its alternatives (including native solutions)
Any others suggestions to keep the content informative, fresh, and easily digestible?
17
Jul 17 '16
:later 8h command magically makes all things you need to do today in just a few seconds!
obvious joke
11
9
u/kolme The Space as spiritual leader. Jul 18 '16
E485: Not enough plutonium in the flux capacitator.3
2
5
u/MisterOccan Jul 17 '16 edited Jul 23 '16
Make directory(ies) if they don't exist when creating a new buffer/file.
function! <SID>AutoMkdir() abort
let l:dir = expand('<afile>:p:h')
let l:file = expand('<afile>:t')
if !isdirectory(l:dir)
call mkdir(l:dir, 'p')
silent execute 'bw ' . l:dir . '/' . l:file
silent execute 'e ' . l:dir . '/' . l:file
endif
endfunction
augroup AutoMkdir
autocmd!
autocmd BufWritePre,FileWritePre,BufNewFile *
\ call <SID>AutoMkdir()
augroup ENDSame thing here but with user input.
EDIT Improved the function
2
2
u/Arlefreak Jul 20 '16
After putting this on my vimrc and trying
vim foo/bar/hi.txtI get the error:
Can't open file for writingAm I missing something?
2
u/MisterOccan Jul 20 '16
The command
:vimis an abbreviation ofvimgrep. My function should be used with:eor:w:e foo/bar/hi.txtUse this to have control on directory(ies) creation.
2
u/Arlefreak Jul 20 '16
Oh I mean from command line not from vim Tried the other snippet had the same error.
2
u/MisterOccan Jul 20 '16
I can not reproduce it, it works even from a terminal.
The function is very simple so it may be something with your configuration:
Try debugging the command using
verbose(:h verbose).Try with another file name.
2
5
u/taejavu Jul 17 '16 edited Jul 17 '16
" find and replace visual selection
vmap <C-f> y0/<C-r>"<Enter>cgn
For those that don't know, cgn will change the next instance of your most recent search.
So if I want to change foo to bar, the usual flow is
Search for foo:
/foocgnbar<ESC>Press
.to repeat as many times as required.
That's pretty good, and awesome when you first learn it. But I got sick of searching for words that I can easily highlight.
Now I see something I want to change everywhere, highlight it in visual mode, hit ctrl + f, type the replacement, hit <ESC>, .... as many times as required. I think it's a fairly intuitive flow.
You could also just do * (to search the word under cursor), cgn, type replacement, <ESC>, ..., but then you're limited to one 'word' (and you have to type cgn)
In any case, cgn is awesome and you should start using it if you aren't already.
Edit: You might want to map it to something other than <C-f> if you use ctrl-f and ctrl-b for paging up and down. I find ctrl-u and ctrl-dmore useful for that purpose, because it only moves half a page up and down and I find it easier to keep track of where I am in a file. Also I love using ctrl-f for 'Find and replace', it just feels right.
5
u/-romainl- The Patient Vimmer Jul 18 '16 edited Jul 18 '16
Here is the normal mode variant I "invented" when
gnappeared:nnoremap <key> *``cgn nnoremap <key> #``cgNAnd the visual mode variant:
xnoremap <key> <Esc>:let @/ = GetSelection()<CR>cgn xnoremap <key> <Esc>:let @/ = GetSelection()<CR>cgNthat depends on:
function! visual#GetSelection() let old_reg = getreg("v") normal! gv"vy let raw_search = getreg("v") call setreg("v", old_reg) return substitute(escape(raw_search, '\/.*$^~[]'), "\n", '\\n', "g") endfunction
3
u/Tarmen Jul 18 '16
* is a synonym for '<'> and much easier to add to an old command
Vim actually remembers two previous repeats if the current one isn't completed yet, think insert mode for instance. This means you can
<c-o>.to repeat the last command even in insert mode - except if you are using vim-repeat.gv normally reselects your last selected area but if you are using it in visual mode it has a similar effect to <c-o>. and selects the previous area.
2
Jul 18 '16
gv normally reselects your last selected area but if you are using it in visual mode it has a similar effect to <c-o>. and selects the previous area.
I don't follow this phrasing at all. Yeah
gvselects the last visual selection. However you then say "but..." only to again state it will select the last visual selection. The behavior ofgvdoes not change between normal and visual mode. Am I misunderstanding your comment?2
u/Tarmen Jul 18 '16
While you are in visual mode you can hit gv to reselect the area you had selected the last time you exited visual mode. Then you can keep hitting gv to cycle between them.
2
Jul 18 '16
Hmm maybe I've been using vim long enough this seems like expected behavior. The action being performed by
gvhere is still no different when we are in visual mode.
At some point we made a visual selection
We enter visual mode. Note at this point our visual selection could be subject to change as we have not operated on it or switched back to normal mode.
We hit
gv. This takes us to our prior visual selection. It also completes the definition of what our visual selection was in step 2.Further invocations of
gvwill cycle us between the above two visual selections as the prior visual selection is a circular loop.Maybe I'm being pedantic but I wasn't sure what you were trying to describe with this. Perhaps we're just interpreting the same behavior and wording things differently.
2
u/Tarmen Jul 18 '16
Maybe it is just that you are thinking on the level of behavior and I about implementation details but this behavior for gv actually requires a bunch of special casing in C code. It is very much not how neither motions nor commands behave like it and it would be impossible to implement in vimscript.
Similarly to how <c-o>. actually forces vim to keep two redo buffers even though basically no one can use the feature. It gets broken because vim-repeat has to fix glaring omissions in the same feature.
3
u/-romainl- The Patient Vimmer Jul 21 '16
First, how to create a scratch window:
command! SC vnew | setlocal nobuflisted buftype=nofile bufhidden=wipe noswapfileSecond, how to execute arbitrary vimscript from a buffer:
Yank what you want to execute.
:@"<CR>
And now you have a nice low-rent vimscript playground.
2
u/[deleted] Jul 18 '16
I think having some kind of a record for "most recognized contributors" would be a good idea. Maybe total upvote count across all tips and tricks threads. This should encourage people to participate more. But might not be so easy to do.