Add new custom option `org-buffer-todos-warning`
[org-buffer-todos.git] / org-buffer-todos.el
blob7c500c38512848c665e90eac2d4706921346efea
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"))
8 ;; Version: 0.1
9 ;; Keywords: org
10 ;; Homepage:
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)
15 ;; any later version.
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/>.
26 ;;; Commentary:
28 ;;; Usage:
29 ;;;
30 ;;; (add-hook 'org-mode-hook #'org-buffer-todos-mode)
32 ;;; Code:
34 (require 'org-element)
36 (defgroup org-buffer-todos nil
37 "The customization group of package org-buffer-todos."
38 :prefix "org-buffer-todos-"
39 :group 'org)
41 (defcustom org-buffer-todos-warning nil
42 "Whether display warning message about `org-buffer-todos-mode'."
43 :type 'boolean
44 :safe #'booleanp
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
63 (lambda (node)
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."
110 :init-value nil
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)
115 (progn
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