7

I have electric-pair-mode on (which isn't really particularly relevant, as this could apply to any auto-pairing mode or even manual parens), but in a nutshell, I'd like it so that in the case I have:

function foo() {|}

(where | is the mark)

If I press enter, I would like to have it automatically go to

function foo() {
|
}

It would also mean that

function foo(|) {}

would become

function foo(
|
){}

I already have things to take care of the indentation, but I'm not sure how to say "if I'm inside any empty pair of matched parenthesis, when I press return, actually insert two new lines and put me at the first one".

Thanks!

Philip Kahn
  • 614
  • 1
  • 5
  • 22
  • you want the second case as well? Or that would be a side-effect? – Rorschach Feb 28 '14 at 23:16
  • the answers [here](http://stackoverflow.com/questions/3801147/how-can-can-i-get-emacs-to-insert-closing-braces-automatically) combined should tell you how to do this – Rorschach Feb 28 '14 at 23:27
  • The second case should be a side effect -- but I don't see how the answers provided work then. The case you linked to is explicitly replacing "{" -- this that I'm suggesting/asking about would replace everything that fits a matched parens. – Philip Kahn Mar 01 '14 at 01:07
  • I suppose the pseudocode would be something like: `On RET: if move_mark_left.matchParens() is move_mark_right: RET, RET, up` – Philip Kahn Mar 01 '14 at 01:16

2 Answers2

6

Here is what I have in my init file, I got this from Magnar Sveen's .emacs.d

(defun new-line-dwim ()
  (interactive)
  (let ((break-open-pair (or (and (looking-back "{") (looking-at "}"))
                             (and (looking-back ">") (looking-at "<"))
                             (and (looking-back "(") (looking-at ")"))
                             (and (looking-back "\\[") (looking-at "\\]")))))
    (newline)
    (when break-open-pair
      (save-excursion
        (newline)
        (indent-for-tab-command)))
    (indent-for-tab-command)))

You can bind it to a key of your choice. I have bound it to M-RET but if you want, you can bind it to RET. The lines

(or (and (looking-back "{") (looking-at "}"))
    (and (looking-back ">") (looking-at "<"))
    (and (looking-back "(") (looking-at ")"))
    (and (looking-back "\\[") (looking-at "\\]")))

check if cursor is at {|}, [|], (|) or >|< (html).

  • Thanks! Almost exactly what I was looking for. It's a shame the paren-match has to be explicit rather than algorithmic, though. – Philip Kahn Mar 01 '14 at 04:50
  • Assuming the modes you're using assign `(` and `)` char-syntax for the delimiters you want, `(and (eq ?\( (char-syntax (char-before))) (eq ?\) (char-syntax (char-after))))` will work. For example this will cover `() [] {}` in `java-mode`. But not `><` -- not even in `html-mode`. Still, that makes it mostly "algorithmic". – Greg Hendershott Feb 17 '16 at 02:48
4

You may also want to look into smartparens. Specifically, see the page on insertion hooks.

Here's the config I personally use:

(with-eval-after-load 'smartparens
  (sp-with-modes
      '(c++-mode objc-mode c-mode)
    (sp-local-pair "{" nil :post-handlers '(:add ("||\n[i]" "RET")))))

This has the added benefit of indenting the current line automatically as well. This can easily be generalized to more modes (using sp-pair for global pairs) and paren types (just duplicate the code), if you please.

PythonNut
  • 6,182
  • 1
  • 25
  • 41