I am looking for a way to remove a pair of brackets in the insertion mode without plugins. It's like


When I press the delete key only the first bracket get deleted


But I want to auto-remove the second one when I press the delete key if there is no content in the pair of brackets. And I want to achieve this without plugins.


With the cursor in or on the parentheses, you can use Ctrl+o combined with dab to delete the parentheses and any text contained within.

Ctrl+o lets you execute one normal mode command, then return to insert mode. dab deletes a block text object, including ( and ). This also works with an empty block ().


Say I am in insert mode with the following text, with the cursor position indicated by :

here is (some text█in ~parentheses~)

After hitting Ctrl+odab, you would then be left in insert mode with the following text:

here is █

You could even wrap it in a mapping if its a functionality you would like to use often (<Leader><BS> in this example):

inoremap <Leader><BS> <C-o>dab

There are analogs for [] and {} blocks too.


:h i_CTRL-O
:h a(
:h text-objects

There are two approaches to detect weither we are within an empty pair.

  • The simple one: getline('.')[col('.')-2 : col('.')] == '()' that's simple to understand. To support more pairs we can test a regex instead: getline('.')[col('.')-2 : col('.')] =~ '\V()\\|[]\\|{}\\|<>\\|$$'

  • The one that supports multicharacters pairs like <del></del>. Instead of playing with a strip of the current line, we can use /\%c. This time it's easier to maintain a list of pairs activated for the current filetype as a list, apply some transformation on that list, and we have our regex. e.g.

    let b:pairs = [['(', ')'], ['\\(', '\\)'], ['<', '>'], ['<del>', '</del>']
    " excerpt from lh-brackets
    let regex = let regex = '\V\('.join(map(copy(crt_pairs), 'join(v:val,"\\%'.col('.').'c")'), '\|').'\)'
    return getline('.') =~ regex

    Of course this b:pairs maintenance is best done with .... a plugin that keeps tracks of the recorded pairs for the current filetype.

Now, regarding the delete part. It's about executing <c-g>U<bs> and <del> as many times as required each. The i_CTRL-U is required to support redo as <bs> moves the cursor. In case of multi-byte characters implied in the pairs, don't forget to count the length with the right function.

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