2

I have come to hate the inconsistency of the electric indent mode and I haven't much of a clue about how it works anyways, so I've disabled it and am trying to get the desired behavior from scratch. I want emacs to indent me to the previous line's indentation level and do nothing else on RET. indent-relative seems to be the right function for the job. Seems easy enough, and yet I cannot get it to work. This is what I have thus far:

(electric-indent-mode -1)

(defun my-newline-and-indent ()
  (interactive)
  (newline)
  (indent-relative))

I used to bind this with global-set-key, but hooking it to the specific modes I use is a better idea (found here):

(defun my-keys ()
  (local-set-key [(return)] 'my-newline-and-indent))

(add-hook 'c-mode-hook 'my-keys)

The above does not indent new lines in C. I also tried the same thing with indent-relative-maybe, but that doesn't work either. What am I doing wrong?


Edit: now that I got it working thanks to @Tyler, the function that better fits the behavior I want is actually indent-relative-maybe (though I can't find any documentation on it online). indent-relative indents to the last whitespace on the previous line, which is too zealous. For example, here is how it indents in F90 mode:

program test
        _

By contrast, indent-relative-maybe seems to only indent to the first non-whitespace character.

  • Does the built-in `newline-and-indent` do what you want? – Tyler Jun 15 '21 at 21:51
  • Your code works for me. Can you provide an example of C code and show us where pressing return doesn't give you the indentation you expect? – Tyler Jun 15 '21 at 21:56
  • @Tyler I added a short demonstration video of the behavior I mean. Electric indent would have started a new line on the 4th column after that comment, which is also what I want to replicate – Andrii Kozytskyi Jun 15 '21 at 22:21
  • When I run your code, and enter the elisp you have above, this works as expected. I enter `int main() {`, press enter, and the cursor moves to the next line under the `m` in main. Pressing two slashes and return, the cursor moves to the next line under the first slash. – Tyler Jun 15 '21 at 22:27
  • Are you sure you set `(electric-indent-mode -1)`? I don't think emacs would automatically indent C code after braces with electric indent disabled, and the code I posted should not do that either – Andrii Kozytskyi Jun 15 '21 at 22:38
  • I just tried again from `emacs -Q`, and turned off electric-indent-mode explicitly. Same behaviour as I described before. It does automatically indent after braces, that's what `my-line-and-indent` does. After you insert the newline, it calls `indent-relative`, which after the first brace lines up with the `m`. – Tyler Jun 15 '21 at 23:12
  • I have no clue how you're getting these results. [Here is a video of me using nothing but the code snippet as the init file and still getting nothing.](https://i.imgur.com/azVGlz6.mp4) What could be causing this? – Andrii Kozytskyi Jun 15 '21 at 23:38
  • Let us [continue this discussion in chat](https://chat.stackexchange.com/rooms/126528/discussion-between-andrii-kozytskyi-and-tyler). – Andrii Kozytskyi Jun 15 '21 at 23:41
  • 2
    You've misspelled `c-mode-hook` in your init file. – NickD Jun 16 '21 at 00:21

1 Answers1

2

In a terminal the value of [(return)] doesn't apply. You need to use (kbd "RET") instead. (or probably other variations would do, but not [(return)]).

Tyler
  • 21,719
  • 1
  • 52
  • 92
  • 1
    But he's called the function: `(electric-indent-mode -1)`. And the init file copied directly from the question seems to work fine (actually, you are right about the terminal bit: I checked in a gui session). The problem I saw was that he misspelled `c-mode-hook` in the init file that he used in his video. – NickD Jun 16 '21 at 01:52
  • @NickD you're right, I was obviously not paying close enough attention! – Tyler Jun 16 '21 at 15:48
  • Well, I wasn't paying close enough attention either, so I cannot throw stones :-) – NickD Jun 16 '21 at 18:10