360 lines
7.9 KiB
VimL
360 lines
7.9 KiB
VimL
" fakeclip - pseude clipboard register for non-GUI version of Vim
|
|
" Version: 0.2.10
|
|
" Copyright (C) 2008-2012 Kana Natsuno <http://whileimautomaton.net/>
|
|
" License: So-called MIT/X license {{{
|
|
" Permission is hereby granted, free of charge, to any person obtaining
|
|
" a copy of this software and associated documentation files (the
|
|
" "Software"), to deal in the Software without restriction, including
|
|
" without limitation the rights to use, copy, modify, merge, publish,
|
|
" distribute, sublicense, and/or sell copies of the Software, and to
|
|
" permit persons to whom the Software is furnished to do so, subject to
|
|
" the following conditions:
|
|
"
|
|
" The above copyright notice and this permission notice shall be included
|
|
" in all copies or substantial portions of the Software.
|
|
"
|
|
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
" IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
" CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
" TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
" SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
" }}}
|
|
" Platform detection "{{{1
|
|
|
|
if has('macunix') || system('uname') =~? '^darwin'
|
|
let s:PLATFORM = 'mac'
|
|
elseif has('win32unix')
|
|
let s:PLATFORM = 'cygwin'
|
|
elseif $DISPLAY != '' && executable('xclip')
|
|
let s:PLATFORM = 'x'
|
|
else
|
|
let s:PLATFORM = 'unknown'
|
|
endif
|
|
|
|
|
|
if executable('tmux') && $TMUX != ''
|
|
let g:fakeclip_terminal_multiplexer_type = 'tmux'
|
|
elseif executable('screen') && $STY != ''
|
|
let g:fakeclip_terminal_multiplexer_type = 'gnuscreen'
|
|
elseif executable('tmux') && executable('screen')
|
|
if exists('g:fakeclip_terminal_multiplexer_type')
|
|
" Use user-defined value as is.
|
|
else
|
|
let g:fakeclip_terminal_multiplexer_type = 'tmux'
|
|
endif
|
|
elseif executable('tmux') && !executable('screen')
|
|
let g:fakeclip_terminal_multiplexer_type = 'tmux'
|
|
elseif !executable('tmux') && executable('screen')
|
|
let g:fakeclip_terminal_multiplexer_type = 'gnuscreen'
|
|
else
|
|
let g:fakeclip_terminal_multiplexer_type = 'unknown'
|
|
endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
" Interface "{{{1
|
|
function! fakeclip#clipboard_delete(motion_type) "{{{2
|
|
return fakeclip#delete('clipboard', a:motion_type)
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! fakeclip#clipboard_yank(motion_type) "{{{2
|
|
return fakeclip#yank('clipboard', a:motion_type)
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! fakeclip#content(system_type) "{{{2
|
|
return s:read_{a:system_type}()
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! fakeclip#delete(system_type, motion_type) "{{{2
|
|
call s:select_last_motion(a:motion_type)
|
|
execute 'normal!' (a:motion_type == 'V' ? 'D' : 'd')
|
|
call s:write_{a:system_type}(@@)
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! fakeclip#pastebuffer_delete(motion_type) "{{{2
|
|
return fakeclip#delete('pastebuffer', a:motion_type)
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! fakeclip#pastebuffer_yank(motion_type) "{{{2
|
|
return fakeclip#yank('pastebuffer', a:motion_type)
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! fakeclip#put(system_type, motion_type, put_type) "{{{2
|
|
let r_ = s:save_register('"')
|
|
let @@ = fakeclip#content(a:system_type)
|
|
|
|
if a:motion_type == ''
|
|
execute 'normal!' s:count().a:put_type
|
|
call s:restore_register('"', r_)
|
|
else
|
|
call s:select_last_motion(a:motion_type)
|
|
execute 'normal!' s:count().a:put_type
|
|
endif
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! fakeclip#yank(system_type, motion_type) "{{{2
|
|
let r0 = s:save_register('0')
|
|
|
|
call s:select_last_motion(a:motion_type)
|
|
normal! y
|
|
call s:write_{a:system_type}(@@)
|
|
|
|
call s:restore_register('0', r0)
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! fakeclip#yank_Y(system_type) "{{{2
|
|
let diff = s:count() - 1
|
|
normal! V
|
|
if 0 < diff
|
|
execute 'normal!' diff.'j'
|
|
endif
|
|
execute 'normal' (a:system_type ==# 'clipboard'
|
|
\ ? "\<Plug>(fakeclip-Y)"
|
|
\ : "\<Plug>(fakeclip-screen-Y)")
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
" Core "{{{1
|
|
function! s:read_clipboard() "{{{2
|
|
return s:read_clipboard_{s:PLATFORM}()
|
|
endfunction
|
|
|
|
|
|
function! s:read_clipboard_mac()
|
|
return system('pbpaste')
|
|
endfunction
|
|
|
|
|
|
function! s:read_clipboard_cygwin()
|
|
let content = ''
|
|
for line in readfile('/dev/clipboard', 'b')
|
|
let content = content . "\x0A" . substitute(line, "\x0D", '', 'g')
|
|
endfor
|
|
return content[1:]
|
|
endfunction
|
|
|
|
|
|
function! s:read_clipboard_x()
|
|
return system('xclip -o')
|
|
endfunction
|
|
|
|
|
|
function! s:read_clipboard_unknown()
|
|
echoerr 'Getting the clipboard content is not supported on this platform:'
|
|
\ s:PLATFORM
|
|
return ''
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:read_pastebuffer() "{{{2
|
|
return s:read_pastebuffer_{g:fakeclip_terminal_multiplexer_type}()
|
|
endfunction
|
|
|
|
|
|
function! s:read_pastebuffer_gnuscreen()
|
|
let _ = tempname()
|
|
call system('screen -X writebuf ' . shellescape(_))
|
|
" FIXME: Here we have to wait "writebuf" for writing, because the
|
|
" following readfile() may read the temporary file which is not
|
|
" flushed yet -- but, how to wait?
|
|
" call system(printf('while ! test -f %s; do true; done',
|
|
" \ shellescape(_)))
|
|
"
|
|
" NB: "writebuf" creates an empty file if the paste buffer is emptied by
|
|
" "readbuf /dev/null", but it doesn't create any file is the paste
|
|
" buffer is emptied by "register . ''". So here we have to check the
|
|
" existence of the temporary file.
|
|
if exists('g:fakeclip_delay_to_read_pastebuffer_gnuscreen')
|
|
execute 'sleep' g:fakeclip_delay_to_read_pastebuffer_gnuscreen
|
|
endif
|
|
let content = filereadable(_) ? join(readfile(_, 'b'), "\n") : ''
|
|
call delete(_)
|
|
return content
|
|
endfunction
|
|
|
|
|
|
function! s:read_pastebuffer_tmux()
|
|
return system('tmux show-buffer')
|
|
endfunction
|
|
|
|
|
|
function! s:read_pastebuffer_unknown()
|
|
echoerr 'Paste buffer is not available'
|
|
return ''
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:write_clipboard(text) "{{{2
|
|
call s:write_clipboard_{s:PLATFORM}(a:text)
|
|
return
|
|
endfunction
|
|
|
|
|
|
function! s:write_clipboard_mac(text)
|
|
call system('pbcopy', a:text)
|
|
return
|
|
endfunction
|
|
|
|
|
|
function! s:write_clipboard_cygwin(text)
|
|
call writefile(split(a:text, "\x0A", 1), '/dev/clipboard', 'b')
|
|
return
|
|
endfunction
|
|
|
|
|
|
function! s:write_clipboard_x(text)
|
|
call system('xclip', a:text)
|
|
return
|
|
endfunction
|
|
|
|
|
|
function! s:write_clipboard_unknown(text)
|
|
echoerr 'Yanking into the clipboard is not supported on this platform:'
|
|
\ s:PLATFORM
|
|
return
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:write_pastebuffer(text) "{{{2
|
|
let lines = split(a:text, '\n', !0)
|
|
return s:write_pastebuffer_{g:fakeclip_terminal_multiplexer_type}(lines)
|
|
endfunction
|
|
|
|
|
|
function! s:write_pastebuffer_gnuscreen(lines)
|
|
let _ = tempname()
|
|
call writefile(a:lines, _, 'b')
|
|
call system('screen -X readbuf ' . shellescape(_))
|
|
call delete(_)
|
|
return
|
|
endfunction
|
|
|
|
|
|
function! s:write_pastebuffer_tmux(lines)
|
|
let _ = tempname()
|
|
call writefile(a:lines, _, 'b')
|
|
call system('tmux load-buffer ' . shellescape(_))
|
|
call delete(_)
|
|
return
|
|
endfunction
|
|
|
|
|
|
function! s:write_pastebuffer_unknown(lines)
|
|
echoerr 'Paste buffer is not available'
|
|
return
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
" Misc. "{{{1
|
|
function! fakeclip#_local_variables() "{{{2
|
|
return s:
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! fakeclip#_sid_prefix() "{{{2
|
|
nnoremap <SID> <SID>
|
|
return maparg('<SID>', 'n')
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:count() "{{{2
|
|
return (v:count == v:count1) ? v:count : ''
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:restore_register(regname, reginfo) "{{{2
|
|
call setreg(a:regname, a:reginfo[0], a:reginfo[1])
|
|
return
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:save_register(regname) "{{{2
|
|
return [getreg(a:regname), getregtype(a:regname)]
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:select_last_motion(motion_type) "{{{2
|
|
let orig_selection = &selection
|
|
let &selection = 'inclusive'
|
|
|
|
if a:motion_type == 'char'
|
|
normal! `[v`]
|
|
elseif a:motion_type == 'line'
|
|
normal! '[V']
|
|
elseif a:motion_type == 'block'
|
|
execute "normal! `[\<C-v>`]"
|
|
else " invoked from visual mode
|
|
normal! gv
|
|
endif
|
|
|
|
let &selection = orig_selection
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
" __END__ "{{{1
|
|
" vim: foldmethod=marker
|