;;; +org-wc.el --- org-wc in the modeline -*- lexical-binding: t; -*- ;;; Commentary: ;;; Code: (require 'org-wc) (require '+modeline) (require 'cl-lib) (defgroup +org-wc nil "Extra fast word-counting in `org-mode'" :group 'org-wc :group 'org) (defvar-local +org-wc-word-count nil "Running total of words in this buffer.") (defcustom +org-wc-update-after-funcs '(org-narrow-to-subtree org-narrow-to-block org-narrow-to-element org-capture-narrow org-taskwise-narrow-to-task) "Functions after which to update the word count." :type '(repeat function)) (defcustom +org-wc-deletion-idle-timer 0.25 "Length of time, in seconds, to wait before updating word-count." :type 'number) (defcustom +org-wc-huge-change 5000 "Number of characters that constitute a \"huge\" insertion." :type 'number) (defvar-local +org-wc-update-timer nil) (defun +org-wc-delayed-update (&rest _) (if +org-wc-update-timer (setq +org-wc-update-timer nil) (setq +org-wc-update-timer (run-with-idle-timer +org-wc-deletion-idle-timer nil #'+org-wc-update)))) (defun +org-wc-force-update () (interactive) (message "Counting words...") (when (timerp +org-wc-update-timer) (cancel-timer +org-wc-update-timer)) (+org-wc-update) (message "Counting words...done")) (defun +org-wc-update () (dlet ((+org-wc-counting t)) (+org-wc-buffer) (force-mode-line-update) (setq +org-wc-update-timer nil))) (defun +org-wc-changed (start end length) (+org-wc-delayed-update)) (defun +org-wc-buffer () "Count the words in the buffer." (when (derived-mode-p 'org-mode) (setq +org-wc-word-count (org-word-count-aux (point-min) (point-max))))) (defvar +org-wc-counting nil "Are we currently counting?") (defun +org-wc-recount-widen (&rest _) (when (and (not +org-wc-counting)) (+org-wc-update))) (defun +org-wc-modeline () (when +org-wc-word-count (format " %sw" +org-wc-word-count))) (define-minor-mode +org-wc-mode "Count words in `org-mode' buffers in the mode-line." :lighter "" :keymap (let ((map (make-sparse-keymap))) (define-key map (kbd "C-c C-.") #'+org-wc-force-update) map) (if +org-wc-mode (progn ; turn on (+org-wc-buffer) (add-hook 'after-change-functions #'+org-wc-delayed-update nil t) (setq-local +modeline-position-function #'+org-wc-modeline) (dolist (fn +org-wc-update-after-funcs) (advice-add fn :after #'+org-wc-update))) (progn ; turn off (remove-hook 'after-change-functions #'+org-wc-delayed-update t) (kill-local-variable '+modeline-position-function) (dolist (fn +org-wc-update-after-funcs) (advice-remove fn #'+org-wc-update))))) (provide '+org-wc) ;;; +org-wc.el ends here