@@ -57,7 +57,7 @@ endfunction
57
57
58
58
" }}}1
59
59
60
- " Wrapping functions {{{1
60
+ " Wrapping/unwrapping functions {{{1
61
61
62
62
function ! s: extractbefore (str)
63
63
if a: str = ~ ' \r'
@@ -75,6 +75,23 @@ function! s:extractafter(str)
75
75
endif
76
76
endfunction
77
77
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
+
78
95
function ! s: fixindent (str,spc )
79
96
let str = substitute (a: str ,' \t' ,repeat (' ' ,&sw ),' g' )
80
97
let spc = substitute (a: spc ,' \t' ,repeat (' ' ,&sw ),' g' )
@@ -148,13 +165,9 @@ function! s:wrap(string,char,type,removed,special)
148
165
let before = ' '
149
166
let after = ' '
150
167
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 )
154
169
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 )
158
171
elseif newchar == # " p"
159
172
let before = " \n "
160
173
let after = " \n\n "
@@ -306,6 +319,45 @@ function! s:wrapreg(reg,char,removed,special)
306
319
let new = s: wrap (orig,a: char ,type ,a: removed ,a: special )
307
320
call setreg (a: reg ,new ,type )
308
321
endfunction
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
+ " searchpair()'s 'c' flag matches both start and end.
331
+ " Append '\zs' to the closer pattern so that it doesn't match the closer on the cursor.
332
+ let found = searchpair (before_pat, ' ' , after_pat.' \zs' , ' bcW' )
333
+ if found <= 0
334
+ return [' ' ,' ' ]
335
+ endif
336
+ " Handle count/nesting only for asymmetric surroundings
337
+ if before !=# after
338
+ for _ in range (a: count - 1 )
339
+ let found = searchpair (before_pat, ' ' , after_pat, ' bW' )
340
+ if found <= 0
341
+ return [' ' ,' ' ]
342
+ endif
343
+ endfor
344
+ endif
345
+ norm! v
346
+ if before == # after
347
+ call search (before_pat, ' ceW' )
348
+ let found = search (after_pat, ' eW' )
349
+ else
350
+ let found = searchpair (before_pat, ' ' , after_pat, ' W' )
351
+ call search (after_pat, ' ceW' )
352
+ endif
353
+ if found <= 0
354
+ exe " norm! \<Esc> "
355
+ return [' ' ,' ' ]
356
+ endif
357
+ norm! d
358
+ return [before, after]
359
+ endfunction
360
+
309
361
" }}}1
310
362
311
363
function ! s: insert (... ) " {{{1
@@ -380,11 +432,12 @@ function! s:dosurround(...) " {{{1
380
432
let char = strpart (char,1 )
381
433
let spc = 1
382
434
endif
383
- if char == ' a'
384
- let char = ' >'
385
- endif
386
- if char == ' r'
387
- let char = ' ]'
435
+ if ! exists (" b:surround_" .char2nr (char)) && ! exists (" g:surround_" .char2nr (char))
436
+ if char == ' a'
437
+ let char = ' >'
438
+ elseif char == ' r'
439
+ let char = ' ]'
440
+ endif
388
441
endif
389
442
let newchar = " "
390
443
if a: 0 > 1
@@ -405,6 +458,10 @@ function! s:dosurround(...) " {{{1
405
458
let strcount = (scount == 1 ? " " : scount)
406
459
if char == ' /'
407
460
exe ' norm! ' .strcount.' [/d' .strcount.' ]/'
461
+ elseif exists (" b:surround_" .char2nr (char))
462
+ let [before, after] = s: deletecustom (char, 1 , scount)
463
+ elseif exists (" g:surround_" .char2nr (char))
464
+ let [before, after] = s: deletecustom (char, 0 , scount)
408
465
elseif char = ~# ' [[:punct:][:space:]]' && char !~# ' [][(){}<>"'' `]'
409
466
exe ' norm! T' .char
410
467
if getline (' .' )[col (' .' )-1 ] == char
@@ -426,7 +483,10 @@ function! s:dosurround(...) " {{{1
426
483
endif
427
484
let oldline = getline (' .' )
428
485
let oldlnum = line (' .' )
429
- if char == # " p"
486
+ if exists (" b:surround_" .char2nr (char)) || exists (" g:surround_" .char2nr (char))
487
+ call setreg (' "' , before.after, " c" )
488
+ let keeper = substitute (substitute (keeper,' \v\C^' .s: escape (before).' \s=' ,' ' ,' ' ), ' \v\C\s=' .s: escape (after).' $' , ' ' ,' ' )
489
+ elseif char == # " p"
430
490
call setreg (' "' ,' ' ,' V' )
431
491
elseif char == # " s" || char == # " w" || char == # " W"
432
492
" Do nothing
0 commit comments