diff --git a/plugin/surround.vim b/plugin/surround.vim index ce33f80..ba573d0 100644 --- a/plugin/surround.vim +++ b/plugin/surround.vim @@ -134,9 +134,7 @@ " " An experimental replacement of a LaTeX environment is provided on \ and l. " The name of the environment and any arguments will be input from a prompt. -" Opening and closing delimiters are not automatically placed on lines of -" their own; you must arrange for this to happen. The following shows the -" resulting environment from csp\tabular}{lc +" The following shows the resulting environment from csp\tabular}{lc " > " \begin{tabular}{lc} " \end{tabular} @@ -144,10 +142,10 @@ " Customizing: *surround-customizing* " " The following adds a potential replacement on "-" (ASCII 45) in PHP files. -" (To determine the ASCII code to use, :echo char2nr("-")). The newline will -" be replaced by the original text. +" (To determine the ASCII code to use, :echo char2nr("-")). The carriage +" return will be replaced by the original text. " > -" autocmd FileType php let b:surround_45 = "" +" autocmd FileType php let b:surround_45 = "" " < " This can be used in a PHP file as in the following example. " @@ -157,7 +155,8 @@ " Additionally, one can use a global variable for globally available " replacements. " > -" let g:surround_45 = "<% \n %>" +" let g:surround_45 = "<% \r %>" +" let g:surround_61 = "<%= \r %>" " < " Issues: *surround-issues* " @@ -269,12 +268,57 @@ endfunction " }}}1 -function! s:wrap(string,char,...) " {{{1 +" Wrapping functions {{{1 + +function! s:extractbefore(str) + if a:str =~ '\r' + return matchstr(a:str,'.*\ze\r') + else + return matchstr(a:str,'.*\ze\n') + endif +endfunction + +function! s:extractafter(str) + if a:str =~ '\r' + return matchstr(a:str,'\r\zs.*') + else + return matchstr(a:str,'\n\zs.*') + endif +endfunction + +function! s:repeat(str,count) + let cnt = a:count + let str = "" + while cnt > 0 + let str = str . a:str + let cnt = cnt - 1 + endwhile + return str +endfunction + +function! s:fixindent(str,spc) + let str = substitute(a:str,'\t',s:repeat(' ',&sw),'g') + let spc = substitute(a:spc,'\t',s:repeat(' ',&sw),'g') + let str = substitute(str,'\n.\@=','\n'.spc,'g') + if ! &et + let str = substitute('\s\{'.&ts.'\}',"\t",'g') + endif + return str +endfunction + +let g:surround_35 = "<%\n\t\r\n%>" + +function! s:wrap(string,char,...) let keeper = a:string let newchar = a:char let linemode = a:0 ? a:1 : 0 let before = "" let after = "" + if linemode + let initspaces = matchstr(keeper,'\%^\s*') + else + let initspaces = matchstr(getline('.'),'\%^\s*') + endif " Duplicate b's are just placeholders (removed) let pairs = "b()B{}r[]a<>" let extraspace = "" @@ -284,21 +328,21 @@ function! s:wrap(string,char,...) " {{{1 endif let idx = stridx(pairs,newchar) if exists("b:surround_".char2nr(newchar)) - let before = matchstr(b:surround_{char2nr(newchar)},'.*\ze\n') - let after = matchstr(b:surround_{char2nr(newchar)},'\n\zs.*') + let before = s:extractbefore(b:surround_{char2nr(newchar)}) + let after = s:extractafter(b:surround_{char2nr(newchar)}) elseif exists("g:surround_".char2nr(newchar)) - let before = matchstr(g:surround_{char2nr(newchar)},'.*\ze\n') - let after = matchstr(g:surround_{char2nr(newchar)},'\n\zs.*') + let before = s:extractbefore(g:surround_{char2nr(newchar)}) + let after = s:extractafter(g:surround_{char2nr(newchar)}) elseif newchar ==# "p" let before = "\n" let after = "\n\n" elseif newchar ==# "t" || newchar ==# "T" || newchar == "<" - let dounmapr = 0 + "let dounmapr = 0 let dounmapb = 0 - if !mapcheck("","c") - let dounmapr = 1 - cnoremap > - endif + "if !mapcheck("","c") + "let dounmapr = 1 + "cnoremap > + "endif if !mapcheck(">","c") let dounmapb= 1 cnoremap > > @@ -309,9 +353,9 @@ function! s:wrap(string,char,...) " {{{1 endif let tag = input("<",default) echo "<".substitute(tag,'>*$','>','') - if dounmapr - silent! cunmap - endif + "if dounmapr + "silent! cunmap + "endif if dounmapb silent! cunmap > endif @@ -321,12 +365,13 @@ function! s:wrap(string,char,...) " {{{1 let after = "" endif elseif newchar ==# 'l' || newchar == '\' - let env = input('\begin','{') + let env = input('\begin{') + let env = '{' . env let env = env . s:closematch(env) echo '\begin'.env if env != "" - let before = '\begin'.env - let after = '\end'.matchstr(env,'[^}]*').'}' + let before = '\begin'.env."\n\t" + let after = "\n".'\end'.matchstr(env,'[^}]*').'}' endif elseif newchar ==# 'f' || newchar ==# 'F' let func = input('function: ') @@ -347,16 +392,31 @@ function! s:wrap(string,char,...) " {{{1 let before = newchar let after = newchar endif + if before =~ '\n\s\+\%$' && keeper =~ '\n' + let beforespc = substitute(matchstr(before,'\s\+\%$'),'\t',s:repeat(' ',&sw),'g') + let keeper = s:fixindent((linemode ? beforespc : "").keeper,beforespc) + endif if linemode || keeper =~ '\%^\s*\n' let before = substitute(before,'\s*\%$','','') endif if linemode || keeper =~ '\n\s*\%$' let after = substitute(after,'\%^\s*','','') endif + let before = s:fixindent(before,initspaces) + let after = s:fixindent(after,initspaces) if linemode - let initspaces = matchstr(keeper,'\%^\s*') - let keeper = initspaces.before."\n".keeper."\n".initspaces.after + if before !~ '\n\s*\%$' + let before = before."\n" + endif + if after !~ '\%^\n' + let after = "\n".initspaces.after + endif + let keeper = initspaces.before.keeper.after else + " Good idea? + if keeper =~ '\n$' && after =~ '^\n' && after !~ '\n$' + let after = substitute(after,'^\n','','') . "\n" + endif let keeper = before.extraspace.keeper.extraspace.after endif return keeper @@ -364,6 +424,7 @@ endfunction " }}}1 function! s:insert(...) " {{{1 " Optional argument causes the result to appear on 3 lines, not 1 + call inputsave() let linemode = a:0 ? a:1 : 0 let char = s:inputreplacement() while char == "\" @@ -371,22 +432,33 @@ function! s:insert(...) " {{{1 let linemode = linemode + 1 let char = s:inputreplacement() endwhile + call inputrestore() if char == "" return "" endif " We could just use null, but nooooo, that won't work - let text = s:wrap("\1",char,0) + call inputsave() + let text = s:wrap("\r",char,0) + call inputrestore() + set paste + let nopaste = "\:set nopaste\:\gi" if linemode - return substitute(text,'\s*\%x01\s*',"\",'')."\O" + let first = matchstr(text,'.\{-\}\ze\s*\r') + let last = matchstr(text,'\r\s*\zs.*') + let text = first.nopaste."\".last."\O" + elseif text =~ '\r\n' + " doesn't work with multiple newlines in second half. + let text = substitute(text,'\r\n',"\",'').nopaste."\\" else - let len = strlen(substitute(substitute(text,'.*\%x01','',''),'.','.','g')) + let len = strlen(substitute(substitute(text,'.*\r','',''),'.','.','g')) let left = "" while len > 0 let len = len - 1 let left = left . "\" endwhile - return substitute(text,'\%x01','','') . left + let text = substitute(text,'\r','','') . left . nopaste endif + return text endfunction " }}}1 function! s:reindent() " {{{1 @@ -407,6 +479,12 @@ function! s:dosurround(...) " {{{1 let char = strpart(char,1) let spc = 1 endif + if char == 'a' + let char = '>' + endif + if char == 'r' + let char = ']' + endif let newchar = "" if a:0 > 1 let newchar = a:2 @@ -485,8 +563,9 @@ function! s:dosurround(...) " {{{1 let @@ = substitute(keeper,'\n\s+\n','\n\n','g') call setreg('"','','a'.regtype) silent exe "norm! ".(a:0 < 2 ? "" : "").pcmd.'`[' - if removed =~ '\n' || okeeper =~ '\n' + if removed =~ '\n' || okeeper =~ '\n' || @@ =~ '\n' call s:reindent() + else endif if getline('.') =~ '^\s\+$' && keeper =~ '^\s*\n' silent norm! cc @@ -538,9 +617,10 @@ function! s:opfunc(type) " {{{1 endif let @@ = reg_save " s:wrap() may peek at this let keeper = s:wrap(keeper,char,linemode) . append - let @@ = keeper + call setreg('"',keeper,linemode ? 'V' : 'v') + "let @@ = keeper silent norm! gvp`[ - if linemode + if linemode || @@ =~ '\n' call s:reindent() endif let @@ = reg_save