After a good bit of digging and learning some features of Emacs Lisp, I managed to make a hack which produces the effect that I desire. I imagine that I'm not the only one who wants to leave trailing whitespace (at least in some scenarios), so here it is:
;; Hack to leave trailing whitespace
(eval-after-load 'electric '(fset 'electric-indent-post-self-insert-function (lambda ()
"Function that `electric-indent-mode' adds to `post-self-insert-hook'.
This indents if the hook `electric-indent-functions' returns non-nil,
or if a member of `electric-indent-chars' was typed; but not in a string
;; FIXME: This reindents the current line, but what we really want instead is
;; to reindent the whole affected text. That's the current line for simple
;; cases, but not all cases. We do take care of the newline case in an
;; ad-hoc fashion, but there are still missing cases such as the case of
;; electric-pair-mode wrapping a region with a pair of parens.
;; There might be a way to get it working by analyzing buffer-undo-list, but
;; it looks challenging.
;; Don't reindent while inserting spaces at beginning of line.
(or (not (memq last-command-event '(?\s ?\t)))
(save-excursion (skip-chars-backward " \t") (not (bolp))))
(setq pos (electric--after-char-pos))
(let ((act (or (run-hook-with-args-until-success
(memq last-command-event electric-indent-chars))))
(or (memq act '(nil no-indent))
;; In a string or comment.
(unless (eq act 'do-indent) (nth 8 (syntax-ppss))))))))
;; For newline, we want to reindent both lines and basically behave like
;; reindent-then-newline-and-indent (whose code we hence copied).
(let ((at-newline (<= pos (line-beginning-position))))
(let ((before (copy-marker (1- pos) t)))
(unless (or (memq indent-line-function
;; Don't reindent the previous line if the indentation function
;; is not a real one.
;; We are at EOL before the call to indent-according-to-mode, and
;; after it we usually are as well, but not always. We tried to
;; address it with `save-excursion' but that uses a normal marker
;; whereas we need `move after insertion', so we do the
;; save/restore by hand.
(unless (and electric-indent-inhibit
This is just a slightly different version of the
electric-indent-post-self-insert-function which is defined in
electric.el. The only difference is that I removed the following code from the hacked version of the function:
;; Remove the trailing whitespace after indentation because
;; indentation may (re)introduce the whitespace.
Here is my hack in action (I'm not running it in
emacs -Q, since that seems to strip away my hack).