If you really do want to change it, it's Emacs, of course you can.
Brutality
In the extreme, one can always use M-x fundamental-mode
to “turn off” all of the mode-specific goodies, but that's probably overkill here.
Conformity
The only thing in your code that seems to be particularly injured by indentation was the use of (if … (progn))
forms.
(if … (progn))
is usually considered bad form; one uses one of when
, unless
, or cond
for such cases more often. Switching these to when
or cond
forms yields what you might have wanted/expected:
Your example code with standard indentation and dangling )
s:
(defun my:push-whitespace (&rest skip)
(if (my:prev-whitespace-pushed) (progn
(setq my:prev-whitespace-mode whitespace-mode)
(setq my:prev-whitespace-pushed t)
(my:force-modes nil 'whitespace-mode)
))
)
↓
(defun my:push-whitespace (&rest skip)
(when (my:prev-whitespace-pushed)
(setq my:prev-whitespace-mode whitespace-mode)
(setq my:prev-whitespace-pushed t)
(my:force-modes nil 'whitespace-mode)
)
)
or
(defun my:push-whitespace (&rest skip)
(cond ((my:prev-whitespace-pushed)
(setq my:prev-whitespace-mode whitespace-mode)
(setq my:prev-whitespace-pushed t)
(my:force-modes nil 'whitespace-mode))
)
)
Customization
The indentation patterns for various special forms are defined by lisp-indent-function
properties on their symbols.
This will change the progn
special form to indent from the prior (containing) form's start point, rather than its own:
(defun progn-java-indent (path state indent-point sexp-column normal-indent)
(declare (ignored path state sexp-column normal-indent))
;; Find the point at the start of the containing sexp
(let ((containing-point (condition-case
nil
(save-excursion
;; Start at the current line
(goto-char indent-point)
;; Up once to `|(progn` and again to its parent
(up-list -2)
;; Take that column
(current-column))
;; If there isn't a containing list, use the
;; left margin, instead.
(scan-error 0))))
;; Increase by standard indentation, or 2, by default.
(+ containing-point (or lisp-indent-offset
2))))
The scan-error
condition is signaled by up-list
when progn
appears as a top-level form.
You could put that into your init.el
and associate it with
(put 'progn 'lisp-indent-function 'progn-java-indent)
With your sample code, I get:
(defun my:push-whitespace (&rest skip)
(if my:prev-whitespace-pushed () (progn
(setq my:prev-whitespace-mode whitespace-mode)
(setq my:prev-whitespace-pushed t)
(my:force-modes nil 'whitespace-mode)
))
)
QED, I think.