Yank n lines upwards without moving - vim

To yank 7 lines downward without moving the cursor, I can 7yy. Is it possible to do the same upwards, not using macros or remapping?

You can use the :yank command with a range to accomplish this effect.
:.-6,.yank
The range explanation:
. or the dot means current line
.-6 means current line minus 6
.-6,. is current line minus 6 to the current line
This can be abbreviated .-6 to just -6 giving us -6,.yank
the current line is also assumed in the end of the range so -6,yank
the yank command can be shortened to just :y giving us -6,y
Final command:
:-6,y
For more help:
:h :yank
:h [range]

You could simply yank to a motion and then return the cursor to the position using either '[ or '].
The yank for 6 lines up, plus the current gives 7 in total:
y6u
Then, use some lesser known marks:
'[ -> to the first character on the first line of
the previously yanked text (or changed)
`[ -> to the first character of the previously yanked text
'] -> to the first character on the last line of yanked text
`] -> to the last character of the preciously yanked text
So:
y6u']
y6u`]
Are two solutions you could use depending on what exactly you want. The former moves the cursor back to the first character on the line your cursor was, and the latter moves to the last character on that line.
But there is another mark that might be handy: '^. It means the last position the cursor was when leaving insert mode.
'^ -> moves to the beginning of the last line when leaving insert mode.
`^ -> moves to the exact position where insert mode was last left.
Then here are two other solutions:
y6u'^
y6u`^
That's not the end! If you pretend to continue inserting text, you can use the gi command. It moves you to the `^ mark and enter insert mode. Then we have a fifth solution:
y6ugi
I hope one of these meets your needs!

You could do the following:
6yk6j
This is will yank the 6 preceding lines and the current one) but the courser will move. 6j jumps back to the previous position.

Related

Which operator can be used to move cursor to the last non-blank character of the screen line in vim?

I know g$ can be used to move the cursor to the last character of the screen line, but which operator can be used to move the cursor to the last non-blank character of the screen line?
g_ (g followed by underscore) moves to the last non-blank character of the screen line text line. (As pointed out by han pingtian in the comments).
To move to the last non-blank character of the screen line, there's no single operator that I could find, but you could combine g$ with ge to achieve this result: use g$ to go to the last character (blank or non-blank) of the screen line, then if the cursor is on whitespace, use ge to move backwards to the last character of the previous word. (And of course, if the character under the cursor is non-blank, just omit the ge operator).
If you're trying to write a script, this won't be as helpful as a single dedicated operator, since it requires making a decision about the character under the cursor after the g$ has completed. But if you're just trying to go to the last non-blank character in visual mode or for interactive editing purposes, the g$ ge combination should suffice for what you need.
Also try substituting gE for ge, depending on whether you want to skip over punctuation or not. (See :help word-motions for the distinction between e and E: basically, E counts ALL non-whitespace characters as word characters, while e counts only letters, digits and underscores.)
Right of Screen
g$
Left of Screen
g0
Top of Screen
H (high)
Middle of Screen
M
Bottom of Screen
L (low)

What is the definition of a non-blank character in Vim?

Launch vim.
In the empty buffer, insert two lines where the first line consists of 3 spaces and the second line consists of hello world.
Here is an example file where the spaces are represented with dots.
...
hello world
Now press gg. The cursor moves to the third space of the first line.
Quoting :help gg:
<C-Home> or *gg* *<C-Home>*
gg Goto line [count], default first line, on the first
non-blank character |linewise|. If 'startofline' not
set, keep the same column.
The documentation says that the cursor should move to the first non-blank character of the first line. I have two questions.
Does :help document the definition of a non-blank character? If so, could you please point me to it?
Is the behaviour that we observe in the experiment mentioned above consistent with the documentation provided in :help gg?
I don't think there is a general definition of non-blank in the vim docs, but I also do not believe this is a "side effect" of gg.
Note that gg is consistent here with ^:
^ To the first non-blank character of the line.
|exclusive| motion.
and [:blank:] of vim's pattern matching behavior (:h blank) defines blank characters as space and tab:
*[:blank:]* [:blank:] space and tab characters
As far as whether or not this is consistent with gg, consider what it says it will do as two steps instead of one:
Go to the first line (default since no count was specified) -- it does this.
Go to the first non-blank character of said line.
Probably the easiest way to implement 2 as an algorithm is to position the cursor after all the blank characters at the beginning of the line. In your case, they are all blank characters (and it cannot move to the next line), so the cursor is positioned at the end of the line (after all the blank characters).

How to jump to the exact last change point in Vim

'. can jump to the line of last change. But I need to jump to the exactly point.
Use `.. That is, backtick followed by a dot.
As a change has a beginning and an end, `[ and `] are also very helpful:
'[ `[ To the first character of the previously changed
or yanked text.
'] `] To the last character of the previously changed or
yanked text.
After executing an operator the Cursor is put at the beginning of the text
that was operated upon. After a put command ("p" or "P") the cursor is
sometimes placed at the first inserted line and sometimes on the last inserted
character. The four commands above put the cursor at either end. Example:
After yanking 10 lines you want to go to the last one of them: "10Y']". After
inserting several lines with the "p" command you want to jump to the lowest
inserted line: "p']". This also works for text that has been inserted.
answers are kinda old, but for current reference:
:changes show a list of changes
g; jump to last edit
g, jump forward in last edit's
found at vimtricks
I suggest a mapping to jump to the last changing point, as we have:
gv ................... repeats last selection
gi ................... enters insert at the last inserting point
" gl to jump to the last change "exactly"
nnoremap gl `.
Reference: https://twitter.com/dotvimrc/status/191163723065462786

Cut and paste in Vim without moving next line up

When I cut and paste in VIM by pressing v, and go to the end of the line using $, and press d, the next line gets moved up to the same line I'm cutting.
How do I stop this?
It moves up because you have removed all the characters including line return/feed.
There are multiple solutions as usual with Vim. There is no "one true way" but you can try the following commands.
You can use D (capital) in normal mode which will erase everything until the end of line.
See :help D
Using another motion
What you could do instead of using $ to move to the end of the line, use g_. It will move to the last non blank character of the line and won't select line return.
See :help g_
So vg_d should work as you want.
Using Replace
Alternatively, what you could do instead of cutting, you could replace the erased character by a blank using the space character.
So v$rSPACE should work to erase but it will not save the replaced characters in register (for pasting later for example).
To cut everything from current cursor position until the end, use C.
:he C will help you:
Delete from the cursor position to the end of the
line and [count]-1 more lines [into register x], and
start insert. Synonym for c$ (not |linewise|).
Doing so will cause the current line (assuming you are on the start of the line when hitting C) to become empty and the content is (by default) yanked into register "
Edit:
As Xavier notes in his comment (and his answer), the same could be achieved with D. It also cuts everything from current cursor position until the end of the line but doesn't go in insert mode after doing it.
If you use these keystroke sequence then next line would not move up.
v $ h d
It is moving up because EOL character $ is also getting deleted without moving cursor 1 character back.
Just skip the visual mode and swap the other two commands, ie. press d $.
This is shorter than your starting one and doesn't break your tradition introducing other keystrokes you may not be familiar with.

Why does Vim position the caret one character off with $ (end of line)?

Observe a line in a Vim instance:
Now I hit $:
Why does my cursor not go all the way to the end? Once I try inserting, the text gets inserted before the last character! Even if I try to move right again while still in normal mode I get the bell. Oddly, when in edit mode I can move to the actual end of line with the right arrow key!
Does anyone know why Vim does this? On 7.3 by the way. Thanks for the help.
Pressing $ while in command mode causes the cursor to move to the end of the line, effectively highlighting the last character. Hit i here to insert before the last character, or a to append to the line. It is slightly ambiguous here, because you're using a pipe character as a cursor rather than a rectangular block cursor. Have a look at ":help termcap-cursor-shape" if you want to change that.
If the goal is to append to the end of the line, A will jump to the end of the line and enter insert mode with a single keypress.
Use a to append a character after the current.
Or, to go to the end of the line and append in 1 step, use capital A. I.e. shiftA.
Similarly shift-I to insert at the beginning of the line without first having to press ^.
The cursor can't be between two characters, it is always on a character.
If you press $ then x, you will correctly delete the last printable character of the current line.
What you are observing is the fact that using i, you are always inserting your text before the selected character. If you want to insert after the selected character, you have to use a or better A as it has already been mentioned.
In other words:
i means "insert before character under cursor".
a means "insert after character under cursor".
mnemonic for a : a for "append".

Resources