Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

file 85 lines (67 sloc) 3.049 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
;;; visual-indentation-mode.el --- minor mode for visualizing indentation

;; This is free and unencumbered software released into the public domain.

;; Author: Christopher Wellons <mosquitopsu@gmail.com>
;; Version: 1.0

;;; Commentary:

;; This does not operate properly with tabs. Tabs are for losers
;; anyway. :-) Since this is only a proof of concept I don't plan on
;; fixing this.

;; Indentation size can be adjusted by `visual-indentation-width'. I'd
;; like to detect this automatically from the mode (2 for Lisp, 4 for
;; Java, c-basic-offset, etc.) but that problem turns out to be highly
;; non-trivial.

;; The idea came from example code this video:
;; http://www.infoq.com/presentations/Bootstrapping-Clojure

;;; Code:

(defgroup visual-indentation-mode nil
  "Group for visual-indentation-mode."
  :group 'applications)

(defcustom visual-indentation-width 2
  "Width of indentation -- different than tab-width."
  :group 'visual-indentation-mode
  :type 'integer)

(defface visual-indentation-light-face
  '((((background light)) (:background "#AFAFAF"))
    (((background dark)) (:background "#4F4F4F")))
  "Face for highlighting odd indents."
  :group 'visual-indentation-mode)

(defface visual-indentation-dark-face
  '((((background light)) (:background "#DFDFDF"))
    (((background dark)) (:background "#101010")))
  "Face for highlighting even indents."
  :group 'visual-indentation-mode)

(defun visual-indentation-choose-color (pos)
  "Determine the color for the given buffer position."
  (let ((col (save-excursion (goto-char pos) (current-column))))
    (if (= 0 (mod (/ col visual-indentation-width) 2))
        'visual-indentation-light-face
      'visual-indentation-dark-face)))

(defun visual-indentation-propertize (pos)
  "Color the indentation at POS."
  (with-silent-modifications
    (add-text-properties pos (1+ pos)
                         `(font-lock-face ,(visual-indentation-choose-color pos)
                                          rear-nonsticky t))))

(defun visual-indentation-propertize-region (start end)
  "Color all indentation in the region."
  (save-excursion
    (goto-char start)
    (while (< (point) end)
      (dotimes (i (- (current-indentation) (current-column)))
        (visual-indentation-propertize (+ i (point))))
      (forward-line))))

(defun visual-indentation-unpropertize-region (start end)
  "Remove all indentation coloring from the region."
  (remove-text-properties start end '(font-lock-face nil rear-nonsticky nil)))

;;;###autoload
(define-minor-mode visual-indentation-mode
  "Visualize indentation in the current buffer."
  :lighter "" ; should be obvious enough already
  (if (not visual-indentation-mode)
      (progn
        (jit-lock-unregister 'visual-indentation-propertize-region)
        (visual-indentation-unpropertize-region (point-min) (point-max)))
    (jit-lock-register 'visual-indentation-propertize-region)
    (make-local-variable 'visual-indentation-width)))

(provide 'visual-indentation-mode)

;;; visual-indentation-mode.el ends here
Something went wrong with that request. Please try again.