Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
" DELIMITERS MADE LESS ANNOYING
"
" Main novelty here (if it is one): this does NOT try to be helpful by
" inserting the closing delimiter for you when you type an opening one.
" Instead it only tries to be smart about what to do when you type a closing
" delimiter yourself.
"
" If you just typed an empty delimiter pair, it'll move the cursor back
" inside. If you type a closing delimiter the cursor is already on (or to
" the left of, if the cursor is on a space), it'll skip the cursor past that
" delimiter without inserting it.
"
" That way you never end with superfluous delimiters to delete, which deletion
" itself can be tricky to perform, since the editor might be trying to be
" helpful about deletions as well. Instead, you only ever get delimiters you
" explicitly typed yourself.
"
" I had trained myself into the good habit of typing pairs together anyway.
" The only annoying part of that habit is the manual cursor placement work;
" but that work is quite predictable almost all of the time. That's exactly
" the sort of work that computers are for.
function! IsEmptyPair(str)
for pair in split( &matchpairs, ',' ) + [ "''", '""', '``' ]
if a:str == join( split( pair, ':' ),'' )
return 1
endif
endfor
return 0
endfunc
function! WithinEmptyPair()
let cur = strpart( getline('.'), col('.')-2, 2 )
return IsEmptyPair( cur )
endfunc
function! SkipDelim(char)
let cur = strpart( getline('.'), col('.')-2, 3 )
if cur[0] == "\\"
return a:char
elseif cur[1] == a:char
return "\<Right>"
elseif cur[1] == ' ' && cur[2] == a:char
return "\<Right>\<Right>"
elseif IsEmptyPair( cur[0] . a:char )
return a:char . "\<Left>"
else
return a:char
endif
endfunc
inoremap <expr> ) SkipDelim(')')
inoremap <expr> ] SkipDelim(']')
inoremap <expr> } SkipDelim('}')
inoremap <expr> ' SkipDelim("'")
inoremap <expr> " SkipDelim('"')
inoremap <expr> ` SkipDelim('`')
inoremap <expr> <BS> WithinEmptyPair() ? "\<Right>\<BS>\<BS>" : "\<BS>"
inoremap <expr> <CR> WithinEmptyPair() ? "\<CR>\<CR>\<Up>" : "\<CR>"
inoremap <expr> <Space> WithinEmptyPair() ? "\<Space>\<Space>\<Left>" : "\<Space>"
vmap q( s()<C-R>"<Esc>
vmap q) s()<C-R>"<Esc>
vmap q[ s[]<C-R>"<Esc>
vmap q] s[]<C-R>"<Esc>
vmap q{ s{}<C-R>"<Esc>
vmap q} s{}<C-R>"<Esc>
vmap q' s''<C-R>"<Esc>
vmap q" s""<C-R>"<Esc>
vmap q` s``<C-R>"<Esc>
@aghast

In my particular version of Vim (VIM - Vi IMproved 7.3 (2010 Aug 15, compiled Aug 24 2013 18:58:47)
the vmap commands do not work as I think you intend them to work. I get ()foo instead of (foo). Changing the mapping to s(") works fine, though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.