Hacker News new | past | comments | ask | show | jobs | submit login
Vim Tips For Intermediate Users (ideasintosoftware.com)
51 points by realyze on May 20, 2015 | hide | past | favorite | 48 comments



I’ve found relative line numbering to be distracting, and I find myself wanting absolute line numbering far more often. The reason that people want relative line numbering is almost always for relative motions, e.g. `6j`. But I find that this is seldom actually all that useful; there are various alternatives; here are a few:

- `}` to go forward by paragraph.

- `zj` to go down to the next fold.

- `gg` and `G` both accept a count (with which they are identical), so that `50gg` means “go to line 50”, and so absolute line numbers suffice though the command will typically be a little longer; of course, unlike `6j`, this will go to the start of the line if 'startofline' is not unset, so it’s not always ideal, but I find myself rather good at knowing at sight how many lines down and up I need to go anyway.


You can use a hybrid of absolute and relative numbering by setting both the 'number' and 'relativenumber' options (in vim 7.4). It displays the absolute number of the current line (instead of 0) but relative numbers of the other lines.


Care to give any links to this? This is probably my biggest annoyance with Vim right now, how my current line is 0 and having to add 1 every time I do any operation gets old quick.


I think what he means is just put both

set relativenumber

set number

In your .vimrc



I use :<line-number><enter> to go to a specific line; it has the advantage of showing the digits of the line number as it's entered.


If you set the 'showcmd' option, the command you're currently typing is displayed on the last line of the screen (same as command line) on the right.

Of course, saving one keypress on this isn't a big deal but it's nice sometimes to be able to see the command you're typing.


At work I use VsVim and this plugin https://visualstudiogallery.msdn.microsoft.com/74d68e2b-ff64... allows both simultaneously, which suits me best. I have not been able to achieve that in vim yet though.


Fair enough. I kinda switch between those two. Like, when I need to yank 5 lines from the middle of a function, I find it quite comfortable to see the relative numbers.


Or just `:<number>`?


Wow, I had no idea about the relative numbering.

One more thing that eases my daily frustration is

    set scrolloff=6
The above prevents getting the cursor stuck at the bottom or top of the screen, unless you're at the absolute bottom or top. 6 lines is perfect for me at 1920x1080, 13.3", 16pt Droid Sans Mono Regular.

It might help you if you find yourself scrolling down to move the view around, then scrolling up again to get where you want to edit.


Just a note that this affects H (jump to top line on the screen) and L (jump to bottom line on the screen).


Thanks here as well. I never even thought such a feature might exist. Love it!


Good one! Just added to my .vimrc. Thanks!


If you're looking for keys to remap, these are prime candidates:

  s: synonym for cl
  <cr> (enter): synonym for j
  _: acts like ^ when given without a count, acts like <count>jk^ when given with a count
  <bs> (backspace): synonym for h
  <space>: synonym for l
Doubling up operators with non-motion characters works well, too. For example, operators like 'c' or 'd' probably shouldn't be rebound, and they're often doubled ('cc', 'dd') or accept a motion ('c$', 'd}'), but combining them with another non-motion isn't valid ('dc','cs'). This makes those combinations good candidates for custom bindings. A lot of plugins like surround.vim take advantage of those combinations.

Vimcasts covered this in more depth here: http://vimcasts.org/blog/2014/02/follow-my-leader/


I remap the semicolon to the colon in my .vimrc:

  nmap ; :
This makes it much easier to type commands, since you don't need to use a keyboard chord.

After using this for a year or so, I found out that the semicolon actually has its own function--it can refer to the current insertion point when writing ranges. But I've never used that; one could remap : to ; if desired.


u p v o t e!! Brilliant (IMHO). I don't even want to think how many shift+: chords I've done could have been just a semicolon.

Even better:

    nmap ; :
    noremap ;; ;
Idea from http://vim.wikia.com/wiki/Map_semicolon_to_colon


In normal mode, after using f or F to jump to a character, ; repeats the motion and jumps to the next match. I find myself using this often enough that if I swapped mappings for : and ; I would be in a world of confusion.


Ha. I did as well, so I remapped <space> to ;. Now when I f, t, F, or T, and want to move to the next one, I hit space.

Come to think of it, maybe I should just remap <space> to : and leave ; alone?


I map <space> to : and it's been great. <space> is normally just a synonym for l, so I never used it; my only muscle memory issue is just an occasional : to enter command mode. Perhaps I should unmap :.


