VIM Select Entire Line - vim

How do you select a single line in VIM, when your cursor as at some random point along that line?
I know you can do (v, $) to get to the end of the line, or (v, ^) to get to the start, but when you do (v,$,^) it logically doesn't select the whole line, it selects from cursor, until end, then switches it to cursor until beginning... So this approach fails of course.

Capital V selects the current line in one key stroke; two, if you include the "shift" in shift+v.

V would be direct answer. However, I rarely need to do this because "selecting the current line" is generally part of a larger task. Example of such tasks includes copying the line and deleting the line. There's generally a better way to accomplish the task as a whole. The following are some of the tasks I can think of:
copy the line: yy
delete the line: dd
indent the line: >> or <<
select the current paragraph: vap or vip
delete from the current line to the end of the file 0dG
highlight the current line to see where my cursor is: use :set cursorline in .vimrc file
One case in which I do use V is to select multiple lines that are not a paragraph or some other text object. In this case, there's a tip that might be useful for you: once in the selection mode, you can use o to jump the cursor between the start and the end of the selection.

While this might be more keystrokes.
If you are already in visual mode you can use o to go to the other end of the visual selection.
So you can type
v0o$
To select the whole line. Take a look at :h visual-change
However from the comments it seems you just want to copy the whole line.
Which would just be yy

Just change your order of operations. You almost have it.
^,v,$
Or as suggested by #Kent: because ^ goes to the first non-empty char, if the line has leading spaces:
0,v,$

I know this thread is super old, but I just had the same question. This thread came up first, but I found a different answer than any found here. Use 'V' to select whole lines. That easy. One character to select the whole current line.

Related

Vim: Yank distant line without moving

