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:
parent
56140b4d3f
commit
47b4e2830e
73
origami.el
73
origami.el
@ -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))))
|
||||||
|
;; 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)))
|
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)
|
||||||
|
(case origami-fold-display-mode
|
||||||
|
('dots
|
||||||
(overlay-put ov 'display "...")
|
(overlay-put ov 'display "...")
|
||||||
(overlay-put ov 'face 'font-lock-comment-delimiter-face))
|
(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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user