stdin stdout copy/paste doesn't work - vim

I using bash to search files on my PC))
so, I type
ls | vim -
It's working.
But I want to copy string from vim and paste it to bash back. And it doesn't work.
From saved file I can copy/paste using
"*Y
but, if file is unsave it not working.

Simply yank a selected text (y key) and then in terminal paste it with Shift+Insert; you'll need this setting in ~/.vimrc to make yank use clipboard:
set clipboard=unnamed " use clipboard reg '*' for all yank & like operations
Works for both vim & gvim.

Related

If I have vim open in two terminals, how can I share the copy/paste buffer?

I want to yy a line from one instance of vim running in one terminal emulator, and p that line into another instance of vim running in another terminal emulator. Possible? Is there a special setting to use?
There is a system clipboard which you can use to share data not only between multiple terminals, but also using shift + insert in GUI application.
First of all, check if system clipboard is enabled for your vim installation
vim --version | grep clipboard
if you see +clipboard you are good to continue, otherwise, follow this page to enable the system clipboard.
Once the system clipboard is enabled, you can copy line via "+yy into + buffer which is a system clipboard, and paste it in another terminal with vim with "+p command.
You can instead:
Esc for canceling all modes
:r! cat file.txt all content of file.txt pasts in your file, but if you want paste for example from 5 to 11 lines of file then
:r! sed -n 5,11p file.txt

Copy from vim to python console in tmux

I have installed tmux.
tmux -V
tmux 2.3
Set my configure file.
cat ~/.tmux.conf
set -g mouse on
Enter tmux and open a two vertical windows in it,open python3 console in the left,open vim in the right.
Now move my cursor at the beginning of the first line in the right with mouse.
Enter into normal mode and input 2yy+, to copy two lines in my + register.
Move cursor at the left python3 console window ,how can i paste content in + register into the python console?
#Kent,do as you say:
1.Move cursor at the beginning of first line,and type "+2Y
2.Move cursor to the left window,and middle-click mouse,nothing happen.
3.press ctrl+b then press ] key.
first your vim should be compiled with +clipboard see vim --version | grep 'clipboard'
To copy ( or delete ) in any vim register you can use the following syntex
"<register name><oprator><motion> (see :h registers )e.g.
"ayy(copy current line in register a) or
"bdd(delete current line in register b) or
"*ce(delete to the end of the current work and place content in register * using c will also put you in insert mode
to copy whole line you can use yy
and system clipboard is mapped to either + or * ( depending on the os )
so to copy the whole line into system clipboard you can use
"*yy or "+yy (depending on the os)
or to copy 2 lines
"*2yy or "+2yy ( to copy current and the line after current line )
once the content is copied in the system clipboard you can paste in tmux using ( command + v or ctrl + shift + v )
or to map system clipboard with tmux paste buffer see https://unix.stackexchange.com/questions/67673/copy-paste-text-selections-between-tmux-and-the-clipboard#72340
2yy+ does NOT copy two lines into + reg, instead, it yanks two lines to " reg, then moves the cursor to first non-blank char in next line
You can on the vim side do: "*2Y then do a mouse middle-click on the python console.
or simply select the lines you want to copy in vim by mouse, then middle click in python console
I didn't quite like with the accepted solution that it depends on a graphical environment for the clipboard since this does not work when vim can not access the clipboard, which is almost always the case for ssh connections.
So I cam up with another solution:
Instead of using the external clipboard vim can pass the text directly into tmux' paste buffer by piping it into
tmux load-buffer -
After that you can paste the content of the buffer with prefix + ] into the active tmux pane.
There are various ways to pass the text from vim to tmux:
# to write the current line into the tmux buffer:
:.w !tmux load-buffer -
# to write all *lines* within the visual selection into the tmux buffer:
:'<,'>w !tmux load-buffer -
# to pipe the content of a register (e.g. from a previous selection) into the buffer:
# #" being the unnamed register, #0 - #9 the numbered registers, and so on
:call system('tmux load-buffer -', #")
Using tmux paste-buffer you can even trigger the pasting into the correct pane at the same time:
# assuming the python pane is at :0.0
:call system('tmux load-buffer -; tmux paste-buffer -t :0.0', #")
You can now also easily map the last line to a key to send the visually selected text to the python pane.

How can I paste the contents of the system clipboard into all files in the argument list?

How can I paste the contents of the system clipboard to all files in the argument list in Vim?
You can do the following:
:argdo execute 'normal! "+p' | w
Explanation:
:argdo Run the command that follows on each file in the argument list. Alternatively, you can use :windo to run a command on each window, or :bufdo to run a command on each buffer.
execute "normal! ..." Run the sequence of commands after normal! as if they were entered in normal mode. Ignore all mappings and replace string escape sequences like \<esc>.
"+p Paste the register for the system clipboard. Note that Vim has to be compiled with the +clipboard feature enabled for this to work.
| w Write every file, whether it was updated or not. Alternatively, use | update to only write files that were changed.
For more details, see:
Learn Vimscript the Hard Way
Vim 101: Search and Replace on Multiple Files
Run a command in multiple buffers
Originally answered by Roberto Balejík

Vifm. Edit file in opened gvim

I use Gvim to write code. And use vifm to make file management ( copy, move files, extract tar's ). Sometimes, when navigating in vifm i need to open some file to edit him. Using :e it opened vim in same window. Is there any way to open file to edit in already opened gvim program?
You can use Vim's client-server feature to send the :edit to the existing GVIM instance. In the terminal Vim / vifm, execute:
:!gvim --remote path/to/file
See :help remote.txt for details. You can also open the file in a new tab page with --remote-tab etc.
Partial solution/workaround (I'm using a mac fwiw):
In vfimrc, define
" yank current file path into the clipboard
nnoremap Cf :!echo -n %c:p | pbcopy %i<cr>
To copy filename and dir into system clipboard
Then in vifm, cursor over file and type
Cf
:!gvim "
<cmd-v>
to paste clipboard,
and finish expression with...
"
<enter>
and now that file should open in gvim. It worked for me

How can I execute the current line as Vim EX commands?

Say I'm editing my _vimrc file and I've just added a couple of lines, for instance a new key mapping. I don't want to reload the whole file (:so %) since that will reset a lot of temporary stuff I'm experimenting with. I just want to run the two lines that I'm currently working on.
I'm having no luck trying to copy/paste the lines into the command buffer, since I can't use the put command in there. Is there any way I could run the current line (or current selection) as EX commands?
Summary:
After Anton Kovalenko's answer and Peter Rincker's comment I ended up with these key maps, which either executes the current line, or the current selected lines if in visual mode:
" Execute current line or current selection as Vim EX commands.
nnoremap <F2> :exe getline(".")<CR>
vnoremap <F2> :<C-w>exe join(getline("'<","'>"),'<Bar>')<CR>
To execute the current line as an ex command, you may also use:
yy:#"
This will yank the current line to the "-register and execute it. I don't think it is too much typing.
Executing the line under cursor as an Ex command:
:execute getline(".")
Convenient enough for 2 lines. (I'd figure out something for doing it with regions, but I'm not a vim user). And for currently selected region, the following seems to do the job:
:execute getreg("*")
As commented by Peter Rincker, this mapping can be used for executing the currently selected lines:
:vnoremap <f2> :<c-u>exe join(getline("'<","'>"),'<bar>')<cr>
For that purpose, I have defined the following commands and mappings:
":[range]Execute Execute text lines as ex commands.
" Handles |line-continuation|.
" The same can be achieved via "zyy#z (or yy#" through the unnamed register);
" but there, the ex command must be preceded by a colon (i.e. :ex)
command! -bar -range Execute silent <line1>,<line2>yank z | let #z = substitute(#z, '\n\s*\\', '', 'g') | #z
" [count]<Leader>e Execute current [count] line(s) as ex commands, then
" {Visual}<Leader>e jump to the following line (to allow speedy sequential
" execution of multiple lines).
nnoremap <silent> <Leader>e :Execute<Bar>execute 'normal! ' . v:count1 . 'j'<CR>
xnoremap <silent> <Leader>e :Execute<Bar>execute 'normal! ' . v:count1 . 'j'<CR>
Just after posting this, I found a work-around. I can copy text into the clipboard using "*y, then put that text into the command buffer by using the middle mouse button. This works for me, but is hardly a convenient solution for people without clipboard support, mouse support or just an aversion to removing their hands from the Vim position.
The accepted answer doesn't handle continuation sections. Also, surprisingly, the bar isn't needed, newlines are fine. This will work, first yanking the text into register x:
vno <c-x> "xy:exe substitute(#x,"\n\\",'','g')<cr>
As someone has already mentioned, the only exception are commands that "eat up" newlines. Eg, executing the above mapping on:
:sign define piet text=>> texthl=Search
:exe ":sign place 2 line=23 name=piet file=" . expand("%:p")
will cause vim to to think that the user is trying to define textl as "Search\n:exe ":sign place... etc.
You could also try
:<C-R><C-L><CR>
Per the vim docs, the combination will plop the current line into the command line. From there, hitting enter should do the trick. I realize that this does not handle multiline cases, however it doesn't require a .vimrc and therefore works out of the box.
If you're doing a lot of experimenting (trying things out that you might want to add to your vimrc, I assume?) it might help to do so in a scratch file like experimental.vim so you aren't just relying on your history to know what you're trying out. Now that you have these great mappings, it will be easy to rerun things from experimental or vimrc without sourcing the whole file.
Also (sorry, I can't comment on answers yet, it seems), I tried this mapping of Peter's:
vnoremap <Leader>es :<c-u>exec join(getline("'<","'>"),'<BAR>')<CR>
This works in most cases, but it fails specifically on function definitions.
function! TestMe()
echo "Yay!"
endfunction
This mapping joins the lines into a single string, separated by <BAR> and then execs them.
I'm not entirely sure why, but if I try to do that with a function definition in normal mode:
:exec 'function! TestMe()| echo "Yay!"|endfunction'
-> E488: Trailing characters
After some testing, I've found that it will work with newline separators instead:
:exec "function! TestMe()\n echo 'Yay!'\nendfunction"
:call TestMe()
-> Yay!
So, I've changed my mapping to this:
vnoremap <Leader>es :<c-u>exec join(getline("'<","'>"),"\n")<CR>
I suppose there is a vim or ex reason why the <BAR> method doesn't work on functions (maybe even some setting I have on?), and I'm curious to hear what it is if someone knows.
I don't want to reload the whole file (:so %) since that will reset a lot of temporary stuff I'm experimenting. I just want to run the two lines that I'm currently working on.
If you want to execute a command because you want to refine it before committing it to _.vimrc, then you should launch a Command Line Window for Ex-mode commands with q:.
At launch the Command Line Window is buffered with the contents of the command line history. It is a normal Vim window the contents of which can be edited as any text buffer with the exception of pressing on any line which executes the command on that line. It is very useful when you want to slightly change a long, complex command you wrote earlier and re-run it.
To launch a 'Command Line Window' for search strings press q/.
!! (shorthand for :.!) executes the current line as input to a command, per POSIX ex & vi. You may need to append sh if it is a system command.
Executing !! on a blank line (and omitting sh) is a shortcut for reading a shell command straight into the buffer. By it's nature :.! overwrites the current line while :.r! inserts on the line below.
ls -A | head -n +4
~
~
!sh
Results:
.sh_history
.sh_logout
.kshrc
corelist.txt
~
~
4 lines added; 1 line deleted`
This means there is no need to redirect pipelines to a file and then examine the data to see if the contents are valid. Just execute commands in vi directly and undo if you make a mistake.
Alternately, yanking a line as a named buffer allows you to execute it as an ex command, almost like a macro. You can still edit and undo the line to get it correct instead of trying to edit the : line in command mode.
The functions recommended here are all POSIX and have been supported for over 40 years, so no special vim or other enhanced features are required.
:%s/meep/pEEp/ | g/foo/ s//BAR
foo
grok
meep
~
~
Yank the ex command (line 1, :%s...) into a named buffer / macro.
I just use the label m for "macro".
"myy
or
:1y m
Now execute the named buffer / macro, in command mode, using #:
#m
Results:
:%s/pEEp/pEEp/ | g/BAR / s//BAR
BAR
grok
pEEp
~
~
4 lines changed
But remember that "multiple undo" is not POSIX. undo is only a toggle between undo and redo in a "historically accurate & compliant" ex / vi implementation.
The work-around is to save to a temporary (or valid) file name before executing a questionable edit:
:w $$.tmp
Then just :e! to "reset and reload" if needed.
You can also use :pre (preserve) to make a special temporary backup file prior to making multiple changes.
Then use :reco! % (recover this!) to restore back to that point.
Realize that :preserve creates a snapshot-like file which is deleted as soon as it is rolled back to. It does not matter if you save the edit(s) or not.
Therefore writing your own file (:w ...) and restoring with :e! may still have value because the system will not automatically delete it.
:pre is perfect when you should have ran sudo vi ... or otherwise do not have the necessary permissions - but you only realized the mistake after making several changes. i.e. vi /etc/sudoers instead of sudo vi /etc/sudoers.
^^ NEVER DO THIS! ONLY AN EXAMPLE! USE sudo visudo INSTEAD!
You can get a list of existing recovery files with vi -r and recover one directly with vi -r filename as needed, optionally with something like sudo vi -r filename.
The distinction here is that even though the ":preserved file" has it's own "special" name and path internally, it will :write to the original, intended location when ":recovered ==> /etc/sudoers
Just be sure to use :wq! and not something like ZZ when done with your "recovery" or you will still lose the edits which you tried to save.
By the way, ^R is expected to redraw or repaint the display per POSIX; it is not "undo" in any compliant vi implementation.

Resources