; also repeats f and t

but : is much more common so it makes sense to swap them


Being able to open up multiple files and arrange them precisely how I want (with the keyboard!) is my absolute favorite part of vim. I use the following shortcuts for opening a file to the right/left or above/below:

    nnoremap <Leader>or :set splitright<CR>:vs
    nnoremap <Leader>ol :set nosplitright<CR>:vs
    nnoremap <Leader>oa :set nosplitbelow<CR>:sp
    nnoremap <Leader>ob :set splitbelow<CR>:sp
    " Don't let vim change the setup when closing windows
    set noequalalways
So I can simply type ',or ' and then the name of a file to get a vertical split.

You can then use <C-w>w<number>+/- to increase/decrease the height of a window and <C-w>w<number>'<'/'>' to change the width.


Since I usually work with small laptop screens I tend to use vim tabs more than split. I find these key combinations quite comfortable:

nnoremap L :tabnext<CR>

nnoremap H :tabprevious<CR>

nnoremap <C-N> :tabnew<CR>

Also if you use offline docs (I only know Zeal) it would be pretty helpful to map the offline doc application to the K key depending on the language

nnoremap K :exec "!/usr/bin/zeal --query ".&ft.":".expand('<cword>')."&"

The above copies the word under the cursor and query it with zeal.


Some more tips that can make your vim life more awesome:

- Learn about registers

- '.' is more powerful than you think

- Having a hotkey to jump to your rc and auto resource the file on safe is awesome

- Learn about quickfix (if you work with a compiled language, still renders a bit crap for Rust, but it works)

- vim-dispatch (or neovim with jobs ext) is probably one of the nicest, time saving plugins around

- If your vim is slow (repaints due to ill setup Syntastic conflicts is common), fix it. Vim has excellent profiling support.


You can simply mark your text with Shift-v, then d to cut, y to paste (correction edit: p is for paste). This saved me so much time and energy than trying to count the lines. The relative numbering is cool unless your text goes off screen...


Wouldn't that be the following, in normal mode?: v (motion commands) d p


You are right, v will highlight per character, Shift-V highlights entire lines. Also, as you pointed out, I made a mistake on the paste, it's p, not y (which is copy).


Sorry, I should have simply tested shift-v


Hey no need to apologize, I didn't even know about v until I tried it. So thanks for that.


The most useful shortcut I have in my .vimrc is the ability to "sudo save":

    command W :execute ':silent w !sudo tee % > /dev/null' | :edit!
No more exiting vim to start it again with sudo.


That is one of the features I get from the https://github.com/tpope/vim-eunuch plugin (SudoWrite).


Huh. Well I kinda consider that `sudo` annoyance a feature. It tells me to think twice before potentially messing up badly. :-)


When I use :W is because I've been editing some system configuration files.. I know what I'm doing.

And messing up is half the fun of systems administration :)


Likewise, but I have the alias added so that when I discover I should have edited under sudo, I don't have to lose my work.


Isn't it much simpler to use tmux for the vertical split? Or are there any advantages of "vertical buffers" in VIM I should know about?


- yanking/cutting and pasting between the two displayed buffers in the panes.

- being able to quickly swap one pane to show a different file, then swap back to that same file again (or do it with the right pane)

- being able to horizontally split either vertical pane, ie you can tile the panes exactly how you like very fast.

:mouse=a

and now you can drag the split around

- showing differences between to versions you have open

:windo diffthis

highlights them - can't really do it at all with tmux

- Having the whole thing inside a screen session you can resume it from where you left off over ssh remotely later.

- Saving it as a vim session if you want to power the box down and resume from where you were, with precisely those splits and buffers open scrolled to what you see now.

- Backgrounding the whole thing to do something else quickly.

Yeah, there's a few, I doubt that list is exhaustive and doing things that way means some other trade offs. Whether these advantages are actually things you want is a different question that only you + experimentation can answer..?


I see lots of discussion about using tmux and vim together. Most of the articles are more about configuring each instead of how that persons workflow. I get stuck on this problem; where to draw the line between tmux splits and vim splits (and by extension window management).

When do you do use tmux for splitting versus vim? What are your key bindings for creating, resizing, and navigating each?

Personally, I drop back to the shell constantly so I tend to launch a lot of separate vims. The only time I use vim splits are if it explicitly occurs to me or if I'm using vimdiff. This means I have a lot of problems copy/pasting or end up opening the same file in multiple vim sessions (but different tmux panes/windows).