Suppose I have the following (* = cursor):
...
*
Kittens
Puppies
Humans
...
How do I yank the "Humans" (cursor relative 3rd line) while leaving the cursor in place?
Preferably in one motion or one (generic) command.
Try this:
:+3y
It uses the range +3 , that it is the point where it will begin to yank. and by default it does one line.
UPDATE: If you wanted to copy both the second and third line without moving cursor, you would use same command but with a range of two points, like:
:+2,+3y
It would copy both Puppies and Humans.
Now, for those who are wondering, based on Birei's answer, you can also do :ny, where n is the line number you want to yank. This is actually what I was looking for when I came to this page, and is helpful if you've got set number on and don't want to count relative lines.
Now, I wonder, how to perform this yank to a particular register! :D
My LineJuggler plugin combines yanks and puts into various short mappings; e.g. with 3[f you can fetch a line 3 lines below the current line and put it below the current line.

Yank first word from specific line

I figured out that :23y will yank the entire 23rd line.
But what I want to do is yank only the first word on line 23.
I tried :23yw, but that does not work. Is there an easy way to do this?
Can this be done without going to the line first and then yanking and then typing ` to go back to the line I was editing on?
23ggyw will do it. I don't think there's a quicker way.
Explanation: 23gg moves the cursor to line 23, yw yanks one word.
Note that this only works if you have the startofline option set (which is the default). Otherwise you need to explicitly move to to the first non-whitespace character: 23gg^yw.
The :y is an abbreviation of the :yank Ex command, that's why :yw does not work; it's a normal mode command. As the other answers have already shown, you can trigger those from the command line via :normal yw.
I'm afraid there's no way avoiding the jump in a practical way (but, as mentioned, <C-O> lets you jump back to the original position). You could use Vimscript:
:let #" = matchstr(getline(23), '^\w\+')
But that's hardly easier to type, and only suitable for a function.
I don't think there's a way to do that without moving the cursor.
Anyway, here is another way to do it:
:23norm! yw
Breakdown:
: because we are using an Ex command,
23 is the line on which we want to do something, it is a range of 1,
norm[al] executes a normal mode command on the given range,
yw yanks the first word.
Add <C-o> to go back to where you come from.
type 23Gyw in normal mode should do the job.
G Goto line [count], default last line, on the first
non-blank character |linewise|. If 'startofline' not
set, keep the same column.
G is a one of |jump-motions|.
Following would work without moving the cursor as requested but it's a hassle to type.
:23y|norm PJ0eld$
or you could try working out something with
:23t.|norm eld$
23jyw should be able to do it, it will take you to 23rd line and yank first word

Append general buffer to the end of every line in VI

I'm trying to add the contents of the general buffer to the end of every line. I'm sure this is fairly simple, however, an hour of google searches have lead me nowhere.
This is what my file looks like
::Things to bring camping
--matches
--tent
--sleeping bags
--inflatable bed
--firewood
--camping stove
--skillet
I want to add "::Things to bring camping" to the end of every line.
This is i have figured out so far.
/:: -> brings me to the line in question
Y -> yanks the entire line to the general buffer
I tried :%s/$/\p -> this added a "p" to the end of every line.
My problem is with step 3. How do I tell the "search and replace command" to used the "p" (the contents of the general buffer) instead of the "p" the character
Thank you so much for your help.
Just a suggestion: If you try doing it with a macro, you will be able to use 'p' to add the contents of the general buffer.
Sorry, I had to go into vim and find out.
The way to copy your entire line while in command mode, is:
^r "
(that's CTRL and r, then " )
That should paste the entire line you yanked into your search and replace command
For step three, instead of \p, you should use ctrl-R-a. Hold down the control key and type an uppercase "R", continue holding control, and type a lowercase "a".
For a line with multiple words, use ctrl-R-" instead.
I agree with using a macro - they're very powerful.
In this case I took your list example and positioned it at the first colon.
I used y$ to grab the remainder of the line in the buffer.
Then I recorded the macro - I chose 1.
q1
j$pq
Then you can call it for any number of rows in your list. E.g. 10#1
Learned something figuring this one out ...
:%s/$/\=getreg()/
The \= says that what follows is an expression to be evaluated, and the getreg() call gets the contents of the register, by default the "general buffer" as it used to be called by vi.

Prepending a character followed by the line number to every line

I'm hand-editing CNC Gcode text files and need a way to reference locations in the file and on the toolpath.
I want to modify every line in the text file so that it begins with the the upper case letter N followed by the line number, incremented in tens for each successive line, then a whitespace followed by the original text on that line. How can I do this in Vim?
I'm not sure about vi, but (since you're using the vim tag) Vim allows you to accomplish your task as follows:
Adjust the first line by hand (insert a N10 at the beginning of the line), then put the cursor at the beginning of the next line.
Press qb to start recording a macro (the b names the register used to store the macro; feel free to use a different letter -- and definitely do use a different letter if you've got something useful stashed away in b).
Move the cursor upward to the beginning of the previous line (which you have adjusted by hand). Press v to start visual selection mode, then f to move the cursor to the next space on the line (if you use a single space as your whitespace separator, that is; adjust this step if you're using a tab or multiple spaces).
Press y to yank the selected text. This will also remove the visual selection.
Move the cursor to the beginning of the next line. Press P to insert the previously yanked text before the cursor, that is, on the very beginning of the line.
Move the cursor to the numeric part of the line header. Press 10 C-a (1, 0, control + A) to increment that number by 10.
Move the cursor to the beginning of the next line. Press q to stop recording the macro.
Press 10000000 #b to execute the macro 10000000 times or until it hits the end of the file. This should be enough to take care of all the lines in your file, unless it is really huge, in which case use a bigger number.
...or use Vim to write a simple script to do the job in whichever language you like best, then run it from a terminal (or from withing Vim with something like :!./your-script-name). ;-)
The following command will prepend ‘N<line number * 10>’ to every line:
:g/^/exe 'normal! 0iN' . (line('.')*10) . ' '
You can do it easily in Vim with this:
:%s/^/\=line(".")*10 . " "/
This replaces the start of every line with the result of an expression that gives the line number times ten, followed by a space.
I have not timed it, but I suspect it might be noticeably faster than the other Vim solutions.
Cheating answer:
:%!awk '{print "N" NR "0", $0}'
There are two ways to implement that without resorting to external
tools: via a macro or by using Vimscript. In my opinion, the first way
is a little cumbersome (and probably not as effective as the solution
listed below).
The second way can be implemented like this (put the code into your
.vimrc or source it some other way):
function! NumberLines(format) range
let lfmt = (empty(a:format) ? 'N%04d' : a:format[0]) . ' %s'
for lnum in range(a:firstline, a:lastline)
call setline(lnum, printf(lfmt, lnum, getline(lnum)))
endfor
endfunction
The NumberLines function enumerates all lines of the file in a given
range and prepends to each line its number according to the provided
printf-format (N%04d, by default).
To simplify the usage of this function, it is convenient to create
a command that accepting a range of lines to process (the whole file,
by default) and a optional argument for the line number format:
command! -range=% -nargs=? NumberLines <line1>,<line2>call NumberLines([<f-args>])

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