Add header style for fold display

Header mode is optional, enabled via origami-fold-display-mode.
Rendering is similar to vimish-fold’s style.
This commit is contained in:
Nicholas Seckar 2015-10-11 12:23:48 -07:00
parent 56140b4d3f
commit 47b4e2830e

View File

@ -37,27 +37,79 @@
(require 'cl) (require 'cl)
(require 'origami-parsers) (require 'origami-parsers)
;;; fold display mode and faces
(defcustom origami-fold-display-mode 'dots
"Display mode for folded areas.
By default, a traditional \"...\" format is used. A highlighted
header is also available."
:tag "Display mode for folds"
:type '(choice (const :tag "Three dots" dots)
(const :tag "Highlighted header" header))
:group 'origami)
(defface origami-fold-header
'((t (:box (:line-width 1 :color "#050")
:background "#001500")))
"Face used to display fold headers.")
(defface origami-fold-fringe
'((t (:inherit highlight)))
"Face used to display fringe contents.")
(defgroup origami '((origami-fold-header custom-face)
(origami-fold-fringe custom-face))
"Origami: A text folding minor mode for Emacs, by Greg Sexton.")
;;; overlay manipulation ;;; overlay manipulation
(defun origami-create-overlay (beg end offset buffer) (defun origami-create-overlay (beg end offset buffer)
(when (> (- end beg) 0) (when (> (- end beg) 0)
(let ((ov (make-overlay (+ beg offset) end buffer))) (let ((ov (make-overlay (+ beg offset) end buffer)))
(overlay-put ov 'creator 'origami)
(overlay-put ov 'isearch-open-invisible 'origami-isearch-show) (overlay-put ov 'isearch-open-invisible 'origami-isearch-show)
(overlay-put ov 'isearch-open-invisible-temporary (overlay-put ov 'isearch-open-invisible-temporary
(lambda (ov hide-p) (if hide-p (origami-hide-overlay ov) (lambda (ov hide-p) (if hide-p (origami-hide-overlay ov)
(origami-show-overlay ov)))) (origami-show-overlay ov))))
ov))) ;; We create a header overlay even when disabled; this could be avoided,
;; especially if we called origami-reset for each buffer if customizations
;; changed.
(with-current-buffer buffer
(let* ((line-begin
(save-excursion
(goto-char (+ beg offset))
(line-beginning-position)))
(fold-end
;; Find the end of the folded region -- try to include the
;; newline if possible. The header will span the entire fold.
(save-excursion
(goto-char end)
(when (looking-at ".")
(forward-char 1)
(when (looking-at "\n")
(forward-char 1)))
(point)))
(header-ov (make-overlay line-begin fold-end buffer)))
(overlay-put header-ov 'creator 'origami)
(overlay-put header-ov 'fold-overlay ov)
(overlay-put ov 'header-ov header-ov)))
ov)))
(defun origami-hide-overlay (ov) (defun origami-hide-overlay (ov)
;; TODO: make all of this customizable ;; TODO: make more of this customizable
(overlay-put ov 'invisible 'origami) (overlay-put ov 'invisible 'origami)
(overlay-put ov 'display "...") (case origami-fold-display-mode
(overlay-put ov 'face 'font-lock-comment-delimiter-face)) ('dots
(overlay-put ov 'display "...")
(overlay-put ov 'face 'font-lock-comment-delimiter-face))
('header
(origami-activate-header (overlay-get ov 'header-ov)))))
(defun origami-show-overlay (ov) (defun origami-show-overlay (ov)
(overlay-put ov 'invisible nil) (overlay-put ov 'invisible nil)
(overlay-put ov 'display nil) (overlay-put ov 'display nil)
(overlay-put ov 'face nil)) (overlay-put ov 'face nil)
(origami-deactivate-header (overlay-get ov 'header-ov)))
(defun origami-hide-node-overlay (node) (defun origami-hide-node-overlay (node)
(-when-let (ov (origami-fold-data node)) (-when-let (ov (origami-fold-data node))
@ -67,6 +119,21 @@
(-when-let (ov (origami-fold-data node)) (-when-let (ov (origami-fold-data node))
(origami-show-overlay ov))) (origami-show-overlay ov)))
(defun origami-activate-header (ov)
(overlay-put ov 'origami-header-active t)
(overlay-put ov 'face 'origami-fold-header)
(overlay-put ov 'before-string
(propertize
""
'display
'(left-fringe empty-line origami-fold-fringe))))
(defun origami-deactivate-header (ov)
(overlay-put ov 'origami-header-active nil)
(overlay-put ov 'face nil)
(overlay-put ov 'before-string nil)
(overlay-put ov 'after-string nil))
(defun origami-isearch-show (ov) (defun origami-isearch-show (ov)
(origami-show-node (current-buffer) (point))) (origami-show-node (current-buffer) (point)))
@ -83,7 +150,7 @@
(defun origami-remove-all-overlays (buffer) (defun origami-remove-all-overlays (buffer)
(with-current-buffer buffer (with-current-buffer buffer
(remove-overlays (point-min) (point-max) 'invisible 'origami))) (remove-overlays (point-min) (point-max) 'creator 'origami)))
;;; fold structure ;;; fold structure