Duplicate tip
This tip is very similar to the following:
These tips need to be merged – see the merge guidelines.
created August 22, 2002 · complexity intermediate · author Abitkin · version 5.7
This is an extension of VimTip153. I found this tip useful, but the jump seemed out of place for me, I couldn't enter just one ' or ", and so I created an improvement
Basically, I set it up so that when you're in perl and have a non keyword charcter, (except for @, $ and % for perl) and you type a { you get:
{ | <- cursor }
Whereas, when I have a keyword I get:
word{}
With the cursor in the middle, for hashes in perl. I can jump out of any block, except the "..." or '...' blocks, by typing their closing character. So } jumps me out past the next } in the file.
Warning, this search may wrap around.
Finally, I made it so that, using the alt key,
- <Alt-'> inserts a '
- <Alt-/> inserts a "
- <Alt-[> inserts a [
- <Alt-]> inserts a ]
- <Alt--> inserts a {
- <Alt-=> inserts a }
- <Alt-,> inserts a <
- <Alt-.> inserts a >
" File - matchMe.vim " Date - Wednesday, August 21, 2002 " This code fixes my problem with " does the one format for perl and acts correctly with " hashes function! InsertBrackets() let fileType = &ft if fileType == 'perl' let col = col('.') - 1 if !col || getline('.')[col - 1] !~ '\k' && getline('.')[col - 1] !~ '\$' && getline('.')[col - 1] !~ '@' && getline('.')[col - 1] !~ '%' && getline('.')[col - 1] !~ '#' return "{\<CR>\<BS>}\<Esc>ko" else return "{}\<Esc>i\<c-o>:echo \<CR>" endif else return "{\<CR>\<BS>}\<Esc>ko" endif endfunction " This code jumps out of the brackets function! JumpNext(startChar, endChar) let ret1 = "\<Esc>:echo searchpair('".a:startChar."','','".a:endChar."','W','synIDattr(synID(line(\".\"), col(\".\"), 0), \"name\") =~? \"string\"')\<CR>i\<Right>" return ret1 endfunction " mappings inoremap " ""<Esc>i<c-o>:echo <CR> inoremap ' ''<Esc>i<c-o>:echo <CR> inoremap < <><Esc>i<c-o>:echo <CR> inoremap ( ()<Esc>i<c-o>:echo <CR> inoremap [ []<Esc>i<c-o>:echo <CR> inoremap { <c-r>=InsertBrackets ()<CR> inoremap > <c-r>=JumpNext("<",">")<CR> inoremap ) <c-r>=JumpNext("(",")")<CR> inoremap ] <c-r>=JumpNext("[","]")<CR> inoremap } <c-r>=JumpNext("{","}")<CR> inoremap <m--> [ inoremap <m-=> ] inoremap <m-/> " inoremap <m-[> { inoremap <m-]> } inoremap <m-,> < inoremap <m-.> > inoremap <m-9> ( inoremap <m-0> ) inoremap <m-'> '
Comments[]
I used a similar (but mostly far more basic...) set of functions and mappings for my C and Python code, but with a slightly different behavior...
Here is some code I find a bit more convenient (at least for my liking).
fun! s:Toggle_EditHelpers() if !exists('b:edithelpers_on') || b:edithelpers_on == 0 let b:edithelpers_on=1 inoremap '' ''<Esc>i inoremap ''' ''' inoremap """ """ inoremap "" ""<Esc>i inoremap <> <><Esc>i inoremap [] []<Esc>i inoremap () ()<Esc>i inoremap {} {}<Esc>i cnoremap '' ''<Left> cnoremap ''' ''' cnoremap """ """ cnoremap "" ""<Left> cnoremap <> <><Left> cnoremap [] []<Left> cnoremap () ()<Left> cnoremap {} {}<Left> else let b:edithelpers_on=0 iunmap '' iunmap ''' iunmap """ iunmap "" iunmap <> iunmap [] iunmap () iunmap {} cunmap '' cunmap ''' cunmap """ cunmap "" cunmap <> cunmap [] cunmap () cunmap {} endif endfun " Allow to be easily switched on and off. nnoremap <silent><F9> :call <SID>Toggle_EditHelpers()<CR> vnoremap <silent><F9> <C-C>:call <SID>Toggle_EditHelpers()<CR> inoremap <silent><F9> <C-O>:call <SID>Toggle_EditHelpers()<CR> " turn on by default :call <SID>Toggle_EditHelpers()
One more update. I found this quite useful, as sometimes I delete the ending char, to insert it around a block, and then when I type it again, I just get a flash...
" This code jumps out of the brackets function! JumpNext(startChar, endChar,oneItem) let ret1 = "\<Esc>:if \"0\"==searchpair('".a:startChar."','','".a:endChar."','W','synIDattr(synID(line(\".\"), col(\".\"), 0), \"name\") =~? \"string\"')\<CR>exec(\"normal i".a:oneItem."\")\<CR>endif\<CR>i\<Right>" return ret1 endfunction " mappings inoremap > <c-r>=JumpNext("<",">","\<m-.>")<CR> inoremap ) <c-r>=JumpNext("(",")","\<m-0>")<CR> inoremap ] <c-r>=JumpNext("[","]","\<m-=>")<CR> inoremap } <c-r>=JumpNext("{","}","\<m-]>")<CR>
My only guess is that your escape char is <m-[> Changing that binding may fix your problem.
Here's an update, with toggle, and the toggle should let your escape work again:
" File - matchMe.vim " Date - Wednesday, August 21, 2002 " This code fixes my problem with " does the one format for perl, and acts " correctly with hashes. function! InsertBrackets() let fileType = &ft if fileType == 'perl' let col = col('.') - 1 if !col || getline('.')[col - 1] !~ '\k' && getline('.')[col - 1] !~ '\$' && getline('.')[col - 1] !~ '@' && getline('.')[col - 1] !~ '%' && getline('.')[col - 1] !~ '#' return "{\<CR>\<BS>}\<Esc>ko" else return "{}\<Esc>i\<c-o>:echo \<CR>" endif else return "{\<CR>\<BS>}\<Esc>ko" endif endfunction " This code jumps out of the brackets function! JumpNext(startChar, endChar,oneItem) let ret1 = "\<Esc>:if \"0\"==searchpair('".a:startChar."','','".a:endChar."','W','synIDattr(synID(line(\".\"), col(\".\"), 0), \"name\") =~? \"string\"')\<CR>exec(\"normal i".a:oneItem."\")\<CR>endif\<CR>i\<Right>" return ret1 endfunction " Added toggle. fun! s:Toggle_Edit2() if exists('b:edithelpers_on') && b:edithelpers_on == 1 if (!exists('b:edithelpers2_on') || b:edithelpers2_on == 0) let b:edithelpers2_on=1 " mappings inoremap > <c-r>=JumpNext("<",">","\<m-.>")<CR> inoremap ) <c-r>=JumpNext("(",")","\<m-0>")<CR> inoremap ] <c-r>=JumpNext("[","]","\<m-=>")<CR> inoremap } <c-r>=JumpNext("{","}","\<m-]>")<CR> inoremap <m-=> ] inoremap <m-]> } inoremap <m-.> > inoremap <m-0> ) else let b:edithelpers2_on=0 iunmap > iunmap ) iunmap ] iunmap } iunmap <m-=> iunmap <m-]> iunmap <m-.> iunmap <m-0> endif endif endfun " Added toggle. fun! s:Toggle_Edit() if !exists('b:edithelpers_on') || b:edithelpers_on == 0 let b:edithelpers_on=1 " mappings inoremap " ""<Esc>i<c-o>:echo <CR> inoremap ' ''<Esc>i<c-o>:echo <CR> inoremap < <><Esc>i<c-o>:echo <CR> inoremap ( ()<Esc>i<c-o>:echo <CR> inoremap [ []<Esc>i<c-o>:echo <CR> inoremap { <c-r>=InsertBrackets ()<CR> inoremap <m--> [ inoremap <m-/> " inoremap <m-[> { inoremap <m-,> < inoremap <m-9> ( inoremap <m-'> ' if !exists('b:edithelpers2_on') || b:edithelpers2_on == 0 call <SID>Toggle_Edit2() endif else iunmap " iunmap ' iunmap < iunmap ( iunmap [ iunmap { iunmap <m--> iunmap <m-/> iunmap <m-[> iunmap <m-,> iunmap <m-9> iunmap <m-'> if exists('b:edithelpers2_on') && b:edithelpers2_on == 1 call <SID>Toggle_Edit2() endif let b:edithelpers_on=0 endif endfun nnoremap <silent><F9> :call <SID>Toggle_Edit()<CR> inoremap <silent><F9> <C-O>:call <SID>Toggle_Edit()<CR> call <SID>Toggle_Edit() nnoremap <silent><F8> :call <SID>Toggle_Edit2()<CR> inoremap <silent><F8> <C-O>:call <SID>Toggle_Edit2()<CR> " F-8 toggles the jump " F-9 toggles the bracketing feature and overrides F-8
I think I understand why it doesn't work.
When the function is first called, you get, e.g.,
inoremap " ""<Esc>i<c-o>:echo <CR>
but by the time you toggle it (calling the fucntion again)
iunmap "
It doesn't work because the " is substituted by " " by the interpreter, which is under the influence of the first inoremap, hence the error "No such mapping". I don't know why the interpreter behaves like this, It might be something I have in my .vimrc. Any solutions?