Compare commits

..

No commits in common. "master" and "v2.1" have entirely different histories.
master ... v2.1

4 changed files with 74 additions and 113 deletions

2
.github/FUNDING.yml vendored
View file

@ -1,2 +0,0 @@
github: tpope
custom: ["https://www.paypal.me/vimpope"]

View file

@ -1,4 +1,5 @@
# surround.vim surround.vim
============
Surround.vim is all about "surroundings": parentheses, brackets, quotes, Surround.vim is all about "surroundings": parentheses, brackets, quotes,
XML tags, and more. The plugin provides mappings to easily delete, XML tags, and more. The plugin provides mappings to easily delete,
@ -60,39 +61,37 @@ and removing pairs of tags simultaneously is a breeze.
The `.` command will work with `ds`, `cs`, and `yss` if you install The `.` command will work with `ds`, `cs`, and `yss` if you install
[repeat.vim](https://github.com/tpope/vim-repeat). [repeat.vim](https://github.com/tpope/vim-repeat).
## Installation Installation
------------
Install using your favorite package manager, or use Vim's built-in package If you don't have a preferred installation method, I recommend
support: installing [pathogen.vim](https://github.com/tpope/vim-pathogen), and
then simply copy and paste:
mkdir -p ~/.vim/pack/tpope/start cd ~/.vim/bundle
cd ~/.vim/pack/tpope/start git clone git://github.com/tpope/vim-surround.git
git clone https://tpope.io/vim/surround.git
vim -u NONE -c "helptags surround/doc" -c q
## FAQ Once help tags have been generated, you can view the manual with
`:help surround`.
> How do I surround without adding a space? Contributing
------------
Only the opening brackets—`[`, `{`, and `(`—add a space. Use a closing
bracket, or the `b` (`(`) and `B` (`{`) aliases.
## Contributing
See the contribution guidelines for See the contribution guidelines for
[pathogen.vim](https://github.com/tpope/vim-pathogen#readme). [pathogen.vim](https://github.com/tpope/vim-pathogen#readme).
## Self-Promotion Self-Promotion
--------------
Like surround.vim? Star the repository on Like surround.vim? Follow the repository on
[GitHub](https://github.com/tpope/vim-surround) and vote for it on [GitHub](https://github.com/tpope/vim-surround) and vote for it on
[vim.org](https://www.vim.org/scripts/script.php?script_id=1697). [vim.org](http://www.vim.org/scripts/script.php?script_id=1697). And if
you're feeling especially charitable, follow [tpope](http://tpo.pe/) on
[Twitter](http://twitter.com/tpope) and
[GitHub](https://github.com/tpope).
Love surround.vim? Follow [tpope](http://tpo.pe/) on License
[GitHub](https://github.com/tpope) and -------
[Twitter](http://twitter.com/tpope).
## License
Copyright (c) Tim Pope. Distributed under the same terms as Vim itself. Copyright (c) Tim Pope. Distributed under the same terms as Vim itself.
See `:help license`. See `:help license`.

View file

@ -130,20 +130,9 @@ code blocks in C-style languages, <C-}> (which is really <C-]>) adds braces on
lines separate from the content. lines separate from the content.
If t or < is used, Vim prompts for an HTML/XML tag to insert. You may specify If t or < is used, Vim prompts for an HTML/XML tag to insert. You may specify
attributes here and they will be stripped from the closing tag. If replacing a attributes here and they will be stripped from the closing tag. End your
tag, its attributes are kept in the new tag. End your input with > to discard input by pressing <CR> or >. If <C-T> is used, the tags will appear on lines
the those attributes. If <C-T> is used, the tags will appear on lines by by themselves.
themselves.
If f, F, or <C-F> is used, Vim prompts for a function name to insert. The target
text will be wrapped in a function call. If f is used, the text is wrapped with
() parentheses; F adds additional spaces inside the parentheses. <C-F> inserts the
function name inside the parentheses.
Old text Command New text ~
"hello" ysWfprint<cr> print("hello")
"hello" ysWFprint<cr> print( "hello" )
"hello" ysW<C-f>print<cr> (print "hello")
If s is used, a leading but not trailing space is added. This is useful for If s is used, a leading but not trailing space is added. This is useful for
removing parentheses from a function call with csbs. removing parentheses from a function call with csbs.
@ -202,4 +191,16 @@ that allow you to jump to such markings.
> >
let g:surround_insert_tail = "<++>" let g:surround_insert_tail = "<++>"
< <
ISSUES *surround-issues*
Vim could potentially get confused when deleting/changing occurs at the very
end of the line. Please report any repeatable instances of this.
Do we need to use |inputsave()|/|inputrestore()| with the tag replacement?
Indenting is handled haphazardly. Need to decide the most appropriate
behavior and implement it. Right now one can do :let b:surround_indent = 1
(or the global equivalent) to enable automatic re-indenting by Vim via |=|;
should this be the default?
vim:tw=78:ts=8:ft=help:norl: vim:tw=78:ts=8:ft=help:norl:

View file

@ -1,6 +1,6 @@
" surround.vim - Surroundings " surround.vim - Surroundings
" Author: Tim Pope <http://tpo.pe/> " Author: Tim Pope <http://tpo.pe/>
" Version: 2.2 " Version: 2.1
" GetLatestVimScripts: 1697 1 :AutoInstall: surround.vim " GetLatestVimScripts: 1697 1 :AutoInstall: surround.vim
if exists("g:loaded_surround") || &cp || v:version < 700 if exists("g:loaded_surround") || &cp || v:version < 700
@ -92,7 +92,7 @@ function! s:process(string)
let m = matchstr(a:string,nr2char(i).'.\{-\}\ze'.nr2char(i)) let m = matchstr(a:string,nr2char(i).'.\{-\}\ze'.nr2char(i))
if m != '' if m != ''
let m = substitute(strpart(m,1),'\r.*','','') let m = substitute(strpart(m,1),'\r.*','','')
let repl_{i} = input(match(m,'\w\+$') >= 0 ? m.': ' : m) let repl_{i} = input(substitute(m,':\s*$','','').': ')
endif endif
endfor endfor
let s = "" let s = ""
@ -124,12 +124,13 @@ function! s:process(string)
return s return s
endfunction endfunction
function! s:wrap(string,char,type,removed,special) function! s:wrap(string,char,type,...)
let keeper = a:string let keeper = a:string
let newchar = a:char let newchar = a:char
let s:input = "" let s:input = ""
let type = a:type let type = a:type
let linemode = type ==# 'V' ? 1 : 0 let linemode = type ==# 'V' ? 1 : 0
let special = a:0 ? a:1 : 0
let before = "" let before = ""
let after = "" let after = ""
if type ==# "V" if type ==# "V"
@ -164,13 +165,13 @@ function! s:wrap(string,char,type,removed,special)
elseif newchar ==# ':' elseif newchar ==# ':'
let before = ':' let before = ':'
let after = '' let after = ''
elseif newchar =~# "[tT\<C-T><]" elseif newchar =~# "[tT\<C-T><,]"
let dounmapp = 0 let dounmapp = 0
let dounmapb = 0 let dounmapb = 0
if !maparg(">","c") if !maparg(">","c")
let dounmapb = 1 let dounmapb = 1
" Hide from AsNeeded " Hide from AsNeeded
exe "cn"."oremap > ><CR>" exe "cn"."oremap > <CR>"
endif endif
let default = "" let default = ""
if newchar ==# "T" if newchar ==# "T"
@ -180,27 +181,21 @@ function! s:wrap(string,char,type,removed,special)
let default = matchstr(s:lastdel,'<\zs.\{-\}\ze>') let default = matchstr(s:lastdel,'<\zs.\{-\}\ze>')
endif endif
let tag = input("<",default) let tag = input("<",default)
echo "<".substitute(tag,'>*$','>','')
if dounmapb if dounmapb
silent! cunmap > silent! cunmap >
endif endif
let s:input = tag let s:input = tag
if tag != "" if tag != ""
let keepAttributes = ( match(tag, ">$") == -1 )
let tag = substitute(tag,'>*$','','') let tag = substitute(tag,'>*$','','')
let attributes = ""
if keepAttributes
let attributes = matchstr(a:removed, '<[^ \t\n]\+\zs\_.\{-\}\ze>')
endif
let s:input = tag . '>' let s:input = tag . '>'
let before = '<'.tag.'>'
if tag =~ '/$' if tag =~ '/$'
let tag = substitute(tag, '/$', '', '')
let before = '<'.tag.attributes.' />'
let after = '' let after = ''
else else
let before = '<'.tag.attributes.'>'
let after = '</'.substitute(tag,' .*','','').'>' let after = '</'.substitute(tag,' .*','','').'>'
endif endif
if newchar == "\<C-T>" if newchar == "\<C-T>" || newchar == ","
if type ==# "v" || type ==# "V" if type ==# "v" || type ==# "V"
let before .= "\n\t" let before .= "\n\t"
endif endif
@ -212,11 +207,10 @@ function! s:wrap(string,char,type,removed,special)
elseif newchar ==# 'l' || newchar == '\' elseif newchar ==# 'l' || newchar == '\'
" LaTeX " LaTeX
let env = input('\begin{') let env = input('\begin{')
let env = '{' . env
let env .= s:closematch(env)
echo '\begin'.env
if env != "" if env != ""
let s:input = env."\<CR>"
let env = '{' . env
let env .= s:closematch(env)
echo '\begin'.env
let before = '\begin'.env let before = '\begin'.env
let after = '\end'.matchstr(env,'[^}]*').'}' let after = '\end'.matchstr(env,'[^}]*').'}'
endif endif
@ -252,7 +246,7 @@ function! s:wrap(string,char,type,removed,special)
let after = '' let after = ''
endif endif
let after = substitute(after ,'\n','\n'.initspaces,'g') let after = substitute(after ,'\n','\n'.initspaces,'g')
if type ==# 'V' || (a:special && type ==# "v") if type ==# 'V' || (special && type ==# "v")
let before = substitute(before,' \+$','','') let before = substitute(before,' \+$','','')
let after = substitute(after ,'^ \+','','') let after = substitute(after ,'^ \+','','')
if after !~ '^\n' if after !~ '^\n'
@ -263,16 +257,11 @@ function! s:wrap(string,char,type,removed,special)
elseif keeper =~ '\n$' && after =~ '^\n' elseif keeper =~ '\n$' && after =~ '^\n'
let after = strpart(after,1) let after = strpart(after,1)
endif endif
if keeper !~ '^\n' && before !~ '\n\s*$' if before !~ '\n\s*$'
let before .= "\n" let before .= "\n"
if a:special if special
let before .= "\t" let before .= "\t"
endif endif
elseif keeper =~ '^\n' && before =~ '\n\s*$'
let keeper = strcharpart(keeper,1)
endif
if type ==# 'V' && keeper =~ '\n\s*\n$'
let keeper = strcharpart(keeper,0,strchars(keeper) - 1)
endif endif
endif endif
if type ==# 'V' if type ==# 'V'
@ -300,10 +289,11 @@ function! s:wrap(string,char,type,removed,special)
return keeper return keeper
endfunction endfunction
function! s:wrapreg(reg,char,removed,special) function! s:wrapreg(reg,char,...)
let orig = getreg(a:reg) let orig = getreg(a:reg)
let type = substitute(getregtype(a:reg),'\d\+$','','') let type = substitute(getregtype(a:reg),'\d\+$','','')
let new = s:wrap(orig,a:char,type,a:removed,a:special) let special = a:0 ? a:1 : 0
let new = s:wrap(orig,a:char,type,special)
call setreg(a:reg,new,type) call setreg(a:reg,new,type)
endfunction endfunction
" }}}1 " }}}1
@ -323,8 +313,8 @@ function! s:insert(...) " {{{1
let cb_save = &clipboard let cb_save = &clipboard
set clipboard-=unnamed clipboard-=unnamedplus set clipboard-=unnamed clipboard-=unnamedplus
let reg_save = @@ let reg_save = @@
call setreg('"',"\032",'v') call setreg('"',"\r",'v')
call s:wrapreg('"',char,"",linemode) call s:wrapreg('"',char,linemode)
" If line mode is used and the surrounding consists solely of a suffix, " If line mode is used and the surrounding consists solely of a suffix,
" remove the initial newline. This fits a use case of mine but is a " remove the initial newline. This fits a use case of mine but is a
" little inconsistent. Is there anyone that would prefer the simpler " little inconsistent. Is there anyone that would prefer the simpler
@ -336,16 +326,7 @@ function! s:insert(...) " {{{1
if exists("g:surround_insert_tail") if exists("g:surround_insert_tail")
call setreg('"',g:surround_insert_tail,"a".getregtype('"')) call setreg('"',g:surround_insert_tail,"a".getregtype('"'))
endif endif
if &ve != 'all' && col('.') >= col('$') if col('.') >= col('$')
if &ve == 'insert'
let extra_cols = virtcol('.') - virtcol('$')
if extra_cols > 0
let [regval,regtype] = [getreg('"',1,1),getregtype('"')]
call setreg('"',join(map(range(extra_cols),'" "'),''),'v')
norm! ""p
call setreg('"',regval,regtype)
endif
endif
norm! ""p norm! ""p
else else
norm! ""P norm! ""P
@ -354,21 +335,19 @@ function! s:insert(...) " {{{1
call s:reindent() call s:reindent()
endif endif
norm! `] norm! `]
call search("\032",'bW') call search('\r','bW')
let @@ = reg_save let @@ = reg_save
let &clipboard = cb_save let &clipboard = cb_save
return "\<Del>" return "\<Del>"
endfunction " }}}1 endfunction " }}}1
function! s:reindent() abort " {{{1 function! s:reindent() " {{{1
if get(b:, 'surround_indent', get(g:, 'surround_indent', 1)) && (!empty(&equalprg) || !empty(&indentexpr) || &cindent || &smartindent || &lisp) if exists("b:surround_indent") ? b:surround_indent : (!exists("g:surround_indent") || g:surround_indent)
silent norm! '[='] silent norm! '[=']
endif endif
endfunction " }}}1 endfunction " }}}1
function! s:dosurround(...) " {{{1 function! s:dosurround(...) " {{{1
let sol_save = &startofline
set startofline
let scount = v:count1 let scount = v:count1
let char = (a:0 ? a:1 : s:inputtarget()) let char = (a:0 ? a:1 : s:inputtarget())
let spc = "" let spc = ""
@ -390,9 +369,6 @@ function! s:dosurround(...) " {{{1
if a:0 > 1 if a:0 > 1
let newchar = a:2 let newchar = a:2
if newchar == "\<Esc>" || newchar == "\<C-C>" || newchar == "" if newchar == "\<Esc>" || newchar == "\<C-C>" || newchar == ""
if !sol_save
set nostartofline
endif
return s:beep() return s:beep()
endif endif
endif endif
@ -405,7 +381,7 @@ function! s:dosurround(...) " {{{1
let strcount = (scount == 1 ? "" : scount) let strcount = (scount == 1 ? "" : scount)
if char == '/' if char == '/'
exe 'norm! '.strcount.'[/d'.strcount.']/' exe 'norm! '.strcount.'[/d'.strcount.']/'
elseif char =~# '[[:punct:][:space:]]' && char !~# '[][(){}<>"''`]' elseif char =~# '[[:punct:]]' && char !~# '[][(){}<>"''`]'
exe 'norm! T'.char exe 'norm! T'.char
if getline('.')[col('.')-1] == char if getline('.')[col('.')-1] == char
exe 'norm! l' exe 'norm! l'
@ -419,9 +395,6 @@ function! s:dosurround(...) " {{{1
if keeper == "" if keeper == ""
call setreg('"',original,otype) call setreg('"',original,otype)
let &clipboard = cb_save let &clipboard = cb_save
if !sol_save
set nostartofline
endif
return "" return ""
endif endif
let oldline = getline('.') let oldline = getline('.')
@ -438,7 +411,7 @@ function! s:dosurround(...) " {{{1
norm! "_x norm! "_x
call setreg('"','/**/',"c") call setreg('"','/**/',"c")
let keeper = substitute(substitute(keeper,'^/\*\s\=','',''),'\s\=\*$','','') let keeper = substitute(substitute(keeper,'^/\*\s\=','',''),'\s\=\*$','','')
elseif char =~# '[[:punct:][:space:]]' && char !~# '[][(){}<>]' elseif char =~# '[[:punct:]]' && char !~# '[][(){}<>]'
exe 'norm! F'.char exe 'norm! F'.char
exe 'norm! df'.char exe 'norm! df'.char
else else
@ -455,7 +428,7 @@ function! s:dosurround(...) " {{{1
let keeper = substitute(keeper,'^\s\+','','') let keeper = substitute(keeper,'^\s\+','','')
let keeper = substitute(keeper,'\s\+$','','') let keeper = substitute(keeper,'\s\+$','','')
endif endif
if col("']") == col("$") && virtcol('.') + 1 == virtcol('$') if col("']") == col("$") && col('.') + 1 == col('$')
if oldhead =~# '^\s*$' && a:0 < 2 if oldhead =~# '^\s*$' && a:0 < 2
let keeper = substitute(keeper,'\%^\n'.oldhead.'\(\s*.\{-\}\)\n\s*\%$','\1','') let keeper = substitute(keeper,'\%^\n'.oldhead.'\(\s*.\{-\}\)\n\s*\%$','\1','')
endif endif
@ -469,7 +442,7 @@ function! s:dosurround(...) " {{{1
call setreg('"',keeper,regtype) call setreg('"',keeper,regtype)
if newchar != "" if newchar != ""
let special = a:0 > 2 ? a:3 : 0 let special = a:0 > 2 ? a:3 : 0
call s:wrapreg('"',newchar,removed,special) call s:wrapreg('"',newchar, special)
endif endif
silent exe 'norm! ""'.pcmd.'`[' silent exe 'norm! ""'.pcmd.'`['
if removed =~ '\n' || okeeper =~ '\n' || getreg('"') =~ '\n' if removed =~ '\n' || okeeper =~ '\n' || getreg('"') =~ '\n'
@ -486,9 +459,6 @@ function! s:dosurround(...) " {{{1
else else
silent! call repeat#set("\<Plug>C".(a:0 > 2 && a:3 ? "S" : "s")."urround".char.newchar.s:input,scount) silent! call repeat#set("\<Plug>C".(a:0 > 2 && a:3 ? "S" : "s")."urround".char.newchar.s:input,scount)
endif endif
if !sol_save
set nostartofline
endif
endfunction " }}}1 endfunction " }}}1
function! s:changesurround(...) " {{{1 function! s:changesurround(...) " {{{1
@ -503,11 +473,7 @@ function! s:changesurround(...) " {{{1
call s:dosurround(a,b,a:0 && a:1) call s:dosurround(a,b,a:0 && a:1)
endfunction " }}}1 endfunction " }}}1
function! s:opfunc(type, ...) abort " {{{1 function! s:opfunc(type,...) " {{{1
if a:type ==# 'setup'
let &opfunc = matchstr(expand('<sfile>'), '<SNR>\w\+$')
return 'g@'
endif
let char = s:inputreplacement() let char = s:inputreplacement()
if char == "" if char == ""
return s:beep() return s:beep()
@ -552,7 +518,7 @@ function! s:opfunc(type, ...) abort " {{{1
let keeper = substitute(keeper,'\_s\@<!\s*$','','') let keeper = substitute(keeper,'\_s\@<!\s*$','','')
endif endif
call setreg(reg,keeper,type) call setreg(reg,keeper,type)
call s:wrapreg(reg,char,"",a:0 && a:1) call s:wrapreg(reg,char,a:0 && a:1)
if type ==# "v" && a:type !=# "v" && append != "" if type ==# "v" && a:type !=# "v" && append != ""
call setreg(reg,append,"ac") call setreg(reg,append,"ac")
endif endif
@ -570,12 +536,8 @@ function! s:opfunc(type, ...) abort " {{{1
endif endif
endfunction endfunction
function! s:opfunc2(...) abort function! s:opfunc2(arg)
if !a:0 || a:1 ==# 'setup' call s:opfunc(a:arg,1)
let &opfunc = matchstr(expand('<sfile>'), '<SNR>\w\+$')
return 'g@'
endif
call s:opfunc(a:1, 1)
endfunction " }}}1 endfunction " }}}1
function! s:closematch(str) " {{{1 function! s:closematch(str) " {{{1
@ -598,10 +560,11 @@ nnoremap <silent> <Plug>SurroundRepeat .
nnoremap <silent> <Plug>Dsurround :<C-U>call <SID>dosurround(<SID>inputtarget())<CR> nnoremap <silent> <Plug>Dsurround :<C-U>call <SID>dosurround(<SID>inputtarget())<CR>
nnoremap <silent> <Plug>Csurround :<C-U>call <SID>changesurround()<CR> nnoremap <silent> <Plug>Csurround :<C-U>call <SID>changesurround()<CR>
nnoremap <silent> <Plug>CSurround :<C-U>call <SID>changesurround(1)<CR> nnoremap <silent> <Plug>CSurround :<C-U>call <SID>changesurround(1)<CR>
nnoremap <expr> <Plug>Yssurround '^'.v:count1.<SID>opfunc('setup').'g_' nnoremap <silent> <Plug>Yssurround :<C-U>call <SID>opfunc(v:count1)<CR>
nnoremap <expr> <Plug>YSsurround <SID>opfunc2('setup').'_' nnoremap <silent> <Plug>YSsurround :<C-U>call <SID>opfunc2(v:count1)<CR>
nnoremap <expr> <Plug>Ysurround <SID>opfunc('setup') " <C-U> discards the numerical argument but there's not much we can do with it
nnoremap <expr> <Plug>YSurround <SID>opfunc2('setup') nnoremap <silent> <Plug>Ysurround :<C-U>set opfunc=<SID>opfunc<CR>g@
nnoremap <silent> <Plug>YSurround :<C-U>set opfunc=<SID>opfunc2<CR>g@
vnoremap <silent> <Plug>VSurround :<C-U>call <SID>opfunc(visualmode(),visualmode() ==# 'V' ? 1 : 0)<CR> vnoremap <silent> <Plug>VSurround :<C-U>call <SID>opfunc(visualmode(),visualmode() ==# 'V' ? 1 : 0)<CR>
vnoremap <silent> <Plug>VgSurround :<C-U>call <SID>opfunc(visualmode(),visualmode() ==# 'V' ? 0 : 1)<CR> vnoremap <silent> <Plug>VgSurround :<C-U>call <SID>opfunc(visualmode(),visualmode() ==# 'V' ? 0 : 1)<CR>
inoremap <silent> <Plug>Isurround <C-R>=<SID>insert()<CR> inoremap <silent> <Plug>Isurround <C-R>=<SID>insert()<CR>