sponsor Vim development Vim logo Vim Book Ad

intermediate Tip #318: Extended Bracket and Parenthesis + extras for perl

 tip karma   Rating 9/3, Viewed by 3031 

Read and edit this tip on the Vim tip wiki. The wiki may have a more recent version of this tip.

created:   August 22, 2002 8:11      complexity:   intermediate
author:   Abitkin      as of Vim:   5.7

This is an extension of vimtip #153
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
}
Where as, 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 charcter.  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 still keeps 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(normChar)
let ret = "\<space>\<esc>ma\<left>/\\".a:normChar."\<cr>mb`ai\<del>\<esc>`bi\<right>"
return ret
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-'> '

"########################################
" End Of File
"########################################

If you have any other suggestions, drop a note...

 rate this tip  Life Changing Helpful Unfulfilling 

<< Mozilla Vim Keybindings | text formatting (lining up ='s,('s etc)) >>

Additional Notes

[email protected], August 22, 2002 9:15
Found a bug or two...
Here's the Fix:
"########################################
" 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-'> '
Alex A. Naanou <[email protected]>, August 22, 2002 15:29
Cool!!!
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 :) )

---cut---

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
" I like most features 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()

---uncut---


thanks!!
[email protected], August 23, 2002 12:58
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>
Anonymous, August 27, 2002 9:39
Look out for other bracketing scripts!
Anonymous, August 28, 2002 18:34
not sure why, but this mapping tip does not work for me when i use it on gvim6.0 on unix (seems to be ok for gvim6.1 on PC and gvim5.5 on Unix).

the <esc> char will be mapped directly as text instead of the usual <esc> function.

any idea why is that so??

thanks in advance!!
[email protected], August 29, 2002 8:43
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
" E-Mail - [email protected]
"########################################

" 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.
" Date: Thursday, August 29, 2002 @ 07:57 AM
" Thanks to: Alex A. Naanou <[email protected]>
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.
" Date: Thursday, August 29, 2002 @ 07:57 AM
" Thanks to: Alex A. Naanou <[email protected]>
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
[email protected], August 15, 2003 23:37
For me, trying to use F9 (Toggle) sends a whole list of error E31 "No such mapping".... Other than that, it works as expected. Tried both unix and windows, same results
I would love to have the Toggle...
Thanks in advance!
[email protected], August 16, 2003 0:22
I think I understand why it doesn't work.

When the fucntion 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?

THanks a lot!

Anonymous, April 15, 2004 10:46
Thanks atkinssc.

I'm using 'vim 6.2 for MS-Window' downloaded from this site.

I tried your script to find all the functions are working fine except JumpNext function with ].

When I tried ] key inside a [] bracket, vim doesn't get out of the bracket, adding an extra ] inside the bracket.

Could you tell me what I have to do to get out of [] brackets?
If you have questions or remarks about this site, visit the vimonline development pages. Please use this site responsibly.
Questions about Vim should go to the maillist. Help Bram help Uganda.
   
Sponsored by Web Concept Group Inc. SourceForge.net Logo