I've learned I can yank, say, 4 lines in visual mode into a register r like so: V4j"r. However, I don't want to have to count lines and just select them in visual mode and copy them into a register (because I want to cut and paste them to another file).
Can this be done?
Thanks,
Damian
Well, V4j doesn't select four lines to begin with, and you are missing a y.
Anyway, V4j"ry is not to be taken as a whole. It really is a composition of three commands:
V to enter visual-line mode,
4j to move the cursor downward four times, expanding the visual selection to cover five lines,
"ry to yank the text covered by the visual selection into register r.
In this case, 4j could literally be any command that moves the cursor in visual mode: /foo<CR>, 'b, etc.
jjjj, which is the exact "count-less" equivalent of 4j is obviously also valid in this context so you could simply do:
Vjjjj"ry
Lets say i have the following text.
this.is.some.text
this.is.emos.text
this.is.some.text
this.is.emos.text
I want to edit this text in 'Visual Block' mode so that the text looks as follows.
this.is.some.text
this.is.emos_suffix.text
this.is.some.text
this.is.emos_suffix.text
It should work like this:
Select a visual block
If the visual block contains emos append '_suffix' to the visual
block (Just like the 'A' command would do)
The only native way to accomplish that from visual-block mode or any other visual mode is to use a substitution:
:'<,'>s/emos/&_suffix<CR>
where…
you press :,
Vim inserts the range '<,'> for you, meaning "from the fist selected line, :help '<, through the last selected line, :help '>`,
s/emos/&_suffix substitutes every first occurrence of emos on each line of the given range with itself, :help s/\&, followed by _suffix.
Visual selection is often an unnecessary step and, in this case, visual-block mode is totally useless because A or I is going to operate on every line of the selection anyway.
Another method:
/emos/e<CR>
a_suffix<Esc>
n
.
Another one:
/emos<CR>
cgn<C-r>"
_suffix<Esc>
.
Another one, assuming the cursor is on the first line of your sample:
:,'}s/emos/&_suffix<CR>
Etc.
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>
I want to take a visual selection and flip it so that the first line of the selection is on the bottom. From:
<other_stuff>
The
wheels
go
round.
<more_stuff>
Visual select the sentence and then flip:
<other_stuff>
round.
go
wheels
The
<more_stuff>
How to do this simply? I would rather not have to install a plugin to do it.
When you make a visual selection Vim automatically makes the bookmarks '< and '> at the start and end of the block respectively, so you can do what you want in a couple of ways.
In normal mode: '>dd'<P
As an ex command: :'>d | '<-1 put
NB the bookmarks remain after you exit visual mode, so you do not have to stay in visual mode to use these.
edit:
Oops, I misread the question and thought you only wanted the last line put at the start, but you want the entire block reversed. The simplest solution if you are on a unix system:
:'<,'>!tac
This pipes the lines through the unix 'reverse cat' program.
According to :help 12.4 you can mark the first line with the mt, move to the last line you want reversed then use the command :'t+1,.g/^/m 't
For those more comfortable with Visual Mode:
1. Identify the line number above the selection you want flipped using :set nu.
2. Use Shift-V to highlight selection you want flipped (visual mode).
3. :g/^/m <Line number from step 1>.
Note that in visual mode it will automatically show up as
:'<,'>g/^/m <Line number> when you type in the command from 3.
This command works by moving the selection one line at a time into the line number that you give it. When the second item gets pushed into the line number given, it pushes the first down to line number + 1. Then the third pushes the first and second down and so on until the entire list has been pushed into the single line number resulting in a reverse ordered list.
Further to Dave Kirby's answer and addressing the "how to do this simply" requirement, you could create a shortcut in your .vimrc file. The following example maps the F5 key to this shortcut:
map <F5> :'<,'>!tail -r<CR>
or for OS X:
map <F5> :'<,'>!tac<CR>
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