I've defined mappings in my vimrc to automatically enter close parentheses and braces when I enter opening ones with inoremap ( ()<esc>i.

I'd like to do the same for " and ', but only when the cursor currently isn't inside a string - as inside a string ' is probably an apostrophe rather than a string delimiter. How can I do this?

2 Answers 2


One approach might be to use syn* functions. Something like:

fun! Qtx(qt)
    let x = synIDattr(synIDtrans(synID(line("."), col("."), 1)), "name")
    if x != "String" && x != "Comment" && x != "Constant"
        return a:qt . a:qt
    return a:qt

inoremap <silent> <expr> ' Qtx("'")
inoremap <silent> <expr> " Qtx('"')

Idea is to take advantage of the syntax for buffer at cursor position. This can perhaps be solved better. But hopefully a start.

  • What's the rationale behind the function name Qtx? Feb 19, 2015 at 20:47
  • @Carpetsmoker: Quouotix Terminates eXitus.
    – Runium
    Feb 20, 2015 at 7:27

As it has been said, you'll have to check the syntax-context. The old lh-brackets API provides functions for that purpose: Map*Context() functions. Since then the brackets definitions has been encapsulated in :Bracket which will take the context (strings or comments) into consideration.

By default context aware mappings are defined for all the usual brackets pairs like this:

  :Brackets! ( )
  :Brackets! [ ] -visual=0
  :Brackets! [ ] -insert=0 -trigger=<leader>[

  :Brackets! " " -visual=0 -insert=1
  :Brackets! " " -visual=1 -insert=0 -trigger=""
  :Brackets! ' ' -visual=0 -insert=1 -but=function('lh#ft#is_text')
  :Brackets! ' ' -visual=1 -insert=0 -trigger=''

  :Brackets! < > -visual=1 -insert=0 -trigger=<localleader><

  :Brackets! { }
  :Brackets! { } -visual=1 -insert=0 -nl -trigger=<leader>{

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.