On 7/10/06, Marc Weber <[EMAIL PROTECTED]> wrote:
This is my attempt to write script which can surround text (either a
word or the text selected in visual mode) with some characters such as "
' ...

But it doesn't work everytime.

Why don't you use :imap and :vmap separately ?
You seem to be complicating you own life by using :map
and then trying to distinguish mode() inside. Indeed, mode() does not
always work as expected. It's *not* recommended to use :map, it's
too generic. It is recommended to use :imap and :vmap.

What if you try to create two separate functions (one for insert-mode
and one for for v-mode) and use :imap and :vmap separately ?

Yakov


Do you see another solution than using @- (:h registers shows that this
register is only used for text beeing less than one line)...

I want to use this to insert brackets, braces and also things like
try{
 ...
catch () {
}

Simple press <m-7>( to surround your text with (), ...

Or did I miss a script providing this functionality?

Marc

============= surround.vim =====================================================
" This script should provide the ability to
" sourround text with ", ', <>,(),[],{} <tag>/</tag>, ....
" and replace a pair with another

" By now these surroundings should be availible:
" I'll add things like tags, try except .. later
let g:pairs=[ ['"', '"'],
            \ ['''', ''''],
            \ ['(', ')'],
            \ ['[', ']'],
            \ ['{', '}'],
            \ ['<', '>'] ]

" create the dict of form key: [left, right]
" so you can enter <mapping><key> to surround the text
let g:pair_dict = {}
for item in g:pairs
  let g:pair_dict[item[0]] = item
  let g:pair_dict[item[1]] = item
endfor

" when called from normal/insertmode the word under the cursor will be
" surrounded, when called from visual mode the selected text will be
" surrounded
function! SurroundText(left, right)
  " no matter in which mode we are, select the characters to surround
  if mode()=='i'
    exec "normal <esc>viw"
  elseif mode()=='n' " FIXME: This doesn't work in visual. It's still 'n'
    normal viw
  endif
  " gv is necessary to get into visual mode again.. (is there a better way of
  " doing this?
  " s is used to remove the to be surrounded text and should be inserted again
  " with @- which doesn't work
  exec 'normal gvs'.a:left.(@-).a:right
endfun

function! GetPairFromKeyboard()
  for k in keys(g:pair_dict)
    let max_len = 0
    if len(k) > max_len
      let max_len = len(k)
    endif
  endfor
  let key = ""
  while len(key) < max_len
    let c = nr2char(getchar())
    let key .= c
    if exists('g:pairs["'.substitute(key,'"','\"','').'"]')
      return g:pair_dict[key]
    endif
  endwhile
  throw "no known pair given!"
endfunction

function! Surround()
  let pair = GetPairFromKeyboard()
  call SurroundText(pair[0],pair[1])
endfunction

function! SubstituteSurroundingText(subst, replace_with)
  " escape [
  let subst = a:subst
  let subst = map(subst,"substitute(v:val,']','\]','')")
  call searchpair(subst[0],'',subst[1],'')
  "start visual mode
  normal v
  call searchpair(subst[0],'',subst[1],'b')
  exec 'normal 
gvs'.a:replace_with[0].substitute(substitute(@-,'^'.subst[0],'',''),subst[1].'$','','').a:replace_with[1]
endfunction

function! SubstituteSurrounding()
  let subst = GetPairFromKeyboard()
  let replace_with = GetPairFromKeyboard()
  call SubstituteSurroundingText(subst, replace_with)
endfunction

map <m-7> :<c-u>call Surround()<cr>
map <m-8> :<c-u>call SubstituteSurrounding()<cr>
============= end surround.vim =================================================

Reply via email to