Fandom

Vim Tips Wiki

Brackets and parentheses in Perl

1,624pages on
this wiki
Add New Page
Talk0 Share

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.

Duplicate tip

This tip is very similar to the following:

These tips need to be merged – see the merge guidelines.

Tip 318 Printable Monobook Previous Next

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-'> '

CommentsEdit

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?


Also on Fandom

Random Wiki