The following code leverages visual-line-mode, font-lock-mode and filladapt to provide a soft indent feature. I’ve only been using it for a while, so it may have some rough edges yet that need to be smoothed out; comments or suggestions would be very welcome. – JamesWright
(defvar adaptive-soft-wrap-font-keywords '((find-next-fillable-line 0 (list 'face nil 'wrap-prefix fill-prefix) append)) "Add this to a mode's keywords to enable adaptive soft-wrapping.")
(define-minor-mode adaptive-soft-wrap-mode "Use font-lock machinery to automatically set `wrap-prefix' properties on each line based on its filladapt fill-prefix." nil nil nil (require 'filladapt) (require 'font-lock) (if adaptive-soft-wrap-mode (progn (font-lock-add-keywords nil adaptive-soft-wrap-font-keywords t) (unless (memq 'wrap-prefix font-lock-extra-managed-props) (setq font-lock-extra-managed-props (cons 'wrap-prefix font-lock-extra-managed-props)))) (progn (font-lock-remove-keywords nil adaptive-soft-wrap-font-keywords) (font-lock-fontify-buffer))))
(defun find-next-fillable-line (bound) (let ((prefix nil) (nleft 0) (bolp nil)) (save-restriction (setq bolp (bolp)) (narrow-to-region (point) bound) (if (and (not bolp) (zerop (setq nleft (forward-line 1)))) (goto-char (point-at-bol))) ;; From this point onward, point is either at bol or we are done (while (and (zerop nleft) (not (setq prefix (fillable-line-prefix))) (zerop (setq nleft (forward-line 1))))) (if prefix (let ((s (point-marker)) (e (save-excursion (goto-char (point-at-eol)) (point-marker)))) (set-match-data (list s e) t) (setq fill-prefix prefix) prefix) (progn (goto-char (point-min)) nil)))))
(defun fillable-line-prefix () "Return a prefix for the current line if at the beginning of a fillable line, or NIL otherwise." (let* ((tokens (filladapt-parse-prefixes)) (prefix (when tokens (filladapt-make-fill-prefix tokens)))) (if (> (length prefix) 0) prefix)))