1

In sublime text 2 when you:

BLOCK { <Return>

It generates (where the pipe is the cursor):

BLOCK {
  |
}

How can I get Vim to behave this way?

I have autoindent on, and smartindent off because with smartindent it does this on return:

BLOCK {
 |}

To be more clear, I'm specifically looking for 2 returns, moving up a line, and tabbing in (2 soft tabs to be specific). I already have it auto-matching characters like {, (, [ etc.

Oscar Godson
  • 31,662
  • 41
  • 121
  • 201
  • `imap { {}O`; depending on your plugin you may need to use `inoremap` – Kevin Dec 03 '12 at 21:30
  • @Kevin all that does is waits a second, then puts a `}` after `{`. No new lines or anything for me at least in a blank file, no extension and a .js file – Oscar Godson Dec 03 '12 at 21:31
  • Did you hit `Enter` after the `{`? It's worked perfectly for me for years. – Kevin Dec 03 '12 at 21:35
  • @Kevin oooh, I was expecting it to automatically do it. thanks! This might be it! I added two spaces after O and it appears to be working exactly as I wanted. Could you make this an answer so I can mark it up and make it the "correct" answer unless someone has something better, but this appears to be perfect. – Oscar Godson Dec 03 '12 at 21:38

5 Answers5

3

A simple mapping will work for most purposes:

imap {<cr> {<cr>}<c-o>O

Depending on plugins, some users may need inoremap instead of imap.

Kevin
  • 53,822
  • 15
  • 101
  • 132
  • 3
    There is likely no reason that the OP would prefer `imap` over `inoremap` so should go with `inoremap` unless there is a good reason to do otherwise. – dash-tom-bang Dec 03 '12 at 21:54
2

Before it was with TextMate, now it's with ST2.

You have basically two paths before you.

  • The "dumb" path

    One could come up with dozens of variations of this method: you simply create a mapping that executes the series of key presses needed to reach your goal:

    inoremap {<CR> {<cr><cr>}<C-o>k<tab>
    

    I called it "dumb" but it doesn't mean that you would be dumb to use it: it's low-tech, has no dependencies, is easy to customize and it can be mapped to anything you like.

  • The "smart" method

    This method involves the use of a plugin. I use DelimitMate but there are many others, choose your poison.

romainl
  • 186,200
  • 21
  • 280
  • 313
1

I did some quick digging for vim addons (which are often the solution to this sort of problem). I don't think I've found what you want: there are a few addons that come close, but nothing that inserts the extra newline before the closing brace.

You could do something like

imap { {<return><return>}<up><tab>

but this will get awkward if you are working in a language that uses braces in other situations. You could instead react to the newline:

inoremap <return> <return><return>}<up><tab>

Of course this will trigger on EVERY entered newline, rather than just those following an opening brace. To get it to check that the brace is the last character of the current line, you can:

  • Have a function (in ~/.vimrc or somewhere in ~/.vim/plugin) that looks like

    function! CloseBraceIfOpened()
      if getline(".")[-1:] == '{'
        " insert a space and then delete it to preserve autoindent level
        exec "normal o "
        normal x
        normal o}
        normal k
      else
        normal o
      endif
    endfunction
    
  • also do

    inoremap <buffer> <enter> <esc>:call CloseBraceIfOpened()<enter>A
    

Note that this imap is buffer-specific, so that mapping will only apply to the buffer you are in when you run it. To have it apply to all buffers, remove <buffer>.

If you are really ambitious/particular, you can do tests in the function to see if the code in the current line really opens a block.

To get the indentation working the way you want it, turn on the 'autoindent' and 'smartindent' settings.

: set autoindent smartindent

To have it on by default, add

set autoindent smartindent

to ~/.vimrc.

Community
  • 1
  • 1
intuited
  • 23,174
  • 7
  • 66
  • 88
  • Smart indent doesn't do this. It actually makes it worst. It creates blocks like: Oops, let me edit my OP. – Oscar Godson Dec 03 '12 at 20:58
  • Well, I have it auto create the matching `{` with a different option. The question is to to create _two_ returns and put the cursor in between the block with a tab/soft-tab. – Oscar Godson Dec 03 '12 at 21:01
  • Thanks, but inserting an auto matching character isn't what I need. My Vim setup already does that. I'm specifically looking for the auto-returns and tab. – Oscar Godson Dec 03 '12 at 21:16
  • Very weird... in a JS file it doesn't work. In my vimrc file this works. `noremap { {}`. I tried `imap` too. – Oscar Godson Dec 03 '12 at 21:29
  • What happens when you use it in the other files? – intuited Dec 03 '12 at 21:57
0

I use the following map:

inoremap {{ {<CR><CR>}<ESC>kcc

so instead of using {<CR> I use this mapping. Besides that I also use the plugin mentioned by romainl, DelimitMate for other mappings with braces.

skeept
  • 12,077
  • 7
  • 41
  • 52
0

I had the same problem and delimitMate solves it. After installing it you can enable it with:

let g:delimitMate_expand_cr = 1

There are lot's of hacks that delivers the SublimeText experience. Because I got frustrated I've created a project that includes all those features in a single vim distribution (without the need of installing/compiling external plugins/tools).

You can check it out from here: https://github.com/fatih/subvim

Fatih Arslan
  • 16,499
  • 9
  • 54
  • 55