1

Here's how emacs indents e.g. Python code:

a = myfun(b,
          c)

I'd like it to be this way:

a = myfun(b,
    c)

Reasoning? If I later replace myfun with myfunction, in the first case it becomes:

a = myfunction(b,
          c)

I can probably use aggressive-indent-mode, but not everybody uses emacs. If I'd like to contribute to, say, an open source project, I can't just impose it on other people.

Is there a way out? For Python? Ruby? Or Javascript? Any of these?

  • What's your setting for indent-tabs-mode? Not sure it's relevant here, but maybe. – Drew Jul 6 at 23:10
  • I believe python-mode sets it to nil. In javascript buffers it's t. In both cases the behavior is as described above. – x-yuri Jul 6 at 23:24
  • The usual solution is to add a newline before b. This works in all Python/Ruby/JS major modes. – Dmitry Jul 8 at 2:03
  • Yeah, that solves it to an extent. And there seems to be no way to override it. At least not for Python. – x-yuri Jul 8 at 19:55
2

You might want to stick to the defaults, since:

r = my_long_function_name(
    param1, param2)

is arguably preferable over:

r = my_long_function_name(param1,
    param2)

But if you care (Emacs 26.3), for Python:

(eval-after-load "python"
  (lambda ()
    (fset 'old-python-indent--calculate-indentation
      (symbol-function 'python-indent--calculate-indentation))
    (defun python-indent--calculate-indentation ()
      (save-excursion
        (pcase (python-indent-context)
          (`(,:inside-paren . ,start)
           (goto-char start)
           (+ (current-indentation) python-indent-offset))
          (_ (old-python-indent--calculate-indentation)))))

    ;; Alternatively, use advice-add
    ;; (defun my/python-indent--calculate-indentation (orig-fun &rest args)
    ;;   ...
    ;;   (apply orig-fun args))
    ;; (advice-add 'python-indent--calculate-indentation :around #'my/python-indent--calculate-indentation)
  ))

For Javascript:

(setq js-indent-align-list-continuation nil)

For Ruby I tried to monkey-patch the Ruby mode, but by default it uses smie-indent-line. Which in its turn might be used not only by the Ruby mode. And I didn't see a better way than to copy the smie-indent-keyword and fix a thing or two. But I'm far from understanding how it works, so I decided to go with the Enhanced Ruby Mode. After installation, you need to add:

(require 'ruby-mode) ;; https://emacs.stackexchange.com/questions/59782/autoloaded-variable-overrides-the-one-from-the-init-file#comment93779_59782
(setq auto-mode-alist
      (mapcar
       (lambda (x)
         (if (eq (cdr x) 'ruby-mode)
             (cons (car x) 'enh-ruby-mode)
           x)) auto-mode-alist))
(setq interpreter-mode-alist
      (mapcar
       (lambda (x)
         (if (eq (cdr x) 'ruby-mode)
             (cons (car x) 'enh-ruby-mode)
           x)) interpreter-mode-alist))

Then to fix the indentation:

(setq enh-ruby-deep-indent-paren nil)
| improve this answer | |

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.