YankRing in insert mode - vim

I'm using vim with YankRing.
Is it possible to paste an element from the YankRing while being in insert mode?
(Like it is possible to paste an element from the usual registers with Ctrl-R + the name of the register.)
Thanks

(NB: I'm not familiar with that particular plugin, so my examples might seem silly.)
When in Insert mode, you can always use CTRL-O (see i_CTRL-O) to execute one Normal mode command and immediately get back into Insert mode. So it appears you can just press CTRL-O followed by CTRL-P to use YankRing. Same goes for command-line mode: CTRL-O followed by :YRShow, for example.

Related

Insert mode default keys in vim

The following items are useful to me in editing text, and I was wondering if vim had something for this built out of the box (though I didn't see it on the https://vimhelp.org/index.txt.html#index.txt page), or I had to create mappings for it:
Forward-delete a character. This is X in normal mode.
Forward-delete all text to the right of the cursor on the line. This is the inverse of ctrl-u.
Are either of these mappings available? And if not, are there 'standard' mappings for this that are common (for example, how it might be done in another unix program).
Note that this is the keyboard I have -- there is only one delete key (which acts like a normal backspace key) and there is no backspace key:
Note: for forward-delete, I am currently mapping ctrl-d as:
"Ctrl-d to forward-delete when in insert or command mode
noremap! <C-d> <Delete>
However, this interferes with the tab in insert mode (which I don't use) and the help-options in command mode (which I do use!) so I may have to modify this later, or hopefully someone suggests a better solution.
though I didn't see it on the https://vimhelp.org/index.txt.html#index.txt page
If you can't find it in the documentation, then it doesn't exist.
You can use fn+delete for "Forward-delete a character".
"Forward-delete all text to the right of the cursor on the line" is ctrl+k in MacOS, but Vim has its own use for that combo, :help i_ctrl-k so it is up to you to create a mapping for it.
Something like:
inoremap <key> <C-o>ld$

Add new line after current line in insert mode vim

I am new at Vim, and the transition from Sublime to Vim is being really hard. I want to know if there's a shortcut to add a new line above or behind the current line while I'm in insert mode without leaving it. In sublime I used
cmd + Enter
cmd + Shift + Enter
to do but I didn't find a similar way to do it on vim.
I found the way to do it in normal mode using 'o' and 'O' and also configuring this amazing way http://vim.wikia.com/wiki/Insert_newline_without_entering_insert_mode
but none of them reach what I need.
Thanks !
Defining a shortcut for adding line below is easy, just type the following on the Vim command-line (after typing : in normal mode) or add it to your vimrc file:
imap <C-Enter> <Esc>o
That adds an insert-mode mapping (imap) so that Ctrl-Enter will leave insert mode, then use o to add a new line after the current line (leaving you back in insert mode where you started). (<C-xxx> is how Vim represents the special key sequence Ctrl+xxx, and <Esc> is the Escape key).
That's very similar to the "amazing way" you link to, but just using the appropriate key sequence to go from insert mode to normal mode and then add the line. The way to create shortcuts in Vim is to build them up from smaller pieces. If you know about O and o then all you need to do is create a mapping to get into normal mode first then use them.
From that, it should be obvious how to do the other mapping too:
imap <C-S-Enter> <Esc>O
(<C-S-xxx> means Ctrl+Shift+xxx)
Those mappings work fine for me in gvim GUI but may not work in the terminal-based vim, as the key sequences might not get passed correctly from the terminal to vim. Use some other mappings such as Ctrl+o if necessary.

Using Ack.vim on visual selection

Currently I have this mapping in my ~/.vimrc
noremap <Leader>a :Ack <cword><cr>
which enables me to search for a word under the cursor.
I would like to search for a current visual selection instead, because sometimes words are not enough.
Is there a way I can send visual selection to ack.vim?
You can write a visual-mode map that yanks the highlighted text and then pastes it verbatim (properly escaped) onto the vim command-line:
vnoremap <Leader>a y:Ack <C-r>=fnameescape(#")<CR><CR>
This solution uses the <C-r>= trick that allows you to enter a kind of second-level command-line, which allows you to enter any vimscript expression, which is then evaluated, and the result is stringified and pasted onto the (original, first-level) command-line where the cursor is.
A slight disadvantage of this approach is that it commandeers the unnamed register, which you may not want.
While bgoldst's answer should work just fine, you could also consider my fork of ack.vim: https://github.com/AndrewRadev/ack.vim
It comes with a working :Ack command in visual mode, and a few other extras that I've summarized at the top of the README.
At the time of this writing this is the default behaviour of Ack.
Just do the following:
move your cursor on any word in normal mode (for instance, hit Esc button to enter in normal mode, you know...)
type :Ack with no argument
it will search for the word under the cursor
Usually I select text during a search in a file (for instance put cursor inside word and type * repeateadly) the type :Ack to look for that word in other files of the project.

How to copy text from command-line mode in Vim?

Say, I just ran this command in Vim:
:nmap <CR> <C-]>
And now I want to copy this line and put it into my .vimrc.
How can I select and copy the whole line in command-line mode?
The fastest way is to run the command, switch to the destination
buffer (with .vimrc loaded, in this case) and paste the whole
command from the : register by typing
":p
in Normal mode.
If the command is further back in time, one can first recall it from
history (e.g., by typing the first few letters and pressing the up
arrow key ↑), rerun it, and then use the above method.
When these shortcuts are unhandy, one can resort to the general
approach of using the command-line window (see :help cmdwin).
To open it, either type q: in Normal mode, or press the key
combination set by the cedit option (Ctrl+F,
by default) in Command-line mode.
You can type Ctrl-F while in command mode to open up a special window with all previous commands. Then you can scroll to the desired line, hit yy to copy that line, then press Ctrl-C to return to command mode, and then ESC to return to normal mode. From there you can paste.
See :help cmdwin for more information on the command window.

Pasting from the clipboard and automatically toggling ":set paste"

When I paste things from the clipboard, they're normally (always) multilined, and in those cases (and those cases only), I'd like :set paste to be triggered, since otherwise the tabbing will increase with each line (you've all seen it!).
Though the problem with :set paste is that it doesn't behave well with set smartindent, causing the cursor to jump to the beginning of a new line instead of at the correct indent. So I'd like to enable it for this instance only.
I'm using Mac, sshing to a Debian machine with Vim, and thus pasting in Insert mode using cmd + v.
I don't use a mac, but I believe I have the prefix right here: <D-v> should mean cmd-v. For insert mode:
:imap <D-v> ^O:set paste<Enter>^R+^O:set nopaste<Enter>
or really, just do this:
:imap <D-V> ^O"+p
The ^O and ^R are literal control-O and control-R, which you can type with ^V^O (control-v control-o) and ^V^R (control-v control-r). Control-O in insert mode allows you to execute one command then return to insert mode; here you can use it to put from the clipboard register.
This worked for me when I tested them mapped to a different key, so you should be all set.
There's no need to map anything when not in insert mode; you can just use "+p.
I have the following in my .vimrc:
inoremap <S-Insert> <ESC>:setl paste<CR>gi<C-R>+<ESC>:setl nopaste<CR>gi
gi is to start insert mode in the same position as where insert mode was stopped last time in the current buffer.
Update:
Jefromi posted a better solution. I have tinkered it a bit
inoremap <S-Insert> <ESC>"+p`]a
It inserts clipboard text and places the cursor right after it.
You're right in that you should only enable 'paste' when you need it. It does more than just affect indenting. You can read everything that it affects in its documentation. A related option that is very useful to ease the use of 'paste' is 'pastetoggle'.
If you were using X-forwarding and a terminal that can properly communicate mouse actions, you could also take advantage of the 'mouse' option. With :set mouse=a, Vim is made aware of what the mouse is doing and therefore won't perform automatic indentation when it receives a multi-line paste via a middle-button mouse click.
Even without the mouse capability, X-forwarding could help because Vim will do the same thing when manually pasting from the clipboard or selection registers ("+ and "* respectively).
This ought to be solvable with a Vim script. (I hate Vim scripting, so it would have to be a much more serious infliction to cause me to solve it myself.) Even with iTerm2's "paste slowly" mode, the default is to break the data to be pasted into 16 byte chunks and send one every 0.125 seconds. Therefore, you should be able to programmatically detect a 16 byte chunk of "keystrokes" and do something about it.
In pseudocode that would look like:
if too_fast_too_be_human():
set('pastemode', True)
else
set('pastemode', False)
# where either
def too_fast_too_be_human
char_threshold = 16
return len(input_buffer) > char_threshold
# or
def too_fast_too_be_human
static byte_times = []
char_threshold = 16
time_threshold = 0.125
byte_times.append(now())
while(len(byte_times) > char_threshold):
byte_times.unshift()
return (byte_times[-1] - byte_times[0]) < time_threshold
There are weaknesses to that, but it would work for most cases.
We can paste (insert mode) without messing up indentation using
Ctrl-r Ctrl-o Register
Ctrl-r Ctrl-o +
Ctrl-r Ctrl-o *
Ctrl-r Ctrl-o 0
CTRL-R CTRL-O {0-9a-z"%#*+/:.-=} *i_CTRL-R_CTRL-O*
Insert the contents of a register literally and don't
auto-indent. Does the same as pasting with the mouse
"MiddleMouse". When the register is linewise this will
insert the text above the current line, like with `P`.
Does not replace characters!
The '.' register (last inserted text) is still inserted as
typed.

Resources