+;;; Backslash alignment
+
+(defvar-local sm-c--bs-changed nil)
+
+(defun sm-c--bs-after-change (beg end _len)
+ (unless undo-in-progress
+ (if (null sm-c--bs-changed)
+ (setq sm-c--bs-changed (cons beg end))
+ (cl-callf (lambda (x) (min x beg)) (car sm-c--bs-changed))
+ (cl-callf (lambda (x) (max x end)) (cdr sm-c--bs-changed)))))
+
+(defun sm-c--bs-realign ()
+ (when sm-c--bs-changed
+ (sm-c--bs-realign-1 (car sm-c--bs-changed) (cdr sm-c--bs-changed))
+ (setq sm-c--bs-changed nil)))
+
+(defun sm-c--bs-realign-1 (from to)
+ (save-excursion
+ (goto-char from)
+ (end-of-line)
+ (unless (zerop (mod (skip-chars-backward "\\\\") 2))
+ (skip-chars-backward " \t")
+ (let ((col (current-column))
+ start end)
+ (while
+ (progn (setq start (point))
+ (end-of-line 0)
+ (and (< (point) start)
+ (not (zerop (mod (skip-chars-backward "\\\\") 2)))))
+ (skip-chars-backward " \t")
+ (setq col (max (current-column) col)))
+ (goto-char from)
+ (while
+ (progn (setq end (point))
+ (end-of-line 2)
+ (and (> (point) start)
+ (not (zerop (mod (skip-chars-backward "\\\\") 2)))))
+ (skip-chars-backward " \t")
+ (setq col (max (current-column) col)))
+ (goto-char to)
+ (beginning-of-line)
+ (unless (or (> (point) end) ;Don't realign if we changed outside!
+ (< end start)) ;A lone \
+
+ (setq col (1+ col)) ;Add a space before the backslashes.
+ (goto-char end)
+ (end-of-line)
+ (while (>= (point) start)
+ (cl-assert (eq (char-before) ?\\))
+ (forward-char -1)
+ (let ((curcol (current-column)))
+ (cond
+ ((> col curcol) (indent-to col))
+ ((< col curcol)
+ (move-to-column col t)
+ (delete-region (point)
+ (progn (skip-chars-forward " \t") (point))))))
+ (end-of-line 0)))))))
+