Skip to content

Commit ca08a4e

Browse files
committed
355: Support deleting/changing custom surrounds
Ported: tpope#355
1 parent 483ed82 commit ca08a4e

File tree

1 file changed

+76
-15
lines changed

1 file changed

+76
-15
lines changed

import/surround.vim

Lines changed: 76 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ def ExtractAfter(str: string): string
3535
return str =~ '\r' ? matchstr(str, '\r\zs.*') : matchstr(str, '\n\zs.*')
3636
enddef
3737

38+
def CustomSurroundings(char: string, d: dict<any>, trim: bool): list<string>
39+
var all = Process(get(d, printf('surround_%d', char2nr(char))))
40+
var before = ExtractBefore(all)
41+
var after = ExtractBefore(all)
42+
43+
return trim ? [trim(before), trim(after)] : [before, after]
44+
enddef
45+
3846
def FixIndent(str: string, spc: string): string
3947
var result = str->substitute('\t', repeat(' ', &sw), 'g')
4048
var spaces = spc->substitute('\t', repeat(' ', &sw), 'g')
@@ -126,14 +134,10 @@ def Wrap(str: string, char: string, wrapType: string, removed: string, linebreak
126134
if newchar == ' '
127135
before = ''
128136
after = ''
129-
elseif exists("b:surround_" .. char2nr(newchar))
130-
var all = Process(b:->get('surround_' .. char2nr(newchar)))
131-
before = ExtractBefore(all)
132-
after = ExtractAfter(all)
133-
elseif exists("g:surround_" .. char2nr(newchar))
134-
var all = Process(g:->get('surround_' .. char2nr(newchar)))
135-
before = ExtractBefore(all)
136-
after = ExtractAfter(all)
137+
elseif !b:->get(custom)->empty()
138+
[before, after] = CustomSurroundings(newchar, b:, false)
139+
elseif !g:->get(custom)->empty()
140+
[before, after] = CustomSurroundings(newchar, g:, false)
137141
elseif newchar ==# "p"
138142
before = "\n"
139143
after = "\n\n"
@@ -316,6 +320,49 @@ def Wrapreg(reg: string, char: string, removed: string, linebreak: bool)
316320
setreg(reg, new, wrapType)
317321
enddef
318322

323+
def Escape(str: string): string
324+
return str->escape('!#$%&()*+,-./:;<=>?@[\]^{|}~')
325+
enddef
326+
327+
def DeleteCustom(char: string, d: dict<any>, count: number): list<string>
328+
var [before, after] = CustomSurroundings(char, d, true)
329+
var [bpat, apat] = ['\v\C' .. Escape(before), '\v\C' .. Escape(after)]
330+
331+
# The 'c' flag for searchpair() matches both start and end.
332+
# Append \zs to the closer pattern so that it doesn't match the closer on the cursor.
333+
if searchpair(bpat, '', apat .. '\zs', 'bcW') <= 0
334+
return ['', '']
335+
endif
336+
337+
if before !=# after
338+
for _ in range(count - 1)
339+
if searchpair(bpat, '', apat, 'bW')
340+
return ['', '']
341+
endif
342+
endfor
343+
endif
344+
345+
normal! v
346+
347+
var found: number
348+
349+
if before ==# after
350+
search(bpat, 'ceW')
351+
found = search(apat, 'eW')
352+
else
353+
found = searchpair(bpat, '', apat, 'W')
354+
search(apat, 'ceW')
355+
endif
356+
357+
if found <= 0
358+
execute "normal! \<Esc>"
359+
return ['', '']
360+
endif
361+
362+
normal! d
363+
return [before, after]
364+
enddef
365+
319366
export def Insert(wantedLinemode: bool = false): string
320367
var char = InputReplacement()
321368
var linemode = wantedLinemode
@@ -396,7 +443,6 @@ export def DoSurround(value: string = null_string, new_value: string = null_stri
396443
var char = value == null_string ? InputTarget() : value
397444
var spc = false
398445

399-
400446
if char =~ '^\d\+'
401447
scount = scount * char->matchstr('^\d\+')->str2nr()
402448
char = char->substitute('^\d\+', '', '')
@@ -407,12 +453,14 @@ export def DoSurround(value: string = null_string, new_value: string = null_stri
407453
spc = true
408454
endif
409455

410-
if char == 'a'
411-
char = '>'
412-
endif
456+
var custom = printf('surround_%d', char2nr(char))
413457

414-
if char == 'r'
415-
char = ']'
458+
if b:->get(custom, g:->get(custom))->empty()
459+
if char == 'a'
460+
char = '>'
461+
elseif char == 'r'
462+
char = ']'
463+
endif
416464
endif
417465

418466
var newchar = ""
@@ -435,13 +483,19 @@ export def DoSurround(value: string = null_string, new_value: string = null_stri
435483
var append = ""
436484
var original = getreg('"')
437485
var otype = getregtype('"')
486+
var before = ""
487+
var after = ""
438488

439489
setreg('"', "")
440490

441491
var strcount = (scount == 1 ? "" : string(scount))
442492

443493
if char == '/'
444494
execute 'normal! ' .. strcount .. "[/\<Plug>(surround-d)" .. strcount .. ']/'
495+
elseif exists(printf('b:surround_%d', char2nr(char)))
496+
[before, after] = DeleteCustom(char, b:, scount)
497+
elseif exists(printf('g:surround_%d', char2nr(char)))
498+
[before, after] = DeleteCustom(char, g:, scount)
445499
elseif char =~# '[[:punct:][:space:]]' && char !~# '[][(){}<>"''`]'
446500
execute 'normal! T' .. char
447501
if getline('.')[col('.') - 1] == char
@@ -467,7 +521,14 @@ export def DoSurround(value: string = null_string, new_value: string = null_stri
467521
var oldline = getline('.')
468522
var oldlnum = line('.')
469523

470-
if char ==# "p"
524+
custom = printf('surround_%d', char2nr(char))
525+
526+
if !b:->get(custom, g:->get(custom))->empty()
527+
setreg('"', before .. after, "c")
528+
keeper = keeper
529+
->substitute('\v\C^' .. Escape(before) .. '\s=', '', '')
530+
->substitute('\v\C\s=' .. Escape(after) .. '$', '', '')
531+
elseif char ==# 'p'
471532
setreg('"', '', 'V')
472533
elseif char ==# "s" || char ==# "w" || char ==# "W"
473534
# Do nothing

0 commit comments

Comments
 (0)