@@ -57,7 +57,7 @@ endfunction
5757
5858" }}}1
5959
60- " Wrapping functions {{{1
60+ " Wrapping/unwrapping functions {{{1
6161
6262function ! s: extractbefore (str)
6363 if a: str = ~ ' \r'
@@ -75,6 +75,23 @@ function! s:extractafter(str)
7575 endif
7676endfunction
7777
78+ if exists (' *trim' )
79+ function ! s: trim (txt) abort
80+ return trim (a: txt )
81+ endfunction
82+ else
83+ function ! s: trim (txt) abort
84+ return substitute (a: txt , ' \%(^\s\+\|\s\+$\)' , ' ' , ' g' )
85+ endfunction
86+ endif
87+
88+ function ! s: customsurroundings (char, b , trim ) abort
89+ let all = s: process (get (a: b ? b: : g: , ' surround_' .char2nr (a: char )))
90+ let before = s: extractbefore (all )
91+ let after = s: extractafter (all )
92+ return a: trim ? [s: trim (before), s: trim (after)] : [before, after]
93+ endfunction
94+
7895function ! s: fixindent (str,spc )
7996 let str = substitute (a: str ,' \t' ,repeat (' ' ,&sw ),' g' )
8097 let spc = substitute (a: spc ,' \t' ,repeat (' ' ,&sw ),' g' )
@@ -148,13 +165,9 @@ function! s:wrap(string,char,type,removed,special)
148165 let before = ' '
149166 let after = ' '
150167 elseif exists (" b:surround_" .char2nr (newchar))
151- let all = s: process (b: surround_ {char2nr (newchar)})
152- let before = s: extractbefore (all )
153- let after = s: extractafter (all )
168+ let [before, after] = s: customsurroundings (newchar, 1 , 0 )
154169 elseif exists (" g:surround_" .char2nr (newchar))
155- let all = s: process (g: surround_ {char2nr (newchar)})
156- let before = s: extractbefore (all )
157- let after = s: extractafter (all )
170+ let [before, after] = s: customsurroundings (newchar, 0 , 0 )
158171 elseif newchar == # " p"
159172 let before = " \n "
160173 let after = " \n\n "
@@ -306,6 +319,43 @@ function! s:wrapreg(reg,char,removed,special)
306319 let new = s: wrap (orig,a: char ,type ,a: removed ,a: special )
307320 call setreg (a: reg ,new ,type )
308321endfunction
322+
323+ function ! s: escape (str) abort
324+ return escape (a: str , ' !#$%&()*+,-./:;<=>?@[\]^{|}~' )
325+ endfunction
326+
327+ function ! s: deletecustom (char, b , count ) abort
328+ let [before, after] = s: customsurroundings (a: char , a: b , 1 )
329+ let [before_pat, after_pat] = [' \v\C' .s: escape (before), ' \v\C' .s: escape (after)]
330+ let found = searchpair (before_pat, ' ' , after_pat, ' bcW' )
331+ if found <= 0
332+ return [' ' ,' ' ]
333+ endif
334+ " Handle count/nesting only for asymmetric surroundings
335+ if before !=# after
336+ for _ in range (a: count - 1 )
337+ let found = searchpair (before_pat, ' ' , after_pat, ' bW' )
338+ if found <= 0
339+ return [' ' ,' ' ]
340+ endif
341+ endfor
342+ endif
343+ norm! v
344+ if before == # after
345+ call search (before_pat, ' ceW' )
346+ let found = search (after_pat, ' eW' )
347+ else
348+ let found = searchpair (before_pat, ' ' , after_pat, ' W' )
349+ call search (after_pat, ' ceW' )
350+ endif
351+ if found <= 0
352+ exe " norm! \<Esc> "
353+ return [' ' ,' ' ]
354+ endif
355+ norm! d
356+ return [before, after]
357+ endfunction
358+
309359" }}}1
310360
311361function ! s: insert (... ) " {{{1
@@ -380,11 +430,12 @@ function! s:dosurround(...) " {{{1
380430 let char = strpart (char,1 )
381431 let spc = 1
382432 endif
383- if char == ' a'
384- let char = ' >'
385- endif
386- if char == ' r'
387- let char = ' ]'
433+ if ! exists (" b:surround_" .char2nr (char)) && ! exists (" g:surround_" .char2nr (char))
434+ if char == ' a'
435+ let char = ' >'
436+ elseif char == ' r'
437+ let char = ' ]'
438+ endif
388439 endif
389440 let newchar = " "
390441 if a: 0 > 1
@@ -405,6 +456,10 @@ function! s:dosurround(...) " {{{1
405456 let strcount = (scount == 1 ? " " : scount)
406457 if char == ' /'
407458 exe ' norm! ' .strcount.' [/d' .strcount.' ]/'
459+ elseif exists (" b:surround_" .char2nr (char))
460+ let [before, after] = s: deletecustom (char, 1 , scount)
461+ elseif exists (" g:surround_" .char2nr (char))
462+ let [before, after] = s: deletecustom (char, 0 , scount)
408463 elseif char = ~# ' [[:punct:][:space:]]' && char !~# ' [][(){}<>"'' `]'
409464 exe ' norm! T' .char
410465 if getline (' .' )[col (' .' )-1 ] == char
@@ -438,6 +493,9 @@ function! s:dosurround(...) " {{{1
438493 norm! " _x
439494 call setreg (' "' ,' /**/' ," c" )
440495 let keeper = substitute (substitute (keeper,' ^/\*\s\=' ,' ' ,' ' ),' \s\=\*$' ,' ' ,' ' )
496+ elseif exists (" b:surround_" .char2nr (char)) || exists (" g:surround_" .char2nr (char))
497+ call setreg (' "' , before.after, " c" )
498+ let keeper = substitute (substitute (keeper,' \v\C^' .s: escape (before).' \s=' ,' ' ,' ' ), ' \v\C\s=' .s: escape (after).' $' , ' ' ,' ' )
441499 elseif char = ~# ' [[:punct:][:space:]]' && char !~# ' [][(){}<>]'
442500 exe ' norm! F' .char
443501 exe ' norm! df' .char
0 commit comments