2

I'm new to Emacs.

I'm trying to write an elisp function that works across all modes. Specifically, I want to write a function that inserts braces (a bit like insert-parentheses) in the same way the following key sequence does for a dumb editor that only supports auto-indent:

"{" <ret> "}" <up-arrow> <end> <ret> <tab>

This key sequence works for both Java and C# (bsd) style indentation. I need it to work in all brace-y emacs modes, and also in plain text files - I have other formats that have no emacs modes but still use braces.

Here's my 12th attempt or so:

(defun insert-braces-macro ()
  (interactive)
  (insert "{")
  (newline)
  (indent-relative t)
  (insert "}")
  (forward-line -1)
  (end-of-line)
  (newline)
  (indent-relative t)
  (indent-relative nil))

Unfortunately, this doesn't work quite right. I don't think indent-relative is the right function, because it doesn't indent correctly in Java-style:

f |

expands into:

f {
  |
}

and in C mode:

somelongword another |

expands to:

somelongword another {
             |
}

But indent-according-to-mode isn't right either, because it will indent too much in C-ish modes (the trailing '}' is indented) and not at all in Fundamental mode.

What's the right way to handle this?

Barry Kelly
  • 41,404
  • 5
  • 117
  • 189
  • Is it because different modes have different default indentations unless the user sets them specifically? `(defun my-tabset-hook () (setq indent-tabs-mode t) (setq tab-stop-list (number-sequence 2 200 2)) (setq tab-width 2) (setq indent-line-function 'insert-tab) ) (add-hook 'text-mode-hook 'my-tabset-hook) (add-hook 'tex-mode-hook 'my-tabset-hook) (add-hook 'LaTeX-mode-hook 'my-tabset-hook)` – lawlist Sep 22 '13 at 05:57

2 Answers2

4

indent-according-to-mode is the right answer, I think, but you need to remember that it can't predict the future, so you need to call it after inserting the text rather than before:

(defun insert-braces-macro ()
  (interactive)
  (insert "{")
  (newline) (indent-according-to-mode)
  (save-excursion
    (newline)
    (insert "}")
    (indent-according-to-mode)))
Stefan
  • 27,908
  • 4
  • 53
  • 82
  • To be frank, I'd prefer to disable emacs' smart indenting altogether. It's too unpredictable and doesn't work in fundamental mode. I can use dumb auto-indent with my eyes closed and know what it does no matter what the source code is written in... – Barry Kelly Sep 22 '13 at 14:45
  • indent-according-to-mode doesn't indent at all in fundamental mode – Barry Kelly Sep 22 '13 at 14:57
  • If you use `fundamental-mode`, that's a problem in itself. – Stefan Sep 22 '13 at 18:39
  • 1
    If the indentation is unpredictable, then it's a bug, which you should report. If it's predictable but different from the style you like, of couse, that's another problem. – Stefan Sep 22 '13 at 18:41
2

Here's what I've been using for a long time:

(defun ins-c++-curly ()
  "Insert {}.
Treat it as a function body when from endline before )"
  (interactive)
  (if (looking-back "\\()\\|try\\|else\\|const\\|:\\)$")
      (progn
        (insert " {\n\n}")
        (indent-according-to-mode)
        (forward-line -1)
        (indent-according-to-mode))
    (insert "{}")
    (backward-char)))

This function:

  1. inserts a {} block when looking back at a place where it's appropriate, e.g. after a ).
  2. otherwise, inserts {} and goes backward one char. Useful for arrays and the new-style initialization.

This works for C++, where I have indentation set to 4 spaces, as well as for Java, where I have it at 2 spaces.

phils
  • 71,335
  • 11
  • 153
  • 198
abo-abo
  • 20,038
  • 3
  • 50
  • 71
  • indent-according-to-mode doesn't indent in Fundamental mode, so it is no good for my purposes. Unless it can be made to indent in fundamental mode? – Barry Kelly Sep 22 '13 at 14:58
  • What are your purposes then? I imagine that curly braces means code, and why write code in fundamental mode? How would you want to indent in fundamental mode? I could slap an `(if (eq major-mode 'fundamental-mode) ...)` onto the code, but I'm not sure what to do afterwards. – abo-abo Sep 22 '13 at 15:09
  • I use curly braces in dumping ASTs from compiler front ends, and other bracketing constructs in other ad-hoc file formats. There are too many to be writing major modes for them, much less configuring all those modes. – Barry Kelly Sep 22 '13 at 15:19
  • I'm going to try and take this in a different direction. I asked another question about disabling smart indent altogether. If I can get a dumb autoindent mode working in Emacs, I can solve this problem for once and for all: http://stackoverflow.com/questions/18945380/how-to-get-auto-indent-not-smart-indent-in-emacs-in-all-modes – Barry Kelly Sep 22 '13 at 15:23