2

How can I achieve the following auto-close bracket behavior in Vim 8 using no external plugins?

If I use

inoremap { {};<Left><Left>

then if I enter

int array[2] = {

it will automatically perform correctly by placing }; as well as placing the cursor inside the brackets.

But what I want is that when I am working with structs I want the following to happen after I press enter immediately after inserting the first bracket,

struct test {
    | <- cursor is here
};

What do I have to change in order to achieve both behaviors shown above in Vim 8?

user395980
  • 356
  • 1
  • 8
  • You could keep your current mapping and add additional mappings as outlined in this answer: https://stackoverflow.com/a/6071166/155299 – Randy Morris Mar 06 '20 at 18:16

2 Answers2

2

The part of "using no external plugins" is the tricky one.

To get the behavior you want, you have to inoremap the <CR> key, probably using an <expr> mapping, that will look at the character under the cursor, see if it's a } and, in that case, move it two lines down, unindent that line (only if the first one was indented), go back up one, re-indent it...

And if it's not a }, then just behave like a normal <CR> (this part is easy with an <expr> mapping.)

The problem is, when you get that far, you're halfway through to writing a plug-in, so you might as well just get one that was thoroughly debugged for all the corner cases that can happen here.

If you want something really simple though:

inoremap <expr> <CR>
    \ getline('.')[col('.')-1]=='}'
    \ ? "\<CR>\<C-d>\<C-o>O" : "\<CR>"

It uses a <CR> followed by a CTRL-D to unindent the }, then CTRL-O to use the O normal mode command, which inserts a new line above this one. (Using O here to get the indentation right.)

But, as mentioned, this will not always work as expected. It's very simple.

And next you'll want to fix backspace, or fix it that when you type } if you're on a } already you'll skip it... You'll want the plug-in, trust me!

filbranden
  • 8,522
  • 2
  • 16
  • 32
0

How about adding this in your ftplugin file:

function! CloseBracket()
        if getline('.') =~ '^struct\s\w\+\s'
                return "{}\<left>\<cr>\<c-o>O\<tab>"
        endif
        return "{};\<left>\<left>"
endfunction

inoremap { <C-R>=CloseBracket()<CR>

So when { is pressed in insert mode we insert the contents of a register , the following = then states we want to use the expression register which in this case is the CloseBracket function.

The function it self gets the current line, and runs some regex to see if the line is a struct definition, if so it does some fancy foot work as requested, otherwise it just closes the brackets and moves the cursor left.

110100100
  • 169
  • 4