]> ruderich.org/simon Gitweb - config/dotfiles.git/blob - autoload/screenpaste.vim
shell: set GOTOOLCHAIN=local
[config/dotfiles.git] / autoload / screenpaste.vim
1 " These functions are used by the screenpaste plugin.
2 " $Id: screenpaste.vim,v 1bdf402abcdd 2008-10-30 16:27 +0100 blacktrash $
3
4 " Script Vars: characters to be escaped on cmdline {{{1
5 " static:
6
7 " dynamic:
8 " these contain the current values for cmdline conversion, and,
9 " at startup, are set to the values corresponding to 'noesc'
10 " because for 'search' and 'sub' Screen_ClConfig is called with
11 " the current value of screen_clmode everytime Screen_CPut is called
12 " with the purpose to adapt to current setting of 'magic'
13 let s:cl_esc = ''
14 let s:cl_eol = '\\n'
15
16 " Function: Screen_ClCfgComplete for cmdline-completion {{{1
17 function! screenpaste#Screen_ClCfgComplete(A, L, P)
18   return "search\nsub\nnoesc"
19 endfunction
20
21 " Function: Screen_ClConfig configures cmdline insertion {{{1
22 " variables configured here and used by Screen_CPut function:
23 " global:
24 " g:screen_clmode     cmdline behaviour
25 " internal:
26 " s:cl_eol            eol-conversion
27 " s:cl_esc            character group pattern to be escaped
28 " s:esc_info          displays escaped characters
29 " s:eol_info          displays eol-conversion
30
31 function! screenpaste#Screen_ClConfig(mod, msg)
32   if a:mod !~# '^\%(s\%(earch\|ub\)\|noesc\)$'
33     echohl WarningMsg
34     echon "`" a:mod "': invalid value for screen_clmode\n"
35           \ "use one of: search | sub | noesc"
36     echohl None
37     return ""
38   endif
39  
40   " patterns and strings (for user info)
41   let l:esc_search_ma    = '][/\^$*.~'
42   let l:esc_search_noma  = ']/\^$'
43   let l:esc_sub_ma       = '/\~&'
44   let l:esc_sub_noma     = '/\'
45   let l:info_search_ma   = "] [ / \\ ^ $ ~ * . (magic)"
46   let l:info_search_noma = "] / \\ ^ $ (nomagic)"
47   let l:info_sub_ma      = "/ \\ ~ & (magic)"
48   let l:info_sub_noma    = "/ \\ (nomagic)"
49   " dict vars
50   let l:cl_esc_dict = {
51         \ "search": {0: l:esc_search_noma, 1: l:esc_search_ma},
52         \ "sub":    {0: l:esc_sub_noma,    1: l:esc_sub_ma   },
53         \ "noesc":  {0: '',                1: ''             }
54         \ }
55   let l:cl_info_dict = {
56         \ "search": {0: l:info_search_noma, 1: l:info_search_ma},
57         \ "sub"   : {0: l:info_sub_noma,    1: l:info_sub_ma   },
58         \ "noesc" : {0: 'none',             1: 'none'          }
59         \ }
60   let l:eol_conv_dict =
61         \ {"search": '\\n', "sub": '\\r', "noesc": '\\n'}
62   let l:eol_info_dict =
63         \ {"search": '\n', "sub": '\r', "noesc": '\n'}
64
65   let g:screen_clmode = a:mod
66   let s:cl_esc   =   l:cl_esc_dict[g:screen_clmode][&magic]
67   let s:esc_info =  l:cl_info_dict[g:screen_clmode][&magic]
68   let s:cl_eol   = l:eol_conv_dict[g:screen_clmode]
69   let s:eol_info = l:eol_info_dict[g:screen_clmode]
70   if a:msg
71     echon "set '" g:screen_clmode "' "
72           \ "for Screen buffer insertion in cmdline:\n"
73           \ "eol-conversion to literal " s:eol_info "\n"
74           \ "escaped characters        " s:esc_info
75   endif
76 endfunction
77 " }}}1
78 " ============================================================================
79 " Function: Screen_Yank snatches current Screen buffer {{{1
80 " Function: Screen_ReadBuf subroutine returns Screen buffer as text {{{2
81
82 function! s:Screen_ReadBuf(screen_tmpfile)
83   if !filereadable(a:screen_tmpfile)
84     " wait in case screen is late in writing screen-exchange file
85     execute "sleep" g:screen_wait
86   endif
87   try
88     return join(readfile(a:screen_tmpfile, "b"), "\n")
89   catch /^Vim\%((\a\+)\)\=:E484/
90     " Screen buffer empty, no tmpfile created
91     return ""
92   endtry
93 endfunction
94 " }}}2
95
96 function! screenpaste#Screen_Yank(...)
97   let l:screen_tmpfile = tempname()
98   call system(g:screen_executable." -X writebuf ".l:screen_tmpfile)
99   if !a:0
100     return <SID>Screen_ReadBuf(l:screen_tmpfile)
101   else
102     let l:screen_buf = <SID>Screen_ReadBuf(l:screen_tmpfile)
103     if strlen(l:screen_buf)
104       if strlen(a:1)
105         call setreg(a:1, l:screen_buf)
106       else
107         call setreg(g:screen_register, l:screen_buf)
108       endif
109       return 1
110     elseif g:screen_register =~ '\u'
111       " do nothing
112       return 1
113     else
114       echohl WarningMsg
115       echo "Screen buffer is empty"
116       echohl None
117       return 0
118     endif
119   endif
120 endfunction
121
122 " Function: Screen_NPut pastes in normal mode {{{1
123 function! screenpaste#Screen_NPut(p)
124   if screenpaste#Screen_Yank(g:screen_register)
125     execute 'normal! "'.g:screen_register.a:p
126   endif
127 endfunction
128
129 " Function: Screen_IPut pastes in insert mode {{{1
130
131 " Function: Screen_TwRestore subroutine restores 'paste' {{{2
132 " helper function, only called right after Screen_IPut
133 " because Screen_IPut must return result before
134 " being able to restore paste its previous value
135 function! screenpaste#Screen_TwRestore()
136   let &paste = s:curr_paste
137   return ""
138 endfunction
139 " }}}2
140
141 function! screenpaste#Screen_IPut()
142   let s:curr_paste = &paste
143   let &paste = 1
144   let l:screen_buf = screenpaste#Screen_Yank()
145   return l:screen_buf
146 endfunction
147
148 " Function: Screen_VPut pastes in visual mode {{{1
149 function! screenpaste#Screen_VPut(go)
150   if screenpaste#Screen_Yank(g:screen_register)
151     if g:screen_register =~ '["@]'
152       " we have to use another register because
153       " visual selection is deleted into unnamed register
154       let l:store_reg = @z
155       let @z = @"
156       let g:screen_register = "z"
157     endif
158     execute 'normal! gv"'.g:screen_register.a:go.'p'
159     if g:screen_visualselect
160       execute "normal! `[".visualmode()."`]"
161     endif
162     if exists("l:store_reg")
163       let g:screen_register = '"'
164       let @0 = @z
165       let @z = l:store_reg
166     endif
167   else
168     " reset visual after showing message for 3 secs
169     sleep 3
170     execute "normal! gv"
171   endif
172 endfunction
173
174 " Function: Screen_PutCommand is called from :ScreenPut {{{1
175 function! screenpaste#Screen_PutCommand(line, bang, reg)
176   if !strlen(a:reg)
177     let l:reg = g:screen_register
178   else
179     let l:reg = a:reg
180   endif
181   if screenpaste#Screen_Yank(l:reg)
182     if a:line
183       execute a:line "put".a:bang l:reg
184     else
185       execute "put".a:bang l:reg
186     endif
187   endif
188 endfunction
189
190 " Function: Screen_CPut pastes in cmdline according to cmdtype {{{1
191 function! screenpaste#Screen_CPut()
192   " automatically adapt 'screen_clmode' to cmdtype if possible
193   " or instant paste in case of :insert or :append
194   let l:cmdtype = getcmdtype()
195   if l:cmdtype == '-' && exists("$STY")
196     " Screen call needed for :insert and :append commands in Screen_CPut
197     " using slowpaste avoids need for manual redraw
198     let l:screen_slowpaste =
199           \ g:screen_executable." -X slowpaste 10;".
200           \ g:screen_executable." -X paste .;".
201           \ g:screen_executable." -X slowpaste 0"
202     " :insert, :append inside Screen session
203     call system(l:screen_slowpaste)
204     return ""
205   endif
206   " store current cmdline behaviour
207   let l:save_clmode = g:screen_clmode
208   " detect cmdtype if not 'noesc'
209   if g:screen_clmode != "noesc"
210     if l:cmdtype =~ '[/?]'
211       " search: always call config to adapt to 'magic'
212       call screenpaste#Screen_ClConfig("search", 0)
213     elseif l:cmdtype =~ '[@-]'
214       " input() or :insert, :append outside Screen session
215       call screenpaste#Screen_ClConfig("noesc", 0)
216     else
217       " search, sub: always call config to adapt to 'magic'
218       call screenpaste#Screen_ClConfig(g:screen_clmode, 0)
219     endif
220   endif
221   " escape chars in Screen buffer for cmdline
222   let l:screen_buf = screenpaste#Screen_Yank()
223   if strlen(s:cl_esc)
224     let l:screen_buf = escape(l:screen_buf, s:cl_esc)
225   endif
226   let l:screen_buf = substitute(l:screen_buf, "\<C-J>", s:cl_eol, 'g')
227   " restore global 'screen_clmode' if changed
228   if l:save_clmode != g:screen_clmode
229     call screenpaste#Screen_ClConfig(l:save_clmode, 0)
230   endif
231   return l:screen_buf
232 endfunction
233 " }}}1
234 " EOF vim600: set foldmethod=marker: