0

Currently I have this javascript code in a js2-mode buffer after I press tab:

const entries = state.get('entries')
          .concat(getWinners(state.get('vote')));

and I would like for it to look like this aligned according to the dots

const entries = state.get('entries')
                     .concat(getWinners(state.get('vote')));

Is there any way to get emacs to behave like this? indent-relative does not seem to be the answer.

1 Answer 1

1

If you don't mind some ugly code, I whipped up something that seems to work:
(Disclaimer: I don't know Javascript, but it works on what I've tested)

(defun my/js2-indent ()
  "If a period is found on the previous line and it's not in a comment
or a string, then indent the current line to the last period on that
line, else indent normally."
  (interactive)
  ;; find column of . if any
  (let ((col (catch 'found
               (save-excursion
                 (back-to-indentation)
                 ;; if the start of the line is not a period (46)
                 ;; or is in a comment then indent normally
                 (when (or (not (eq (char-after) 46))
                           (nth 4 (syntax-ppss)))
                   (throw 'found nil))
                 (end-of-line 0)
                 (backward-char)
                 ;; if the previous line ends with a comment
                 ;; then skip the comment
                 (if (nth 4 (syntax-ppss (1- (point))))
                     (progn
                       (forward-line)
                       (forward-comment -1))
                   ;; syntax-ppss moved point backward
                   ;; so go forward a char
                   (forward-char))
                 ;; while the char isn't a newline (10)
                 (while (not (eq (char-after) 10))
                   ;; break if it's a period (46)
                   ;; and not in a string
                   (if (and (eq (char-after) 46)
                            (not (nth 3 (syntax-ppss))))
                       (throw 'found (current-column))
                     (backward-char)))
                 nil))))
    ;; indent to the found column, otherwise indent normally
    (if col
        (indent-line-to col)
      (js2-indent-line))))

Then to set the indenting so that indent-region or electric-indent-mode don't undo the changes, set the variable indent-line-function to it:

(add-hook 'js2-mode-hook (lambda ()
                           (setq indent-line-function #'my/js2-indent)))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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