Is there a reason some of VIM's motion commands are restricted to one line? - vim

I'm beginning to learn VIM (I've downloaded an emulator plugin for my IDE) and unsurprisingly it's making me irritated and extremely slow. That is all fine and I realize it's a phaze everyone goes through.
However this one feature is quite frustrating - being unable to jump to the next line via l, previous with h or search more than one line with f.
Is there a valid, typing speed enhancing reason for this?

You can make h and l wrap lines by adding h and l to the whichwrap option (:he whichwrap), although for the sake of compatibility with scripts and macros that don't expect h and l to wrap, you might want to avoid adding them, and add the < and > options instead (which allow the left and right arrow keys to wrap).
As for f (and F and t and T), they're just really not meant to do that, but you can use / and ? as movements -- d/foo<Enter> to delete everything between here and a following "foo" (whether it's on this line or a later one).

Related

Selecting multiple text spots with visual mode?

I'm doing some markdown editing in vim on a file. I'm trying to convert it to markdown with code highlighting, etc.
- Arithmetic operators:`+,−,*, /`
- Constants: `e`, `pi`
- Functions: (abs x), (max x y... ), (ceiling x) (expt x y), (exp x),
(cos x), ...
I want to select only the things that are in parantheses (including the parantheses) in the following using visual mode (so they would be disjoint by the commas):
(abs x), (max x y... ), (ceiling x) (expt x y), (exp x),
(cos x), ...
And then do S` to surround the each piece of text with backticks. How can I do this without selcting each one, then doing S` repeatedly?
How can I do this without selcting each one, then doing S` repeatedly?
This is actually what works best in Vim. With a bit of help from macros:
Interactive version:
/(.\{-})<CR>
qqysa)`nnq
#q
##
##
... till you do them all and wrap around to where you started.
Non-interactive "just do it" version:
:set nows<CR>
gg
/(.\{-})<CR>
qqqqqysa)`nn#qq#q
You'll probably want to go back to :set ns afterwards.
Of course, if you know that there are no nested parentheses, then the simplest answer is using :s, like the other answerer suggested.
EDIT with the explanation of the macro:
qqqqq...#qq#q is a loop. Here's how it works:
qq followed by q clears the q register. This will be important later.
qq starts the macro recording.
ysa) surrounds around the parentheses with `.
nn goes to the next match. We have to do it twice, because surround jumps to before the paren, and n will match the same parentheses again.
#q invokes the q macro. It is empty, so this does nothing... now. However, read further...
q stops the macro recording, and stores it to the q register.
Now that q is not empty any more, we can execute it with #q. However, during the execution q will still not be empty, so when we get to the point in the macro that did nothing during the recording, the macro will relaunch, giving us a primitive, but functioning, recursion loop.
The loop stops when something in it breaks: for example, not being able to go to the next match. Usually, you'd just change all the matches so no more matches remain; however, the edit this macro does does not make the match fail, so we have to rely on :set nows to make sure we don't continue infinitely adding backticks to all parentheses.
After a bit of thought, you can actually rewrite the pattern so that :set nows (and additional n) is not needed:
/`\#<!(.\{-})<CR>
qqqqqysa)`n#qq#q
This matches a pair of parentheses not preceded by a backtick, so that after all matches have been dealt with there is no match for n, naturally breaking the loop.
If anyone thinks this is complex... note that most editors plain can't do it (since this takes into account proper parenthesis nesting, whereas I haven't yet seen an editor with search-replace robust enough to be able to pull it off).
Using a global command (assuming `S`` comes from surround.vim):
:global/(/normal f(ysab`
(This affects the whole file, and may only do one change at a time. Repeat with #:)
With a macro:
qqf(ysab`q
Repeat with #q and then ##
Or with substitute:
:substitute/([^)]\+)/`&`/g

EasyMotion repeat

I've replaced my fFtT completely with EasyMotion's equivalent and I've found it to be adequate in most cases except when I need to repeat the last motion with text objects. For example, dot command following ct or cf don't work the way they're supposed to. Is there a way make this work somehow, or do I have to resort to mapping the original ftFT for cases like this?
I try to be bold, without testing and say, NO, it cannot be repeated.
you typed some magic key (for example, f . Default <leader><leader>f), triggered easyMotion, try to move to letter x. but on your current screen, there are 10 x after your cursor. Then you typed c to move to the right one. now you try to type dot . to repeat it. how easyMotion know which x you want to go to next?

Preferred way to move around in vim (normal mode)

I haven't seen this asked on stackoverflow, and this is my biggest pain point in vim:
How do you all navigate within a file? I found myself using the hjkl too much, or too repetitively, and I want to get better at this. This is frustrating when you're on a large monitor.
I installed EasyMotion - and so far it's been good for me - I just want to know if there's something better...
Thanks!
I like the cheatsheet of Ted Naleid. It's like a reticle so you can easily find the horizontal and vertical movements. Put it on a wall next to your monitor and you will soon pick up new movements on the fly.
The movements that I liked recently are:
() and {} which let you hop function wise in source code
/ and ? + n/N just search, you normally know where you want to go
fx and tx - to jump to or before the next character x
of course you can do a 2fx to jump to the second occurrence of x, like you can do with all movements
% to move between starting and ending parenthesis
I use b and w to move left and right respectively on a single line. For up and down, I use Ctrl+u and Ctrl+d respectively. IMO Ctrl+u and Ctrl+d are better than Ctrl+b and Ctrl+f because they scroll half window at a time so that you don't loose context.
I haven't really used any plugin for moving around in vim so far.
Forgot to mention two other important keystrokes, $ and ^ to move to end of line and start of line respectively.
Several move commands:
b B e E f F ge gE gj gk go G h H j k l L M n N t T w W { } / ? ^ $ # * ` ' | %
Learn them, plus all commands starting with [ like [{ which is very useful when editing C-style code…
See :help index.txt for reference.
Mostly I use the following (in order of frequency):
'R go to marked position (the ` is too off the baseline keyboard to use much)
/search|?search forward|backward search
n|N next|previous in search
H|L|M top|bottom|middle of display
G go to end of file
1G go to line 1
{ go backward a 'paragraph' (often a code block)
} go forward one 'paragraph'
Most all of these can be augmented with a count before the command.
It depends on how you want to move around, but generally,
A puts you in insert mode at the end of a line
I at the beginning
o inserts a line below
O above
and more powerfully, searching with /<thing you want to jump to> is very handy. In a c file where the functions are formatted
int
funcname()
/^funcname will jump you to the start of the function. There's a bunch more, but this shold be a good start for someone new to vim.
Simple documentation:
http://vim.wikia.com/wiki/Moving_around
Regular movement:
hjkl/arrow keys/page up/page down
% will switch between open/ending braces
gg/G move to top/bottom
Folding:
For collapsing large blocks of code, you can use folding.
http://vimdoc.sourceforge.net/htmldoc/fold.html
Search:
To jump to something in particular type /searchstring (use with set inc for jumping to matches while typing)
* to search forward for the same word the cursor is on
# same but search backward
You can also use marks.
http://vim.wikia.com/wiki/Using_marks
I also use ctags and jumping to find stuff across multiple files.
http://vimdoc.sourceforge.net/htmldoc/tagsrch.html
I've never needed anything else.
I don't really see much to add in terms of general enlightenment but I use (ranked by how often I use them):
w and b
to move by one word to the right and to the left.
/ and ?
to search for a word or pattern to the bottom or to the top.
G and gg
to jump to the bottom and the top of the buffer.
<C-f> and <C-b>
to jump to the next and previous screen.
* and #
to jump to next and previous occurence of the word under the cursor.
f and F
to jump before a character to the right or to the left.
t and T
to jump on a character to the right or to the left.
Ho! and
$ and ^
a lot, too, to jump to the end and the beginning of a line.
Read http://www.viemu.com/a-why-vi-vim.html and run vimtutor, also :help motion.txt will be usefull. I recommend also staying in normal mode all the time - as described in article above. Generally, learning vim is learning piano - you have to practice much.

Vim motion vertical version of f & t?

In vim, I really love f & t in Normal mode. Are there vertical versions of these? If not, what's the best way to jump so many lines downward to a word that I see? Do I just have to count the lines and do 12j or something?
Can you use /foo (or ?foo for backwards)? I tend to use that more than t or f anyway.
I think you'll love the EasyMotion plugin.
You'll type <leader>fb to go to a b, horizontally and vertically.
(you can also find the vim.org mirror git here)
Try vim-sneak, a plugin I wrote for this very reason. It enables you to jump to any location in three keystrokes by specifying the first two characters of the target:
s{char}{char}
For example, sab moves the cursor to the next instance of the string "ab". And Sab moves backwards to the previous instance of "ab".
It also supports:
visual mode
operations (like dzab, czab, and yzab)
operation-repeat with .
motion-repeat with ; and ,
vim-sneak is similar to vim-seek, with many improvements.

Is there some pattern behind the many VIM commands?

I have to add a VIM personality to an IDE. I never used VIM for more than the most basic edits and i'm now overwhelmed by the complexity of the command structure.
Is there any overall structure for the combination of counts moves and insert/delete commands?
I just can't see the wood for the trees.
Well, there is obviously a finger position pattern behind h, j, k, l.
The fact that ^ goes to the beginning of a line and $ goes to the end is patterned on common regular expression syntax.
Ctrl-F and Ctrl-B page forward and back, and that's fairly intuitive.
i inserts (before) and a appends (after the cursor). Similarly,
I inserts at the beginning of the line, and A appends at the very end.
> and < indent and outdent, respectively. That's also kind of intuitive.
But on the whole, many of the other commands are on whatever keys were left – it's hard to find an intuitive mapping between the letters of the alphabet and an editor's commands.
Repeat counts are always entered before a command, and mostly repeat the command that many times, but in some cases do something clever but analogous.
I think the secret to not going crazy over vi is to start out with only a small handful of commands. I have a lot of colleagues who don't know to do anything other than
move the cursor around using the arrow keys (you don't have to use h, j, k, l);
insert with i, delete with Del (you don't have to use x);
delete a line with dd
get out of input mode with Esc
get out of vi with :x (exit) or q! (quit, and throw away my changes!)
Because I'm much smarter, the additional commands I know and use are:
go to the top of the file with gg, the bottom with G.
I can go to a specified line number with (line-number)G.
copy a line with y (yank), paste it with p
change a word with cw, the rest of the line with C
delete a word with dw, the rest of the line with D
I sometimes use . to repeat the last command, or u (undo) if I messed up.
When you have occasion to use other commands, you can teach them to yourself one by one as needed.
This is a good article for explaining the VIM philosophy.
I think the characteristic that better defines VIM in respect to other editors is its wide array of motion commands. The first thing to learn to fully use VIM is hitting the arrow keys as little as possible, and think at the text in terms of "blocks" like "a sentence" "a tag" "a word" "a group of brackets".
Say you have function foo($bar, $fooz) you can change the parameters by simply positioning your cursor anywhere inside the brackets and pressing ci) (mnemonic: change inner bracket). The same pattern applies to other commands: yank (y), delete (d) and so on.
I know this doesn't explain the whole "VIM philosophy" but combining normal mode commands with the vast amount of motion modifiers is what really made me see the light.
There are plenty of nice and interesting tutorials. One example is
http://blog.interlinked.org/tutorials/vim_tutorial.html
But the broad structure that most of them would give you is
There are two main modes for editing - Command mode and insert mode. You can move from insert mode to command mode using the key.
You can execute commands in the command mode by typing a single key or a sequence of keys.
Commands can help you achieve a wide variety of things
deletion of lines - dd
yanking (copying of lines ) - yy
pasting lines below the current line - p
pasting lines above the current line - P ( and so on)
Most commands in the command mode can be pre-fixed by a "count" to indicate the number of times the command has to be executed. For example, 3dd would delete three lines.
One set of commands in the command mode lets you move to the insert mode. That is explained below.
There are different ways of entering the insert mode from the command mode. Prominent among them are (i-insert at cursor, I-insert at beginning of line, o-insert a line below, O-insert a line above, a-append, A-append at end of line.
The quick reference at
http://www.andy-roberts.net/misc/vim/vim.pdf
Will help you understand the relevance of "count"

Resources