Skip to content

Instantly share code, notes, and snippets.

@no-defun-allowed
Last active January 19, 2023 01:20
Show Gist options
  • Save no-defun-allowed/34b097954cc5af6f80abbd2f7fa94f77 to your computer and use it in GitHub Desktop.
Save no-defun-allowed/34b097954cc5af6f80abbd2f7fa94f77 to your computer and use it in GitHub Desktop.
;; A grown up version of https://lists.gnu.org/archive/html/emacs-devel/2018-03/msg00127.html
(defvar-local *vpi-did-full-indent?* nil)
(defun vpi-find-start ()
(loop
(back-to-indentation)
(when (or (= (point-min) (point)) (zerop (current-column)))
(return))
(forward-line -1)))
(cl-defun variable-pitch-indent ()
(interactive)
(save-excursion
(let ((spine "")
(face `(:foreground ,(face-attribute 'default :background nil)))
(needs-full? (not *vpi-did-full-indent?*))
(lines 0))
;; Start early if we know the rest of the buffer is okay. Note
;; that we won't propagate anything beyond lines with no
;; indentation.
(if needs-full?
(goto-char (point-min))
(vpi-find-start))
(while (not (eobp))
(back-to-indentation)
;; Get out early if we know the rest of the buffer is okay.
(when (and (not needs-full?) (zerop (current-column)) (plusp lines))
(return-from variable-pitch-indent lines))
(unless (eolp)
(let* ((indentation-amount (current-column))
(spine-cut (min (length spine) indentation-amount))
(spine-prefix (substring spine 0 spine-cut))
(spine-padding (make-string (- indentation-amount spine-cut) ?\s))
(spine-end (buffer-substring (point) (point-at-eol))))
(setq spine
(with-temp-buffer
(insert spine-prefix spine-padding spine-end)
(untabify (point-min) (point-max))
(buffer-string)))
(put-text-property (point-at-bol) (point) 'display
(propertize (concat spine-prefix spine-padding)
'face face))))
(forward-line 1)
(incf lines))
(when needs-full? (setf *vpi-did-full-indent?* t))
lines)))
(defun variable-pitch-hook-handler (s e l)
(variable-pitch-indent))
(push 'variable-pitch-hook-handler after-change-functions)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment