Vim - Go to previous location - vim

Say I open a file in vim. I start on line 1 column 1 and hold down j until I am on line 14. Pressing :7CR puts me on line 7. I press yy to "yank".
How do I return to line 14? Using CTRL + o takes me back to the top of the file. ` ` gives me the same results.

You can type 7G to jump to line#7, then type Ctrl-o to jump back.
:set showcmd to show what you have typed at the right bottom.
To yank line#7 (No cursor moving):
:7y
To paste line#7 below line#14:
:7t14

<C-o> and <C-i> allow you to go down and up the jumplist. They work with "jump" commands but not with jjjjjjjjjjj.
To take advantage of this feature — and save a lot of time and keypresses in the process — I'd advise you to get into the habit of using better ways to navigate through your code : /?^$fFtTbBeEwW{} and so on.
And yes, use marks.

One more way: To jump back to another line, you can use ''. This works similar to an automatic mark, which is set for certain jump movements.

Why not set a mark using ma for example, and then return to it later using `a or 'a?

Mark the line you were originally on using ma, then 'a to return there.

If you want to return to a previous location, first you have to mark that location using the mark (m) command, followed by any letter a-z or A-Z, like ma to mark a location as 'a'.
To return to that location you would enter `a.

Related

vi to delete from the beginning of the line till the cursor

How can we use vim to delete characters from the beginning of the line till the cursor.
Say, we have a string "hello world" while the cursor is on "w". How can we delete from "h" till "w".
Try d0. 0 denotes the beginning of the line.
I believe that the following should work (d^):
d^
This assumes that you only want to delete to the h even if there is white space in front of it. It will leave the white space.
TLDR:
The easiest way is to do the following
use the navigate mode
set the cursor at whatever line you want
press dgg - this will remove everything from cursor to the beginning
press dG - this will remove all the lines from cursor till the end of the doc.
But why?
gg - goes to the begin of the document
G - navigates at its very end
d - delete mode
I was also looking for some combinations with the notation of d and line number, and when you are editing huge files like GB in size I found it bit annoying.
Like to remove first 3 lines you need to do this :0,d3, but when the docu is over 1mln lines its tough for my eyes to read this crap...
The other suggestions didn't work for me, but I used visual mode to achieve this.
I moved the cursor to the position I wanted to delete through, and hit v to enter visual mode. Then I hit ^ to select back to the beginning of the current line, and then d to delete all of the highlighted text.
If you're in insert mode and you want to delete to the start of the line (and stay in insert mode), you can use CTRL+u
This matches the bash meaning of CTRL+u as shown here.
I don't know if this is undocumented or just a quirk of my setup (neovim on Ubuntu) but doing :help CTRL-U shows the help for the keystroke out of insert mode. Maybe someone can help me find the help which points to the usage I'm describing here.
not sure what happened but when I enter the d0, the line got deleted from my
cursor location to start of the line. – YouAreAwesome Dec 14 '17 at 6:43
Confirming that this worked. It seems to be the simplest method. (You can't upvote a comment, so I'm adding it as an answer in it's own right.)
Example: In .ssh/authorized_keys, I had:
no-port-forwarding,no-agent-forwarding,no-X11-forwarding,command="echo 'Please login as the user "centos" rather than the user "root".';echo;sleep 10" ssh-rsa AAAAB3NzaC1yc2...
This is the way Amazon AWS keeps you from logging in as root.
I put the cursor on the s in ssh-rsa and hit 'd0' and got a perfect delete to beginning of line.
Well, if your cursor is on "w", you'll be deleting backwards...
You can use vim's "till" t, but moving backwards it requires an uppercase T.
The same works for "find" f moving backwards it's F.
So, in your case, you can delete back "till" the quote symbol:
dT"
Or, if to prefer targeting/finding the "h":
dFh
Try jumping around first without the delete to get a feel for it, then you can just layer in the action as the prefix.
Happy Vimming! :)

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

Vim yanking range of lines

