vim updates
[~madcoder/dotfiles.git] / vim / plugin / vis.vim
1 " vis.vim:
2 " Function:     Perform an Ex command on a visual highlighted block (CTRL-V).
3 " Version:      18
4 " Date:         Aug 26, 2005
5 " GetLatestVimScripts: 1066 1 cecutil.vim
6 " GetLatestVimScripts: 1195 1 :AutoInstall: vis.vim
7 " Verse: For am I now seeking the favor of men, or of God? Or am I striving
8 " to please men? For if I were still pleasing men, I wouldn't be a servant
9 " of Christ. (Gal 1:10, WEB)
10
11 " ---------------------------------------------------------------------
12 "  Details: {{{1
13 " Requires: Requires 6.0 or later  (this script is a plugin)
14 "           Requires <cecutil.vim> (see :he vis-required)
15 "
16 " Usage:    Mark visual block (CTRL-V) or visual character (v),
17 "           press ':B ' and enter an Ex command [cmd].
18 "
19 "           ex. Use ctrl-v to visually mark the block then use
20 "                 :B cmd     (will appear as   :'<,'>B cmd )
21 "
22 "           ex. Use v to visually mark the block then use
23 "                 :B cmd     (will appear as   :'<,'>B cmd )
24 "
25 "           Command-line completion is supported for Ex commands.
26 "
27 " Note:     There must be a space before the '!' when invoking external shell
28 "           commands, eg. ':B !sort'. Otherwise an error is reported.
29 "
30 " Author:   Charles E. Campbell <NdrchipO@ScampbellPfamily.AbizM> - NOSPAM
31 "           Based on idea of Stefan Roemer <roemer@informatik.tu-muenchen.de>
32 "
33 " ------------------------------------------------------------------------------
34 " Initialization: {{{1
35 " Exit quickly when <Vis.vim> has already been loaded or
36 " when 'compatible' is set
37 if &cp || exists("g:loaded_vis")
38   finish
39 endif
40 let s:keepcpo    = &cpo
41 let g:loaded_vis = "v18"
42 set cpo&vim
43
44 " ------------------------------------------------------------------------------
45 " Public Interface: {{{1
46 "  -range       : VisBlockCmd operates on the range itself
47 "  -com=command : Ex command and arguments
48 "  -nargs=+     : arguments may be supplied, up to any quantity
49 com! -range -nargs=+ -com=command    B  silent <line1>,<line2>call s:VisBlockCmd(<q-args>)
50 com! -range -nargs=* -com=expression S  silent <line1>,<line2>call s:VisBlockSearch(<q-args>)
51
52 " Suggested by Hari --
53 vn // <esc>/<c-r>=<SID>VisBlockSearch()<cr>
54 vn ?? <esc>?<c-r>=<SID>VisBlockSearch()<cr>
55
56 " ---------------------------------------------------------------------
57 "  Support Functions: {{{1
58 " ------------------------------------------------------------------------------
59 " VisBlockCmd: {{{2
60 fun! <SID>VisBlockCmd(cmd) range
61 "  call Dfunc("VisBlockCmd(cmd<".a:cmd.">")
62
63   " retain and re-use same visual mode
64   norm `<
65   let curposn = SaveWinPosn()
66   let vmode   = visualmode()
67 "  call Decho("vmode<".vmode.">")
68
69   " save options which otherwise may interfere
70   let keep_lz    = &lz
71   let keep_fen   = &fen
72   let keep_ic    = &ic
73   let keep_magic = &magic
74   let keep_sol   = &sol
75   let keep_ve    = &ve
76   let keep_ww    = &ww
77   set lz
78   set magic
79   set nofen
80   set noic
81   set nosol
82   set ve=
83   set ww=
84
85   " Save any contents in register a
86   let rega= @a
87
88   if vmode == 'V'
89 "   call Decho("cmd<".a:cmd.">")
90    exe "'<,'>".a:cmd
91   else
92
93    " Initialize so begcol<endcol for non-v modes
94    let begcol   = s:VirtcolM1("<")
95    let endcol   = s:VirtcolM1(">")
96    if vmode != 'v'
97     if begcol > endcol
98      let begcol  = s:VirtcolM1(">")
99      let endcol  = s:VirtcolM1("<")
100     endif
101    endif
102
103    " Initialize so that begline<endline
104    let begline  = a:firstline
105    let endline  = a:lastline
106    if begline > endline
107     let begline = a:lastline
108     let endline = a:firstline
109    endif
110 "   call Decho('beg['.begline.','.begcol.'] end['.endline.','.endcol.']')
111
112    " =======================
113    " Modify Selected Region:
114    " =======================
115    " 1. delete selected region into register "a
116 "   call Decho("delete selected region into register a")
117    norm! gv"ad
118
119    " 2. put cut-out text at end-of-file
120 "   call Decho("put cut-out text at end-of-file")
121    $
122    pu_
123    let lastline= line("$")
124    silent norm! "ap
125 "   call Decho("reg-A<".@a.">")
126
127    " 3. apply command to those lines
128 "   call Decho("apply command to those lines")
129    exe '.,$'.a:cmd
130
131    " 4. visual-block select the modified text in those lines
132 "   call Decho("visual-block select modified text at end-of-file")
133    exe lastline
134    exe "norm! 0".vmode."G$\"ad"
135
136    " 5. delete excess lines
137 "   call Decho("delete excess lines")
138    silent exe lastline.',$d'
139
140    " 6. put modified text back into file
141 "   call Decho("put modifed text back into file (beginning=".begline.".".begcol.")")
142    exe begline
143    if begcol > 1
144     exe 'norm! '.begcol."\<bar>\"ap"
145    elseif begcol == 1
146     norm! 0"ap
147    else
148     norm! 0"aP
149    endif
150
151    " 7. attempt to restore gv -- this is limited, it will
152    " select the same size region in the same place as before,
153    " not necessarily the changed region
154    let begcol= begcol+1
155    let endcol= endcol+1
156    silent exe begline
157    silent exe 'norm! '.begcol."\<bar>".vmode
158    silent exe endline
159    silent exe 'norm! '.endcol."\<bar>\<esc>"
160    silent exe begline
161    silent exe 'norm! '.begcol."\<bar>"
162   endif
163
164   " restore register a and options
165 "  call Decho("restore register a, options, and window pos'n")
166   let @a  = rega
167   let &lz = keep_lz
168   let &fen= keep_fen
169   let &ic = keep_ic
170   let &sol= keep_sol
171   let &ve = keep_ve
172   let &ww = keep_ww
173   call RestoreWinPosn(curposn)
174
175 "  call Dret("VisBlockCmd")
176 endfun
177
178 " ------------------------------------------------------------------------------
179 " VisBlockSearch: {{{2
180 fun! <SID>VisBlockSearch(...) range
181 "  call Dfunc("VisBlockSearch() a:0=".a:0." lines[".a:firstline.",".a:lastline."]")
182   let keepic= &ic
183   set noic
184
185   if a:0 >= 1 && strlen(a:1) > 0
186    let pattern   = a:1
187    let s:pattern = pattern
188 "   call Decho("a:0=".a:0.": pattern<".pattern.">")
189   elseif exists("s:pattern")
190    let pattern= s:pattern
191   else
192    let pattern   = @/
193    let s:pattern = pattern
194   endif
195   let vmode= visualmode()
196
197   " collect search restrictions
198   let firstline  = line("'<")
199   let lastline   = line("'>")
200   let firstcolm1 = s:VirtcolM1("<")
201   let lastcolm1  = s:VirtcolM1(">")
202 "  call Decho("1: firstline=".firstline." lastline=".lastline." firstcolm1=".firstcolm1." lastcolm1=".lastcolm1)
203
204   if(firstline > lastline)
205    let firstline = line("'>")
206    let lastline  = line("'<")
207    if a:0 >= 1
208     norm! `>
209    endif
210   else
211    if a:0 >= 1
212     norm! `<
213    endif
214   endif
215 "  call Decho("2: firstline=".firstline." lastline=".lastline." firstcolm1=".firstcolm1." lastcolm1=".lastcolm1)
216
217   if vmode != 'v'
218    if firstcolm1 > lastcolm1
219         let tmp        = firstcolm1
220         let firstcolm1 = lastcolm1
221         let lastcolm1  = tmp
222    endif
223   endif
224 "  call Decho("3: firstline=".firstline." lastline=".lastline." firstcolm1=".firstcolm1." lastcolm1=".lastcolm1)
225
226   let firstlinem1 = firstline  - 1
227   let lastlinep1  = lastline   + 1
228   let firstcol    = firstcolm1 + 1
229   let lastcol     = lastcolm1  + 1
230   let lastcolp1   = lastcol    + 1
231 "  call Decho("4: firstline=".firstline." lastline=".lastline." firstcolm1=".firstcolm1." lastcolp1=".lastcolp1)
232
233   " construct search string
234   if vmode == 'V'
235    let srch= '\%(\%>'.firstlinem1.'l\%<'.lastlinep1.'l\)\&'
236 "   call Decho("V  srch: ".srch)
237   elseif vmode == 'v'
238    if firstline == lastline || firstline == lastlinep1
239         let srch= '\%(\%'.firstline.'l\%>'.firstcolm1.'v\%<'.lastcolp1.'v\)\&'
240    else
241     let srch= '\%(\%(\%'.firstline.'l\%>'.firstcolm1.'v\)\|\%(\%'.lastline.'l\%<'.lastcolp1.'v\)\|\%(\%>'.firstline.'l\%<'.lastline.'l\)\)\&'
242    endif
243 "   call Decho("v  srch: ".srch)
244   else
245    let srch= '\%(\%>'.firstlinem1.'l\%>'.firstcolm1.'v\%<'.lastlinep1.'l\%<'.lastcolp1.'v\)\&'
246 "   call Decho("^v srch: ".srch)
247   endif
248
249   " perform search
250   if a:0 <= 1
251 "   call Decho("Search forward: <".srch.pattern.">")
252    call search(srch.pattern)
253    let @/= srch.pattern
254
255   elseif a:0 == 2
256 "   call Decho("Search backward: <".srch.pattern.">")
257    call search(srch.pattern,a:2)
258    let @/= srch.pattern
259   endif
260
261   " restore ignorecase
262   let &ic= keepic
263
264 "  call Dret("VisBlockSearch <".srch.">")
265   return srch
266 endfun
267
268 " ------------------------------------------------------------------------------
269 " VirtcolM1: usually a virtcol(mark)-1, but due to tabs this can be different {{{2
270 fun! s:VirtcolM1(mark)
271 "  call Dfunc("VirtcolM1(mark ".a:mark.")")
272   let mark   = "'".a:mark
273
274   if virtcol(mark) <= 1
275 "   call Dret("VirtcolM1 0")
276    return 0
277   endif
278
279   if &ve == "block"
280    " works around a ve=all vs ve=block difference with virtcol()
281    set ve=all
282 "   call Decho("temporarily setting ve=all")
283   endif
284
285 "  call Decho("exe norm! `".a:mark."h")
286   exe "norm! `".a:mark."h"
287
288   let vekeep = &ve
289   let vc  = virtcol(".")
290   let &ve = vekeep
291
292 "  call Dret("VirtcolM1 ".vc)
293   return vc
294 endfun
295
296 let &cpo= s:keepcpo
297 unlet s:keepcpo
298 " ------------------------------------------------------------------------------
299 "  Modelines: {{{1
300 " vim: fdm=marker