Vim yank span given column start and end position - vim

I'm wondering in vim, when given a start and end column position, is there a way to yank corresponding content starts from the start position to end.
for example, given a line in vim
aaaabbbbcccc
start = 4
end = 8
I want the yanked content is bbbb
The visual mode does finish it, but I think there may a vim command for it

I think there may a vim command for it
The v to enter visual mode, the motions to extend the area, and the y to yank are all "vim commands".
Assuming the cursor is somewhere on the line, you can do this with visual mode:
5|
v8|
y
In command-line mode, it would look like this:
:call feedkeys('5|v8|y')
In a script, assuming the start and end are variable, it would look like this:
call feedkeys(start .. '|v' .. end .. '|y')
See :help | and :help feedkeys().
Of note, yanking is exclusive in operator-pending mode so, if you want to yank up to and including column 8, you need to involve visual mode somehow, where yanking is inclusive. Explicitly, as above, or implicitly, with 5|yv8|. It doesn't really change anything to the problem at hand but it is a feature I don't often see mentioned. See :help forced-motion.

We can use yank with motion 5|y9| for this without v.
5| go to column 5.
y9| yank until column 9.
*y* *yank*
["x]y{motion} Yank {motion} text [into register x]. When no
characters are to be yanked (e.g., "y0" in column 1),
this is an error when 'cpoptions' includes the 'E'
flag.

Related

How can I select all the text on a line without the indentation in Vim?

I want to replace all the text of the current line under the cursor and change the text so I start typing the new code. But I want to keep the indentation.
Currently I am using ddO. This will delete the line and open a line before the cursor in insert mode, it's good because vim will take notice of the previous indentation and place the cursor as expected.
But I want to use c similar to ciw (change inner word) because it feels natural to think "change the line". Vc is almost what I want but it will lose the indentation.
Any idea ?
Maybe you are looking for cc?
:h cc
["x]cc Delete [count] lines [into register x] and start
insert |linewise|. If 'autoindent' is on, preserve
the indent of the first line.
You can try this (to put in your vimrc):
:onoremap ii :<c-u>normal! v^o$h<cr>
:xnoremap ii ^o$h
The first line defines the mapping ii which will work with any command expecting a motion (cii, dii, yii...).
The second mapping allows to use it in visual mode (e.g., vii).
Brief explanation of the :normal! command:
v : visual mode, ^ : go to 1st non-blank char, o : go to the opposite side of the selection, $h : go past to the end of line then go 1 char left.

What is the difference between s, c and r commands in vi/vim?

I am trying to clarify this from the OReilly book on Vim, but the examples presented aren't clear enough.
Clarification via examples/use-cases instead of direct explanation would be very helpful.
The Sample text could be:
With a
screen editor,
you can
scroll the page, move the cursor.
Assume you have foo in the document, and the cursor is on the f.
Now, pressing rb will change this to boo, and you are back in command mode. Pressing sb will accomplish the same, but you are in insert mode and can insert more characters. Finally, c requires some kind of motion; e.g. you can type cw to remove the whole word and enter insert mode. On the other hand, cl is essentially the same as s.
Descriptions
s (substitute) will delete the current character and place the user in insert mode with the cursor between the two surrounding characters. 3s, for example, will delete the next three characters and place the user in insert mode.
c (change) takes a vi/vim motion (such as w, j, b, etc.). It deletes the characters from the current cursor position up to the end of the movement. Note that this means that s is equivalent to cl (vim documentation itself claims these are synonyms).
r (replace) never enters insert mode at all. Instead, it expects another character, which it will then use to replace the character currently under the cursor.
Examples
Take your sample text, and image the cursor at the beginning of the word 'can' (line 3).
Typing spl<Esc> in vi/vim.
Here, we have s for substitute. pl is the text to insert, and <Esc> will exit insert mode. Put together, it will change can to plan like this:
With a
screen editor,
you plan
scroll the page, move the cursor.
Typing cwcould<Esc> in vi/vim.
c is for change, and w tells c to delete through the next word, can. Next we type the text for insert mode, could. Lastly, we need to type <Esc> again to exit insert mode. The command will change can to could like this:
With a
screen editor,
you could
scroll the page, move the cursor.
Typing rf in vi/vim.
Here we type r for replace, then f as the new character which r uses to replace the original character with. This changes can to fan like this:
With a
screen editor,
you fan
scroll the page, move the cursor.
Notes
There's a lot of hidden uses to the simple commands in vi/vim that highlight more differences between these commands. Since I almost always use vim over vi, these features might be vim-exclusive, I'm not certain.
Maximizing the utility of commands like c, y, and d that take motions requires having a good grasp of text-objects (type help text-objects in vim. These aren't in vi.)
Because r takes a character instead of entering insert mode, you can input characters that would otherwise be difficult to add in. Typing r<C-R> (that's r, then ctrl-r) replaces the current character with a ctrl-r character. This might be surprising since pressing ctrl-r in insert mode awaits another key that is the register to paste.
All three of these commands can be repeated with the . command, substituting, changing, or replacing the same region relative to the cursor with the given text.
When typing a number n before the command, s and c delete n items (characters for s, or movements for c), and then inserts text once. Using a number n before r, however, replaces the next n characters with that many copies of the chosen character. For example, 4r0 could replace 1234 with 0000 all at once.
:help c
:help s
:help r
Easy.
Instead of wasting your time on that book, learn how to use Vim's awesome internal documentation:
:h s
:h :command
:h 'option'
:h function()
:h ctrl-x
:h i_ctrl-x
:h subject
:h foo<Tab>
:helpgrep foo
You may try these commands in visual block mode (press <C-v> to enter), they act a little different.
When you select a block of characters and then type s, it will immediately remove the block and enter insert mode, whatever you input next will be inserted in the same position on each of the lines affected by the visual block selection.
Command c basically does the same thing.
What interesting is command r, when you type ra after you select a block, it will replace every character in that block to a instead of just leave one column of a. I think this can be very useful at some point.

How to paste in the line where the cursor is?

The command p pastes below the cursor and P pastes above the cursor. What's the command to paste in the line where cursor is?
This all depends on the type of data in the register you're pasting. If the data is line-oriented data (yanked with yy for instance) it will be pasted as a whole line above or below the cursor. If the data is character-oriented (yanked with e.g. y2w) then it will be pasted at or before the cursor position in the current line.
See :help linewise-register for more info on the interaction between the type of register and the put command.
The Edit menu in gvim lists the following:
Paste = "+gP
Put Before = [p
Put After = ]p
If you're running vim in Windows, you can do the following to get Ctrl+C and Ctrl+V to work as expected:
source $VIMRUNTIME/mswin.vim
behave mswin
If you want to keep the current line as it is, you either paste above or below the line.
If you want to overwrite the current line you'll have to delete it first, which means that the following line takes its place, then paste above the new current line.
There are more than one way to do it:
"_ddP
"_dd deletes the whole current line in the "black hole register", the following line is now the current line.
P puts the content of the unnamed register above the current line.
Vp
V puts you in VISUAL LINE mode and selects visually the whole current line
p replaces the selection with the content of the unnamed register
S<C-r>"
S deletes the content of the current line and puts you in INSERT mode
<C-r>" puts the content of the unnamed register
The two last options have an interesting side effect: the content of the previous line is put into the unnamed register which makes it impossible to do multiple pastes with the same content.
Luckily, you can work around this situation:
The "black hole register", mentioned in the first solution works, well… like a black hole. Whatever you put into it disappears forever so you can continue using p and P with some degree of confidence that the unnamed register is still the same from paste to paste.
Vim gives you access to 26 alphabetic registers that you can use to save macros or… paste stuff repeatedly.
Taking the second solution as a starting point, you start by yanking a whole line into register "a with "ayy then you do V"ap on another line.
But all of the above assumes that the text you want to paste is an actual line. Vim makes the difference between "line-wise" and "character-wise" : it won't let you paste a line in a character-wise context or the other way around.
Yanking a whole line with yy keeps its line-wiseness or character-wiseness and you won't be able to p between two characters on a same line. For that you need to make sure that what you yank won't be interpreted as line-wise by Vim. For example, let's assume you are on the first character of the first line and want to yank ipsum dolor and put it at its normal place between lorem and sit:
ipsum dolor
lorem sit amet
You should type "ayee to put your yanked text in register "a, place the cursor where needed and type "aP.
To paste in insert mode you just press Control+R. Then enter the register, e.g. Shift++.
To paste in command mode, you press P, however you've to make sure your line doesn't have a new line character (e.g. yanked by 0v$hy), otherwise it'll appear above the cursor.
The same for visual mode, see: How to paste a line in a vertical selection block? at Vim SE
You can use D to delete from current cursor position to the end of line, and the p to the new cursor position.
That is to cut and paste a whole line use ^D and p.
Shift + v will select the entire line, but you don't want to do that. Instead, press CTRL + v from the beginning of the line which will select by character, then $ to select to the end of the line. yank y and paste p.
I needed to "cast" register contents into a certain (characterwise / linewise / blockwise) mode so often, I wrote the UnconditionalPaste plugin for it. It provides gcp, glp, etc. alternatives to the built-in paste commands that force a certain mode (and by now several more variations on this theme, like pasting with joined by commas or queried characters).
With it, you can just use gcp / gcP to paste after / before the cursor position, regardless of how you've yanked the text.
(I know this thread is old, just leaving this and hope this may help someone)
Inspired by #wbg's comment above regarding deleting the line feed, I added these to my mappings:
nnoremap <leader>p :let #"=substitute(#", '\n\+$', '', '')<CR>p
inoremap <leader>p <esc>:let #"=substitute(#", '\n\+$', '', '')<CR>pa
This is useful when I have a file with some SQLs (line by line) and I have to yank into the code.
vp that's how, type vp in normal mode
How is this not an answer to a 10 year old question, stackoverflow slip'n?
The character under the cursor will be replaced by the the put
To help with and many others scenarios, I've mapped rr for the ability to quickly add a space, or some other 1-off character.
noremap rr i<space><esc>r in my ~/.vimrc
divide the line into 2 wherever you want to insert
paste the section between them
merge the 3 lines with j as described here (Delete newline in Vim)
works, but tedious, and had to think about, look it up
=> vi and emacs are garbage software
I'm not sure there is one. I tried to find documentation and ran across the following three documents:
Vim commands cheat sheet
Vim editor commands
Mastering the VI editor
Unfortunately, all three only have the two commands that you list. Particularly, the third link states that The commands to paste are p and P...

How to move yanked text into particular register in vim?

When editing in vim, often enough I find myself stopping when I'm going to delete text and I notice that previously yanked text would become handy for next operations.
So - how to move already yanked text into particular register (e.g. under a)?
To move register 0 to register a:
:let #a=#0
You can use something like:
noremap <leader>ma :let #a=#<CR>
Now, when you press \ma in normal mode, your last yanked text will go to register 'a'.
Note : Assuming leader is '\'
You could also use the 0 register, if you only need it for a short amount of time. From :help quote_number (just below :help registers):
2. Numbered registers "0 to "9
Vim fills these registers with text from yank and delete commands.
Numbered register 0 contains the text from the most recent yank command,
unless the command specified another register with ["x].
(link to the rest)
Alternatively, you can delete text to the devnull registry with "_d (actually it is called the blackhole registry). See :help quote_. No need then to move registers, your previously yanked text will still be available with p.

How to paste yanked text into the Vim command line

I'd like to paste yanked text into Vim's command line. Is it possible?
Yes. Hit Ctrl-R then ". If you have literal control characters in what you have yanked, use Ctrl-R, Ctrl-O, ".
Here is an explanation of what you can do with registers. What you can do with registers is extraordinary, and once you know how to use them you cannot live without them.
Registers are basically storage locations for strings. Vim has many registers that work in different ways:
0 (yank register: when you use y in normal mode, without specifying a register, yanked text goes there and also to the default register),
1 to 9 (shifting delete registers, when you use commands such as c or d, what has been deleted goes to register 1, what was in register 1 goes to register 2, etc.),
" (default register, also known as unnamed register. This is where the " comes in Ctrl-R, "),
a to z for your own use (capitalized A to Z are for appending to corresponding registers).
_ (acts like /dev/null (Unix) or NUL (Windows), you can write to it but it's discarded and when you read from it, it is always empty),
- (small delete register),
/ (search pattern register, updated when you look for text with /, ?, * or # for instance; you can also write to it to dynamically change the search pattern),
: (stores last VimL typed command via Q or :, readonly),
+ and * (system clipboard registers, you can write to them to set the clipboard and read the clipboard contents from them)
See :help registers for the full reference.
You can, at any moment, use :registers to display the contents of all registers. Synonyms and shorthands for this command are :display, :reg and :di.
In Insert or Command-line mode, Ctrl-R plus a register name, inserts the contents of this register. If you want to insert them literally (no auto-indenting, no conversion of control characters like 0x08 to backspace, etc), you can use Ctrl-R, Ctrl-O, register name.
See :help i_CTRL-R and following paragraphs for more reference.
But you can also do the following (and I probably forgot many uses for registers).
In normal mode, hit ":p. The last command you used in vim is pasted into your buffer.
Let's decompose: " is a Normal mode command that lets you select what register is to be used during the next yank, delete or paste operation. So ": selects the colon register (storing last command). Then p is a command you already know, it pastes the contents of the register.
cf. :help ", :help quote_:
You're editing a VimL file (for instance your .vimrc) and would like to execute a couple of consecutive lines right now: yj:#"Enter.
Here, yj yanks current and next line (this is because j is a linewise motion but this is out of scope of this answer) into the default register (also known as the unnamed register). Then the :# Ex command plays Ex commands stored in the register given as argument, and " is how you refer to the unnamed register. Also see the top of this answer, which is related.
Do not confuse " used here (which is a register name) with the " from the previous example, which was a Normal-mode command.
cf. :help :# and :help quote_quote
Insert the last search pattern into your file in Insert mode, or into the command line, with Ctrl-R, /.
cf. :help quote_/, help i_CTRL-R
Corollary: Keep your search pattern but add an alternative: / Ctrl-R, / \|alternative.
You've selected two words in the middle of a line in visual mode, yanked them with y, they are in the unnamed register. Now you want to open a new line just below where you are, with those two words: :pu. This is shorthand for :put ". The :put command, like many Ex commands, works only linewise.
cf. :help :put
You could also have done: :call setreg('"', #", 'V') then p. The setreg function sets the register of which the name is given as first argument (as a string), initializes it with the contents of the second argument (and you can use registers as variables with the name #x where x is the register name in VimL), and turns it into the mode specified in the third argument, V for linewise, nothing for characterwise and literal ^V for blockwise.
cf. :help setreg(). The reverse functions are getreg() and getregtype().
If you have recorded a macro with qa...q, then :echo #a will tell you what you have typed, and #a will replay the macro (probably you knew that one, very useful in order to avoid repetitive tasks)
cf. :help q, help #
Corollary from the previous example: If you have 8go in the clipboard, then #+ will play the clipboard contents as a macro, and thus go to the 8th byte of your file. Actually this will work with almost every register. If your last inserted string was dd in Insert mode, then #. will (because the . register contains the last inserted string) delete a line. (Vim documentation is wrong in this regard, since it states that the registers #, %, : and . will only work with p, P, :put and Ctrl-R).
cf. :help #
Don't confuse :# (command that plays Vim commands from a register) and # (normal-mode command that plays normal-mode commands from a register).
Notable exception is #:. The command register does not contain the initial colon neither does it contain the final carriage return. However in Normal mode, #: will do what you expect, interpreting the register as an Ex command, not trying to play it in Normal mode. So if your last command was :e, the register contains e but #: will reload the file, not go to end of word.
cf. :help #:
Show what you will be doing in Normal mode before running it: #='dd' Enter. As soon as you hit the = key, Vim switches to expression evaluation: as you enter an expression and hit Enter, Vim computes it, and the result acts as a register content. Of course the register = is read-only, and one-shot. Each time you start using it, you will have to enter a new expression.
cf. :help quote_=
Corollary: If you are editing a command, and you realize that you should need to insert into your command line some line from your current buffer: don't press Esc! Use Ctrl-R =getline(58) Enter. After that you will be back to command line editing, but it has inserted the contents of the 58th line.
Define a search pattern manually: :let #/ = 'foo'
cf. :help :let
Note that doing that, you needn't to escape / in the pattern. However you need to double all single quotes of course.
Copy all lines beginning with foo, and afterwards all lines containing bar to clipboard, chain these commands: qaq (resets the a register storing an empty macro inside it), :g/^foo/y A, :g/bar/y A, :let #+ = #a.
Using a capital register name makes the register work in append mode
Better, if Q has not been remapped by mswin.vim, start Ex mode with Q, chain those “colon commands” which are actually better called “Ex commands”, and go back to Normal mode by typing visual.
cf. :help :g, :help :y, :help Q
Double-space your file: :g/^/put _. This puts the contents of the black hole register (empty when reading, but writable, behaving like /dev/null) linewise, after each line (because every line has a beginning!).
Add a line containing foo before each line: :g/^/-put ='foo'. This is a clever use of the expression register. Here, - is a synonym for .-1 (cf. :help :range). Since :put puts the text after the line, you have to explicitly tell it to act on the previous one.
Copy the entire buffer to the system clipboard: :%y+.
cf. :help :range (for the % part) and :help :y.
If you have misrecorded a macro, you can type :let #a=' Ctrl-R =replace(#a,"'","''",'g') Enter ' and edit it. This will modify the contents of the macro stored in register a, and it's shown here how you can use the expression register to do that. Another, simpler, way of modifying a macro is to paste it in a buffer ("ap), edit it, and put it again into the register, by selecting it and "ay.
If you did dddd, you might do uu in order to undo. With p you could get the last deleted line. But actually you can also recover up to 9 deletes with the registers #1 through #9.
Even better, if you do "1P, then . in Normal mode will play "2P, and so on.
cf. :help . and :help quote_number
If you want to insert the current date in Insert mode: Ctrl-R=strftime('%y%m%d')Enter.
cf. :help strftime()
Once again, what can be confusing:
:# is a command-line command that interprets the contents of a register as vimscript and sources it
# in normal mode command that interprets the contents of a register as normal-mode keystrokes (except when you use : register, that contains last played command without the initial colon: in this case it replays the command as if you also re-typed the colon and the final return key).
" in normal mode command that helps you select a register for yank, paste, delete, correct, etc.
" is also a valid register name (the default, or unnamed, register) and therefore can be passed as an arguments for commands that expect register names
For pasting something that is the system clipboard you can just use SHIFT - INS.
It works in Windows, but I am guessing it works well in Linux too.
"I'd like to paste yanked text into Vim command line."
While the top voted answer is very complete, I prefer editing the command history.
In normal mode, type: q:. This will give you a list of recent commands, editable and searchable with normal vim commands. You'll start on a blank command line at the bottom.
For the exact thing that the article asks, pasting a yanked line (or yanked anything) into a command line, yank your text and then: q:p (get into command history edit mode, and then (p)ut your yanked text into a new command line. Edit at will, enter to execute.
To get out of command history mode, it's the opposite. In normal mode in command history, type: :q + enter
For pasting something from the system clipboard into the Vim command line ("command mode"), use Ctrl+R followed by +. For me, at least on Ubuntu, Shift+Ins is not working.
PS: I am not sure why Ctrl+R followed by *, which is theoretically the same as Ctrl+R followed by + doesn't seem to work always. I searched and discovered the + version and it seems to work always, at least on my box.
It's worth noting also that the yank registers are the same as the macro buffers. In other words, you can simply write out your whole command in your document (including your pasted snippet), then "by to yank it to the b register, and then run it with #b.
For context, this information comes from out-of-the-box, no plugins, no .vimrc Vim 7.4 behavior in Linux Mint with the default options.
You can always select text with the mouse (or using V or v and placing the selection in the "* register), and paste it into the command line with Shift + Ctrl + v.
Typing Ctrl + r in the command line will cause a prompt for a register name. so typing :CTRL-r* will place the content register * into the command line. It will paste any register, not just "*. See :help c_CTRL-R.
Furthermore, the middle mouse button will paste into the command line.
See :help->quote-plus for a description of the how X Window deals with selection. Even in a plain, out-of-the-box Vim (again, in Vim 7.4 in Linux Mint, anyway), any selection made with the left mouse button can be pasted in the command line with the middle mouse button.
In addition, the middle mouse button will also paste text selected in Vim into many other X Window applications, even GUI ones (for example, Firefox and Thunderbird) and pasting text into the command line is also possible where the text was selected from other apps.
See :help->x11-selection for addl information.
tl;dr
Try the :CTRL-r approach first, and then use Shift + Ctrl + v or the middle mouse button if you need something else.
It is conceded that it can be confusing.
I was having a similar problem. I wanted the selected text to end up in a command, but not rely on pasting it in. Here's the command I was trying to write a mapping for:
:call VimuxRunCommand("python")
The docs for this plugin only show using string literals. The following will break if you try to select text that contains doublequotes:
vnoremap y:call VimuxRunCommand("<c-r>"")<cr>
To get around this, you just reference the contents of the macro using # :
vnoremap y:call VimuxRunCommand(#")<cr>
Passes the contents of the unnamed register in and works with my double quote and multiline edgecases.
OS X
If you are using Vim in Mac OS X, unfortunately it comes with older version, and not complied with clipboard options. Luckily, Homebrew can easily solve this problem.
Install Vim:
brew install vim --with-lua --with-override-system-vi
Install the GUI version of Vim:
brew install macvim --with-lua --with-override-system-vi
Restart the terminal for it to take effect.
Append the following line to ~/.vimrc
set clipboard=unnamed
Now you can copy the line in Vim with yy and paste it system-wide.
"[a-z]y: Copy text to the [a-z] register
Use :! to go to the edit command
Ctrl + R: Follow the register identity to paste what you copy.
It used to CentOS 7.
If you have two values yanked into two different registers (for example register a and register b) then you can simply set a variable c and do the operation on it.
For example, :set c = str2float(#a) + str2float(#b) and then you can paste the content of c anywhere.
For example whilst in INSERT mode, CTRL + R then type = to enter into the expression register and just type c after equal sign and hit ENTER. Done you should now have the total of a and b registers.
All these can be recorded in a macro and repeated over!
The str2float function is used if you are working with floats, if you don't, you will get integers instead.
I am not sure if this is idiomatic but it worked for my case where I needed to add 2 numbers in a row and repeat it for 500 more lines.
I like to use Control-v to paste from the system clipboard, so I use:
cnoremap <C-v> <C-r>+

Resources