I'm a C# developer who has just recently decided to expand my knowledge of the tools available to me. The first tool I've decided to learn is Vi/Vim. Everything has been going well so far, but there are a couple of questions I can't seem to find the answer to:
Lets say I wanted to yank a range of lines. I know there are many ways of doing so, but I would like to do it by line number. I figured it would be similar to how the substitute commands work, something like 81,91y. Is there a way to do this?
I'm a little confused about the g command in normal mode. It seems to do a myriad of things and I can't really determine what the g command does at its core. I'm confused on whether or not it's a motion command or a kind of "catch all" for other commands ran through normal mode. Can someone please explain this or point me to a reference that gives a good explanation of the g command?
Yank lines 81-91
:81,91y<enter>
If your fingers don't like to find the : and , keys, this would work as well (go to line 81, yank 11 lines)
81gg11yy
My only use of g is 5gg. To go to the 5th line. 22gg: 22nd line. As jimbo said, it's really only a modifier for some other commands.
For completeness, (http://vim.wikia.com/wiki/Power_of_g) explains a lot of how g works in command mode.
You can also copy the current lines to your present cursor location using 't'.
:81,91t.<enter>
This will paste the lines 81-91 under the line the cursor is on.
I learned this from http://vimcasts.org which is an excellent resource on VIM.
I also like to use vim's relative line number option which means I can just enter:
:-10,-7ya a
to yank the text into named buffer a.
N.B. Specifying A will append what you're yanking to the current contents of buffer a.
Don't forget you can also copy blocks of text and move blocks of text around as well with the similar commands:
:-10,-7co .
means copy the four lines of text 10 lines above to below the current line, and
:-10,-7mo .
means move the four lines of text 10 lines above to below the current line.
The G command goes to a certain line number, if it's accompanied by a count value. 81G puts you on line 81.
The y command can be combined with a movement, like G. So to yank everything until line 91 you can use y91G.
Together you get:
81Gy91G
Go to line 81, then yank while going to line 91.
g doesn't do anything by itself. It's one of a couple meta-commands that holds a bunch of sorta-unrelated commands.
z is yet another command like that.
In addition to :91,96y a which yanks (y) lines 91 through 96 into register a, (pasted with "ap), the yanked lines can be appended to the register with:
:91,96y A
I.e. the capitalization of the A register causes an appending operation into register a instead of an overwrite. Capitalization of the register always works like this, e.g. :let #A=';' appends a ; to register a.
Using plus (+) or minus (-) references lines relative to the current cursor position:
:-10,+10y b
I.e. it would yank(y) 21 lines around the current cursor position and put them in register b.
An absence of input actually represents the current cursor position as well, which means that this:
:-5,y a
would yank the text from 5 lines above to current cursor position into named buffer a, and:
:,+5y a
would yank the 5 lines after the current cursor position into buffer a.
Note: If you have a macro in buffer a it was just overwritten by the previous yank, as yank registers and macro registers are really the same thing. Which is why, coincidentally, you can paste a macro, edit it, and then yank it back into it's register. I personally use letters reached by my left hand for yanks, and letters reached by my right hand for macros.
Moving blocks of text around, looks like this:
:+10,+13m.
which means move the four lines positioned 10 lines ahead of current cursor, to below the current line.
Addendum
I previously confused ya in :91,95ya a to be somehow synonymous with ya{motion} where the motion was supplied by 91,95. This was incorrect and the "a" in ya is completely unnecessary. In my defense, my help yank does not convey that ya is a possible alias of yank.
The best solution would be to enter "visual mode", by pressing v. And after selecting lines just copy them by pressing y. Then paste copied lines by pressing p.
Vim's :help index describes g as:
|g| g{char} extended commands, see |g| below
Scroll down (or :help g) for a list.
As a long time Vi/Vim user I tend to use 'marks' instead of line numbers (or 'line markers'). It works like this: m is the 'mark' character; then use any letter to identify/name the mark. To return to a mark preface the named mark with a single quote ( 'a)These marks can be used as the range. Examples:
File:
<line 1>
<line 2>
<line 3>
<line 4>
<line 5>
When in command mode move cursor to line 2, typema. scroll to line 4, typemb.
To yank from mark a to mark b type:
:'a,'byank
To delete from mark a to mark b type:
:'a,'bdel
To search from mark a to mark b and replace 'ine' with 'ink':
:'a,'bs/ine/ink/g
To copy mark a through mark b and paste below the current position (the 'dot' always references the line where the cursor currently is positioned):
:'a,'bco .
Shift lines of code, between mark a through mark b, one tab to the right (use opposite chevron, <, to move left):
:'a,'b>
In command mode you can move back to marks by simply typing 'a to move back to the line marked a. Typing '' moves you back to previous position (unfortuantely only remembers the previous position, not two back).
You can yank to named buffers, copy, delete lines, search&replace just portions of your code, etc. without needing to know the line numbers.
To yank lines from line number 81 to 91 :
approach 1: 81gg11yy
not bad but you have to do little bit of math to find out how many lines to yank
approach 2: 81gg then shift+v then 91gg then y
BEST IN MY OPINION because this is straight forward, you only have to know the obvious thing i.e from which line number to which line number you want to yank

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

In vim, how do I go back to where I was before a search?

Programming in vim I often go search for something, yank it, then go back to where I was, insert it, modify it.
The problem is that after I search and find, I need to MANUALLY find my way back to where I was.
Is there an automatic way to go back to where I was when I initiated my last search?
Ctrl+O takes me to the previous location. Don't know about location before the search.
Edit: Also, `. will take you to the last change you made.
Use `` to jump back to the exact position you were in before you searched/jumped, or '' to jump back to the start of the line you were on before you searched/jumped.
I've always done by it setting a mark.
In command-mode, press m[letter]. For example, ma sets a mark at the current line using a as the mark identifier.
To get back to the mark press ' [letter]. For example, 'a takes you back to the line mark set in step 1. To get back to the column position of the row where you marked the line, use `a (back-tick [letter]).
To see all of the marks that currently set, type :marks.
On a slightly unrelated note, I just discovered another nifty thing about marks.
Let's say you jump to mark b by doing mb. Vim automatically sets the mark ' (that's a single-quote) to be whichever line you were on before jumping to mark b.
That means you can do 'b to jump to that mark, then do '' (2 single-quotes) to jump back to wherever you were before.
I discovered this accidentally using the :marks command, which shows a list of all marks.
You really should read :help jumplist it explains all of this very well.
CTRL+O and CTRL+I, for jumping back and forward.
I use this one:
nnoremap / ms/
nnoremap ? ms?
Then if I search something by using / or ?, I can go back quickly by `s. You could replace the letter s to any letter you like.
The simplest way is to set a mark, with m[letter], then go back to it with '[letter]

Resources