branch: externals/denote
commit cd6dd03f8015fee4618368edd0d5bc332a82a8f2
Merge: 13a4de04c8 d69a679b2c
Author: Protesilaos Stavrou <[email protected]>
Commit: Protesilaos Stavrou <[email protected]>
Merge branch 'changes-for-4.2.0'
---
README.org | 29 ++++++++++-----
denote.el | 121 ++++++++++++++++++++++++++++++++++++++++++-------------------
2 files changed, 104 insertions(+), 46 deletions(-)
diff --git a/README.org b/README.org
index 6cd3424441..b8e57e0696 100644
--- a/README.org
+++ b/README.org
@@ -230,7 +230,7 @@ Here we include more of what you can configure with Denote
([[#h:998ae528-9276-4
(setq denote-sort-keywords t)
(setq denote-prompts '(title keywords))
(setq denote-excluded-directories-regexp nil)
- (setq denote-excluded-keywords-regexp nil)
+ (setq denote-keywords-to-not-infer-regexp nil)
(setq denote-rename-confirmations '(rewrite-front-matter modify-file-name))
;; Pick dates, where relevant, with Org's advanced interface:
@@ -428,10 +428,11 @@ alias ~denote-create-note~.
:END:
#+vindex: denote-directory
-The user option ~denote-directory~ specifies the file system path
-where new notes are created. The value is a string. New notes are
-generated by the ~denote~ command and everything else building on top
-of it ([[#h:6a92a8b5-d766-42cc-8e5b-8dc255466a23][Standard note creation]]).
+The Denote file-naming scheme can be applied to any file anywhere on
+the file system ([[#h:532e8e2a-9b7d-41c0-8f4b-3c5cbb7d4dca][Renaming files]]).
Still, Denote needs a dedicated
+directory to store the files it creates. To this end, the user option
+~denote-directory~ specifies the directory, as a string, where new
+files are created ([[#h:6a92a8b5-d766-42cc-8e5b-8dc255466a23][Standard note
creation]]).
The default path is =~/Documents/notes/=. If the directory does not
exist, Denote will create it upon generating a new note.
@@ -1488,9 +1489,12 @@ The match is performed with ~string-match-p~.
:CUSTOM_ID: h:69e518ee-ed43-40ab-a5f4-c780a23e5358
:END:
-#+vindex: denote-excluded-keywords-regexp
-The user option ~denote-excluded-keywords-regexp~ omits keywords that
-match a regular expression from the list of inferred keywords.
+#+vindex: denote-keywords-to-not-infer-regexp
+The user option ~denote-keywords-to-not-infer-regexp~ omits keywords
+that match a regular expression from the list of inferred keywords.
+
+[ The ~denote-excluded-keywords-regexp~ is an obsolete alias for
+ ~denote-keywords-to-not-infer-regexp~ as part of {{{development-version}}}. ]
Keywords are inferred from file names and provided at relevant prompts
as completion candidates when the user option ~denote-infer-keywords~
@@ -1525,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
@@ -5461,7 +5470,9 @@ The following sections cover the specifics.
([[#h:6a92a8b5-d766-42cc-8e5b-8dc255466a23][Standard note creation]]). In
the case of keyword inferrence, use
optional =FILES-MATCHING-REGEXP=, to extract keywords only from the
matching files. Otherwise, do it for all files. Filter inferred
- keywords with the user option ~denote-excluded-keywords-regexp~.
+ keywords with the user option ~denote-keywords-to-not-infer-regexp~.
+ [ The ~denote-excluded-keywords-regexp~ is an obsolete alias for
+ ~denote-keywords-to-not-infer-regexp~ as part of
{{{development-version}}}. ]
#+findex: denote-keywords-sort
+ Function ~denote-keywords-sort~ :: Sort =KEYWORDS= if
diff --git a/denote.el b/denote.el
index 4291f88811..3e3852455e 100644
--- a/denote.el
+++ b/denote.el
@@ -125,17 +125,44 @@
;;;###autoload (put 'denote-directory 'safe-local-variable (lambda (val) (or
(stringp val) (listp val) (eq val 'local) (eq val 'default-directory))))
(defcustom denote-directory (expand-file-name "~/Documents/notes/")
- "Directory for storing personal notes.
-
-This can also be a list of directories.
-
-If you intend to reference this variable in Lisp, consider using
-the function `denote-directories' instead."
+ "Directory, as a string, for storing personal notes.
+This is the destination `denote' and all other file-creating Denote
+commands use.
+
+The value can also be a list of directories as strings. In that case,
+`denote' and related commands will pick the first one among them, unless
+the user option `denote-prompts' is configured to prompt for a
+directory, among other possible prompts. Files within those directories
+can link to each other, as they are considered part of one expansive
+`denote-directory'.
+
+Whether the value is a string or a list of strings, all relevant Denote
+commands work with the subdirectories of those directories as well. In
+other words, a list value is not needed to enumerate all the
+subdirectories of a common parent directory: simply specify the parent.
+
+To create a \"silo\", i.e. a self-contained `denote-directory' whose
+files do no link to any file outside of it, set the value of this user
+option in a .dir-locals file. Read Info node `(denote) Maintain
+separate directory silos for notes'.
+
+If the target directory does not exist, `denote' and related commands
+will create it.
+
+The value of this variable is read by commands other than `denote', such
+as `denote-link', `denote-backlinks', `denote-dired', and `denote-grep',
+among others. File-renaming commands such as `denote-rename-file' and
+`denote-dired-rename-marked-files' can still be used on any file
+anywhere on the file system.
+
+To use the value of this variable from Lisp, call the function
+`denote-directories'."
:group 'denote
:safe (lambda (val) (or (stringp val) (listp val) (eq val 'local) (eq val
'default-directory)))
- :package-version '(denote . "2.0.0")
+ :package-version '(denote . "4.1.0")
:link '(info-link "(denote) Maintain separate directories for notes")
- :type 'directory)
+ :type '(choice (directory :tag "Single directory")
+ (repeat :tag "List of directories" directory)))
(define-obsolete-variable-alias 'denote-save-buffer-after-creation
'denote-save-buffers "3.0.0")
@@ -187,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")
@@ -199,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)
@@ -649,7 +682,12 @@ The match is performed with `string-match-p'."
:package-version '(denote . "1.2.0")
:type 'string)
-(defcustom denote-excluded-keywords-regexp nil
+(define-obsolete-variable-alias
+ 'denote-excluded-keywords-regexp
+ 'denote-keywords-to-not-infer-regexp
+ "4.2.0")
+
+(defcustom denote-keywords-to-not-infer-regexp nil
"Regular expression of keywords to not infer.
Keywords are inferred from file names and provided at relevant
prompts as completion candidates when the user option
@@ -657,7 +695,7 @@ prompts as completion candidates when the user option
The match is performed with `string-match-p'."
:group 'denote
- :package-version '(denote . "1.2.0")
+ :package-version '(denote . "4.2.0")
:type 'string)
(defcustom denote-excluded-files-regexp nil
@@ -1985,7 +2023,7 @@ Keep any duplicates. Users who do not want duplicates
should refer to
the functions `denote-keywords'."
(when-let* ((files (denote-directory-files files-matching-regexp))
(keywords (mapcan #'denote-extract-keywords-from-path files)))
- (if-let* ((regexp denote-excluded-keywords-regexp))
+ (if-let* ((regexp denote-keywords-to-not-infer-regexp))
(seq-remove
(lambda (k)
(string-match-p regexp k))
@@ -2002,7 +2040,7 @@ In the case of keyword inferrence, use optional
FILES-MATCHING-REGEXP,
to extract keywords only from the matching files. Otherwise, do it for
all files.
-Filter inferred keywords with the user option
`denote-excluded-keywords-regexp'."
+Filter inferred keywords per `denote-keywords-to-not-infer-regexp'."
(delete-dups
(if denote-infer-keywords
(append (denote-infer-keywords-from-files files-matching-regexp)
denote-known-keywords)
@@ -2023,11 +2061,20 @@ Filter inferred keywords with the user option
`denote-excluded-keywords-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.