-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathorg-weights.el
129 lines (113 loc) · 4.81 KB
/
org-weights.el
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
;;; org-weights.el --- Show how heavy Org subtrees are.
;; Copyright © 2013 Progiciels Bourbeau-Pinard inc.
;; Author: François Pinard <[email protected]>
;; Maintainer: François Pinard <[email protected]>
;; URL: https://github.com/pinard/org-weights
;; This is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program; if not, write to the Free Software Foundation,
;; Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
;;; Commentary:
;; Display the weights for every Org header which was visible at the
;; time the mode was activated. The weights of a header are the
;; counts of subtrees and paragraphs for the the subtree starting with
;; that header. Paragraphs includes items and other equivalent
;; structures.
;;; Code:
(defface org-weights-face
'((((class color) (background light))
(:background "beige" :foreground "black"))
(((class color) (background dark))
(:background "purple" :foreground "white")))
"Face for weights information higlights.")
(defvar org-weights-overlays nil
"Running list of currently displayed overlays.")
(make-variable-buffer-local 'org-weights-overlays)
(defvar org-weights-saved-start nil
"Header start position if, before command, point was within a header line.")
(define-minor-mode org-weights-mode
"Show header weights in the entire buffer."
nil nil nil
(mapc 'delete-overlay org-weights-overlays)
(setq org-weights-overlays nil)
(remove-hook 'after-change-functions
'org-weights-after-change 'local)
(when org-weights-mode
(save-excursion
(goto-char (point-min))
(outline-next-visible-heading 1)
(while (not (eobp))
(save-excursion
(org-weights-set-overlay (org-weights-at-point)))
(outline-next-visible-heading 1))
(add-hook 'after-change-functions 'org-weights-after-change
nil 'local))))
;;;; Hooks.
(defun org-weights-after-change (begin end replaced)
"Recompute overlays for all headers between BEGIN and END, and up for each."
(save-match-data
(save-excursion
(let ((bol (point-at-bol))
(force t))
(goto-char end)
(condition-case nil
(while (and (outline-back-to-heading)
(or force (>= (point) begin)))
(unless (= (point) bol)
(org-weights-set-overlay (org-weights-at-point)))
(save-excursion
(while (outline-up-heading 1)
(org-weights-set-overlay (org-weights-at-point))))
(setq force nil))
(error nil))))))
;;;; Routines
(defun org-weights-set-overlay (weights)
"Put an overlays on the current line, displaying WEIGHTS."
(let ((headers (car weights))
(paragraphs (cdr weights))
overlay)
(beginning-of-line)
(skip-chars-forward "*")
(let ((overlays org-weights-overlays))
(while overlays
(let ((candidate (pop overlays)))
(when (and (>= (point) (overlay-start candidate))
(<= (point) (overlay-end candidate)))
(setq overlay candidate
overlays nil)))))
(unless overlay
(setq overlay (make-overlay (1- (point)) (point) nil t)))
(let ((text (concat
(buffer-substring (1- (point)) (point))
(org-add-props
(if (zerop headers)
(format " %3s " paragraphs)
(format " %3s %2s " paragraphs headers))
(list 'face 'org-weights-face)))))
(if (not (featurep 'xemacs))
(overlay-put overlay 'display text)
(overlay-put overlay 'invisible t)
(overlay-put overlay 'end-glyph (make-glyph text)))
(push overlay org-weights-overlays))))
;; Compliment of Nicolas Goaziou <[email protected]>, 2012-02-26
(defun org-weights-at-point ()
"Return cons of number of subtrees and paragraphs in the subtree at point.
Paragraphs (also encompasses equivalent structures)."
(org-with-wide-buffer
(org-narrow-to-subtree)
(let ((tree (org-element-parse-buffer 'element)) (num-hl 0) (num-el 0))
(org-element-map tree 'headline (lambda (hl) (incf num-hl)))
(org-element-map
tree '(paragraph table verse-block quote-block src-block example-block)
(lambda (el) (incf num-el)))
(cons (1- num-hl) num-el))))
;;; org-weights.el ends here