I am writing source code and a lot of times I need to press Enter and have the newline indented with 4 spaces more than the previous. As I don't want to do it always, I would like to be able to use C-RET to achieve this.

While searching I found C-j (newline-and-indent) but it always indents with the same amount of spaces and not relatively to the current line.

How can I achieve that?

To make myself clear, what I want is:

First line

/* Not indented. */

    Second line 

    /* Second line indented with 4 spaces. */

        Third line

        /* Third line indented with 4 spaces
        but relative to the second so now it
        has 8 spaces. */

Here's a simple function that indents (with spaces) 4 spaces relative to the previous line:

(defun indent-relative (&optional arg)
  "Newline and indent 4 spaces relative to previous line.  With
C-u, indent to same level as previous line."
  (interactive "P")
  (let* ((amount (if arg 0 4))
         (indent (+ amount (save-excursion
    (newline 1)
    (insert (make-string indent ?\s))))

(global-set-key (kbd "C-<return>") #'indent-relative)
| improve this answer | |
  • Thank you that works great. As I was testing it I found that I also need another feature. A key, let's say Enter, that when pressed it will go to the newline but with the intend of the previous. So if I press Enter in the second line the third will be created with 4 spaces. I'm sorry for not mentioning it previously but I just found out about that. – Adam Nov 22 '14 at 21:01
  • @Adam: maybe I'm misunderstanding, but isn't that what newline-and-indent gives you? – Dan Nov 22 '14 at 21:29
  • When I am using it after lets say 2 C-RET (having 8 spaces) the newline-and-indent gives me only an indent of 2 spaces not 8 as I want. :) – Adam Nov 22 '14 at 21:32
  • @Adam, if I understand correctly, you can use the revised function as C-u C-return to get what you're after. Please edit your question to reflect this part of the question. – Dan Nov 22 '14 at 21:39
  • Thank you that works great! I will edit it. I am trying to understand your code and I can't see how does C-u C-RET is defined so to bind it to Enter. :) – Adam Nov 22 '14 at 22:02

You can bind the C-RET to do exactly that: newline and 4 spaces.

(global-set-key (kbd "C-<return>") "\C-j    ")
| improve this answer | |
  • Thank you but the problem is not the binding. The C-j indents each newline with the same amount of spaces and I don't want that. :) – Adam Nov 22 '14 at 21:02
  • That's pretty clever! One minor issue is that it depends on C-j being bound to newline-and-indent. – Dan Nov 22 '14 at 21:48
  • @Adam Yes, that's why I added the 4 spaces. :-) – Malabarba Nov 22 '14 at 21:55
  • @Malabarba sorry I didn't understand the meaning of the code! – Adam Nov 22 '14 at 21:59
  • 1
    Dan: That's not a bug, it's a feature! C-j (and indeed M-j, which is the functionality I prefer) are the standard bindings for this functionality, but newline-and-indent is not necessarily the command bound to that key. Some major mode implement their own way of doing this, but they will invariably use that same key binding. By depending on the key sequence convention instead of the function name, you actually get better compatibility with other modes. (Obviously if you've messed with those bindings yourself, you'll also know what you need to change for this solution.) – phils Nov 22 '14 at 23:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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