branch: externals/denote
commit d69a679b2c6622adc680de4d41b10aea7cf66124
Author: Protesilaos Stavrou <[email protected]>
Commit: Protesilaos Stavrou <[email protected]>
Make denote-infer-keywords enforce a controlled vocabulary when nil
This was always the implied use-case, but we were not enforcing it at
the minibuffer prompt.
---
README.org | 5 +++++
denote.el | 65 ++++++++++++++++++++++++++++++++++++++------------------------
2 files changed, 45 insertions(+), 25 deletions(-)
diff --git a/README.org b/README.org
index 3638cc829f..b8e57e0696 100644
--- a/README.org
+++ b/README.org
@@ -1529,6 +1529,11 @@ something like this in their configuration:
(setq denote-known-keywords (list "politics" "economics" "emacs" "philosophy"))
#+end_src
+[ As part of {{{development-version}}}, setting ~denote-infer-keywords~
+ to ~nil~ also makes the ~denote-keywords-prompt~ demand that the
+ input matches one of the keywords in ~denote-known-keywords~. In
+ previous versions, the prompt would accept arbitrary text. ]
+
** Use Denote commands from the menu bar or context menu
:PROPERTIES:
:CUSTOM_ID: h:c4290e15-e97e-4a9b-b8db-6b9738e37e78
diff --git a/denote.el b/denote.el
index 48396c3dc7..88d9c743bc 100644
--- a/denote.el
+++ b/denote.el
@@ -214,9 +214,19 @@ it is NOT automatically killed."
;;;###autoload (put 'denote-known-keywords 'safe-local-variable #'listp)
(defcustom denote-known-keywords
'("emacs" "philosophy" "politics" "economics")
- "List of strings with predefined keywords for `denote'.
-Also see user options: `denote-infer-keywords',
-`denote-sort-keywords', `denote-file-name-slug-functions'."
+ "List of strings with predefined keywords.
+This is used by the `denote-keywords-prompt' to get keywords when
+creating or renaming a file, such as via the commands `denote' and
+`denote-rename-file'.
+
+The `denote-keywords-prompt' does not enforce the keywords defined in
+`denote-known-keywords', as users can input arbitrary text. Those newly
+introduced keywords are then available for completion, if
+`denote-infer-keywords' is set to a non-nil value (its default). If
+`denote-infer-keywords' is nil, then the `denote-keywords-prompt' only
+accepts input that is among the `denote-known-keywords'.
+
+Also see: `denote-sort-keywords', `denote-file-name-slug-functions'."
:group 'denote
:safe #'listp
:package-version '(denote . "0.1.0")
@@ -226,30 +236,26 @@ Also see user options: `denote-infer-keywords',
(defcustom denote-infer-keywords t
"Whether to infer keywords from existing notes' file names.
-When non-nil, search the file names of existing notes in the
-variable `denote-directory' for their keyword field and extract
-the entries as \"inferred keywords\". These are combined with
-`denote-known-keywords' and are presented as completion
-candidates while using `denote' and related commands
-interactively.
+When non-nil (the default), search the file names of existing notes in
+the variable `denote-directory' for their keyword field and extract the
+entries as \"inferred keywords\". These are combined with
+`denote-known-keywords' and are presented as completion candidates while
+using `denote' and related commands interactively.
-If nil, refrain from inferring keywords. The aforementioned
-completion prompt only shows the `denote-known-keywords'. Use
-this if you want to enforce a restricted vocabulary.
+If nil, refrain from inferring keywords. In this case, make the
+aforementioned completion prompt show just the `denote-known-keywords'
+and enforce them as the only acceptable input. Use this if you want to
+work with a controlled vocabulary.
-The user option `denote-excluded-keywords-regexp' can be used to
+The user option `denote-keywords-to-not-infer-regexp' can be used to
exclude keywords that match a regular expression.
Inferred keywords are specific to the value of the variable
-`denote-directory'. If a silo with a local value is used, as
-explained in that variable's doc string, the inferred keywords
-are specific to the given silo.
-
-For advanced Lisp usage, the function `denote-keywords' returns
-the appropriate list of strings."
+`denote-directory'. In a silo, as explained in that variable's doc
+string, the inferred keywords are specific to the silo."
:group 'denote
:safe (lambda (val) (or val (null val)))
- :package-version '(denote . "0.1.0")
+ :package-version '(denote . "4.2.0")
:type 'boolean)
(defcustom denote-prompts '(title keywords)
@@ -2055,11 +2061,20 @@ Filter inferred keywords per
`denote-keywords-to-not-infer-regexp'."
"Use `completing-read-multiple' for KEYWORDS.
With optional PROMPT, use it instead of a generic text for file
keywords. With optional INITIAL, add it to the minibuffer as
-initial input."
- (delete-dups
- (completing-read-multiple
- (format-prompt (or prompt "New file KEYWORDS") nil)
- keywords nil nil initial 'denote-keyword-history)))
+initial input.
+
+When `denote-infer-keywords' is nil, pass REQUIRE-MATCH to the
+completion prompt. Otherwise, use nil for that parameter."
+ (let* ((restricted-p (null denote-infer-keywords))
+ (initial-prompt (or prompt "New file KEYWORDS"))
+ (final-prompt (if restricted-p
+ (format "%s %s" initial-prompt
+ (propertize "(controlled vocabulary)" 'face
'denote-faces-prompt-current-name))
+ initial-prompt)))
+ (delete-dups
+ (completing-read-multiple
+ (format-prompt final-prompt nil)
+ keywords nil restricted-p initial 'denote-keyword-history))))
(defun denote-keywords-prompt (&optional prompt-text initial-keywords
infer-from-files-matching-regexp)
"Prompt for one or more keywords.