1 ;;; org-buffer-todos.el --- Show Org buffer local todo tasks number. -*- lexical-binding: t; -*-
2 ;; -*- coding: utf-8 -*-
4 ;; Copyright (C) 2020-2021 Free Software Foundation, Inc.
6 ;; Authors: stardiviner <numbchild@gmail.com>
7 ;; Package-Requires: ((emacs "26.1"))
12 ;; org-buffer-todos is free software; you can redistribute it and/or modify it
13 ;; under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 3, or (at your option)
17 ;; org-buffer-todos is distributed in the hope that it will be useful, but WITHOUT
18 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
20 ;; License for more details.
23 ;; You should have received a copy of the GNU General Public License
24 ;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
30 ;;; (add-hook 'org-mode-hook #'org-buffer-todos-mode)
34 (require 'org-element
)
36 (defgroup org-buffer-todos nil
37 "The customization group of package org-buffer-todos."
38 :prefix
"org-buffer-todos-"
41 (defcustom org-buffer-todos-warning nil
42 "Whether display warning message about `org-buffer-todos-mode'."
45 :group
'org-buffer-todos
)
47 ;;; Use a variable for `after-save-hook' updating instead of `mode-line-misc-info' instant `:eval'.
48 (defvar org-buffer-todos-counter nil
49 "The number of Org buffer local todo tasks counter.")
51 (put 'org-buffer-todos-counter
'risky-local-variable t
)
53 (defun org-buffer-todos--buffer-big-p ()
54 "Detect whether current Org buffer is big?"
55 (> (buffer-size) 100000))
57 (defun org-buffer-todos-counter ()
58 "Return tasks counting number in current org-mode buffer."
59 (when (eq major-mode
'org-mode
)
60 (with-current-buffer (current-buffer)
61 (let ((headline-todos))
62 (org-element-map (org-element-parse-buffer) 'headline
64 (let ((headline node
)) ; `node' is `headline' like `org-element-context'.
65 (when (member (org-element-property :todo-keyword headline
)
66 (or org-todo-keywords-for-agenda
67 (mapcar 'car org-todo-keyword-faces
)))
68 (let ((headline-title (org-element-property :title headline
)))
69 (push headline-title headline-todos
))))))
70 (seq-count #'identity headline-todos
)))))
72 (defvar org-buffer-todos-mode-lighter nil
73 "The `org-buffer-todos-mode' minor-mode mode-line lighter.")
75 (put 'org-buffer-todos-mode-lighter
'risky-local-variable t
)
77 (defun org-buffer-todos-counter--mode-line-format ()
78 "Show tasks counting number in a mode-line format."
79 (let ((org-buffer-todos-counter (org-buffer-todos-counter)))
80 (when (and (eq major-mode
'org-mode
)
81 (bound-and-true-p org-buffer-todos-counter
)
82 (> org-buffer-todos-counter
0))
83 (setq org-buffer-todos-mode-lighter
84 (format " [Todos: %s]" org-buffer-todos-counter
)))))
86 (defun org-buffer-todos-counter--mode-line-update ()
87 "Update org-mode buffer local tasks counting number in mode-line."
88 (setq-local org-buffer-todos-counter
(org-buffer-todos-counter))
89 (setq-local org-buffer-todos-mode-lighter
(org-buffer-todos-counter--mode-line-format))
90 ;; (add-to-list 'mode-line-misc-info '(:eval (org-buffer-todos-counter--mode-line-format)))
93 (defun org-buffer-todos-mode--enable ()
94 "Enable `org-buffer-todos-mode'"
95 ;; Hook updater function on `after-save-hook'.
96 (add-hook 'after-save-hook
#'org-buffer-todos-counter--mode-line-update nil
'local
)
97 ;; (add-to-list 'mode-line-misc-info
98 ;; '(org-buffer-todos-mode (:eval org-buffer-todos-mode-lighter)))
101 (defun org-buffer-todos-mode--disable ()
102 "Disable `org-buffer-todos-mode'"
103 (remove-hook 'after-save-hook
#'org-buffer-todos-counter--mode-line-update
'local
)
104 ;; (setq mode-line-misc-info
105 ;; (delete '(org-buffer-todos-mode (:eval org-buffer-todos-mode-lighter)) mode-line-misc-info))
108 (define-minor-mode org-buffer-todos-mode
109 "Show Org buffer local todo tasks number in mode-line."
111 :lighter org-buffer-todos-mode-lighter
; The mode-line lighter shows string.
112 :group
'org-buffer-todos
113 (if org-buffer-todos-mode
114 (if (org-buffer-todos--buffer-big-p)
116 (when org-buffer-todos-warning
117 (message "[org-buffer-todos] Not enabled in big Org file %s in size: %s"
118 (buffer-name) (file-size-human-readable (buffer-size))))
119 (setq-local org-buffer-todos-mode-lighter nil
))
120 (org-buffer-todos-mode--enable))
121 (org-buffer-todos-mode--disable)))
125 (provide 'org-buffer-todos
)
127 ;;; org-buffer-todos.el ends here