Fast switching between two lines in file in vim - vim

sometimes I have to switch between 2 lines. To do this, I have to pass line number. Are there shortcuts to moving between 2 last 'visited' list. Something similar to '. (it moves to last edited line)

You can use bookmarks, something like ma to mark a bookmark named a, and then 'a to go to it. Naming boomarks a and b for example, you can switch between them with 'a and 'b.

Double-backtick or double single-quote will do exactly that
There is a command that will bounce to the last location you jumped away from. If repeated, it will then return to the jump destination you were just on. If repeated further it will bounce you back and forth between the two locations.
The command has two forms:
``
or
''

ctrl-o and ctrl-i will move backwards and forwards through your history of jump points. A jump point is pretty much any command that moves the cursor more than one line. It will also go back to previous files that were loaded into the current buffer.
See :h jump-motions for more information.

Related

Vim: Delete from cursor to next period

Is there a shortcut in vim to delete from the current cursor to the end of the sentence?
cursor
v
This is half a sentence. My cursor is here, but I would
like to delete to this period. I do not want to delete this part.
^
delete from cursor to here
Imagine my cursor is somewhere on the text that says My cursor is here,. How can I delete from this line all the way (and including) that next .?
Though there's no exact motion for that, there are several possibilities:
The ) motion deletes the remainder of the sentence, but that also includes the whitespace after the period.
If there were no hard line break, you could use the useful f motion (which only works in the current line, unless you install a plugin): f. This is also useful if you want to keep the period: t.
The most general motion is search via /. You need to search for a literal period (\.), and to include it, move to the end (/e) of it: /\./e<Enter>.
All of these have to be appended to the d "delete" command, which takes a {motion}.
Learn how to look up commands and navigate the built-in :help (here, :help motion.txt in particular); it is comprehensive and offers many tips. You won't learn Vim as fast as other editors, but if you commit to continuous learning, it'll prove a very powerful and efficient editor.
you should combine d with motion command. for your example, this will be d/\.<Ret>
This visual-mode editing may help you understand what actually happen:
v/\.<Ret>ld

How to delete, including the current character?

Let's say I've typed "abcdefg", with the cursor at the end. I want to delete back to the c, so that I only have "abc" left.
Is there a command like d that includes the current character? I know I could do dTcx, but the x feels like a work-around and I suppose there's a better solution.
No. Backward motions always start on the left of the current character for c, y and d which is somehow logical but also unnerving.
The only "clean" solutions I could think of either imply moving to the char after c first and then do a forward delete:
Tcde
or using visual mode:
vTcd
v3hd
But, given your sample and assuming you are entering normal mode just for that correction, the whole thing sounds extremely wasteful to me.
What about staying in insert mode and simply doing ←←←←?
try this:
TcD
this will leave abc for your example... well if the abcdefg is the last word of the line.
if it is not the last word in that line, you may do:
ldTc
or golfing, do it within 3 key-stroke:
3Xx or l4X
See this answer to a similar question : there is a setting to be allowed to go beyond the end of the line
From the doc :
Virtual editing means that the cursor can be positioned where there is
no actual character. This can be halfway into a tab or beyond the end
of the line. Useful for selecting a rectangle in Visual mode and
editing a table.
"onemore" is not the same, it will only allow moving the cursor just
after the last character of the line. This makes some commands more
consistent. Previously the cursor was always past the end of the line
if the line was empty. But it is far from Vi compatible. It may also
break some plugins or Vim scripts. For example because |l| can move
the cursor after the last character. Use with care!
Using the $ command will move to the last character in the line, not
past it. This may actually move the cursor to the left!
The g$ command will move to the end of the screen line.
It doesn't make sense to combine "all" with "onemore", but you will
not get a warning for it.
In short, you could try :set virtualedit=onemore, and see if your environment is stable or not with it.
Use d?c
That will start d mode, search back to 'c' and then delete up to your cursor position.
Edit: nope, that does not include current position...
I may be misunderstanding your request, but does 3hd$ do it?
I would use vFdd in this example. I think it's nicer than the other solutions since the command explicitly shows what to delete. It includes the current character and the specified character when deleting.
v: enter visual mode (mark text)
F: find/goto character backwards
d: the character "d" that will be included for removal.
d: delete command
Since it is visual mode, the cursor can also be moved before executing the actual removal d. This makes the command powerful even for deleting up to a non unique character by first marking a special character close to the character and then adjusting the position.

Move cursor x lines from current position in vi/vim

Is there a way to move the cursor a relative amount of lines in vi/vim? Say you have the cursor 10 lines under a block of code you want to remove. If you have the line numbers shown in relative order, it would be nice to have a "jump 10 lines up command" that would take you there.
Or perhaps it's better to have the absolute line numbers shown and go xgg where x is the line number?
Yep, of course there's a way. j and k move down and up one line, so 10j and 10k move down and up ten lines. You can repeat any motion by putting a number before it.
You might also want to set relativenumber if this is something you do a lot of - it'll help save you counting by printing line numbers relative to the current line, instead of absolute numbers.
Moving 10 lines up and down might not suit your task as well as other options. Consider other movements:
Ctrlf, Ctrlb page forward and back.
}, { move forward and back by one paragraph.
You can write rules in your vimrc to bind 10j to a key, say J to move down 10 lines by adding the following line to your vimrc file:
map <S-j> 10j
However you'd be overwriting the useful existing J command (join two lines). Finding a well positioned unused key combination for 10j/10k might be difficult, so I suggest using the existing movements that I mentioned.
You may also want to know that you can move backwards to a word that you see by doing:
?someword and forward to a word you see by doing /someword. These are going to be faster than trying to move up/down 10 lines and then repositioning your cursor to the exact location. If you cant think of a simple search string for the line in question, you can always go to the line number as you said (xgg).
I was messing with vim and I noticed - moves you up and + moves you down, so you can:
10-
or you could use k since you're most likely used to hjkl cursor movement.

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, 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