[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] master 463d752 11/13: Cleaned up code and added documentation of
From: |
Ian Dunn |
Subject: |
[elpa] master 463d752 11/13: Cleaned up code and added documentation of new features |
Date: |
Sun, 4 Feb 2018 12:32:35 -0500 (EST) |
branch: master
commit 463d752d4703af93ea86df8f07b244e8fc851617
Author: Ian Dunn <address@hidden>
Commit: Ian Dunn <address@hidden>
Cleaned up code and added documentation of new features
* paced.el: Bumped version
(paced-throw-error-on-no-registered):
(paced-throw-error-on-no-current): New variables.
(paced-operate-on-named-dictionary): Macro to replace ensured-registered.
(paced-save-named-dictionary):
(paced-reset-named-dictionary):
(paced-sort-named-dictionary):
(paced-repopulate-named-dictionary):
(paced-edit-named-dictionary):
(paced-print-named-dictionary): Use it.
(paced-operate-on-current-dictionary): Macro to mimic named operations.
(paced-save-current-dictionary):
(paced-add-word-to-current-dictionary):
(paced-populate-current-dictionary-from-buffer):
(paced-populate-current-dictionary-from-region):
(paced-reset-current-dictionary):
(paced-sort-current-dictionary):
(paced-repopulate-current-dictionary):
(paced-edit-current-dictionary):
(paced-print-current-dictionary): Use it.
(paced-global-dictionary-enable-alist): Renamed from now obsolete variable
paced-global-dict-enable-alist.
(paced-local-dictionary-enable-alist): Likewise for local.
(paced-dictionary-enable-list): Renamed from paced-dict-enable-list.
(paced-test-dictionary-enable-condition): Likewise.
(paced-populate-current-dictionary-from-buffer): Renamed from obsolete
function
paced-populate-buffer-dictionary.
(paced-populate-current-dictionary-from-region): Renamed from obsolete
function
paced-populate-from-region.
(paced-add-current-thing-to-dictionary): Renamed from obsolete function
paced-add-current-thing-to-dict.
* paced-async.el (paced-dictionary-repopulate-async): Renamed from
paced-repopulate-dictionary-async.
* paced-tests.el: Update names of variables and functions.
* paced.org: Add documentation on new features.
* paced.info: Regenerated from paced.org.
---
paced-async.el | 10 +-
paced-tests.el | 92 +++++++--------
paced.el | 367 +++++++++++++++++++++++++++++++++++++++------------------
paced.info | 278 ++++++++++++++++++++++++++++++++++++-------
paced.org | 192 ++++++++++++++++++++++++++++--
test.mk | 2 +-
6 files changed, 718 insertions(+), 223 deletions(-)
diff --git a/paced-async.el b/paced-async.el
index 0f2777c..97c7de1 100644
--- a/paced-async.el
+++ b/paced-async.el
@@ -7,9 +7,9 @@
;; Keywords: convenience, completion
;; Package-Requires: ((emacs "25.1") (async "1.9.1"))
;; URL: https://savannah.nongnu.org/projects/paced-el/
-;; Version: 1.0
+;; Version: 1.1
;; Created: 22 Jan 2017
-;; Modified: 08 Dec 2017
+;; Modified: 04 Feb 2018
;; This file is part of GNU Emacs.
@@ -48,7 +48,7 @@ population commmands, or load additional files."
:group 'paced
:type 'file)
-(cl-defmethod paced-repopulate-dictionary-async ((dictionary paced-dictionary))
+(cl-defmethod paced-dictionary-repopulate-async ((dictionary paced-dictionary))
"Repopulate DICTIONARY asynchronously.
Note that DICTIONARY isn't modified directly by this process, but
@@ -94,7 +94,7 @@ Note that this will empty the dictionary's contents."
(list (paced-read-dictionary)))
(paced-ensure-registered key)
(let ((dict (paced-named-dictionary key)))
- (paced-repopulate-dictionary-async dict)))
+ (paced-dictionary-repopulate-async dict)))
;;;###autoload
(defun paced-repopulate-current-dictionary-async ()
@@ -105,7 +105,7 @@ Population commands are stored in the field of the same
name.
Note that this will empty the dictionary's contents."
(interactive)
(if-let* ((dict (paced-current-dictionary)))
- (paced-repopulate-dictionary-async dict)
+ (paced-dictionary-repopulate-async dict)
(error "No current dictionary found")))
(provide 'paced-async)
diff --git a/paced-tests.el b/paced-tests.el
index e7b5552..c7dc3bb 100644
--- a/paced-tests.el
+++ b/paced-tests.el
@@ -7,9 +7,9 @@
;; Keywords: convenience, completion
;; Package-Requires: ((emacs "25.1") (async "1.9.1"))
;; URL: https://savannah.nongnu.org/projects/paced-el/
-;; Version: 1.0
+;; Version: 1.1
;; Created: 22 Jan 2017
-;; Modified: 08 Dec 2017
+;; Modified: 04 Feb 2018
;; This file is part of GNU Emacs.
@@ -89,11 +89,11 @@
(ert-deftest paced-enable-list-symbol ()
"Test case for `paced-dictionary-enable-alist' being an arbitrary symbol."
(let* ((paced--registered-dictionaries paced-test-default-registered-map)
- (paced-global-dict-enable-alist '((paced-test-enable-symbol .
"test-dict-case")))
- (new-buffer (find-file-noselect paced-first-test-file))
- (new-dict (paced-make-dictionary "test-dict-case"
- paced-test-dict-save-file
- 'downcase)))
+ (paced-global-dictionary-enable-alist '((paced-test-enable-symbol .
"test-dict-case")))
+ (new-buffer (find-file-noselect paced-first-test-file)))
+ (paced-make-dictionary "test-dict-case"
+ paced-test-dict-save-file
+ 'downcase)
(with-current-buffer new-buffer
(setq paced-test-enable-symbol nil)
(should-not (paced-current-dictionary))
@@ -105,12 +105,12 @@
(ert-deftest paced-enable-list-mode ()
"Test case for `paced-dictionary-enable-alist' being a mode symbol."
(let* ((paced--registered-dictionaries paced-test-default-registered-map)
- (paced-global-dict-enable-alist '((text-mode . "test-dict-case")))
+ (paced-global-dictionary-enable-alist '((text-mode .
"test-dict-case")))
(buffer-one (find-file-noselect paced-first-test-file))
- (buffer-two (find-file-noselect paced-second-test-file))
- (new-dict (paced-make-dictionary "test-dict-case"
- paced-test-dict-save-file
- 'downcase)))
+ (buffer-two (find-file-noselect paced-second-test-file)))
+ (paced-make-dictionary "test-dict-case"
+ paced-test-dict-save-file
+ 'downcase)
(with-current-buffer buffer-two
(should-not (paced-current-dictionary)))
(kill-buffer buffer-two)
@@ -125,11 +125,11 @@
(ert-deftest paced-enable-list-function-symbol ()
"Test case for `paced-dictionary-enable-alist' being a function symbol."
(let* ((paced--registered-dictionaries paced-test-default-registered-map)
- (paced-global-dict-enable-alist '((paced-test-function-symbol .
"test-dict-case")))
- (buffer-one (find-file-noselect paced-first-test-file))
- (new-dict (paced-make-dictionary "test-dict-case"
- paced-test-dict-save-file
- 'downcase)))
+ (paced-global-dictionary-enable-alist '((paced-test-function-symbol .
"test-dict-case")))
+ (buffer-one (find-file-noselect paced-first-test-file)))
+ (paced-make-dictionary "test-dict-case"
+ paced-test-dict-save-file
+ 'downcase)
(with-current-buffer buffer-one
(setq-local paced-test-enable-symbol nil)
(should-not (paced-current-dictionary))
@@ -141,11 +141,11 @@
(ert-deftest paced-enable-list-lambda-function ()
"Test case for `paced-dictionary-enable-alist' being a lambda form."
(let* ((paced--registered-dictionaries paced-test-default-registered-map)
- (paced-global-dict-enable-alist '(((lambda nil
paced-test-enable-symbol) . "test-dict-case")))
- (buffer-one (find-file-noselect paced-first-test-file))
- (new-dict (paced-make-dictionary "test-dict-case"
- paced-test-dict-save-file
- 'downcase)))
+ (paced-global-dictionary-enable-alist '(((lambda nil
paced-test-enable-symbol) . "test-dict-case")))
+ (buffer-one (find-file-noselect paced-first-test-file)))
+ (paced-make-dictionary "test-dict-case"
+ paced-test-dict-save-file
+ 'downcase)
(with-current-buffer buffer-one
(setq-local paced-test-enable-symbol nil)
(should-not (paced-current-dictionary))
@@ -157,12 +157,12 @@
(ert-deftest paced-enable-list-and-form ()
"Test case for `paced-dictionary-enable-alist' being an 'and' form."
(let* ((paced--registered-dictionaries paced-test-default-registered-map)
- (paced-global-dict-enable-alist '(((and text-mode
paced-test-enable-symbol) . "test-dict-case")))
+ (paced-global-dictionary-enable-alist '(((and text-mode
paced-test-enable-symbol) . "test-dict-case")))
(buffer-one (find-file-noselect paced-first-test-file))
- (buffer-two (find-file-noselect paced-second-test-file))
- (new-dict (paced-make-dictionary "test-dict-case"
- paced-test-dict-save-file
- 'downcase)))
+ (buffer-two (find-file-noselect paced-second-test-file)))
+ (paced-make-dictionary "test-dict-case"
+ paced-test-dict-save-file
+ 'downcase)
(with-current-buffer buffer-two
(setq-local paced-test-enable-symbol nil)
(should-not (paced-current-dictionary))
@@ -180,12 +180,12 @@
(ert-deftest paced-enable-list-or-form ()
"Test case for `paced-dictionary-enable-alist' being an 'or' form."
(let* ((paced--registered-dictionaries paced-test-default-registered-map)
- (paced-global-dict-enable-alist '(((or text-mode
paced-test-enable-symbol) . "test-dict-case")))
+ (paced-global-dictionary-enable-alist '(((or text-mode
paced-test-enable-symbol) . "test-dict-case")))
(buffer-one (find-file-noselect paced-first-test-file))
- (buffer-two (find-file-noselect paced-second-test-file))
- (new-dict (paced-make-dictionary "test-dict-case"
- paced-test-dict-save-file
- 'downcase)))
+ (buffer-two (find-file-noselect paced-second-test-file)))
+ (paced-make-dictionary "test-dict-case"
+ paced-test-dict-save-file
+ 'downcase)
(with-current-buffer buffer-two
(setq-local paced-test-enable-symbol nil)
(should-not (paced-current-dictionary))
@@ -205,7 +205,7 @@
(ert-deftest paced-populate-file ()
"Test case for single file populator."
(let* ((paced--registered-dictionaries paced-test-default-registered-map)
- (paced-global-dict-enable-alist '((text-mode . "test-dict-case")))
+ (paced-global-dictionary-enable-alist '((text-mode .
"test-dict-case")))
(cmd (paced-file-population-command :file paced-first-test-file))
(test-dict (paced-make-dictionary "test-dict-case"
paced-test-dict-save-file
@@ -224,7 +224,7 @@
(ert-deftest paced-populate-buffer ()
"Test case for single buffer populator."
(let* ((paced--registered-dictionaries paced-test-default-registered-map)
- (paced-global-dict-enable-alist '((text-mode . "test-dict-case")))
+ (paced-global-dictionary-enable-alist '((text-mode .
"test-dict-case")))
(buffer "first.txt")
(buffer-one (find-file-noselect paced-first-test-file))
(cmd (paced-buffer-population-command :buffer buffer))
@@ -246,7 +246,7 @@
(ert-deftest paced-populate-file-function ()
"Test case for file-function populator."
(let* ((paced--registered-dictionaries paced-test-default-registered-map)
- (paced-global-dict-enable-alist '((text-mode . "test-dict-case")))
+ (paced-global-dictionary-enable-alist '((text-mode .
"test-dict-case")))
(pre-func (lambda () (insert (buffer-string)) t))
(cmd (paced-file-function-population-command :file
paced-first-test-file
:setup-func pre-func))
@@ -267,7 +267,7 @@
(ert-deftest paced-populate-directory-regexp ()
"Test case for directory-regexp populator."
(let* ((paced--registered-dictionaries paced-test-default-registered-map)
- (paced-global-dict-enable-alist '((text-mode . "test-dict-case")))
+ (paced-global-dictionary-enable-alist '((text-mode .
"test-dict-case")))
(cmd (paced-directory-regexp-population-command :directory
paced-test-dir
:regexp ".*\\.txt"
:recursive t))
@@ -288,12 +288,12 @@
(ert-deftest paced-populate-file-list ()
"Test case for file-list populator."
(let* ((paced--registered-dictionaries paced-test-default-registered-map)
- (paced-global-dict-enable-alist '((text-mode . "test-dict-case")))
+ (paced-global-dictionary-enable-alist '((text-mode .
"test-dict-case")))
(file-list (lambda () `(,paced-first-test-file)))
(cmd (paced-file-list-population-command :generator file-list))
(test-dict (paced-make-dictionary "test-dict-case"
- paced-test-dict-save-file
- 'downcase)))
+ paced-test-dict-save-file
+ 'downcase)))
(should (paced-dictionary-p test-dict))
(oset test-dict population-commands (list cmd))
(paced-dictionary-repopulate test-dict)
@@ -307,7 +307,7 @@
(ert-deftest paced-multiple-population-commands ()
(let* ((paced--registered-dictionaries paced-test-default-registered-map)
- (paced-global-dict-enable-alist '((text-mode . "test-dict-case")))
+ (paced-global-dictionary-enable-alist '((text-mode .
"test-dict-case")))
(cmd1 (paced-file-population-command :file paced-first-test-file))
(cmd2 (paced-file-population-command :file paced-third-test-file))
(test-dict (paced-make-dictionary "test-dict-case"
@@ -329,7 +329,7 @@
(ert-deftest paced-populator-settings ()
(let* ((paced--registered-dictionaries paced-test-default-registered-map)
- (paced-global-dict-enable-alist '((text-mode . "test-dict-case")))
+ (paced-global-dictionary-enable-alist '((text-mode .
"test-dict-case")))
(exclude-command (lambda nil (nth 8 (syntax-ppss)))) ;; exclude
comments
(cmd1 (paced-file-population-command :file paced-first-test-file))
(cmd2 (paced-file-population-command :file paced-second-test-file
@@ -351,7 +351,7 @@
(ert-deftest paced-populate-sort-order ()
"Test case for sorting after population."
(let* ((paced--registered-dictionaries paced-test-default-registered-map)
- (paced-global-dict-enable-alist '((text-mode . "test-dict-case")))
+ (paced-global-dictionary-enable-alist '((text-mode .
"test-dict-case")))
(cmd (paced-file-population-command :file paced-first-test-file))
(test-dict (paced-make-dictionary "test-dict-case"
paced-test-dict-save-file
@@ -395,7 +395,7 @@
(ert-deftest paced-completions-try-completion ()
(let* ((paced--registered-dictionaries paced-test-default-registered-map)
- (paced-global-dict-enable-alist '((text-mode . "test-dict-case")))
+ (paced-global-dictionary-enable-alist '((text-mode .
"test-dict-case")))
(cmd (paced-file-population-command :file paced-first-test-file))
(test-dict (paced-make-dictionary "test-dict-case"
paced-test-dict-save-file
@@ -408,7 +408,7 @@
(ert-deftest paced-completions-try-completion-mixed-case ()
(let* ((paced--registered-dictionaries paced-test-default-registered-map)
- (paced-global-dict-enable-alist '((text-mode . "test-dict-case")))
+ (paced-global-dictionary-enable-alist '((text-mode .
"test-dict-case")))
(cmd (paced-file-population-command :file paced-first-test-file))
(test-dict (paced-make-dictionary "test-dict-case"
paced-test-dict-save-file
@@ -421,7 +421,7 @@
(ert-deftest paced-completions-all-completions ()
(let* ((paced--registered-dictionaries paced-test-default-registered-map)
- (paced-global-dict-enable-alist '((text-mode . "test-dict-case")))
+ (paced-global-dictionary-enable-alist '((text-mode .
"test-dict-case")))
(cmd (paced-file-population-command :file paced-first-test-file))
(test-dict (paced-make-dictionary "test-dict-case"
paced-test-dict-save-file
@@ -440,7 +440,7 @@
(ert-deftest paced-completions-test-completion ()
(let* ((paced--registered-dictionaries paced-test-default-registered-map)
- (paced-global-dict-enable-alist '((text-mode . "test-dict-case")))
+ (paced-global-dictionary-enable-alist '((text-mode .
"test-dict-case")))
(cmd (paced-file-population-command :file paced-first-test-file))
(test-dict (paced-make-dictionary "test-dict-case"
paced-test-dict-save-file
diff --git a/paced.el b/paced.el
index 81bd748..79fe483 100644
--- a/paced.el
+++ b/paced.el
@@ -7,9 +7,9 @@
;; Keywords: convenience, completion
;; Package-Requires: ((emacs "25.1") (async "1.9.1"))
;; URL: https://savannah.nongnu.org/projects/paced-el/
-;; Version: 1.0.1
+;; Version: 1.1
;; Created: 22 Jan 2017
-;; Modified: 08 Dec 2017
+;; Modified: 04 Feb 2018
;; This file is part of GNU Emacs.
@@ -270,10 +270,18 @@ If none exists, return nil."
"Return non-nil if a dictionary with name KEY has been registered."
(map-contains-key paced--registered-dictionaries key))
-(defsubst paced-ensure-registered (key)
- "Throw an error if a dictionary with name KEY has not been registered."
- (unless (paced-dictionary-key-registered-p key)
- (error "No paced dictionary called '%s' has been registered" key)))
+(defvar paced-throw-error-on-no-registered t
+ "Whether to throw an error when a named dictionary can't be found.")
+
+(defmacro paced-operate-on-named-dictionary (name &rest form)
+ "Run FORM on the dictionary with name NAME, bound to `dict'.
+
+If no dictionary named NAME exists, throw an error."
+ (declare (indent 1))
+ `(if-let* ((dict (paced-named-dictionary ,name)))
+ (progn ,@form)
+ (when paced-throw-error-on-no-registered
+ (error "No paced dictionary called '%s' has been registered" ,name))))
(cl-defmethod paced-dictionary-register ((dict paced-dictionary))
"Registered dictionary DICT."
@@ -323,7 +331,9 @@ customization interface."
"Return the name of dictionary OBJ."
(oref obj object-name))
-(defcustom paced-global-dict-enable-alist nil
+;;; Current Dictionary
+
+(defcustom paced-global-dictionary-enable-alist nil
"List that determines which dictionaries should be active.
Each entry has the form (CONDITION . DICT-KEY), where CONDITION
@@ -355,28 +365,40 @@ enabled unless `paced-mode' is active."
:group 'paced
:type '(alist :key-type sexp :value-type string))
-(defvar-local paced-local-dict-enable-alist nil
+(define-obsolete-variable-alias 'paced-global-dict-enable-alist
+ 'paced-global-dictionary-enable-alist
+ "1.1")
+
+(defvar-local paced-local-dictionary-enable-alist nil
"Local enable list.
Has the same form as and takes priority over
-`paced-global-dict-enable-alist'.")
+`paced-global-dictionary-enable-alist'.")
-(defun paced-dict-enable-list ()
+(define-obsolete-variable-alias 'paced-local-dict-enable-alist
+ 'paced-local-dictionary-enable-alist
+ "1.1")
+
+(defun paced-dictionary-enable-list ()
"Return the combination of the local and global enable-alists.
-See `paced-local-dict-enable-alist' and
-`paced-global-dict-enable-alist' for more information."
- (append paced-local-dict-enable-alist
- paced-global-dict-enable-alist))
+See `paced-local-dictionary-enable-alist' and
+`paced-global-dictionary-enable-alist' for more information."
+ (append paced-local-dictionary-enable-alist
+ paced-global-dictionary-enable-alist))
+
+(define-obsolete-function-alias 'paced-dict-enable-list
+ 'paced-dictionary-enable-list
+ "1.1")
(defun paced-mode-symbol-p (sym)
"Return non-nil if SYM is a mode symbol."
(string-match-p (rx "-mode" string-end) (symbol-name sym)))
-(defun paced-test-dict-enable-condition (condition)
+(defun paced-test-dictionary-enable-condition (condition)
"Determines if CONDITION passes in the current buffer.
-See `paced-global-dict-enable-alist' for an explanation."
+See `paced-global-dictionary-enable-alist' for an explanation."
(pcase condition
((and (pred symbolp)
(pred paced-mode-symbol-p))
@@ -390,9 +412,9 @@ See `paced-global-dict-enable-alist' for an explanation."
((pred functionp)
(funcall condition))
(`(or . ,rest)
- (seq-some 'paced-test-dict-enable-condition rest))
+ (seq-some 'paced-test-dictionary-enable-condition rest))
(`(and . ,rest)
- (seq-every-p 'paced-test-dict-enable-condition rest))))
+ (seq-every-p 'paced-test-dictionary-enable-condition rest))))
(defun paced-current-dictionary ()
"Determine the current dictionary.
@@ -400,18 +422,39 @@ See `paced-global-dict-enable-alist' for an explanation."
Returns nil if no dictionary should be enabled.
If a dictionary is found in the list that doesn't exist, it will
-be skipped."
- (let ((conditions (paced-dict-enable-list))
+be skipped.
+
+See `paced-global-dictionary-enable-alist' or
+`paced-local-dictionary-enable-alist' for how to set the current
+dictionary conditions."
+ (let ((conditions (paced-dictionary-enable-list))
(dictionary))
(while (and conditions
(not dictionary))
(pcase-let* ((`(,condition . ,dict) (pop conditions)))
(when (and (paced-dictionary-key-registered-p dict)
- (paced-test-dict-enable-condition condition))
+ (paced-test-dictionary-enable-condition condition))
(setq dictionary dict))))
(when dictionary
(paced-named-dictionary dictionary))))
+(defvar paced-throw-error-on-no-current t
+ "Whether to throw an error when no current dictionary can be
+found.")
+
+(defmacro paced-operate-on-current-dictionary (&rest form)
+ "Run FORM with the current dictionary bound to `dict'.
+
+If no dictionary can be found for the buffer, throw an error. To
+suppress the error, set `paced-throw-error-on-no-current' to
+nil."
+ `(if-let* ((dict (paced-current-dictionary)))
+ (progn ,@form)
+ (when paced-throw-error-on-no-current
+ (user-error "No dictionary found for current buffer"))))
+
+;;; Saving and Loading
+
(cl-defmethod paced-dictionary-save ((dict paced-dictionary) &optional force)
"Save dictionary DICT according to its filename.
@@ -428,10 +471,18 @@ If FORCE is non-nil (given with a prefix arg), forcibly
save the
dictionary if found."
(declare (interactive-only paced-dictionary-save))
(interactive (list (paced-read-dictionary) current-prefix-arg))
- (paced-ensure-registered key)
- (let ((dict (paced-named-dictionary key)))
+ (paced-operate-on-named-dictionary key
(paced-dictionary-save dict force)))
+(defun paced-save-current-dictionary (force)
+ "Save the dictionary for the current buffer.
+
+For how the current dictionary is determined, see
+`paced-current-dictionary'."
+ (interactive "P")
+ (paced-operate-on-current-dictionary
+ (paced-dictionary-save dict force)))
+
(defun paced-load-dictionary-from-file (file)
"Load dictionary from FILE."
(interactive
@@ -470,32 +521,7 @@ dictionary if found."
(paced-dictionary-save dict t))
-
-(defvar-local paced--current-source nil
- "The source from which a dictionary is being populated.
-
-This is used internally to inform the user of the current source,
-since population mostly uses temporary buffers.")
-
-(defvar-local paced-exclude-function (lambda () nil)
- "Local predicate to determine if thing at point should be excluded.
-
-This should be a function of no arguments that returns non-nil if
-the current thing-at-point should be excluded from paced
-dictionaries. Exclusion is checked from the start or the end of
-the current thing, depending on `paced-point-in-thing-at-point-for-exclusion'.
-Point returns to its original position after the function is
-called.
-
-By default, this allows everything.
-
-A useful function for this is `paced-in-comment-p'.")
-
-(defun paced-in-comment-p (&optional pos)
- "Return non-nil if POS is in a comment.
-
-If POS is not specified, defaults to `point'."
- (nth 8 (syntax-ppss (or pos (point)))))
+;;; Handling of Thing at Point
(defun paced-bounds-of-thing-at-point ()
"Get the bounds of the thing at point."
@@ -530,6 +556,8 @@ Thing is based on `paced-thing-at-point-constituent'."
Thing is based on `paced-thing-at-point-constituent'."
(goto-char (cdr (paced-bounds-of-thing-at-point))))
+;;; Character Limits
+
(defun paced-length-of-thing-at-point ()
"Return the length, in characters, of the current thing at point."
(length (paced-thing-at-point)))
@@ -541,6 +569,28 @@ The limit requirement is set with `paced-character-limit'."
(or (eq paced-character-limit 0)
(<= (paced-length-of-thing-at-point) paced-character-limit)))
+;;; Exclusion
+
+(defvar-local paced-exclude-function (lambda () nil)
+ "Local predicate to determine if thing at point should be excluded.
+
+This should be a function of no arguments that returns non-nil if
+the current thing-at-point should be excluded from paced
+dictionaries. Exclusion is checked from the start or the end of
+the current thing, depending on `paced-point-in-thing-at-point-for-exclusion'.
+Point returns to its original position after the function is
+called.
+
+By default, this allows everything.
+
+A useful function for this is `paced-in-comment-p'.")
+
+(defun paced-in-comment-p (&optional pos)
+ "Return non-nil if POS is in a comment.
+
+If POS is not specified, defaults to `point'."
+ (nth 8 (syntax-ppss (or pos (point)))))
+
(defun paced-excluded-p ()
"Return non-nil to exclude current thing at point.
@@ -562,6 +612,8 @@ This also handles character limits set by
(paced-goto-end-of-thing-at-point)))
(funcall paced-exclude-function))))
+;;; Case Handling
+
(defun paced-mixed-case-word-p (word)
"Return non-nil if WORD is mixed-case.
@@ -603,6 +655,14 @@ This is a separate function only for testing; use
"Return WORD, modified based on DICT's case handling."
(paced--handle-word-case (oref dict case-handling) word))
+;;; Population
+
+(defvar-local paced--current-source nil
+ "The source from which a dictionary is being populated.
+
+This is used internally to inform the user of the current source,
+since population mostly uses temporary buffers.")
+
(cl-defmethod paced-dictionary-add-word ((dict paced-dictionary) word)
"Add WORD to paced dictionary DICT."
(let ((new-word (paced-dictionary-process-word dict word)))
@@ -610,11 +670,13 @@ This is a separate function only for testing; use
(cl-incf (map-elt (oref dict usage-hash) new-word 0))
(oset dict updated t)))
-(defsubst paced-add-word-to-current-dict (word)
- "Add WORD to the current paced dictionary."
- (if-let* ((dict (paced-current-dictionary)))
- (paced-dictionary-add-word dict word)
- (error "No current dictionary found")))
+(defun paced-add-word-to-current-dictionary (word)
+ "Add WORD to the current dictionary.
+
+For how the current dictionary is determined, see
+`paced-current-dictionary'."
+ (paced-operate-on-current-dictionary
+ (paced-dictionary-add-word dict word)))
(cl-defmethod paced-dictionary-populate-from-buffer ((dict paced-dictionary)
&optional buffer)
"Repopulate DICT from BUFFER.
@@ -637,41 +699,76 @@ If BUFFER is nil, use the current one."
(paced-dictionary-add-word dict (paced-thing-at-point))))
(progress-reporter-done reporter)))))
-(defun paced-populate-dictionary-from-region (dict start end)
- "Populate DICT from the region in the current buffer between START and END.
+(defun paced-populate-current-dictionary-from-buffer (&optional buffer)
+ "Populate the current dictionary from BUFFER.
-Note that this doesn't add the current buffer to DICT's
-population commands, so if DICT is later repopulated using
+This means add a usage of each included thing in BUFFER.
+
+BUFFER is either the name of a buffer, or the buffer itself. If
+not given, use the current buffer.
+
+In order to only populate the dictionary from a region,
+`paced-populate-current-dictionary-from-region'.
+
+Note that this doesn't add the buffer to the dictionary's
+population commands, so if it is later repopulated using
`paced-dictionary-repopulate' or
`paced-repopulate-named-dictionary', anything added with this
-command will be lost."
- (save-restriction
- (narrow-to-region start end)
- (paced-dictionary-populate-from-buffer dict)))
+command will be lost.
-(defun paced-populate-buffer-dictionary (&optional buffer)
- "Populate BUFFER's current dictionary with BUFFER.
+In order to make changes permanent, use
+`paced-add-buffer-file-to-dictionary'.
-This means add a usage of each included thing in buffer.
+For how the current dictionary is determined, see
+`paced-current-dictionary'."
+ (interactive "b")
+ (paced-operate-on-current-dictionary
+ (paced-dictionary-populate-from-buffer dict buffer)))
-If called interactively, the current buffer is used. In order to
-only populate the dictionary from a region,
-`paced-populate-from-region'.
+(define-obsolete-function-alias 'paced-populate-buffer-dictionary
+ 'paced-populate-current-dictionary-from-buffer
+ "1.1")
-Note that this doesn't add BUFFER to the dictionary's population
-commands, so if it is later repopulated using
+(defun paced-populate-named-dictionary-from-buffer (name &optional buffer)
+ "Populate the dictionary named NAME from BUFFER.
+
+This means add a usage of each included thing in BUFFER.
+
+BUFFER is either the name of a buffer, or the buffer itself. If
+not given, use the current buffer.
+
+In order to only populate the dictionary from a region,
+`paced-populate-current-dictionary-from-region'.
+
+Note that this doesn't add the buffer to the dictionary's
+population commands, so if it is later repopulated using
`paced-dictionary-repopulate' or
`paced-repopulate-named-dictionary', anything added with this
command will be lost.
In order to make changes permanent, use
-`paced-add-buffer-file-to-dictionary'."
- (interactive)
- (if-let* ((dict (paced-current-dictionary)))
- (paced-dictionary-populate-from-buffer dict buffer)
- (user-error "No dictionary found")))
+`paced-add-buffer-file-to-dictionary'.
+
+For how the current dictionary is determined, see
+`paced-current-dictionary'."
+ (interactive
+ (list (paced-read-dictionary) (read-buffer "Buffer: " nil t)))
+ (paced-operate-on-named-dictionary name
+ (paced-dictionary-populate-from-buffer dict buffer)))
+
+(cl-defmethod paced-dictionary-populate-from-region ((dict paced-dictionary)
start end)
+ "Populate DICT from the region in the current buffer between START and END.
-(defun paced-populate-from-region (start end)
+Note that this doesn't add the current buffer to DICT's
+population commands, so if DICT is later repopulated using
+`paced-dictionary-repopulate' or
+`paced-repopulate-named-dictionary', anything added with this
+command will be lost."
+ (save-restriction
+ (narrow-to-region start end)
+ (paced-dictionary-populate-from-buffer dict)))
+
+(defun paced-populate-current-dictionary-from-region (start end)
"Populate the current dictionary from the region START to END.
Note that this doesn't add the current buffer to the dictionary's
@@ -680,11 +777,14 @@ population commands, so if it is later repopulated using
`paced-repopulate-named-dictionary', anything added with this
command will be lost."
(interactive "r")
- (if-let* ((dict (paced-current-dictionary)))
- (paced-populate-dictionary-from-region dict start end)
- (user-error "No dictionary found")))
+ (paced-operate-on-current-dictionary
+ (paced-dictionary-populate-from-region dict start end)))
-(defun paced-add-current-thing-to-dict ()
+(define-obsolete-function-alias 'paced-populate-from-region
+ 'paced-populate-current-dictionary-from-region
+ "1.1")
+
+(defun paced-add-current-thing-to-dictionary ()
"Add the current thing at point to the current dictionary.
No check is done to determine if the current thing should be
@@ -696,7 +796,10 @@ population commands, so if it is later repopulated using
`paced-repopulate-named-dictionary', anything added with this
command will be lost."
(interactive)
- (paced-add-word-to-current-dict (paced-thing-at-point)))
+ (paced-operate-on-current-dictionary
+ (paced-dictionary-add-word dict (paced-thing-at-point))))
+
+;;; Dictionary Reset
(cl-defmethod paced-dictionary-reset ((dict paced-dictionary))
"Reset the usage-hash of paced-dictionary DICT."
@@ -704,12 +807,23 @@ command will be lost."
(defun paced-reset-named-dictionary (key)
"Reset the paced dictionary with key KEY."
+ (declare (interactive-only paced-dictionary-reset))
(interactive
(list (paced-read-dictionary)))
- (paced-ensure-registered key)
- (let ((dict (paced-named-dictionary key)))
+ (paced-operate-on-named-dictionary key
(paced-dictionary-reset dict)))
+(defun paced-reset-current-dictionary ()
+ "Reset the current dictionary.
+
+For how the current dictionary is determined, see
+`paced-current-dictionary'."
+ (interactive)
+ (paced-operate-on-current-dictionary
+ (paced-dictionary-reset dict)))
+
+;;; Dictionary Sorting
+
(cl-defmethod paced-dictionary-sort ((dict paced-dictionary))
"Sort the words in dictionary DICT by usage."
(oset dict usage-hash
@@ -718,12 +832,22 @@ command will be lost."
(defun paced-sort-named-dictionary (key)
"Sort the paced dictionary with key KEY."
+ (declare (interactive-only paced-dictionary-sort))
(interactive (list (paced-read-dictionary)))
- (paced-ensure-registered key)
- (let ((dict (paced-named-dictionary key)))
+ (paced-operate-on-named-dictionary key
(paced-dictionary-sort dict)))
+(defun paced-sort-current-dictionary ()
+ "Sort the current paced dictionary.
+
+For how the current dictionary is determined, see
+`paced-current-dictionary'."
+ (interactive)
+ (paced-operate-on-current-dictionary
+ (paced-dictionary-sort dict)))
+
+;;; The Minor Mode
(define-minor-mode paced-mode
"Toggle paced mode.
@@ -740,10 +864,7 @@ This adds `paced-completion-at-point' to
(define-globalized-minor-mode global-paced-mode paced-mode paced-mode
:group 'paced)
-
- ; ;;;;;;;;;;;;;;;; ;
- ; ;; Completion ;; ;
- ; ;;;;;;;;;;;;;;;; ;
+;;; Completion
(cl-defmethod paced-dictionary-fix-completion-case ((dict paced-dictionary)
prefix completions)
"Account for case differences in the prefix by prepending PREFIX to
COMPLETIONS.
@@ -818,6 +939,8 @@ the prefix before completions are returned."
(let* ((completion-ignore-case paced-completion-ignore-case))
(pcase action
((or `nil `t `lambda)
+ ;; Intentionally don't throw an error here, so as not to disrupt
+ ;; completion.
(when-let* ((dict (paced-current-dictionary)))
(paced-dictionary-completions dict string action pred)))
(`(boundaries . _) nil)
@@ -847,8 +970,10 @@ This should only be called from
`paced-completion-at-point'."
;; Might not be the entire completion, so don't add it.
)
(finished
+ ;; We know there's a current dictionary, since this should only be called
+ ;; from `paced-completion-at-point'.
(when paced-auto-update-p
- (paced-add-word-to-current-dict word)))))
+ (paced-add-word-to-current-dictionary word)))))
(defun paced-completion-at-point ()
"Function for `completion-at-point-functions' to get the paced completions."
@@ -860,9 +985,7 @@ This should only be called from
`paced-completion-at-point'."
:exclusive 'no))))
- ; ;;;;;;;;;;;;;;;;;; ;
- ; ;; Repopulation ;; ;
- ; ;;;;;;;;;;;;;;;;;; ;
+;;; Repopulation
(defun paced--insert-file-contents (file)
"Insert the contents of FILE into the current buffer.
@@ -1074,19 +1197,30 @@ repopulating it. If `paced-populate-warn-about-reset'
is
non-nil, confirmation will be requested before continuing."
(interactive
(list (paced-read-dictionary)))
- (paced-ensure-registered key)
- (let ((dict (paced-named-dictionary key)))
+ (paced-operate-on-named-dictionary key
(when (or (not paced-populate-warn-about-reset)
(y-or-n-p "Warning: Repopulating dictionary will reset it.
Continue?"))
(paced-dictionary-repopulate dict))))
+(defun paced-repopulate-current-dictionary ()
+ "Repopulate the current dictionary.
+
+Note that this will empty the dictionary's contents before
+repopulating it. If `paced-populate-warn-about-reset' is
+non-nil, confirmation will be requested before continuing."
+ (interactive)
+ (paced-operate-on-current-dictionary
+ (when (or (not paced-populate-warn-about-reset)
+ (y-or-n-p "Warning: Repopulating dictionary will reset it.
Continue?"))
+ (paced-dictionary-repopulate dict))))
+
(cl-defmethod paced-dictionary-add-population-command ((dict paced-dictionary)
(cmd
paced-population-command))
"Add population command CMD to dictionary DICT."
(cl-pushnew cmd (oref dict population-commands) :test 'equal))
(defun paced-add-buffer-file-to-dictionary (&optional buffer)
- "Populate the dictionary of BUFFER with BUFFER.
+ "Populate the current dictionary of BUFFER with BUFFER.
The file corresponding to BUFFER is then added to the current
dictionary's population commands.
@@ -1098,33 +1232,35 @@ must be set with `paced-edit-named-dictionary' or
(with-current-buffer (or buffer (current-buffer))
(unless (buffer-file-name)
(user-error "paced-add-buffer-file-to-dictionary called inside a
non-file buffer."))
- (if-let* ((dict (paced-current-dictionary))
- (file-name (buffer-file-name))
- (cmd (paced-file-population-command :file file-name)))
- (progn
- (paced-dictionary-populate-from-buffer dict buffer)
- (paced-dictionary-add-population-command dict cmd))
- (user-error "No dictionary found for current buffer"))))
+ (paced-operate-on-current-dictionary
+ (let* ((file-name (buffer-file-name))
+ (cmd (paced-file-population-command :file file-name)))
+ (paced-dictionary-populate-from-buffer dict buffer)
+ (paced-dictionary-add-population-command dict cmd)))))
+;;; Edit a Dictionary
+
(cl-defmethod paced-dictionary-edit ((dict paced-dictionary))
"Edit paced-dictionary DICT."
(customize-object dict))
(defun paced-edit-named-dictionary (name)
"Edit the paced-dictionary named NAME."
+ (declare (interactive-only paced-dictionary-edit))
(interactive (list (paced-read-dictionary)))
- (if-let* ((dict (paced-named-dictionary name)))
- (paced-dictionary-edit dict)
- (error "No paced dictionary called '%s' has been registered" name)))
+ (paced-operate-on-named-dictionary name
+ (paced-dictionary-edit dict)))
(defun paced-edit-current-dictionary ()
- "Edit the current paced dictionary."
+ "Edit the current paced dictionary.
+
+For how the current dictionary is determined, see
+`paced-current-dictionary'."
(interactive)
- (if-let* ((dict (paced-current-dictionary)))
- (paced-dictionary-edit dict)
- (user-error "No dictionary found for current buffer")))
+ (paced-operate-on-current-dictionary
+ (paced-dictionary-edit dict)))
@@ -1172,16 +1308,15 @@ must be set with `paced-edit-named-dictionary' or
(defun paced-print-current-dictionary ()
"Print the contents of the current dictionary in a dedicated buffer."
(interactive)
- (if-let* ((dict (paced-current-dictionary)))
- (paced-dictionary-print dict)
- (user-error "No dictionary found for current buffer")))
+ (paced-operate-on-current-dictionary
+ (paced-dictionary-print)))
(defun paced-print-named-dictionary (name)
"Print the contents of the dictionary with name NAME."
+ (declare (interactive-only paced-dictionary-print))
(interactive (list (paced-read-dictionary)))
- (if-let* ((dict (paced-named-dictionary name)))
- (paced-dictionary-print dict)
- (error "No paced dictionary called '%s' has been registered" name)))
+ (paced-operate-on-named-dictionary name
+ (paced-dictionary-print name)))
diff --git a/paced.info b/paced.info
index 1fb5c84..7ab606e 100644
--- a/paced.info
+++ b/paced.info
@@ -41,6 +41,7 @@ Dictionaries
* Editing a Dictionary:: How to edit your new dictionary
* Selective Dictionaries:: Enabling certain dictionaries under certain
conditions
* Dictionary Files:: Loading and Saving the Dictionaries
+* Printing a Dictionary:: Seeing the contents of a dictionary
Population Commands
@@ -53,6 +54,9 @@ Example Setups
* Org Agenda Files::
* Project Files::
+* Markdown Files::
+* Repopulating Dictionary After Saving::
+* Repopulating Dictionary After Spellchecking the Buffer::
Contributing
@@ -63,6 +67,7 @@ Contributing
Changelog
+* 1.1: 11.
* 1.0.1: 101.
* 1.0: 10.
@@ -191,17 +196,27 @@ Installation
Emacs 25.1
async 1.9.1
- Right now, the only way to install paced is from source.
+ Paced may be installed from source, or from GNU ELPA.
+
+ From ELPA:
+
+ M-x package-install RET paced RET
From Source:
bzr branch https://bzr.savannah.gnu.org/r/paced-el paced
- After that, add the following to your init file (typically .emacs):
+ After installing from source, add the following to your init file
+(typically .emacs):
(add-to-list 'load-path "/full/path/to/paced/")
(require 'paced)
+ However you install paced, you must also make sure dictionaries are
+loaded on startup:
+
+ (paced-load-all-dictionaries)
+
File: paced.info, Node: Basic Setup, Prev: Installation, Up: Introduction
@@ -213,8 +228,8 @@ is as follows:
1. Create a new dictionary, “Default” (See *note Creating a
Dictionary::)
- 2. Set paced-global-dict-enable-alist to ‘((t . "Default"))’ (See
- *note Selective Dictionaries::)
+ 2. Set ‘paced-global-dictionary-enable-alist’ to ‘((t . "Default"))’
+ (See *note Selective Dictionaries::)
3. Run ‘M-x global-paced-mode’
4. To add a file to the dictionary, use ‘M-x
paced-add-buffer-file-to-dictionary’
@@ -234,6 +249,7 @@ Dictionaries
* Editing a Dictionary:: How to edit your new dictionary
* Selective Dictionaries:: Enabling certain dictionaries under certain
conditions
* Dictionary Files:: Loading and Saving the Dictionaries
+* Printing a Dictionary:: Seeing the contents of a dictionary
File: paced.info, Node: Creating a Dictionary, Next: Editing a Dictionary,
Up: Dictionaries
@@ -284,9 +300,11 @@ Selective Dictionaries
Paced provides a mechanism called the “enable list”, that allows a user
to enable certain dictionaries for completion given certain conditions.
- There are two enable lists: a global and local one. They both work
-the same, with the local one taking precedence. Each entry in the list
-has a condition and a key.
+ There are two enable lists: a global
+(‘paced-global-dictionary-enable-alist’) and local
+(‘paced-local-dictionary-enable-alist’) one. They both work the same,
+with the local one taking precedence. Each entry in the list has a
+condition and a key.
The conditions are one of the following:
@@ -317,7 +335,7 @@ active.
The key is the dictionary name you set during dictionary creation.
-File: paced.info, Node: Dictionary Files, Prev: Selective Dictionaries, Up:
Dictionaries
+File: paced.info, Node: Dictionary Files, Next: Printing a Dictionary,
Prev: Selective Dictionaries, Up: Dictionaries
Dictionary Files
================
@@ -348,6 +366,24 @@ setting ‘paced-repopulate-saves-dictionary’ to t.
Population is covered
in the next section.
+File: paced.info, Node: Printing a Dictionary, Prev: Dictionary Files, Up:
Dictionaries
+
+Printing a Dictionary
+=====================
+
+Paced allows a user to print the contents of a dictionary to a buffer.
+Uses for this might be to tweak population commands or exclude
+functions, or to simply make sure a dictionary is populating correctly.
+
+ To use this feature, run:
+
+ M-x paced-print-named-dictionary RET NAME-OF-DICTIONARY RET
+
+ Or for the current dictionary:
+
+ M-x paced-print-current-dictionary RET
+
+
File: paced.info, Node: Population Commands, Next: Example Setups, Prev:
Dictionaries, Up: Top
Population Commands
@@ -407,7 +443,7 @@ When setting the population commands of a dictionary, one
may also set
certain properties. Each property is a variable binding, bound while
the population command runs.
- Two variables are of note here:
+ A few variables are of note here:
paced-exclude-function
Function of no arguments that returns non-nil if the thing at point
@@ -415,6 +451,9 @@ paced-exclude-function
paced-thing-at-point-constituent
Symbol defining thing on which population works. Typically set to
either ’symbol or ’word.
+paced-character-limit
+ Maximum length of a thing to include it in a dictionary. If set to
+ 0 (default), no limit is imposed.
For convenience, properties that are intended for all population
commands of a given dictionary may be set in the dictionary itself. In
@@ -498,10 +537,17 @@ A common problem is that population can take a long time.
Some of us
populate dictionaries from org agenda files, which can get pretty big.
To solve this, paced uses the async
-(https://github.com/jwiegley/emacs-async) package. Setup should be
-seamless; just stick whatever code you need in
-‘~/.emacs.d/paced-async.el’, type M-x
-paced-repopulate-named-dictionary-async, and push enter.
+(https://github.com/jwiegley/emacs-async) package. Setup is seamless;
+just stick whatever code you need in ‘~/.emacs.d/paced-async.el’, and
+use one of the two population commands:
+
+ A named dictionary:
+
+ M-x paced-repopulate-named-dictionary-async RET NAME RET
+
+ Or the current dictionary:
+
+ M-x paced-repopulate-current-dictionary-async RET
A few things to note about this:
@@ -509,7 +555,9 @@ paced-repopulate-named-dictionary-async, and push enter.
population
2. Asynchronous population doesn’t change anything until after
population is finished, so a user may continue to use their
- dictionary while population is happening.
+ dictionary while population is happening. This also means that
+ multiple populations may run in parallel without interfering with
+ one another.
3. Because async runs population in a separate Emacs process, any
custom code required for population must be in paced-async.el.
This includes additional population command types, but doesn’t
@@ -529,6 +577,9 @@ Example Setups
* Org Agenda Files::
* Project Files::
+* Markdown Files::
+* Repopulating Dictionary After Saving::
+* Repopulating Dictionary After Spellchecking the Buffer::
File: paced.info, Node: Org Agenda Files, Next: Project Files, Up: Example
Setups
@@ -549,7 +600,20 @@ code and drawers.
Done.
- Now, the exclude command, which sits inside the properties option:
+ Now, the exclude command, which sits inside the properties option.
+This can be added to ‘paced-async.el’:
+
+ (require 'org)
+
+ (defun org-at-tag-p ()
+ (let* ((p (point)))
+ ;; Ignore errors from `org-get-tags-string'.
+ (ignore-errors
+ ;; Checks the match string for a tag heading, setting match-string
1 to the
+ ;; tags. Also sets match-beginning and match-end.
+ (org-get-tags-string)
+ (when (match-string 1)
+ (<= (match-beginning 1) p (match-end 1))))))
(defun org-paced-exclude ()
(or
@@ -557,6 +621,8 @@ code and drawers.
(org-between-regexps-p org-drawer-regexp ":END:") ;; Doesn't catch END
(org-in-regexp ":END:") ;; but this does
+ (org-at-tag-p) ;; tags
+
(org-at-comment-p) ;; comments
(org-in-regexp org-any-link-re) ;; links
(org-in-block-p '("src" "quote" "verse")) ;; blocks
@@ -574,7 +640,7 @@ customize buffer as such:
And you’re done. See how easy that was?
-File: paced.info, Node: Project Files, Prev: Org Agenda Files, Up: Example
Setups
+File: paced.info, Node: Project Files, Next: Markdown Files, Prev: Org
Agenda Files, Up: Example Setups
Project Files
=============
@@ -605,6 +671,89 @@ dedicated solutions for almost everything, but it makes an
excellent
fallback.
+File: paced.info, Node: Markdown Files, Next: Repopulating Dictionary After
Saving, Prev: Project Files, Up: Example Setups
+
+Markdown Files
+==============
+
+Another common request is markdown files. In order for this to work,
+you’ll need to install ‘markdown-mode’:
+
+ M-x package-install RET markdown-mode RET
+
+ After that, add the following to your ‘paced-async.el’ file:
+
+ (require 'markdown-mode)
+
+ (defun paced-markdown-exclude-p ()
+ "Taken from `markdown-flyspell-check-word-p'."
+ ;; Exclude anything markdown mode thinks flyspell should skip.
+ (or
+ ;; Ignore code blocks
+ (markdown-code-block-at-point-p)
+ (markdown-inline-code-at-point-p)
+ ;; Ignore comments
+ (markdown-in-comment-p)
+ ;; Ignore special text
+ (let ((faces (get-text-property (point) 'face)))
+ (if (listp faces)
+ (or (memq 'markdown-reference-face faces)
+ (memq 'markdown-markup-face faces)
+ (memq 'markdown-plain-url-face faces)
+ (memq 'markdown-inline-code-face faces)
+ (memq 'markdown-url-face faces))
+ (memq faces '(markdown-reference-face
+ markdown-markup-face
+ markdown-plain-url-face
+ markdown-inline-code-face
+ markdown-url-face))))))
+
+ That excludes anything that the developers of markdown-mode felt
+should be excluded from flyspell.
+
+ Set this as your exclude function in your dictionary’s settings, then
+add each markdown file by hand.
+
+
+File: paced.info, Node: Repopulating Dictionary After Saving, Next:
Repopulating Dictionary After Spellchecking the Buffer, Prev: Markdown Files,
Up: Example Setups
+
+Repopulating Dictionary After Saving
+====================================
+
+This is a common request, although with the power of async, it’s an easy
+one to fulfill. This will repopulate the current buffer’s dictionary
+every time you save a file with a dictionary. This may seem daunting,
+but the dictionary will remain usable during population, and multiple
+populations won’t interfere with one another.
+
+ ;; Repopulate the current dictionary after saving
+ (add-hook 'after-save-hook 'paced-repopulate-current-dictionary-async)
+
+ Add that to your .emacs file, and paced will take it from there.
+
+ If you decide that’s too much, do the following:
+
+ M-: (remove-hook 'after-save-hook
'paced-repopulate-current-dictionary-async) RET
+
+
+File: paced.info, Node: Repopulating Dictionary After Spellchecking the
Buffer, Prev: Repopulating Dictionary After Saving, Up: Example Setups
+
+Repopulating Dictionary After Spellchecking the Buffer
+======================================================
+
+Another request, although much trickier to do. This one involves using
+Emacs’s advice mechanism:
+
+ (define-advice ispell-pdict-save (:after (&optional _no-query
_force-save) paced-populate)
+ ;; Repopulate the current dictionary after running spell check
+ (paced-repopulate-current-dictionary-async))
+
+ If you decide this isn’t for you, do the following to revert the
+changes:
+
+ M-: (advice-remove #'ispell-pdict-save #'address@hidden) RET
+
+
File: paced.info, Node: Contributing, Next: Changelog, Prev: Example
Setups, Up: Top
Contributing
@@ -671,6 +820,19 @@ can then merge that into the main development branch.
paced-POPULATION-COMMAND-TYPE-population-command
• Run ’make check’ to verify that your mods don’t break anything
• Avoid additional or altered dependencies if at all possible
+ • Dictionary commands come in threes (“the operation triad”):
+ 1. paced-dictionary-OPERATION, a cl-defmethod which performs
+ OPERATION on a dictionary
+ 2. paced-OPERATION-on-named-dictionary, an interactive only
+ function that prompts for a dictionary name and performs
+ OPERATION on that dictionary:
+ (interactive (list (paced-read-dictionary)))
+ (paced-ensure-registered name)
+ (paced-dictionary-OPERATION (paced-named-dictionary name))
+ 3. paced-OPERATION-on-current-dictionary, an interactive function
+ that performs OPERATION on the current dictionary
+ (interactive)
+ (paced-dictionary-OPERATION
(paced-current-dictionary-or-die))
File: paced.info, Node: Documentation, Next: Working with EDE, Prev:
Development, Up: Contributing
@@ -721,11 +883,32 @@ Changelog
* Menu:
+* 1.1: 11.
* 1.0.1: 101.
* 1.0: 10.
-File: paced.info, Node: 101, Next: 10, Up: Changelog
+File: paced.info, Node: 11, Next: 101, Up: Changelog
+
+1.1
+===
+
+ • Cleaned up the code to reflect the “operation triad”
+ • -OP, OP-on-named, OP-on-current
+ • Retained backwards compatibility by obsoleting a bunch of
+ functions, but didn’t remove any of them
+ • Also removed the use of dict- in global variables and
+ functions
+
+ • Added the ability to print the contents of a dictionary in a
+ separate buffer
+
+ • Added the option to limit the words added during population by size
+
+ • Various documentation improvements
+
+
+File: paced.info, Node: 101, Next: 10, Prev: 11, Up: Changelog
1.0.1
=====
@@ -746,34 +929,39 @@ Initial release.
Tag Table:
Node: Top228
-Node: Copying1772
-Node: Introduction2591
-Node: Similar Packages3711
-Node: pabbrev3997
-Node: predictive5140
-Node: Installation6188
-Node: Basic Setup6653
-Node: Dictionaries7256
-Node: Creating a Dictionary7660
-Node: Editing a Dictionary8700
-Node: Selective Dictionaries9176
-Node: Dictionary Files10825
-Node: Population Commands11916
-Node: Built-in Commands12852
-Node: Properties13649
-Node: Custom Commands14511
-Node: Asynchronous Population17238
-Node: Example Setups18431
-Node: Org Agenda Files18613
-Node: Project Files19869
-Node: Contributing20982
-Node: Bugs21756
-Node: Development22145
-Node: Documentation23112
-Node: Working with EDE23579
-Node: Changelog24622
-Node: 10124747
-Node: 1024944
+Node: Copying1971
+Node: Introduction2790
+Node: Similar Packages3910
+Node: pabbrev4196
+Node: predictive5339
+Node: Installation6387
+Node: Basic Setup7049
+Node: Dictionaries7664
+Node: Creating a Dictionary8137
+Node: Editing a Dictionary9177
+Node: Selective Dictionaries9653
+Node: Dictionary Files11391
+Node: Printing a Dictionary12512
+Node: Population Commands13034
+Node: Built-in Commands13970
+Node: Properties14767
+Node: Custom Commands15765
+Node: Asynchronous Population18492
+Node: Example Setups19941
+Node: Org Agenda Files20242
+Node: Project Files22002
+Node: Markdown Files23138
+Node: Repopulating Dictionary After Saving24763
+Node: Repopulating Dictionary After Spellchecking the Buffer25691
+Node: Contributing26436
+Node: Bugs27210
+Node: Development27599
+Node: Documentation29360
+Node: Working with EDE29827
+Node: Changelog30870
+Node: 1131006
+Node: 10131601
+Node: 1031809
End Tag Table
diff --git a/paced.org b/paced.org
index c3c4596..8a6e54e 100644
--- a/paced.org
+++ b/paced.org
@@ -98,7 +98,13 @@ need it to do that.
| Emacs | 25.1 |
| async | 1.9.1 |
-Right now, the only way to install paced is from source.
+Paced may be installed from source, or from GNU ELPA.
+
+From ELPA:
+
+#+begin_example
+M-x package-install RET paced RET
+#+end_example
From Source:
@@ -106,12 +112,20 @@ From Source:
bzr branch https://bzr.savannah.gnu.org/r/paced-el paced
#+end_src
-After that, add the following to your init file (typically .emacs):
+After installing from source, add the following to your init file (typically
.emacs):
#+BEGIN_SRC emacs-lisp
(add-to-list 'load-path "/full/path/to/paced/")
(require 'paced)
#+END_SRC
+
+However you install paced, you must also make sure dictionaries are loaded on
+startup:
+
+#+begin_src emacs-lisp
+(paced-load-all-dictionaries)
+#+end_src
+
** Basic Setup
:PROPERTIES:
:DESCRIPTION: The simplest setup
@@ -121,7 +135,7 @@ Paced needn't have a lot of setup to run. In fact, the
simplest setup is as
follows:
1. Create a new dictionary, "Default" (See [[#dictionary_creation][Creating a
Dictionary]])
-2. Set paced-global-dict-enable-alist to ~((t . "Default"))~ (See
[[#selective_dictionaries][Selective Dictionaries]])
+2. Set ~paced-global-dictionary-enable-alist~ to ~((t . "Default"))~ (See
[[#selective_dictionaries][Selective Dictionaries]])
3. Run ~M-x global-paced-mode~
4. To add a file to the dictionary, use ~M-x
paced-add-buffer-file-to-dictionary~
@@ -176,7 +190,8 @@ documented in the edit buffer.
Paced provides a mechanism called the "enable list", that allows a user to
enable certain dictionaries for completion given certain conditions.
-There are two enable lists: a global and local one. They both work the same,
+There are two enable lists: a global (~paced-global-dictionary-enable-alist~)
+and local (~paced-local-dictionary-enable-alist~) one. They both work the
same,
with the local one taking precedence. Each entry in the list has a condition
and a key.
@@ -238,6 +253,26 @@ M-x paced-save-all-dictionaries RET
Dictionaries may also be automatically saved whenever changed by setting
~paced-repopulate-saves-dictionary~ to t. Population is covered in the next
section.
+** Printing a Dictionary
+:PROPERTIES:
+:DESCRIPTION: Seeing the contents of a dictionary
+:END:
+
+Paced allows a user to print the contents of a dictionary to a buffer. Uses
for
+this might be to tweak population commands or exclude functions, or to simply
+make sure a dictionary is populating correctly.
+
+To use this feature, run:
+
+#+begin_example
+M-x paced-print-named-dictionary RET NAME-OF-DICTIONARY RET
+#+end_example
+
+Or for the current dictionary:
+
+#+begin_example
+M-x paced-print-current-dictionary RET
+#+end_example
* Population Commands
:PROPERTIES:
@@ -286,12 +321,14 @@ When setting the population commands of a dictionary, one
may also set certain
properties. Each property is a variable binding, bound while the population
command runs.
-Two variables are of note here:
+A few variables are of note here:
- paced-exclude-function :: Function of no arguments that returns non-nil if
the
thing at point should be excluded from population.
- paced-thing-at-point-constituent :: Symbol defining thing on which population
works. Typically set to either 'symbol or 'word.
+- paced-character-limit :: Maximum length of a thing to include it in a
+ dictionary. If set to 0 (default), no limit is imposed.
For convenience, properties that are intended for all population commands of a
given dictionary may be set in the dictionary itself. In the event of a
@@ -374,16 +411,29 @@ in this case.
A common problem is that population can take a long time. Some of us populate
dictionaries from org agenda files, which can get pretty big.
-To solve this, paced uses the
[[https://github.com/jwiegley/emacs-async][async]] package. Setup should be
seamless; just
-stick whatever code you need in ~~/.emacs.d/paced-async.el~, type M-x
-paced-repopulate-named-dictionary-async, and push enter.
+To solve this, paced uses the
[[https://github.com/jwiegley/emacs-async][async]] package. Setup is seamless;
just stick
+whatever code you need in ~~/.emacs.d/paced-async.el~, and use one of the two
+population commands:
+
+A named dictionary:
+
+#+begin_example
+M-x paced-repopulate-named-dictionary-async RET NAME RET
+#+end_example
+
+Or the current dictionary:
+
+#+begin_example
+M-x paced-repopulate-current-dictionary-async RET
+#+end_example
A few things to note about this:
1. Dictionaries will be automatically saved by this method after population
2. Asynchronous population doesn't change anything until after population is
finished, so a user may continue to use their dictionary while population is
- happening.
+ happening. This also means that multiple populations may run in parallel
+ without interfering with one another.
3. Because async runs population in a separate Emacs process, any custom code
required for population must be in paced-async.el. This includes additional
population command types, but doesn't include the following variables:
@@ -411,15 +461,30 @@ The generator for file-list is easy:
Done.
-Now, the exclude command, which sits inside the properties option:
+Now, the exclude command, which sits inside the properties option. This can be
+added to ~paced-async.el~:
#+begin_src emacs-lisp
+(require 'org)
+
+(defun org-at-tag-p ()
+ (let* ((p (point)))
+ ;; Ignore errors from `org-get-tags-string'.
+ (ignore-errors
+ ;; Checks the match string for a tag heading, setting match-string 1 to
the
+ ;; tags. Also sets match-beginning and match-end.
+ (org-get-tags-string)
+ (when (match-string 1)
+ (<= (match-beginning 1) p (match-end 1))))))
+
(defun org-paced-exclude ()
(or
;; Drawers
(org-between-regexps-p org-drawer-regexp ":END:") ;; Doesn't catch END
(org-in-regexp ":END:") ;; but this does
+ (org-at-tag-p) ;; tags
+
(org-at-comment-p) ;; comments
(org-in-regexp org-any-link-re) ;; links
(org-in-block-p '("src" "quote" "verse")) ;; blocks
@@ -467,6 +532,86 @@ small function for excluding those:
Use that for paced-exclude-function, and you're done. We can't necessarily
recommend this for any programming language, as there are dedicated solutions
for almost everything, but it makes an excellent fallback.
+** Markdown Files
+
+Another common request is markdown files. In order for this to work, you'll
need to install ~markdown-mode~:
+
+#+begin_example
+M-x package-install RET markdown-mode RET
+#+end_example
+
+After that, add the following to your ~paced-async.el~ file:
+
+#+begin_src emacs-lisp
+(require 'markdown-mode)
+
+(defun paced-markdown-exclude-p ()
+ "Taken from `markdown-flyspell-check-word-p'."
+ ;; Exclude anything markdown mode thinks flyspell should skip.
+ (or
+ ;; Ignore code blocks
+ (markdown-code-block-at-point-p)
+ (markdown-inline-code-at-point-p)
+ ;; Ignore comments
+ (markdown-in-comment-p)
+ ;; Ignore special text
+ (let ((faces (get-text-property (point) 'face)))
+ (if (listp faces)
+ (or (memq 'markdown-reference-face faces)
+ (memq 'markdown-markup-face faces)
+ (memq 'markdown-plain-url-face faces)
+ (memq 'markdown-inline-code-face faces)
+ (memq 'markdown-url-face faces))
+ (memq faces '(markdown-reference-face
+ markdown-markup-face
+ markdown-plain-url-face
+ markdown-inline-code-face
+ markdown-url-face))))))
+#+end_src
+
+That excludes anything that the developers of markdown-mode felt should be
+excluded from flyspell.
+
+Set this as your exclude function in your dictionary's settings, then add each
+markdown file by hand.
+
+** Repopulating Dictionary After Saving
+
+This is a common request, although with the power of async, it's an easy one to
+fulfill. This will repopulate the current buffer's dictionary every time you
+save a file with a dictionary. This may seem daunting, but the dictionary will
+remain usable during population, and multiple populations won't interfere with
+one another.
+
+#+begin_src emacs-lisp
+;; Repopulate the current dictionary after saving
+(add-hook 'after-save-hook 'paced-repopulate-current-dictionary-async)
+#+end_src
+
+Add that to your .emacs file, and paced will take it from there.
+
+If you decide that's too much, do the following:
+
+#+begin_example
+M-: (remove-hook 'after-save-hook 'paced-repopulate-current-dictionary-async)
RET
+#+end_example
+
+** Repopulating Dictionary After Spellchecking the Buffer
+
+Another request, although much trickier to do. This one involves using Emacs's
+advice mechanism:
+
+#+begin_src emacs-lisp
+(define-advice ispell-pdict-save (:after (&optional _no-query _force-save)
paced-populate)
+ ;; Repopulate the current dictionary after running spell check
+ (paced-repopulate-current-dictionary-async))
+#+end_src
+
+If you decide this isn't for you, do the following to revert the changes:
+
+#+begin_example
+M-: (advice-remove #'ispell-pdict-save #'address@hidden) RET
+#+end_example
* Contributing
:PROPERTIES:
@@ -528,6 +673,21 @@ There are a few rules to follow:
- New population commands should be named
paced-POPULATION-COMMAND-TYPE-population-command
- Run 'make check' to verify that your mods don't break anything
- Avoid additional or altered dependencies if at all possible
+- Dictionary commands come in threes ("the operation triad"):
+ 1. paced-dictionary-OPERATION, a cl-defmethod which performs OPERATION on a
dictionary
+ 2. paced-OPERATION-on-named-dictionary, an interactive only function that
prompts
+ for a dictionary name and performs OPERATION on that dictionary:
+ #+begin_src emacs-lisp
+ (interactive (list (paced-read-dictionary)))
+ (paced-ensure-registered name)
+ (paced-dictionary-OPERATION (paced-named-dictionary name))
+ #+end_src
+ 3. paced-OPERATION-on-current-dictionary, an interactive function that
+ performs OPERATION on the current dictionary
+ #+begin_src emacs-lisp
+ (interactive)
+ (paced-dictionary-OPERATION (paced-current-dictionary-or-die))
+ #+end_src
** Documentation
:PROPERTIES:
@@ -574,6 +734,18 @@ and letting one of us handle it is a good way to go.
:PROPERTIES:
:DESCRIPTION: List of changes by version
:END:
+** 1.1
+- Cleaned up the code to reflect the "operation triad"
+ - -OP, OP-on-named, OP-on-current
+ - Retained backwards compatibility by obsoleting a bunch of functions, but
didn't remove any of them
+ - Also removed the use of dict- in global variables and functions
+
+- Added the ability to print the contents of a dictionary in a separate buffer
+
+- Added the option to limit the words added during population by size
+
+- Various documentation improvements
+
** 1.0.1
Bug fix release
- Save dictionaries right after they're created
diff --git a/test.mk b/test.mk
index 392cb81..fa886a3 100644
--- a/test.mk
+++ b/test.mk
@@ -16,7 +16,7 @@
# EDE only allows arbitrary code from an external makefile, so this is how
we've
# got to do testing.
-test:
+test: compile
@$(EMACS) \
$(EMACSFLAGS) \
-L "." \
- [elpa] master c7fc9a4 01/13: Updated copyright, (continued)
- [elpa] master c7fc9a4 01/13: Updated copyright, Ian Dunn, 2018/02/04
- [elpa] master 13c02a6 06/13: Added dictionary printing, Ian Dunn, 2018/02/04
- [elpa] master a9d3d12 07/13: Added support for choosing which side of thing-at-point to consider for exclusion, Ian Dunn, 2018/02/04
- [elpa] master 56eeaff 04/13: Fixed up Changelog in documentation, Ian Dunn, 2018/02/04
- [elpa] master b73fff8 09/13: Added paced-repopulate-current-dictionary-async, Ian Dunn, 2018/02/04
- [elpa] master 1171a76 08/13: Added support for excluding words past a certain character limit, Ian Dunn, 2018/02/04
- [elpa] master bc5d7cd 10/13: Silenced byte-compiler, Ian Dunn, 2018/02/04
- [elpa] master d57675f 03/13: Added new forms for set-property! and fixed up build system, Ian Dunn, 2018/02/04
- [elpa] master 35acd8c 05/13: Cleaned up Changelog some more, Ian Dunn, 2018/02/04
- [elpa] master a9eb761 13/13: Merge commit '35acd8c2f9710e54ec3f433ae4af40cfff635295', Ian Dunn, 2018/02/04
- [elpa] master 463d752 11/13: Cleaned up code and added documentation of new features,
Ian Dunn <=
- [elpa] master f4d03a3 12/13: Merge commit '463d752d4703af93ea86df8f07b244e8fc851617', Ian Dunn, 2018/02/04