Prevent Vim from clearing the clipboard on exit - vim

When I open Vim from a terminal, copy some text to the system clipboard, and exit Vim, the system clipboard gets cleared.
How to keep the copied text in the clipboard?

Synthesizing answers from superuser, just add the following to your .vimrc
autocmd VimLeave * call system("xsel -ib", getreg('+'))

Install Parcellite, or glipper for Gnome and klipper for KDE.
Restart your computer or run it manually.
see: https://wiki.ubuntu.com/ClipboardPersistence

Based on Matt's answer, the following uses xclip instead of xsel:
autocmd VimLeave * call system('echo ' . shellescape(getreg('+')) .
\ ' | xclip -selection clipboard')

I ran into this issue and a related problem where suspending vim with ctrl-z would also clear the clipboard. I've extended Matt's solution to fix both:
set clipboard=unnamedplus
if executable("xsel")
function! PreserveClipboard()
call system("xsel -ib", getreg('+'))
endfunction
function! PreserveClipboadAndSuspend()
call PreserveClipboard()
suspend
endfunction
autocmd VimLeave * call PreserveClipboard()
nnoremap <silent> <c-z> :call PreserveClipboadAndSuspend()<cr>
vnoremap <silent> <c-z> :<c-u>call PreserveClipboadAndSuspend()<cr>
endif
The if executable("xsel") guard is there to avoid errors if xsel is not installed. The nnoremap mapping preserves the clipboard when suspending from normal mode and the vnoremap mapping handles suspending from visual or select modes.
I've confirmed this works on vim 7.4 and 8.0.

Use NeoVim. It by default doesn't clear the clipboard on exit. You will still need to set clipboard=unnamedplus (typically in ~/.config/nvim/init.vim) and have xsel or xclip tools installed.
Keep in mind that some other defaults are different as well.

Please correct me if I'm wrong but from my understandings of Vim...
1) Vim uses registers instead of the clipboard to store copied/cut data.
2) These registers are preserved when exiting vim in a status file but are not accessible outside of the running process unless you manually open the file and inspect its contents
3) Saving stuff to the + registre while Vim runs allows you to paste to other applications.
4) By suspending vim (CTRL-Z) instead of closing it, these registers are still accessible.
Does that provide assistance?

Based on Matt's answer
When using his method copying multiple lines added slashes to the end of lines when pasting.
This should remedy that.
autocmd VimLeave * exe ":!echo " . shellescape(getreg('+')) . " | xclip -selection clipboard"
When i used "shellescape" with "system" newlines kept getting escaped. But that didn't happen when i used exe.
Don't know the real reason. but this worked.

Related

I can't paste to vim from external clipboard

