25 Commits
v2.1 ... master

Author SHA1 Message Date
Tim Pope
3d188ed211 Call out opening bracket behavior in FAQ
Apparently mentioning in the both the README intro and the help file
isn't enough.  I give up.

Resolves: https://github.com/tpope/vim-surround/issues/366
Resolves: https://github.com/tpope/vim-surround/issues/363
Resolves: https://github.com/tpope/vim-surround/issues/314
Resolves: https://github.com/tpope/vim-surround/issues/303
Resolves: https://github.com/tpope/vim-surround/issues/240
Resolves: https://github.com/tpope/vim-surround/issues/205
Resolves: https://github.com/tpope/vim-surround/issues/108
Resolves: https://github.com/tpope/vim-surround/issues/27
2022-10-25 16:41:16 -04:00
Tim Pope
bf3480dc9a Remove issues section from help file
I haven't even looked at this in over a decade.
2022-04-22 19:25:12 -04:00
Tim Pope
81fc0ec460 Fix insert mode maps after "\r" change
Resolves: https://github.com/tpope/vim-surround/issues/349
2022-04-09 22:21:13 -04:00
Tim Pope
427f80f254 Avoid "\r" as a cursor stand-in
This confuses Neovim's LSP.  I'd be surprised if there are LSPs it
*doesn't* confuse.

References: https://github.com/neovim/neovim/issues/15532
2022-04-09 16:04:28 -04:00
Enrico Maria De Angelis
9857a87463 Save, set, and restore startofline
Consider this code:
```javascript
_.map(
  (
    mapObjOnK
  )
);
```
If the cursor is on the 3rd line and you press <kbd>d</kbd><kbd>s</kbd><kbd>b</kbd>, the code will become
```javascript
_.map(
);
mapObjOnK
```

The problem occurs if `startofline` is off.

With this change, I set it before processing the the call to
`dosurround`, and then, after the call, I'm unsetting it if
it was unset.
2022-03-25 16:13:16 -04:00
Tim Pope
baf89ad264 Only reindent when enabled by Vim option
References: https://github.com/tpope/vim-markdown/pull/187
2022-01-29 21:05:37 -05:00
Tim Pope
aeb933272e surround.vim 2.2
* Keep HTML attributes when changing tags.
* Support <Space><Space> as space replacement.
* Bug fixes.
2021-10-12 12:15:51 -04:00
agguser
f51a26d371 Fix bug when closing delimiter is at line end (#284) (#285) 2019-11-28 01:29:20 -05:00
Tim Pope
e4c4cc0f81 Add sponsor button 2019-11-12 18:33:40 -05:00
Viacheslav Lotsmanov
fab8621670 Fix for "all" and "insert" "virtualedit" in Insert mode 2019-07-22 16:30:45 -04:00
Chris AtLee
ca58a2d886 Documentation for function name replacements (fixes #222) 2019-03-26 17:22:34 -04:00
matsuhav
597068870b Fix blank lines issue
In #254, probably because the tag is followed by <CR>, cstta<CR> sets
regtype 'V'(linewise) though its keeper doesn't end with <CR>.  And
setreg() adds extra <CR> at @".  Remove this extra <CR> and fix adding
<CR> method.
2018-07-23 14:52:25 -04:00
Tim Pope
aa1f120ad3 Fix yss in middle of line
Closes https://github.com/tpope/vim-surround/issues/256
2018-06-15 15:17:44 -04:00
Tim Pope
643a42454b Fix yss adding newlines 2018-05-29 19:08:56 -04:00
Tim Pope
4e7d573c14 Make ys maps atomic
Closes https://github.com/tpope/vim-surround/issues/253
2018-05-29 17:37:25 -04:00
Tim Pope
e8dca61597 Modernize README 2018-05-29 17:35:44 -04:00
Adriaan Zonnenberg
e49d6c2459 Only add colon if prompt ends with word (#204)
Lets you use your own ending characters, instead of always adding ': '.

Closes #203
2016-06-01 18:06:04 -04:00
Tim Pope
2d05440ad2 Merge pull request #175 from yuex/ds__
support ds<space><space>
2015-08-07 23:37:10 -04:00
Tim Pope
c492390126 Merge pull request #167 from sunaku/issue-159
GH-159: don't use comma as alias for HTML/XML tags
2015-08-07 23:22:40 -04:00
Yue Xin
e38dea3972 support ds<space><space> 2015-08-08 01:28:26 +08:00
Suraj N. Kurapati
5c6a64f333 GH-159: don't use comma as alias for HTML/XML tags
This change allows us to surround text with commas.
2015-04-30 10:36:59 -07:00
Tim Pope
772ab9587b Merge pull request #163 from kiryph/feature-repeat-late
Add repeat.vim support to surround with LaTeX environment 'ys<>l'
2015-03-15 13:32:12 -05:00
kiryph
605c12d7d2 Add repeat.vim support to surround with LaTeX environment 'ys<>l' 2015-02-25 21:28:28 +01:00
Tim Pope
ec579a5047 Merge pull request #131 from shanesmith/master
Keep HTML attributes when changing tags
2015-02-22 12:37:25 -06:00
Shane Smith
5d6b91ce80 Keep HTML attributes when changing tags
By default keep the HTML attributes of the previous surrounding tag.

Option to remove attributes if the new tag prompt is ended with '>'.

Fixes #95.
2015-02-22 11:50:33 -05:00
4 changed files with 113 additions and 74 deletions

2
.github/FUNDING.yml vendored Normal file
View File

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

View File

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

View File

@@ -130,9 +130,20 @@ code blocks in C-style languages, <C-}> (which is really <C-]>) adds braces on
lines separate from the content.
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. End your
input by pressing <CR> or >. If <C-T> is used, the tags will appear on lines
by themselves.
attributes here and they will be stripped from the closing tag. If replacing a
tag, its attributes are kept in the new tag. End your input with > to discard
the those attributes. If <C-T> is used, the tags will appear on lines by
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
removing parentheses from a function call with csbs.
@@ -191,16 +202,4 @@ that allow you to jump to such markings.
>
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:

View File

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