Fancy Outline Bullets

We improve upon the outline bullets presented in the previous post <a href='/post/outline-ivy/'>Managing code with Outlines</a>.

My Headings Editing my config
/img/outline-bullets-fancy.png /img/outline-bullets-config.png

This solution:

  1. Allows for face application to the bullet. The default faces outline-1/2/3... only apply to the text, not the bullet.

  2. Adds spaces for higher level bullets. So not every outline-level needs to have its text start at the same column.

  3. Works for any number of outline levels.

  4. Generalized - uses outline regexes, all that is required to add the bullets to a mode is adding to its hook.

The package can be found at: https://github.com/ekaschalk/.spacemacs.d/tree/master/layers/display/local/pretty-outlines

(require 'dash)
(require 'outshine)
(require 's)

(provide 'pretty-outlines)

;;; Config

(defvar pretty-outline-bullets-bullet-list '("" "" "" "")
  "An implemention of `org-bullets-bullet-list' for outlines")

;;; Outline-bullets

(defun pretty-outline--add-font-locks (FONT-LOCK-ALIST)
  "Put text property for FONT-LOCK-ALIST for var-width replacements."
  (font-lock-add-keywords
   nil (--map (-let (((rgx uni-point) it))
             `(,rgx (0 (progn
                         (put-text-property
                          (match-beginning 1) (match-end 1)
                          'display
                          ,uni-point)
                         nil))))
           FONT-LOCK-ALIST)))

(defun pretty-outline--bullets-rgx-at-level (LEVEL)
  "Calculate regex or outline-bullets at LEVEL."
  (concat "\\(^"
          (->> LEVEL
             outshine-calc-outline-string-at-level
             s-trim-right
             (s-replace "*" "\\*"))
          "\\) "))

(defun pretty-outline--propertize-bullet (LEVEL BULLET)
  "Add LEVEL-dependent face to BULLET."
  (with-face BULLET
             (pcase LEVEL
               (0 '(:inherit outline-1 :underline nil))
               (1 '(:inherit outline-2 :underline nil))
               (2 '(:inherit outline-3 :underline nil))
               (3 '(:inherit outline-4 :underline nil))
               (_ nil))))

(defun pretty-outline-add-bullets ()
  "Use with `add-hook' to enable pretty-outline-bullets-bullet-list for mode."
  (pretty-outline--add-font-locks
   (--map-indexed
    (list
     (pretty-outline--bullets-rgx-at-level (+ 1 it-index))
     (concat
      (s-repeat it-index " ")
      (pretty-outline--propertize-bullet it-index it)))
    (-take 8 (-cycle pretty-outline-bullets-bullet-list)))))

(add-hook 'emacs-lisp-mode-hook 'pretty-outline-add-bullets)
(add-hook 'hy-mode-hook 'pretty-outline-add-bullets)
(add-hook 'python-mode-hook 'pretty-outline-add-bullets)
comments powered by Disqus