I use VIM via termux with and faced with the following ploblem i can't to paste data from external clipboard inside VIM. I checked that my vim installation support pasting from external clipboard via following command
:echo has('clipboard')
#its return me 1 but when
# i trying to paste in vim
#via "+p or "*p or Ctrl V or Ctrl Shift V
It is't paste anything. What i am doing wrong. Is it possible that i can't to paste data which is in Android clipboard
I solved my problem. Vim package in termux have problems with recognizing android clipboard. If you faced with same problem do following.To access android clipboard via vim you should to install Termux-api that allow to accessing some android features than inside VIM type the following command
:r !termux-clipboard-get
You can add short-key mapping for it in .vimrc file just type
nnoremap <C-v> :r !termux-clipboard-get <CR>
Now i can use Ctrl V for paste in Vim
I sent bug report to termux github page that standart short-key "*p isn't working
Add the following in .vimrc
au TextYankPost * call system('termux-clipboard-set &', #")
function Paste(p)
let sysclip=system('termux-clipboard-get')
if sysclip != #"
let #"=sysclip
endif
return a:p
endfunction
noremap <expr> p Paste('p')
noremap <expr> P Paste('P')
This works for all copy, cut, and paste commands, including dw, 2p, etc.

MacOs Terminal Vim Copy to System Clipboard

I am using Homebrew Vim from MacOS Terminal. The problem I am having now is to copy in vim to System Clipboard. I follow the guide online, which told me to use "+y after selection texts in visual mode. However, when I hit the corresponding keys on "+y, the system responds with a sound indicating that such key combination is illegal. What am I doing wrong?
I did what is suggested. Here is what my dot file looks like:
set runtimepath+=~/.vim_runtime
source ~/.vim_runtime/vimrcs/basic.vim
source ~/.vim_runtime/vimrcs/filetypes.vim
source ~/.vim_runtime/vimrcs/plugins_config.vim
source ~/.vim_runtime/vimrcs/extended.vim
try
source ~/.vim_runtime/my_configs.vim
catch
endtry
" Define Key Mapping
inoremap jj <Esc>
set clipboard=unnamedplus
" Run Python file with one command
nnoremap <buffer> <C-M> :exec '!python' shellescape(#%, 1)<cr>
"YouCompleteMe virtual env config
let g:ycm_global_ycm_extra_conf = '~/.vim/.ycm_extra_conf.py'
Further, the :reg does not show the "+ or "* registry.
You can try with add the line:
set clipboard=unnamed
to your .vimrc ^1. For using + you might want to try with set clipboard=unnamedplus.
If you are not sure how to do this, just type in:
cd ~ && echo 'set clipboard=unnamedplus' >> .vimrc
See more information by :h clipboard-unnamedplus.
Notice that this this option works only in vim that is compiled with X11 & clipboard feature.
Regards

force vim to overwrite external changes

I use Vim 7.4 (Mac OS) to edit and run Lua scripts. I've mapped a key in my .vimrc to save the current buffer and run an external script.
The key map in .vimrc:
map V :w!<CR> :!python "$HOME/tools/client/concli.py" --lua %<CR>
It works fine but every once in a while the files are 'touched' by Xcode (touch shell command). Then when I hit the mapped key vim warns me that the file has been changed externally and I have to confirm to write to it.
This is quite annoying since the files are often touched. How could I force vim to overwrite external changes without prompting? I tried 'w!' without success.
Thank you, Laurent
Indeed, the overwrite confirmation cannot be turned off with :w!, and :set autoread doesn't help in this case, neither. What does work is instructing Vim to explicitly check for changes before the write:
:checktime | w
I believe
set autoread
should do it. It tells Vim to automatically re-reads the file changed outside Vim.
I saw this in a mailing list. Apparently it is called if the file has changed timestamp, after a call to an external shell command.
function! ProcessFileChangedShell()
if v:fcs_reason == 'mode' || v:fcs_reason == 'time'
let v:fcs_choice = ''
else
let v:fcs_choice = 'ask'
endif
endfunction
autocmd FileChangedShell call ProcessFileChangedShell()
But it did not consistently fire for me. (Depending whether or not I had edited the file since the change, which in my case was external.)
There are some more tricks on the VimTips wiki which may help.
Add this to your ~/.vimrc file:
set autoread
nnoremap <C-u> :checktime<CR>
Now whenever you want vim to reload external changes, just click CTRL-U :)

How to open pdf files under cursor (using 'gf') with external PDF readers in vim

The current gf command will open *.pdf files as ascii text. I want the pdf file opened with external tools (like okular, foxitreader, etc.). I tried to use autocmd to achieve it like this:
au BufReadCmd *.pdf silent !FoxitReader % & "open file under cursor with FoxitReader
au BufEnter *.pdf <Ctrl-O> "since we do not really open the file, go back to the previous buffer
However, the second autocmd failed to work as expected. I could not figure out a way to execute <Ctrl-o> command in a autocmd way.
Could anyone give me a hint on how to <Ctrl-O> in autocmd, or just directly suggest a better way to open pdf files with gf?
Thanks.
That's because what follows an autocmd is an ex command (the ones beginning
with a colon). To simulate the execution of a normal mode command, use the
:normal command. The problem is that you can't pass a <C-O> (and not
<Ctrl-O>) directly to :normal, it will be taken as literal characters (<,
then C, then r) which is not a very meaningful normal command. You have two
options:
1.Insert a literal ^O Character
Use controlvcontrolo to get one:
au BufEnter *.pdf normal! ^O
2.Use :execute to Build Your Command
This way you can get a more readable result with the escaped sequence:
au BufEnter *.pdf exe "normal! \<c-o>"
Anyway, this is not the most appropriate command. <C-O> just jumps to the
previous location in the jump list, so your buffer remains opened. I would do
something like:
au BufEnter *.pdf bdelete
Instead. Still I have another solution for you.
Create another command with a map, say gO. Then use your PDF reader
directly, or a utility like open if you're in MacOS X or Darwin (not sure if
other Unix systems have it, and how it's called). It's just like double clicking
the icon of the file passed as argument, so it will open your default PDF reader
or any other application configured to open any file by default, like images or
so.
:nnoremap gO :!open <cfile><CR>
This <cfile> will be expanded to the file under the cursor. So if you want to
open the file in Vim, use gf. If you want to open it with the default
application, use gO.
If you don't have this command or prefer a PDF-only solution, create a map to
your preferred command:
:nnoremap gO :!FoxitReader <cfile> &<CR>
If the default app is acceptable, then simply using :!open % in command mode works. You can always map this to a suitable leader combination in your vim config file etc.
If you want something that works with normal mode, then you could try something like the following (i use this too for opening HTML files), and modify to your own needs:
if has('win32') || has ('win64')
autocmd FileType html nmap <Leader>g :silent ! start firefox "%"<cr>
elseif has('mac')
autocmd FileType html nmap <Leader>g :!open "%"<cr><cr>
endif

vim redraw does not redraw on OSX 10.6

I'm trying to open a PDF file from Vim using the commands
let openpdfname = "!open " . expand("%:t:r") . ".pdf"
map <F6> :silent execute openpdfname<CR> | redraw!
The PDF opens up in Preview and all is well, except that the Vim screen is not repainted. I use vim 7.2.108 (shipped standard with OSX 10.6) from the terminal window. I tried removing my ~/.vimrc entirely to try and determine the cause, with no luck.
Hitting Ctrl-L repaints the screen, but I thought 'redraw!' would have the same effect!?
Thanks for any hints!
Move <CR> to the end of mapping. You are trying to execute redraw after you exited command mode. Of course, it does not work.
The correct syntax that does what I expect is:
map <F6> :silent execute openpdfname<CR>:redraw!<CR>
Try this:
map <silent> <F6> :silent execute openpdfname<CR>

Resources