In my 6 years of coding and writing LaTeX in Vim, I have found that the greatest boost to my Vim productivity is learning all about the vi and ex foundation of Vim. My Vim knowledge applies 100% to any default Vim installation on a modern distro, and my vimrc contains mostly trivial tweaks.
This means using :normal and macros instead of :s for most of my search/replace actions; using H, M, L, {, } to navigate quickly in the lines visible on the screen, and using f/F/t/T/;/,/% to navigate quickly within a line.
I would say that 98% of my autocomplete needs are fulfilled by token completion (:help i_CTRL-N) and line completion (:help i_CTRL-X_CTRL-L).
I frequently use the command-line window (:help c_CTRL-F) and listing matching names (:help c_CTRL-D).
I specifically don't have mappings that involve the leader key, and I don't use the Ctrl-P plugin or a package manager or anything like that -- I honestly don't think that mapping <Leader>w to :w<CR> will make me any more productive in Vim.
Suppose a range of lines contains function calls in some programming language:
i = foo(a, 42, 1)
j = bar(b, c, 100, 2) # this is a comment (well, duh)
bazbar(etc, 3)
You want to edit the last parameter in each function call -- change it to 'hello'. I have two ways of approaching this: macros (interactive) or :norm (less interactive).
1. Put your cursor on the first byte in the first line, type qq to record a macro of your change, q to finish. Select the rest of the lines in visual line mode and type :'<,'>norm @q to run the macro on each of the remaining lines.
2. Select the lines in visual line mode and type, for instance,
:'<,'>norm %F,ws'hello'
This is the "non-interactive" version of the above since the macro keystrokes are given directly to :normal. Pro: ability to undo keystrokes unlike when recording a macro. Con: cannot actually see the effect of the keystrokes (but with practice, this is not a problem).
(Note that colon in visual mode automatically inserts the :'<,'> so you only have to type :norm ...)
I find the declarative nature of regexes/:s to be too restrictive -- I much prefer the operational nature of macros/:normal, since that lets me make the change I want directly, without me having to phrase the change as a regular expression.
I could also use CTRL-A in normal mode to increment the last argument in each line:
:'<,'>norm %b^A
(where ^A is the literal, typed CTRL-V CTRL-A)
I feel like a wizard whenever I use :normal in a non-trivial manner.
I normally include a move to next line part in my macro and then guess at how many times to run it (20@q, repeat until I get it right). It's actually the main reason I often don't bother using macros.
@@ applies the previously applied macro, so after applying the macro (including the move to next line, but see below too) you can you just hold down @ and quickly go through as many lines as you need. If you overshoot, you can just press u a few times.
Another tip: when you forget to add the move to next line to your macro, you don't have to start over. You can append to a macro, just use the upper-case register name instead. So to append a down and move to beginning of line to macro 'a', you'd type qAj0
Using :norm, this transformation can be achieved in the following way:
:'<,'>norm I{^[eldedecw, "^[A"},
(where ^[ is a literal escape, typed CTRL-V ESC.)
Anecdotally, it is faster for me to type up such a line than an equivalent regular expression, since I use vi normal mode commands much more than regular expressions.
I would have piped this through awk, but this is probably better done with macros. Thanks for taking the time to elaborate. I will definitely give macros a try.
You need to know how dw, de, cw, ce relate to each other, when the cursor is on a token character vs. a whitespace character, and so on, in order for this to be truly useful -- but luckily, ordinary practice with those commands in Vim can lead to an efficient internal idea of how it works. "You get used to it, though. Your brain does the translating. I don't even see the code. All I see is blonde, brunette, redhead."
this is awesome, can you please suggest some resources for me, a long-time basic user of vim, ( know a lot of commands for actions, but not the underlying relationships?
Something i've been using more lately is Ctrl-R + Register. Great for inserting text in command mode. For instance, you can do this to insert your recorded macro (if it's in register q) as a norm command:
:norm Ctrl-R q
I would have almost simply started recording a macro, convert the first one using as many idempotent normal mode commands in place of insert mode commands as possible, and simply replayed it. Thanks for the idea.
As a side note, I love how Vim is basically a functional programming language for text editing.
Well you're leaving the middle columns there, then on your first keystrokes it would be acutally {+down+left as Sublime does not put cursor back at beginning of line when going down. In all I used 26 keystrokes in Sublime, and 27 in Vim. Also, if you understand Vim's vocabulary, the "cognitive overhead" is, as you put it "far less" in Vim's favor. IMO.
I am sorry, but I don't know any resources... I have collected a few things on the following page: http://users-cs.au.dk/rav/vim/
Basically, I achieved my wizard-level C++, Vim and Git knowledge during my three years as a part-time student programmer in the basic research center MADALGO. I took the time to study the documentation (respectively the C++11 draft, :help and the git man pages) whenever I was curious. For Vim in particular, I made sure to eliminate all repeated keysmashing in my daily workflow, which "unfortunately" required me to learn about macro wizardry.
My only advice is to keep practicing, to keep trying to spot inefficiencies in your own workflows, and to actively eliminate these inefficiencies by studying the Vim help pages.
Over the years, I've got a lot of mileage out of "Learning the vi and vim Editors" from O'Reilly, and web pages like http://www.lagmonster.org/docs/vi.html. Practicing and testing compositions based on what you learn from these will go a _long_ way. Try new ways to move (by screens, by sentences, by blocks), test using your buffers, experiment w/ transforms. Then, one day, you realize you're pretty good with vi.
I usually use the asterisk to search for the token under the cursor, edit the sought token using cw and then n.n.n.n. to replace later occurrences. I don't see how the mapping makes this more efficient.
Wow I have only been using H and L, and only because of you have I come to know M, {, and }. Thank you!
But would you mind giving an explanation as to what the other things you listed do (f/F/t/T/;/,)?
From just playing with them, it seems like f goes to the next character that you type and F does the same but backwards. t/T does the same but instead of going to the character it goes one before/after.
fx moves the cursor to the next occurrence of x, and semicolon repeats the search. To repeat the search in the opposite direction, use comma. 4tx moves the cursor right before the 4th occurrence of x right of the cursor in the line. F and T move backwards instead of forwards; in that case, semicolon continues moving backwards and comma moves forwards (similar to / ? n N).
It takes a while to get used to, but it has made me much more efficient compared to when I just pressed wwwww or eeeee or bbbb to get where I wanted in a line.
I also make liberal use of '/' to get around. Sometimes the bit you want is a line or two down so 't' doesn't quite cut it.
I use t / f a lot when cutting things, though there's probably a better way (from the article, I just discovered gn to visually select the next item matching the previous search).
eg, I might have a name that I want to replace in a couple of spots so I find it easy to do something like:
/AIDOS<CR>cfSNEWNAME<ESC>n.n.n.
It's generally when it's a bit less calculated. If I knew I was replacing a load of stuff I'd use :%s/AIDOS/NEWNAME/gc
when I learned about f and F a whole new world opened up for me. It never ceases to amaze me how amazing vim is. Another quick thing I recently learned (yes, novice vim user here) is stuff like this
\includegraphics{test.png}
if you stand inside the curly brackets and type ciB (change in Brackets) you get this
\includegraphics{}
with your cursor active inside the brackets, just awesome ..
nice. I was wondering how one would accomplish the same with parens, i.e. ci(. Why does this work? It doesn't seem to match the usual building of commands. I mean this obviously isn't c command followed by i command followed by paren. Is it just special?
I don't know if I am understanding your question correctly.
I read 'ci(' as change what's inside parents. I read 'ci{' as change inside braces. 'ca(' and 'ca{' grab the parents and the braces as well.
=========================
These combinations work for (d)elete as well. If your cursor is over the 4th letter of a 6 letter word, 'dw' will delete to the end of the word. 'diw' on the other hand will delete the whole word. (I've never tried 'daw' although I know 'da(' works)
right. I guess what I meant was 'c' and 'd' are usually followed by movements, so stuff like 'dt)' makes sense to me. 'i' on the other hand is not a movement, so the behavior of 'di)' was surprising to me.
It's because 'iw', 'aw', and the like are commands of their own when an operator like 'c' or 'd' precedes [1]. So 'di)' is interpreted as 'd' followed by the 'i)' command (if I'm interpreting it correctly!), not as 'd' followed by 'i' followed by ')', which is nonsense.
I hope that was clear - just trying to understand vim better :)
> I specifically don't have mappings that involve the leader key, and I don't use the Ctrl-P plugin or a package manager or anything like that -- I honestly don't think that mapping <Leader>w to :w<CR> will make me any more productive in Vim.
I'm not as much of a purist, but that line jumped out at me too. For me, the attraction of vim is primarily in raw out-of-the-box editing power and ubiquity. Relying on custom binds for basic actions really hurts the ubiquity half of the equation. And really is :w<CR> where one wastes time in vim? If I wanted to customize everything I'd probably switch to emacs.
Still, it's interesting to see how many different ways vim can be optimized according to individual workflows.
While all of that is correct, it's also the core of vim philosophy that using 2 key strokes instead of 3 is what speeds you up. That said I also haven't used too fancy configuration or mapping or plugins in vim yet because I fear I don't have them when I ssh into another system, which happens quite often. But I have to say that I use a few aliases in git and that speeds me up a lot, as long as I stay on my system.
"%" works fine for moving around, but when I use it to edit it always surprises me, which direction it goes. I almost think vim is psychic, because "%" goes the wrong direction for me at least 80% of the time. There must be a deterministic rule governing this, but can anyone explain to me what it is?
Find first brace to the right of the cursor (be either an opening or closing brace) and jump to the matching one. If the cursor is at the beginning of a line of matched parentheses, % will go to the closing parenthesis of the first group, as in my example in a cousin comment.
This means using :normal and macros instead of :s for most of my search/replace actions; using H, M, L, {, } to navigate quickly in the lines visible on the screen, and using f/F/t/T/;/,/% to navigate quickly within a line.
I would say that 98% of my autocomplete needs are fulfilled by token completion (:help i_CTRL-N) and line completion (:help i_CTRL-X_CTRL-L).
I frequently use the command-line window (:help c_CTRL-F) and listing matching names (:help c_CTRL-D).
I specifically don't have mappings that involve the leader key, and I don't use the Ctrl-P plugin or a package manager or anything like that -- I honestly don't think that mapping <Leader>w to :w<CR> will make me any more productive in Vim.