2 " Function: Perform an Ex command on a visual highlighted block (CTRL-V).
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)
11 " ---------------------------------------------------------------------
13 " Requires: Requires 6.0 or later (this script is a plugin)
14 " Requires <cecutil.vim> (see :he vis-required)
16 " Usage: Mark visual block (CTRL-V) or visual character (v),
17 " press ':B ' and enter an Ex command [cmd].
19 " ex. Use ctrl-v to visually mark the block then use
20 " :B cmd (will appear as :'<,'>B cmd )
22 " ex. Use v to visually mark the block then use
23 " :B cmd (will appear as :'<,'>B cmd )
25 " Command-line completion is supported for Ex commands.
27 " Note: There must be a space before the '!' when invoking external shell
28 " commands, eg. ':B !sort'. Otherwise an error is reported.
30 " Author: Charles E. Campbell <NdrchipO@ScampbellPfamily.AbizM> - NOSPAM
31 " Based on idea of Stefan Roemer <roemer@informatik.tu-muenchen.de>
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")
41 let g:loaded_vis = "v18"
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>)
52 " Suggested by Hari --
53 vn // <esc>/<c-r>=<SID>VisBlockSearch()<cr>
54 vn ?? <esc>?<c-r>=<SID>VisBlockSearch()<cr>
56 " ---------------------------------------------------------------------
57 " Support Functions: {{{1
58 " ------------------------------------------------------------------------------
60 fun! <SID>VisBlockCmd(cmd) range
61 " call Dfunc("VisBlockCmd(cmd<".a:cmd.">")
63 " retain and re-use same visual mode
65 let curposn = SaveWinPosn()
66 let vmode = visualmode()
67 " call Decho("vmode<".vmode.">")
69 " save options which otherwise may interfere
73 let keep_magic = &magic
85 " Save any contents in register a
89 " call Decho("cmd<".a:cmd.">")
93 " Initialize so begcol<endcol for non-v modes
94 let begcol = s:VirtcolM1("<")
95 let endcol = s:VirtcolM1(">")
98 let begcol = s:VirtcolM1(">")
99 let endcol = s:VirtcolM1("<")
103 " Initialize so that begline<endline
104 let begline = a:firstline
105 let endline = a:lastline
107 let begline = a:lastline
108 let endline = a:firstline
110 " call Decho('beg['.begline.','.begcol.'] end['.endline.','.endcol.']')
112 " =======================
113 " Modify Selected Region:
114 " =======================
115 " 1. delete selected region into register "a
116 " call Decho("delete selected region into register a")
119 " 2. put cut-out text at end-of-file
120 " call Decho("put cut-out text at end-of-file")
123 let lastline= line("$")
125 " call Decho("reg-A<".@a.">")
127 " 3. apply command to those lines
128 " call Decho("apply command to those lines")
131 " 4. visual-block select the modified text in those lines
132 " call Decho("visual-block select modified text at end-of-file")
134 exe "norm! 0".vmode."G$\"ad"
136 " 5. delete excess lines
137 " call Decho("delete excess lines")
138 silent exe lastline.',$d'
140 " 6. put modified text back into file
141 " call Decho("put modifed text back into file (beginning=".begline.".".begcol.")")
144 exe 'norm! '.begcol."\<bar>\"ap"
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
157 silent exe 'norm! '.begcol."\<bar>".vmode
159 silent exe 'norm! '.endcol."\<bar>\<esc>"
161 silent exe 'norm! '.begcol."\<bar>"
164 " restore register a and options
165 " call Decho("restore register a, options, and window pos'n")
173 call RestoreWinPosn(curposn)
175 " call Dret("VisBlockCmd")
178 " ------------------------------------------------------------------------------
179 " VisBlockSearch: {{{2
180 fun! <SID>VisBlockSearch(...) range
181 " call Dfunc("VisBlockSearch() a:0=".a:0." lines[".a:firstline.",".a:lastline."]")
185 if a:0 >= 1 && strlen(a:1) > 0
187 let s:pattern = pattern
188 " call Decho("a:0=".a:0.": pattern<".pattern.">")
189 elseif exists("s:pattern")
190 let pattern= s:pattern
193 let s:pattern = pattern
195 let vmode= visualmode()
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)
204 if(firstline > lastline)
205 let firstline = line("'>")
206 let lastline = line("'<")
215 " call Decho("2: firstline=".firstline." lastline=".lastline." firstcolm1=".firstcolm1." lastcolm1=".lastcolm1)
218 if firstcolm1 > lastcolm1
220 let firstcolm1 = lastcolm1
224 " call Decho("3: firstline=".firstline." lastline=".lastline." firstcolm1=".firstcolm1." lastcolm1=".lastcolm1)
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)
233 " construct search string
235 let srch= '\%(\%>'.firstlinem1.'l\%<'.lastlinep1.'l\)\&'
236 " call Decho("V srch: ".srch)
238 if firstline == lastline || firstline == lastlinep1
239 let srch= '\%(\%'.firstline.'l\%>'.firstcolm1.'v\%<'.lastcolp1.'v\)\&'
241 let srch= '\%(\%(\%'.firstline.'l\%>'.firstcolm1.'v\)\|\%(\%'.lastline.'l\%<'.lastcolp1.'v\)\|\%(\%>'.firstline.'l\%<'.lastline.'l\)\)\&'
243 " call Decho("v srch: ".srch)
245 let srch= '\%(\%>'.firstlinem1.'l\%>'.firstcolm1.'v\%<'.lastlinep1.'l\%<'.lastcolp1.'v\)\&'
246 " call Decho("^v srch: ".srch)
251 " call Decho("Search forward: <".srch.pattern.">")
252 call search(srch.pattern)
256 " call Decho("Search backward: <".srch.pattern.">")
257 call search(srch.pattern,a:2)
264 " call Dret("VisBlockSearch <".srch.">")
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
274 if virtcol(mark) <= 1
275 " call Dret("VirtcolM1 0")
280 " works around a ve=all vs ve=block difference with virtcol()
282 " call Decho("temporarily setting ve=all")
285 " call Decho("exe norm! `".a:mark."h")
286 exe "norm! `".a:mark."h"
289 let vc = virtcol(".")
292 " call Dret("VirtcolM1 ".vc)
298 " ------------------------------------------------------------------------------