vim - How do you save line numbers so you can easily jump to them whenever you want? - vim

Suppose I am working on three functions and I will be jumping back and forth between them. Suppose functions A,B, and C are on lines a, b and c. Is there a way to bind the following (which jump to the line position)
:a
:b
:c
to keys during runtime so I can easily jump to these positions. If you play Starcraft this is kind of like binding a selected group of units to your number keys, and then using the number keys to quickly change your selected group (or jump to the designated line, in this case).
Or is there another way of getting a similar result that I am unaware of? I just recently discovered that =% autoformats your tabs within the highlighted brace, so I am pretty new to vim.
Thanks.

You want to use marks. They allow you to save your current position in the file to a variable.

In Starcraft, you "Hotkey" your guys by pressing Ctrl+1 to tag them, then tap 1 to select them again.
In Vim, you "Mark" a place by pressing [m], then [a](or any letter) to mark them, then [`], then [a] to go back to that mark.
So you have hotkeys to 1,2,3,4, etc in SC, but marks are a-z(and probably other characters but I'm not sure) in Vim.
For more technical info try
:help marks

Related

Visual selection and replacement in vim

How can I select different portions of multiple non-contiguous lines and replace them with the same/different text?
Example: Let's say my buffer looks like this-
Roses are reed,
Violets aree blue,
Sugaar is sweet,
And so are you,
I want to change in 1st line the 3rd word ('reed') to 'red, yellow and green', in 2nd line 'aree' to 'are', in 3rd line 'Sugaar' to 'Sugar and molasses' and in 4th line 'you,' to 'you.'.
Say my cursor is at 'R' of 'Roses'. I want to select all four of these wrongs at once and nothing other the wrongs. After I'm done selecting I want to be able to move to 'reed' by pressing some key (say Ctrl+j), then after changing I want to be able to press some key (say Ctrl+j) and move the next visual selection which is 'aree'.
Is there any plugin that does this?
There are multiple cursors plugins that attempt to create parallel editing functionality seen in other editors to Vim (which is difficult). If I understand your use case right, that wouldn't help here, though, because all places would be edited in the same way (so reed, areee, etc. would all be replaced with the same red).
Instead, what you seem to be asking for, is a way to search for all wrongly spelled words, and then edit them one by one, individually. You can do this with standard search, using regular expression branches:
/reed\|areee\|Sugaar\|you,/
You can then simply press next to go to the next match after you're done. Note that the branches have to be unique (so I searched for you, instead of simply ,). Adding word boundaries (\<reed\> instead of reed) is a good idea, too.
plugin recommendations
multiple cursors is a famous plugin for parallel editing
My SearchAlternatives plugin lets you add the current word under the cursor as a search branch with a quick (<Leader>+ by default) key mapping. (However, if you're already on the word, why not correct it immediately?)
My SpellCheck plugin populates the quickfix list with all misspelled words and locations. You can then use quickfix navigation (e.g. :cnext) to quickly go to each. The plugin also offers mappings to fix spelling errors directly from the quickfix list.

How to repeat a navigation command in Vim

The . key can be used to repeat the last insert command. However, we might do some navigation that is not part of the insert, but we want it repeated.
Imagine commenting out lines like so:
// line of text
// line of text
line of text
line of text
The insert command is to put the two forward slashes and a space. That can be repeated using the . key. The navigation would be to navigate down one line and then left some number of characters. That part is not captured by the . key command.
How can we achieve this functionality? I read that it was not available in Vi some years ago, but I'm wondering if it exists now in the latest version of Vim.
Press qX, where X is any of the writable registers (typically: pick any lowercase letter).
Do whatever actions you want to record.
Press q again to stop recording.
Press #X (where X is the same register) to play it back (count times, if used with a count).
Press ## to replay the most recently used macro (count times).
I read that it was not available in Vi some years ago, but I'm wondering if it exists now in the latest version of Vim.
If the Vim docs are to be believed, Vi did not support recording (steps 1-3), but did support #. Then you would have to manually yank the characters into the target register with "Xy<motion> or some other register-writing command. That also works under Vim, but I can't recommend it because it is much more error prone.
Another approach would be "block select then edit" approach:
ctrl + v - block select
then go down j or down-arrow
shift + i will put you in insert mode. Make the change here where you want it to be reflected on all the other lines you've selected.
esc twice will show/repeat that change you made on the line one.
If you have a big range of similar lines and want to put // at the beginning of it, you can do something like:
:15,25norm! I//<space>
You can also use visual area (vip selects an entire paragraph)
:'<,'>norm! I//<space>
using a pattern
:g/TODO/norm! I//<space>

What are the most-used vim commands/keypresses?

I'm a Ruby programming trying to switch from Textmate to MacVim, and I'm having trouble wading through the gargantuan lists of things you can do in VIM and all of the keypresses for them. I'm tired of hearing "You can use 'I' for inserting text, or 'a' for appending text after the character, or 'A' for appending text at the end of the line, or…" I can't imagine everyone uses all 20 different keypresses to navigate text, 10 or so keys to start adding text, and 18 ways to visually select an inner block. Or do you!?
My ideal cheat sheet would be the 30-40 most-used keypresses or commands that everyone uses for writing code on a daily basis, along with the absolute essential plugins that rubyists use daily and the 10 most-used commands for them. In theory, once I have that and start becoming as proficient in VIM as I am in Textmate, then I can start learning the thousands of other VIM commands that will make me more efficient.
Or, am I learning VIM the wrong way altogether?
Here's a tip sheet I wrote up once, with the commands I actually use regularly:
References
vim documentation online
advanced vim tips
more useful tips and graphical cheat sheet
General
Nearly all commands can be preceded by a number for a repeat count. eg. 5dd delete 5 lines
<Esc> gets you out of any mode and back to command mode
Commands preceded by : are executed on the command line at the bottom of the screen
:help help with any command
Navigation
Cursor movement: ←h ↓j ↑k l→
By words:
w next word (by punctuation); W next word (by spaces)
b back word (by punctuation); B back word (by spaces)
e end word (by punctuation); E end word (by spaces)
By line:
0 start of line; ^ first non-whitespace
$ end of line
By paragraph:
{ previous blank line; } next blank line
By file:
gg start of file; G end of file
123G go to specific line number
By marker:
mx set mark x; 'x go to mark x
'. go to position of last edit
' ' go back to last point before jump
Scrolling:
^F forward full screen; ^B backward full screen
^D down half screen; ^U up half screen
^E scroll one line up; ^Y scroll one line down
zz centre cursor line
Editing
u undo; ^R redo
. repeat last editing command
Inserting
All insertion commands are terminated with <Esc> to return to command mode.
i insert text at cursor; I insert text at start of line
a append text after cursor; A append text after end of line
o open new line below; O open new line above
Changing
r replace single character; R replace multiple characters
s change single character
cw change word; C change to end of line; cc change whole line
c<motion> changes text in the direction of the motion
ci( change inside parentheses (see text object selection for more examples)
Deleting
x delete char
dw delete word; D delete to end of line; dd delete whole line
d<motion> deletes in the direction of the motion
Cut and paste
yy copy line into paste buffer; dd cut line into paste buffer
p paste buffer below cursor line; P paste buffer above cursor line
xp swap two characters (x to delete one character, then p to put it back after the cursor position)
Blocks
v visual block stream; V visual block line; ^V visual block column
most motion commands extend the block to the new cursor position
o moves the cursor to the other end of the block
d or x cut block into paste buffer
y copy block into paste buffer
> indent block; < unindent block
gv reselect last visual block
Global
:%s/foo/bar/g substitute all occurrences of "foo" to "bar"
% is a range that indicates every line in the file
/g is a flag that changes all occurrences on a line instead of just the first one
Searching
/ search forward; ? search backward
* search forward for word under cursor; # search backward for word under cursor
n next match in same direction; N next match in opposite direction
fx forward to next character x; Fx backward to previous character x
; move again to same character in same direction; , move again to same character in opposite direction
Files
:w write file to disk
:w name write file to disk as name
ZZ write file to disk and quit
:n edit a new file; :n! edit a new file without saving current changes
:q quit editing a file; :q! quit editing without saving changes
:e edit same file again (if changed outside vim)
:e . directory explorer
Windows
^Wn new window
^Wj down to next window; ^Wk up to previous window
^W_ maximise current window; ^W= make all windows equal size
^W+ increase window size; ^W- decrease window size
Source Navigation
% jump to matching parenthesis/bracket/brace, or language block if language module loaded
gd go to definition of local symbol under cursor; ^O return to previous position
^] jump to definition of global symbol (requires tags file); ^T return to previous position (arbitrary stack of positions maintained)
^N (in insert mode) automatic word completion
Show local changes
Vim has some features that make it easy to highlight lines that have been changed from a base version in source control. I have created a small vim script that makes this easy: http://github.com/ghewgill/vim-scmdiff
http://www.viemu.com/a_vi_vim_graphical_cheat_sheet_tutorial.html
This is the greatest thing ever for learning VIM.
Here is a great cheat sheet for vim:
Have you run through Vim's built-in tutorial? If not, drop to the command-line and type vimtutor. It's a great way to learn the initial commands.
Vim has an incredible amount of flexibility and power and, if you're like most vim users, you'll learn a lot of new commands and forget old ones, then relearn them. The built-in help is good and worthy of periodic browsing to learn new stuff.
There are several good FAQs and cheatsheets for vim on the internet. I'd recommend searching for vim + faq and vim + cheatsheet. Cheat-Sheets.org#vim is a good source, as is Vim Tips wiki.
What most people do is start out with the bare basics, like maybe i, yw, yy, and p. You can continue to use arrow keys to move around, selecting text with the mouse, using the menus, etc. Then when something is slowing you down, you look up the faster way to do it, and gradually add more and more commands. You might learn one new command per day for a while, then it will trickle to one per week. You'll feel fairly productive in a month. After a year you will have a pretty solid repertoire, and after 2-3 years you won't even consciously think what your fingers are typing, and it will look weird if you have to spell it out for someone. I learned vi in 1993 and still pick up 2 or 3 new commands a year.
#Greg Hewgill's cheatsheet is very good. I started my switch from TextMate a few months ago. Now I'm as productive as I was with TM and constantly amazed by Vim's power.
Here is how I switched. Maybe it can be useful to you.
Grosso modo, I don't think it's a good idea to do a radical switch. Vim is very different and it's best to go progressively.
And to answer your subquestion, yes, I use all of iaIAoO everyday to enter insert mode. It certainly seems weird at first but you don't really think about it after a while.
Some commands incredibly useful for any programming related tasks:
r and R to replace characters
<C-a> and <C-x>to increase and decrease numbers
cit to change the content of an HTML tag, and its variants (cat, dit, dat, ci(, etc.)
<C-x><C-o> (mapped to ,,) for omnicompletion
visual block selection with <C-v>
and so on…
Once you are accustomed to the Vim way it becomes really hard to not hit o or x all the time when editing text in some other editor or textfield.
I can't imagine everyone uses all 20 different keypresses to navigate text, 10 or so keys to start adding text, and 18 ways to visually select an inner block. Or do you!?
I do.
In theory, once I have that and start becoming as proficient in VIM as I am in Textmate, then I can start learning the thousands of other VIM commands that will make me more efficient.
That's the right way to do it. Start with basic commands and then pick up ones that improve your productivity. I like following this blog for tips on how to improve my productivity with vim.
tuxfiles.org holds a pretty good cheat sheet. I think there are a couple of points to learning the commands:
Read the cheat sheet regularly. Don't worry about using all of them, or remembering all the keys, just know that the command exists. Look up the command and use it when you find yourself doing something repetitive.
If you find yourself doing something regularly (like deleting an entire line after a particular character d$), go a quick google search to see if you can find a command for it.
Write down commands you think you'll find useful and keep that list where you can see it while you're writing your code. I would argue against printing something out and instead encourage you to use post it notes for just a few commands at a time.
If possible, watch other programmers use vim, and ask them what commands they are using as you see them do something interesting.
Besides these tips, there are some basic concepts you should understand.
vim will use the same character to represent the same function. For example, to delete a line after a character use d$. To highlight a line after a particular character use v$. So notice that $ indicates you will be doing something to the end of the line from where your cursor currently is.
u is undo, and ctrl+r is redo.
putting a number in front of a command will execute it repeatedly. 3dd will delete the line your cursor is on and the two lines that follow, similarly 3yy will copy the line your cursor is on and the two lines that follow.
understand how to navigate through the buffers use :ls to list the buffers, and :bn, :bp to cycle through them.
read through the tutorial found in :help This is probably the best way to 'learn the ropes', and the rest of the commands you will learn through usage.
Go to Efficient Editing with vim and learn what you need to get started. Not everything on that page is essential starting off, so cherry pick what you want.
From there, use vim for everything. "hjkl", "y", and "p" will get you a long way, even if it's not the most efficient way. When you come up against a task for which you don't know the magic key to do it efficiently (or at all), and you find yourself doing it more than a few times, go look it up. Little by little it will become second nature.
I found vim daunting many moons ago (back when it didn't have the "m" on the end), but it only took about a week of steady use to get efficient. I still find it the quickest editor in which to get stuff done.
Put this in your .bashrc to open vim with last edited file at last edited line
alias vil="vim +\"'\"0"

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"

In Vim, what is the best way to select, delete, or comment out large portions of multi-screen text?

Selecting a large amount of text that extends over many screens in an IDE like Eclipse is fairly easy since you can use the mouse, but what is the best way to e.g. select and delete multiscreen blocks of text or write e.g. three large methods out to another file and then delete them for testing purposes in Vim when using it via putty/ssh where you cannot use the mouse?
I can easily yank-to-the-end-of-line or yank-to-the-end-of-code-block but if the text extends over many screens, or has lots of blank lines in it, I feel like my hands are tied in Vim. Any solutions?
And a related question: is there a way to somehow select 40 lines, and then comment them all out (with "#" or "//"), as is common in most IDEs?
Well, first of all, you can set vim to work with the mouse, which would allow you to select text just like you would in Eclipse.
You can also use the Visual selection - v, by default. Once selected, you can yank, cut, etc.
As far as commenting out the block, I usually select it with VISUAL, then do
:'<,'>s/^/# /
Replacing the beginning of each line with a #. (The '< and '> markers are the beginning and and of the visual selection.
Use markers.
Go to the top of the text block you want to delete and enter
ma
anywhere on that line. No need for the colon.
Then go to the end of the block and enter the following:
:'a,.d
Entering ma has set marker a for the character under the cursor.
The command you have entered after moving to the bottom of the text block says "from the line containing the character described by marker a ('a) to the current line (.) delete."
This sort of thing can be used for other things as well.
:'a,.ya b - yank from 'a to current line and put in buffer 'b'
:'a,.ya B - yank from 'a to current line and append to buffer 'b'
:'a,.s/^/#/ - from 'a to current line, substitute '#' for line begin
(i.e. comment out in Perl)
:'s,.s#^#//# - from 'a to current line, substitute '//' for line begin
(i.e. comment out in C++)
N.B. 'a (apostrophe-a) refers to the line containing the character marked by a. ``a(backtick-a) refers to the character marked bya`.
To insert comments select the beginning characters of the lines using CTRL-v (blockwise-visual, not 'v' character wise-visual or 'V' linewise-visual). Then go to insert-mode using 'I', enter your comment-character(s) on the first line (for example '#') and finally escape to normal mode using 'Esc'. Voila!
To remove the comments use blockwise-visual to select the comments and just delete them using 'x'.
Use the visual block command v (or V for whole lines and C-V for rectangular blocks). While in visual block mode, you can use any motion commands including search; I use } frequently to skip to the next blank line. Once the block is marked, you can :w it to a file, delete, yank, or whatever. If you execute a command and the visual block goes away, re-select the same block with gv. See :help visual-change for more.
I think there are language-specific scripts that come with vim that do things like comment out blocks of code in a way that fits your language of choice.
Press V (uppercase V) and then press 40j to select 40 lines and then press d to delete them. Or as #zigdon replied, you can comment them out.
The visual mode is the solution for your main problem. As to commenting out sections of code, there are many plugins for that on vim.org, I am using tComment.vim at the moment.
There is also a neat way to comment out a block without a plugin. Lets say you work in python and # is the comment character. Make a visual block selection of the column you want the hash sign to be in, and type I#ESCAPE. To enter a visual block mode press C-q on windows or C-v on linux.
My block comment technique:
Ctrl+V to start blockwise visual mode.
Make your selection.
With the selection still active, Shift+I. This put you into column insert mode.
Type you comment characters '#' or '//' or whatever.
ESC.
Or you may want to give this script a try...
http://www.vim.org/scripts/script.php?script_id=23
For commenting out lines, I would suggest one of these plugins:
EnhancedCommentify
NERD Commenter
I find myself using NERD more these days, but I've used EnhancedCommentify for years.
If you want to perform an action on a range of lines, and you know the line numbers, you can put the range on the command line. For instance, to delete lines 20 through 200 you can do:
:20,200d
To move lines 20 through 200 to where line 300 is you can use:
:20,200m300
And so on.
Use Shift+V to go in visual mode, then you can select lines and delete / change them.
My usual method for commenting out 40 lines would be to put the cursor on the first line and enter the command:
:.,+40s/^/# /
(For here thru 40 lines forward, substitute start-of-line with hash, space)
Seems a bit longer than some other methods suggested, but I like to do things with the keyboard instead of the mouse.
First answer is currently not quite right?
To comment out selection press ':' and type command
:'<,'>s/^/# /g
('<, '> - will be there automatically)
You should be aware of the normal mode command [count]CTRL-D.
It optionally changes the 'scroll' option from 10 to [count], and then scrolls down that many lines. Pressing CTRL-D again will scroll down that same lines again.
So try entering
V "visual line selection mode
30 "optionally set scroll value to 30
CTRL-D "jump down a screen, repeated as necessary
y " yank your selection
CTRL-U works the same way but scrolls up.
v enters visual block mode, where you can select as if with shift in most common editors, later you can do anything you can normally do with normal commands (substitution :'<,'>s/^/#/ to prepend with a comment, for instance) where '<,'> means the selected visual block instead of all the text.
marks would be the simplest mb where u want to begin and me where u want to end once this is done you can do pretty much anything you want
:'b,'ed
deletes from marker b to marker e
commenting out 40 lines you can do in the visual mode
V40j:s/^/#/
will comment out 40 lines from where u start the sequence

Resources