diff options
author | Case Duckworth | 2021-05-19 22:03:24 -0500 |
---|---|---|
committer | Case Duckworth | 2021-05-19 22:03:24 -0500 |
commit | 2edbc01d872ff988508ab35cce80cc5986f3cfd2 (patch) | |
tree | ca17f364df673a718e581a202cb9fbdee90b3eb3 | |
parent | Fix typo (diff) | |
parent | Merge branch 'main' of https://tildegit.org/acdw/emacs (diff) | |
download | emacs-2edbc01d872ff988508ab35cce80cc5986f3cfd2.tar.gz emacs-2edbc01d872ff988508ab35cce80cc5986f3cfd2.zip |
Merge branch 'main' of https://tildegit.org/acdw/emacs
-rw-r--r-- | groups.txt | 1 | ||||
-rw-r--r-- | init.el | 120 | ||||
-rw-r--r-- | lisp/acdw-fonts.el | 45 | ||||
-rw-r--r-- | lisp/acdw-modeline.el | 20 | ||||
-rw-r--r-- | lisp/acdw-org.el | 142 |
5 files changed, 199 insertions, 129 deletions
diff --git a/groups.txt b/groups.txt index 08c604c..1fda266 100644 --- a/groups.txt +++ b/groups.txt | |||
@@ -23,6 +23,7 @@ nntp+news.gwene.org:gwene.com.realbakingwith.month | |||
23 | nntp+news.gwene.org:gwene.com.usesthis | 23 | nntp+news.gwene.org:gwene.com.usesthis |
24 | nntp+news.gwene.org:gwene.com.wflewis | 24 | nntp+news.gwene.org:gwene.com.wflewis |
25 | nntp+news.gwene.org:gwene.com.whyarentyoucod | 25 | nntp+news.gwene.org:gwene.com.whyarentyoucod |
26 | nntp+news.gwene.org:gwene.com.wordpress.filledwithcrea | ||
26 | nntp+news.gwene.org:gwene.com.xkcd | 27 | nntp+news.gwene.org:gwene.com.xkcd |
27 | nntp+news.gwene.org:gwene.dance.hamster.blog | 28 | nntp+news.gwene.org:gwene.dance.hamster.blog |
28 | nntp+news.gwene.org:gwene.de.uninformativ.blog.feeds.en | 29 | nntp+news.gwene.org:gwene.de.uninformativ.blog.feeds.en |
diff --git a/init.el b/init.el index 99b7645..cf69c1b 100644 --- a/init.el +++ b/init.el | |||
@@ -96,15 +96,17 @@ | |||
96 | (global-auto-revert-mode +1)) | 96 | (global-auto-revert-mode +1)) |
97 | 97 | ||
98 | (setup browse-url | 98 | (setup browse-url |
99 | (setq-default browse-url-browser-function 'eww-browse-url | 99 | (when (acdw/system :work) |
100 | (add-to-list 'exec-path "C:/Program Files/Mozilla Firefox")) | ||
101 | |||
102 | (setq-default browse-url-browser-function ; can be alist (regex . function) | ||
103 | '(("." . eww-browse-url)) | ||
100 | browse-url-secondary-browser-function | 104 | browse-url-secondary-browser-function |
101 | (if (executable-find "firefox") | 105 | (if (executable-find "firefox") ; prefer Firefox |
102 | 'browse-url-firefox | 106 | 'browse-url-firefox |
103 | 'browse-url-default-browser) | 107 | 'browse-url-default-browser) |
104 | browse-url-new-window-flag t | 108 | browse-url-new-window-flag t |
105 | browse-url-firefox-new-window-is-tab t) | 109 | browse-url-firefox-new-window-is-tab t)) |
106 | (when (acdw/system :work) | ||
107 | (add-to-list 'exec-path "C:/Program Files/Mozilla Firefox"))) | ||
108 | 110 | ||
109 | (setup buffers | 111 | (setup buffers |
110 | (:global "C-x k" acdw/kill-a-buffer)) | 112 | (:global "C-x k" acdw/kill-a-buffer)) |
@@ -112,12 +114,6 @@ | |||
112 | (setup completion | 114 | (setup completion |
113 | (:option completion-ignore-case t | 115 | (:option completion-ignore-case t |
114 | read-buffer-completion-ignore-case t | 116 | read-buffer-completion-ignore-case t |
115 | icomplete-delay-completions-threshold 0 | ||
116 | icomplete-max-delay-chars 0 | ||
117 | icomplete-compute-delay 0 | ||
118 | icomplete-show-matches-on-no-input t | ||
119 | icomplete-with-buffer-completion-tables t | ||
120 | icomplete-in-buffer t | ||
121 | completion-styles '(partial-completion substring flex) | 117 | completion-styles '(partial-completion substring flex) |
122 | completion-category-defaults nil | 118 | completion-category-defaults nil |
123 | completion-category-overrides | 119 | completion-category-overrides |
@@ -259,7 +255,8 @@ | |||
259 | 255 | ||
260 | (setup eshell | 256 | (setup eshell |
261 | (:option eshell-directory-name (acdw/dir "eshell/" t) | 257 | (:option eshell-directory-name (acdw/dir "eshell/" t) |
262 | eshell-aliases-file (acdw/dir "eshell/aliases" t)) | 258 | eshell-aliases-file (acdw/dir "eshell/aliases" t) |
259 | eshell-kill-on-exit nil) | ||
263 | 260 | ||
264 | (defun eshell-quit-or-delete-char (arg) | 261 | (defun eshell-quit-or-delete-char (arg) |
265 | "Delete the character to the right, or quit eshell on an empty line." | 262 | "Delete the character to the right, or quit eshell on an empty line." |
@@ -268,10 +265,16 @@ | |||
268 | (eshell-life-is-too-much) | 265 | (eshell-life-is-too-much) |
269 | (delete-forward-char arg))) | 266 | (delete-forward-char arg))) |
270 | 267 | ||
271 | (global-set-key (kbd "<f12>") #'eshell) | 268 | (defun eshell-pop-or-quit (&optional buffer-name) |
269 | "Pop open an eshell buffer, or if in an eshell buffer, bury it." | ||
270 | (interactive) | ||
271 | (if (eq (current-buffer) (get-buffer (or buffer-name "*eshell*"))) | ||
272 | (eshell-life-is-too-much) | ||
273 | (eshell))) | ||
274 | |||
275 | (:leader "s" eshell-pop-or-quit) | ||
272 | 276 | ||
273 | (hook-defun eshell-setup 'eshell-mode-hook | 277 | (hook-defun eshell-setup 'eshell-mode-hook |
274 | (define-key eshell-mode-map (kbd "<f12>") #'bury-buffer) | ||
275 | (define-key eshell-mode-map (kbd "C-d") #'eshell-quit-or-delete-char) | 278 | (define-key eshell-mode-map (kbd "C-d") #'eshell-quit-or-delete-char) |
276 | (when (boundp 'simple-modeline--mode-line) | 279 | (when (boundp 'simple-modeline--mode-line) |
277 | (setq mode-line-format '(:eval simple-modeline--mode-line))))) | 280 | (setq mode-line-format '(:eval simple-modeline--mode-line))))) |
@@ -308,15 +311,18 @@ | |||
308 | (unless (file-exists-p ispell-personal-dictionary) | 311 | (unless (file-exists-p ispell-personal-dictionary) |
309 | (write-region "" nil ispell-personal-dictionary nil 0)) | 312 | (write-region "" nil ispell-personal-dictionary nil 0)) |
310 | 313 | ||
311 | (defun flyspell-start () | 314 | (defun flyspell-start (&optional dont-warn-when-unknown-mode) |
312 | "Start `flyspell-mode' or `flyspell-prog-mode', depending on current mode." | 315 | "Start `flyspell-mode' or `flyspell-prog-mode', depending on current mode." |
313 | (interactive) | 316 | (interactive) |
314 | (cond ((derived-mode-p 'text-mode) | 317 | (cond ((derived-mode-p 'text-mode) |
315 | (flyspell-mode)) | 318 | (flyspell-mode)) |
316 | ((derived-mode-p 'prog-mode) | 319 | ((derived-mode-p 'prog-mode) |
317 | (flyspell-prog-mode)) | 320 | (flyspell-prog-mode)) |
318 | (t (message "Non-text or -prog mode. Run `flyspell-mode'.")))) | 321 | ((not dont-warn-when-unknown-mode) ; god this is ugly |
319 | (:leader "s" flyspell-start) | 322 | (message "Non-text or -prog mode. Run `flyspell-mode'.")))) |
323 | |||
324 | (when (acdw/system :home) | ||
325 | (flyspell-start t)) | ||
320 | 326 | ||
321 | (:when-loaded | 327 | (:when-loaded |
322 | (setup (:straight flyspell-correct) | 328 | (setup (:straight flyspell-correct) |
@@ -366,6 +372,9 @@ | |||
366 | (setup imenu | 372 | (setup imenu |
367 | (:option imenu-auto-rescan t)) | 373 | (:option imenu-auto-rescan t)) |
368 | 374 | ||
375 | (setup Info | ||
376 | (:hook variable-pitch-mode)) | ||
377 | |||
369 | (setup isearch | 378 | (setup isearch |
370 | (:option search-default-mode t)) | 379 | (:option search-default-mode t)) |
371 | 380 | ||
@@ -562,6 +571,14 @@ | |||
562 | (:hook flymake-mode | 571 | (:hook flymake-mode |
563 | flymake-shellcheck-load))) | 572 | flymake-shellcheck-load))) |
564 | 573 | ||
574 | (setup shell-command | ||
575 | (:option shell-command-switch (acdw/system | ||
576 | ;; I should be testing on some variable | ||
577 | (:home "-csi") | ||
578 | (:work "-c")) | ||
579 | shell-command-prompt-show-cwd t | ||
580 | shell-command-default-error-buffer "*shell-command-errors*")) | ||
581 | |||
565 | (setup shr | 582 | (setup shr |
566 | (:option shr-width fill-column | 583 | (:option shr-width fill-column |
567 | shr-max-width fill-column | 584 | shr-max-width fill-column |
@@ -580,6 +597,9 @@ | |||
580 | uniquify-after-kill-buffer-p t | 597 | uniquify-after-kill-buffer-p t |
581 | uniquify-ignore-buffers-re "^\\*")) | 598 | uniquify-ignore-buffers-re "^\\*")) |
582 | 599 | ||
600 | (setup variable-pitch-mode | ||
601 | (:hook acdw-fonts/adapt-variable-pitch)) | ||
602 | |||
583 | (setup view | 603 | (setup view |
584 | (:option view-read-only t) | 604 | (:option view-read-only t) |
585 | 605 | ||
@@ -944,7 +964,11 @@ if ripgrep is installed, otherwise `consult-grep'." | |||
944 | (:bind "RET" acdw-org/return-dwim | 964 | (:bind "RET" acdw-org/return-dwim |
945 | "<S-return>" acdw-org/org-table-copy-down) | 965 | "<S-return>" acdw-org/org-table-copy-down) |
946 | 966 | ||
947 | (add-hook 'before-save-hook #'acdw-org/fix-blank-lines-in-buffer) | 967 | (defun acdw/org-fix-lines-before-save () |
968 | (add-hook 'before-save-hook #'acdw-org/fix-blank-lines-in-buffer 0 :local)) | ||
969 | |||
970 | (:hook variable-pitch-mode | ||
971 | acdw/org-fix-lines-before-save) | ||
948 | 972 | ||
949 | (advice-add 'org-delete-backward-char | 973 | (advice-add 'org-delete-backward-char |
950 | :override #'acdw-org/delete-backward-char)) | 974 | :override #'acdw-org/delete-backward-char)) |
@@ -981,19 +1005,21 @@ if ripgrep is installed, otherwise `consult-grep'." | |||
981 | 1005 | ||
982 | (setup (:straight simple-modeline) | 1006 | (setup (:straight simple-modeline) |
983 | (setup (:straight minions)) | 1007 | (setup (:straight minions)) |
984 | (:option simple-modeline-segments | 1008 | (:option |
985 | '((acdw-modeline/modified | 1009 | ;; `acdw-org/count-words' is too slow to use in the modeline. |
986 | acdw-modeline/buffer-name | 1010 | ;; (prepend acdw-modeline/word-count-modes) '(org-mode . acdw-org/count-words) |
987 | acdw-modeline/vc-branch | 1011 | simple-modeline-segments '((acdw-modeline/modified |
988 | simple-modeline-segment-position | 1012 | acdw-modeline/buffer-name |
989 | simple-modeline-segment-word-count) | 1013 | acdw-modeline/vc-branch |
990 | (simple-modeline-segment-misc-info | 1014 | simple-modeline-segment-position) |
991 | acdw-modeline/winum | 1015 | (simple-modeline-segment-misc-info |
992 | acdw-modeline/text-scale | 1016 | acdw-modeline/word-count |
993 | simple-modeline-segment-process | 1017 | acdw-modeline/winum |
994 | acdw-modeline/god-mode-indicator | 1018 | acdw-modeline/text-scale |
995 | acdw-modeline/minions | 1019 | simple-modeline-segment-process |
996 | simple-modeline-segment-major-mode))) | 1020 | acdw-modeline/god-mode-indicator |
1021 | acdw-modeline/minions | ||
1022 | simple-modeline-segment-major-mode))) | ||
997 | 1023 | ||
998 | (require 'acdw-modeline) | 1024 | (require 'acdw-modeline) |
999 | (simple-modeline-mode +1)) | 1025 | (simple-modeline-mode +1)) |
@@ -1070,21 +1096,27 @@ if ripgrep is installed, otherwise `consult-grep'." | |||
1070 | (global-whitespace-cleanup-mode +1)) | 1096 | (global-whitespace-cleanup-mode +1)) |
1071 | 1097 | ||
1072 | (setup (:straight winum) | 1098 | (setup (:straight winum) |
1073 | (:option winum-auto-setup-mode-line nil | 1099 | (:option winum-scope 'frame-local |
1100 | winum-auto-setup-mode-line nil | ||
1074 | winum-ignored-buffers '(" *which-key*")) | 1101 | winum-ignored-buffers '(" *which-key*")) |
1075 | 1102 | ||
1076 | (when (display-graphic-p) | 1103 | (when-unfocused winum-map-keys |
1077 | (:with-map winum-keymap | 1104 | (defvar winum--keys-mapped nil |
1078 | (:bind "M-0" winum-select-window-0-or-10 | 1105 | "Whether `winum' keys have been mapped already.") |
1079 | "M-1" winum-select-window-1 | 1106 | (when (and (not winum--keys-mapped) |
1080 | "M-2" winum-select-window-2 | 1107 | (display-graphic-p)) |
1081 | "M-3" winum-select-window-3 | 1108 | (:with-map winum-keymap |
1082 | "M-4" winum-select-window-4 | 1109 | (:bind "M-0" winum-select-window-0-or-10 |
1083 | "M-5" winum-select-window-5 | 1110 | "M-1" winum-select-window-1 |
1084 | "M-6" winum-select-window-6 | 1111 | "M-2" winum-select-window-2 |
1085 | "M-7" winum-select-window-7 | 1112 | "M-3" winum-select-window-3 |
1086 | "M-8" winum-select-window-8 | 1113 | "M-4" winum-select-window-4 |
1087 | "M-9" winum-select-window-9))) | 1114 | "M-5" winum-select-window-5 |
1115 | "M-6" winum-select-window-6 | ||
1116 | "M-7" winum-select-window-7 | ||
1117 | "M-8" winum-select-window-8 | ||
1118 | "M-9" winum-select-window-9)) | ||
1119 | (setq winum--keys-mapped t))) | ||
1088 | 1120 | ||
1089 | (winum-mode +1)) | 1121 | (winum-mode +1)) |
1090 | 1122 | ||
diff --git a/lisp/acdw-fonts.el b/lisp/acdw-fonts.el index 6c0cb8d..1b73af7 100644 --- a/lisp/acdw-fonts.el +++ b/lisp/acdw-fonts.el | |||
@@ -127,5 +127,50 @@ This is for emoji fonts." | |||
127 | (set-fontset-font t 'symbol | 127 | (set-fontset-font t 'symbol |
128 | (font-spec :family font) nil 'append))))) | 128 | (font-spec :family font) nil 'append))))) |
129 | 129 | ||
130 | |||
131 | ;;; Variable-pitch | ||
132 | ;; from https://github.com/turbana/emacs-config#variable-pitch | ||
133 | |||
134 | (defcustom acdw-fonts/fixed-pitch-faces '(linum | ||
135 | org-block | ||
136 | org-block-begin-line | ||
137 | org-block-end-line | ||
138 | org-checkbox | ||
139 | org-code | ||
140 | org-date | ||
141 | org-document-info-keyword | ||
142 | org-hide | ||
143 | org-indent | ||
144 | org-link | ||
145 | org-meta-line | ||
146 | org-special-keyword | ||
147 | org-table | ||
148 | whitespace-space) | ||
149 | "Faces to keep fixed-pitch in `acdw/variable-pitch-mode'." | ||
150 | :type 'sexp | ||
151 | :group 'faces) | ||
152 | |||
153 | (defun acdw-fonts//variable-pitch-add-inherit (attrs parent) | ||
154 | "Add `:inherit PARENT' to ATTRS unless already present. | ||
155 | Handles cases where `:inherit' is already specified." | ||
156 | (let ((current-parent (plist-get attrs :inherit))) | ||
157 | (unless (or (eq parent current-parent) | ||
158 | (and (listp current-parent) | ||
159 | (member parent current-parent))) | ||
160 | (plist-put attrs :inherit (if current-parent | ||
161 | (list current-parent parent) | ||
162 | parent))))) | ||
163 | |||
164 | (defun acdw-fonts/adapt-variable-pitch () | ||
165 | "Adapt `variable-pitch-mode' to keep some fonts fixed-pitch." | ||
166 | (when variable-pitch-mode | ||
167 | (mapc (lambda (face) | ||
168 | (when (facep face) | ||
169 | (apply #'set-face-attribute | ||
170 | face nil (acdw-fonts//variable-pitch-add-inherit | ||
171 | (face-attr-construct face) | ||
172 | 'fixed-pitch)))) | ||
173 | acdw-fonts/fixed-pitch-faces))) | ||
174 | |||
130 | (provide 'acdw-fonts) | 175 | (provide 'acdw-fonts) |
131 | ;;; acdw-fonts.el ends here | 176 | ;;; acdw-fonts.el ends here |
diff --git a/lisp/acdw-modeline.el b/lisp/acdw-modeline.el index 81b808d..4f78816 100644 --- a/lisp/acdw-modeline.el +++ b/lisp/acdw-modeline.el | |||
@@ -93,4 +93,24 @@ indicator in the mode-line." | |||
93 | (> winum--window-count 1)) | 93 | (> winum--window-count 1)) |
94 | (format winum-format (winum-get-number-string)))) | 94 | (format winum-format (winum-get-number-string)))) |
95 | 95 | ||
96 | (defcustom acdw-modeline/word-count-modes | ||
97 | (mapcar (lambda (m) (cons m nil)) simple-modeline-word-count-modes) | ||
98 | "Alist of modes to functions that `acdw-modeline/word-count' should dispatch. | ||
99 | If the cdr of the cons cell is nil, use the default function (`count-words'). | ||
100 | Otherwise, cdr should be a function that takes two points (see `count-words')." | ||
101 | :type '(alist :key-type (symbol :tag "Major-Mode") | ||
102 | :value-type function) | ||
103 | :group 'simple-modeline) | ||
104 | |||
105 | (defun acdw-modeline/word-count () | ||
106 | "Display a buffer word count, depending on the major mode. | ||
107 | Uses `acdw-modeline/word-count-modes' to determine which function to use." | ||
108 | (when-let ((modefun | ||
109 | (assoc major-mode acdw-modeline/word-count-modes #'equal))) | ||
110 | (let ((fn (or (cdr modefun) | ||
111 | #'count-words)) | ||
112 | (min (if (region-active-p) (region-beginning) (point-min))) | ||
113 | (max (if (region-active-p) (region-end) (point-max)))) | ||
114 | (format "%dW" (funcall fn min max))))) | ||
115 | |||
96 | (provide 'acdw-modeline) | 116 | (provide 'acdw-modeline) |
diff --git a/lisp/acdw-org.el b/lisp/acdw-org.el index 3f0c4ea..7e68712 100644 --- a/lisp/acdw-org.el +++ b/lisp/acdw-org.el | |||
@@ -243,91 +243,63 @@ the deletion might narrow the column." | |||
243 | (org-table-copy-down n) | 243 | (org-table-copy-down n) |
244 | (acdw-org/return-dwim n))) | 244 | (acdw-org/return-dwim n))) |
245 | 245 | ||
246 | (defun acdw-org/word-count (beg end | 246 | (defun acdw-org/count-words (start end) |
247 | &optional count-latex-macro-args? | 247 | "Count words between START and END, respecting `org-mode' conventions." |
248 | count-footnotes?) | 248 | (interactive (list nil nil)) |
249 | "Report the number of words in the Org mode buffer or selected region. | 249 | (cond ((not (called-interactively-p 'any)) |
250 | Ignores: | 250 | (let ((words 0)) |
251 | - comments | 251 | (save-excursion |
252 | - tables | 252 | (save-restriction |
253 | - source code blocks (#+BEGIN_SRC ... #+END_SRC, and inline blocks) | 253 | (narrow-to-region start end) |
254 | - hyperlinks (but does count words in hyperlink descriptions) | 254 | (goto-char (point-min)) |
255 | - tags, priorities, and TODO keywords in headers | 255 | (while (< (point) (point-max)) |
256 | - sections tagged as 'not for export'. | 256 | (cond |
257 | ;; Ignore comments | ||
258 | ((or (org-at-comment-p) | ||
259 | (org-in-commented-heading-p)) nil) | ||
260 | ;; Ignore tables | ||
261 | ((org-at-table-p) nil) | ||
262 | ;; Ignore hyperlinks, but count the descriptions | ||
263 | ((looking-at org-bracket-link-analytic-regexp) | ||
264 | (when-let ((desc (match-string-no-properties 5))) | ||
265 | (save-match-data | ||
266 | (setq words (+ words | ||
267 | (length (remove "" | ||
268 | (org-split-string | ||
269 | desc "\\W"))))))) | ||
270 | (goto-char (match-end 0))) | ||
271 | ;; Ignore source code blocks | ||
272 | ((org-in-src-block-p) nil) | ||
273 | ;; Ignore footnotes | ||
274 | ((or (org-footnote-at-definition-p) | ||
275 | (org-footnote-at-reference-p)) | ||
276 | nil) | ||
277 | ;; else... check the context | ||
278 | (t (let ((contexts (org-context))) | ||
279 | (cond | ||
280 | ;; Ignore tags, TODO keywords, etc. | ||
281 | ((or (assoc :todo-keyword contexts) | ||
282 | (assoc :priority contexts) | ||
283 | (assoc :keyword contexts) | ||
284 | (assoc :checkbox contexts)) | ||
285 | nil) | ||
286 | ;; Ignore sections tagged :no-export | ||
287 | ((assoc :tags contexts) | ||
288 | (if (intersection (org-get-tags-at) | ||
289 | org-export-exclude-tags | ||
290 | :test 'equal) | ||
291 | (org-forward-same-level 1) | ||
292 | nil)) | ||
293 | ;; else... count the word | ||
294 | (t (setq words (1+ words))))))) | ||
295 | (re-search-forward "\\w+\\W*"))) | ||
296 | words))) | ||
297 | ((use-region-p) | ||
298 | (message "%d words in region" | ||
299 | (acdw-org/count-words (region-beginning) (region-end)))) | ||
300 | (t | ||
301 | (message "%d words in buffer" | ||
302 | (acdw-org/count-words (point-min) (point-max)))))) | ||
257 | 303 | ||
258 | The text of footnote definitions is ignored, unless the optional argument | ||
259 | COUNT-FOOTNOTES? is non-nil. | ||
260 | |||
261 | If the optional argument COUNT-LATEX-MACRO-ARGS? is non-nil, the word count | ||
262 | includes LaTeX macro arguments (the material between {curly braces}). | ||
263 | Otherwise, and by default, every LaTeX macro counts as 1 word regardless | ||
264 | of its arguments." | ||
265 | (interactive "r") | ||
266 | (unless mark-active | ||
267 | (setf beg (point-min) | ||
268 | end (point-max))) | ||
269 | (let ((wc 0) | ||
270 | (latex-macro-regexp "\\\\[A-Za-z]+\\(\\[[^]]*\\]\\|\\){\\([^}]*\\)}")) | ||
271 | (save-excursion | ||
272 | (goto-char beg) | ||
273 | (while (< (point) end) | ||
274 | (cond | ||
275 | ;; Ignore comments. | ||
276 | ((or (org-in-commented-line) (org-at-table-p)) | ||
277 | nil) | ||
278 | ;; Ignore hyperlinks. But if link has a description, count | ||
279 | ;; the words within the description. | ||
280 | ((looking-at org-bracket-link-analytic-regexp) | ||
281 | (when (match-string-no-properties 5) | ||
282 | (let ((desc (match-string-no-properties 5))) | ||
283 | (save-match-data | ||
284 | (incf wc (length (remove "" (org-split-string | ||
285 | desc "\\W"))))))) | ||
286 | (goto-char (match-end 0))) | ||
287 | ((looking-at org-any-link-re) | ||
288 | (goto-char (match-end 0))) | ||
289 | ;; Ignore source code blocks. | ||
290 | ((org-in-regexps-block-p "^#\\+BEGIN_SRC\\W" "^#\\+END_SRC\\W") | ||
291 | nil) | ||
292 | ;; Ignore inline source blocks, counting them as 1 word. | ||
293 | ((save-excursion | ||
294 | (backward-char) | ||
295 | (looking-at org-babel-inline-src-block-regexp)) | ||
296 | (goto-char (match-end 0)) | ||
297 | (setf wc (+ 2 wc))) | ||
298 | ;; Count latex macros as 1 word, ignoring their arguments. | ||
299 | ((save-excursion | ||
300 | (backward-char) | ||
301 | (looking-at latex-macro-regexp)) | ||
302 | (goto-char (if count-latex-macro-args? | ||
303 | (match-beginning 2) | ||
304 | (match-end 0))) | ||
305 | (setf wc (+ 2 wc))) | ||
306 | ;; Ignore footnotes. | ||
307 | ((and (not count-footnotes?) | ||
308 | (or (org-footnote-at-definition-p) | ||
309 | (org-footnote-at-reference-p))) | ||
310 | nil) | ||
311 | (t | ||
312 | (let ((contexts (org-context))) | ||
313 | (cond | ||
314 | ;; Ignore tags and TODO keywords, etc. | ||
315 | ((or (assoc :todo-keyword contexts) | ||
316 | (assoc :priority contexts) | ||
317 | (assoc :keyword contexts) | ||
318 | (assoc :checkbox contexts)) | ||
319 | nil) | ||
320 | ;; Ignore sections marked with tags that are | ||
321 | ;; excluded from export. | ||
322 | ((assoc :tags contexts) | ||
323 | (if (intersection (org-get-tags-at) org-export-exclude-tags | ||
324 | :test 'equal) | ||
325 | (org-forward-same-level 1) | ||
326 | nil)) | ||
327 | (t | ||
328 | (incf wc)))))) | ||
329 | (re-search-forward "\\w+\\W*"))) | ||
330 | (message (format "%d words in %s." wc | ||
331 | (if mark-active "region" "buffer"))))) | ||
332 | 304 | ||
333 | (provide 'acdw-org) | 305 | (provide 'acdw-org) |