Even without any configuration the workflow of using tmux for panes and windows and within I start and quit vim as required seems totally fine.


Oh yeah, it's not a problem or conflict. Many of the examples people give tend to remap similar or the same keys for splitting in vim and tmux or navigating between splits (alt or ctrl + hjkl for navigating them).

I'm looking for more of a mental model or workflow of when to use vimsplits over tmux splits and how to navigate. I generally avoid vimsplits because I haven't found a good workflow to use both and my muscle memory gets messed up when I mix them.


This is a longshot, but has anyone ever seen a way to drop into some sort of debugger for vim that is on a higher abstraction layer than gdb?


Vim actually has a built in debugger and a couple extra features for debugging:

http://inlehmansterms.net/2014/10/31/debugging-vim/

http://vimdoc.sourceforge.net/htmldoc/repeat.html#debug-mode ( or :h debug-mode )

I recall there being a few gotchas last time I used debug mode and they're mentioned in the doc, but unfortunately I don't quite remember what they were.


Is there any way to set relative numbering in Vim to be 1-indexed? I want to avoid mentally adding 1 every time I want to yank a few lines.



Rather than <number>yy, you could do y<number>j or y<number>k and it works appropriately with the relative numbers; yj == 2yy. I always use this with c, d, and y commands.


The vertical split recommendation is really great. I agree with the author that I always forget and often times end up doing horizontal.


Several years ago[1] I requested an option called 'splitvertical' that would cause all window splits to be vertical by default. Christian Brabandt made me a patch I use to this day even though it was never merged: https://github.com/chrisbra/vim-mq-patches/blob/master/verst....

It's still fairly straightforward to merge. Ping me if you need help (email in profile)

[1] http://thread.gmane.org/gmane.editors.vim.devel/28395/focus=... http://www.reddit.com/r/vim/comments/2irn8j/vertical_split_b...


    nnoremap <leader>w <C-w>v<C-w>l
If you set 'splitright', you should remove the <C-w>l.


This mapping makes my life much nicer:

  nnoremap Q @q
It turns 'Q' into a sort of enhanced '.' command that can repeat a sequence of multiple commands. To use it, first start recording a macro to the 'q' register. That's the easiest register because 'q' is also the command to start and stop recording a macro: to start recording you just simply press 'qq'. Then you make your changes and press 'q' to stop. Now you can repeat that sequence of commands with 'Q'.

It turns out that macros are really useful, but I would rarely use them because it's just so awkward to press '@' each time I want to apply one. Unfortunately, '.' doesn't repeat the '@' command to apply a macro. I would often find myself mechanically repeating things by hand, or else wasting time writing complicated sequences of :s/substitution/commands/. Now I use quick ad-hoc macros all the time.

The speed and convenience are the real key for me. You might call it synergy, or a tipping point, or the straw that breaks the camel's back. For me, 'qq' is just a little bit faster and easier than any other register. Repeating 'Q' is just a little bit nicer than typing '@q' followed by repeating '@@'. (It's also kinda nice that it's all the same key.) Macros are nice, but two carefully made choices that each are only slightly better than the alternatives combine to make something vastly more useful. In my mind, 'Q' is almost its own thing, separate from the idea of other macros.

Now that I use macros, I've discovered some useful patterns. One technique I often use is to include a final motion in my macro to move to the next place I want to change. For example, maybe I want to edit several lines in a row. I press 'qq', make my changes to the current line, then press 'j' to move down a line. Only then do I stop recording. After that, I can just hold down the shift key and press 'Q' repeatedly until I'm done. Even if my changes are simple enough that '.' would work, it saves me from making mistakes when bouncing back and forth: 'j.j.j.j.jj.'. Oops.

You can do that with any motion(s), and I often use 'n'. Sometimes finding some simple marker text on each problem line is easy, but using find-replace to make the actual changes requires a hideous regex. In those cases, I'll do the simple search, record a macro as I make the first change, and finally press 'n' to move to the next match. Then I just lean on 'Q' until I'm done.

Sometimes I'll also throw a 'zz' after the last motion to center the current line in the window so I don't have to look around to locate the cursor when a change scrolls the window.

Normally 'Q' enters Ex mode, but so far I haven't found much use for that. If that ever changes, I'll probably use a <leader> mapping to get Ex mode back. Using something even a little bit slower than 'Q' would destroy the effect. I forget where I originally learned this mapping.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: