[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/denote 60915b3104 33/39: Merge branch 'refactor-denote-
From: |
ELPA Syncer |
Subject: |
[elpa] externals/denote 60915b3104 33/39: Merge branch 'refactor-denote-prompts' |
Date: |
Mon, 11 Jul 2022 00:57:46 -0400 (EDT) |
branch: externals/denote
commit 60915b310425052f110a3376ee8532ce69df2f5f
Merge: 934c8c362f 2c0727eb37
Author: Protesilaos Stavrou <info@protesilaos.com>
Commit: Protesilaos Stavrou <info@protesilaos.com>
Merge branch 'refactor-denote-prompts'
---
README.org | 166 +++++++++++++++++++++++++++++++++++++--------------
denote.el | 199 ++++++++++++++++++++++++++++++++++++++++++-------------------
2 files changed, 260 insertions(+), 105 deletions(-)
diff --git a/README.org b/README.org
index d69df154c3..b0b397ee2a 100644
--- a/README.org
+++ b/README.org
@@ -153,10 +153,11 @@ The file type of the new note is determined by the user
option
#+vindex: denote-known-keywords
#+vindex: denote-infer-keywords
-The keyword prompt supports minibuffer completion. Available candidates
-are those defined in the user option ~denote-known-keywords~. More
-candidates can be inferred from the names of existing notes, by setting
-~denote-infer-keywords~ to non-nil (which is the case by default).
+The keywords' prompt supports minibuffer completion. Available
+candidates are those defined in the user option ~denote-known-keywords~.
+More candidates can be inferred from the names of existing notes, by
+setting ~denote-infer-keywords~ to non-nil (which is the case by
+default).
#+vindex: denote-sort-keywords
Multiple keywords can be inserted by separating them with a comma (or
@@ -165,65 +166,140 @@ When the user option ~denote-sort-keywords~ is non-nil
(the default),
keywords are sorted alphabetically (technically, the sorting is done
with ~string-lessp~).
-The ~denote~ command can also be called from Lisp, in which case it
-expects the =TITLE= and =KEYWORDS= arguments. The former is a string,
-the latter a list of strings.
+[ The ~denote-prompts~ is part of {{{development-version}}} ]
+
+The interactive behaviour of the ~denote~ command is influenced by the
+user option ~denote-prompts~ ([[#h:f9204f1f-fcee-49b1-8081-16a08a338099][The
denote-prompts option]]).
+
+The ~denote~ command can also be called from Lisp. Read its doc string
+for the technicalities.
#+findex: denote-create-note
In the interest of discoverability, ~denote~ is also available under the
alias ~denote-create-note~.
-** Create note by specifying file type
+*** The ~denote-prompts~ option
:PROPERTIES:
-:CUSTOM_ID: h:2ee9736b-327c-44a6-8c00-c73253d8c326
+:CUSTOM_ID: h:f9204f1f-fcee-49b1-8081-16a08a338099
:END:
-The ~denote-type~ command is like ~denote~ except it also prompts for a
-file type to use as an ad-hoc value for ~denote-file-type~. In practical
-terms, this lets you produce, say, a note in Markdown even though you
-normally write in Org ([[#h:6a92a8b5-d766-42cc-8e5b-8dc255466a23][Standard
note creation]]).
+[ What is described in this section is part of
+ {{{development-version}}}. ]
-#+findex: denote-create-note-using-type
-The ~denote-create-note-using-type~ is an alias of ~denote-type~.
+#+vindex: denote-prompts
+The user option ~denote-prompts~ determines how the ~denote~ command
+will behave interactively ([[#h:6a92a8b5-d766-42cc-8e5b-8dc255466a23][Standard
note creation]]).
-** Create note using a date
-:PROPERTIES:
-:CUSTOM_ID: h:70b8d932-3783-4f81-afdc-30d12fbadd0f
-:END:
+The value is a list of symbols, which includes any of the following:
+
+- =title=: Prompt for the title of the new note.
+
+- =keywords=: Prompts with completion for the keywords of the new
+ note. Available candidates are those specified in the user
+ option ~denote-known-keywords~. If the user option
+ ~denote-infer-keywords~ is non-nil, keywords in existing note
+ file names are included in the list of candidates. The
+ =keywords= prompt uses ~completing-read-multiple~, meaning that
+ it can accept multiple keywords separated by a comma (or
+ whatever the value of ~crm-sepator~ is).
+
+- =file-type=: Prompts with completion for the file type of the
+ new note. Available candidates are those specified in the user
+ option ~denote-file-type~. Without this prompt, ~denote~ uses
+ the value of ~denote-file-type~.
-Normally, Denote reads the current date and time to derive the
-identifier of a new note ([[#h:6a92a8b5-d766-42cc-8e5b-8dc255466a23][Standard
note creation]]). Sometimes, however,
-the user needs to set an explicit date+time value.
+- =subdirectory=: Prompts with completion for a subdirectory in
+ which to create the note. Available candidates are the value
+ of the user option ~denote-directory~ and all of its
+ subdirectories. Any subdirectory must already exist: Denote
+ will not create it.
-This is where the ~denote-date~ command comes in. It accepts the
-familiar =TITLE= and =KEYWORDS= arguments, though it starts by asking
-for a date. The input for the =DATE= argument is like =2022-06-16= or
-=2022-06-16 14:30=. When the time is omitted, it is interpreted as
-=00:00=.
+- =date=: Prompts for the date of the new note. It will expect
+ an input like 2022-06-16 or a date plus time: 2022-06-16 14:30.
+ Without the =date= prompt, the ~denote~ command uses the
+ ~current-time~.
-Since the ability to insert a date may result in duplicate identifiers,
-Denote takes care to abort the operation if such an identity is
-established (e.g. when you use ~denote-date~ with =2022-06-16= twice, it
-will generate the same identifier of =20220616T000000=). The user must
-thus call the ~denote-date~ command again and provide a unique date or
-date+time value.
+The prompts occur in the given order.
-#+findex: denote-create-note-using-date
-The ~denote-create-note-using-date~ is an alias of ~denote-date~.
+If the value of this user option is nil, no prompts are used. The
+resulting file name will consist of an identifier (i.e. the date and
+time) and a supported file type extension (per ~denote-file-type~).
-** Create note in a specific directory
+Recall that Denote's standard file-naming scheme is defined as follows
+([[#h:4e9c7512-84dc-4dfb-9fa9-e15d51178e5d][The file-naming scheme]]):
+
+: DATE--TITLE__KEYWORDS.EXT
+
+If either or both of the =title= and =keywords= prompts are not
+included in the value of this variable, file names will be any of
+those permutations:
+
+: DATE.EXT
+: DATE--TITLE.EXT
+: DATE__KEYWORDS.EXT
+
+When in doubt, always include the =title= and =keywords= prompts.
+
+Finally, this user option only affects the interactive use of the
+~denote~ command (advanced users can call it from Lisp). For ad-hoc
+interactive actions that do not change the default behaviour of the
+~denote~ command, users can invoke these convenience commands:
+~denote-type~, ~denote-subdirectory~, ~denote-date~. They are described
+in the subsequent section
([[#h:887bdced-9686-4e80-906f-789e407f2e8f][Convenience commands for note
creation]]).
+
+*** Convenience commands for note creation
:PROPERTIES:
-:CUSTOM_ID: h:588c1f96-ca01-4c2c-be7a-ca6359c9465b
+:CUSTOM_ID: h:887bdced-9686-4e80-906f-789e407f2e8f
:END:
-The ~denote-subdirectory~ command is like ~denote~ except it prompts for
-a directory to place the new note in
([[#h:6a92a8b5-d766-42cc-8e5b-8dc255466a23][Standard note creation]]).
-Candidates are the value of the user option ~denote-directory~ and any
-subdirectory inside of it. Denote does not create subdirectories.
-
-#+findex: denote-create-note-in-subdirectory
-The ~denote-create-note-in-subdirectory~ is a more descriptive alias of
-~denote-subdirectory~.
+Sometimes the user needs to create a note that has different
+requirements from those of ~denote~
([[#h:6a92a8b5-d766-42cc-8e5b-8dc255466a23][Standard note creation]]). While
+this can be achieved globally by changing the ~denote-prompts~ user
+option, there are cases where an ad-hoc method is the appropriate one
+([[#h:f9204f1f-fcee-49b1-8081-16a08a338099][The denote-prompts option]]).
+
+To this end, Denote provides the follow convenience commands for note
+creation:
+
++ Create note by specifying file type :: The ~denote-type~ command is
+ like ~denote~ except it also prompts for a file type to use as an
+ ad-hoc value for ~denote-file-type~. In practical terms, this lets
+ you produce, say, a note in Markdown even though you normally write in
+ Org ([[#h:6a92a8b5-d766-42cc-8e5b-8dc255466a23][Standard note creation]]).
+
+ #+findex: denote-create-note-using-type
+ The ~denote-create-note-using-type~ is an alias of ~denote-type~.
+
++ Create note using a date :: Normally, Denote reads the current date
+ and time to construct the unique identifier of a newly created note
+ ([[#h:6a92a8b5-d766-42cc-8e5b-8dc255466a23][Standard note creation]]).
Sometimes, however, the user needs to set
+ an explicit date+time value.
+
+ This is where the ~denote-date~ command comes in. It accepts the
+ familiar =TITLE= and =KEYWORDS= arguments, though it starts by asking
+ for a date. The input for the =DATE= argument is like =2022-06-16= or
+ =2022-06-16 14:30=. When the time is omitted, it is interpreted as
+ =00:00=.
+
+ Since the ability to insert a date may result in duplicate
+ identifiers, Denote takes care to abort the operation if such an
+ identity is established (e.g. when you use ~denote-date~ with
+ =2022-06-16= twice, it will generate the same identifier of
+ =20220616T000000=). The user must thus call the ~denote-date~ command
+ again and provide a unique date or date+time value.
+
+ #+findex: denote-create-note-using-date
+ The ~denote-create-note-using-date~ is an alias of ~denote-date~.
+
++ Create note in a specific directory :: The ~denote-subdirectory~
+ command is like ~denote~ except it prompts for a directory to place
+ the new note in ([[#h:6a92a8b5-d766-42cc-8e5b-8dc255466a23][Standard note
creation]]). Candidates are the value of
+ the user option ~denote-directory~ and any subdirectory inside of it.
+ Denote does not create subdirectories.
+
+ #+findex: denote-create-note-in-subdirectory
+ The ~denote-create-note-in-subdirectory~ is a more descriptive alias
+ of ~denote-subdirectory~.
** Create note using Org capture
:PROPERTIES:
diff --git a/denote.el b/denote.el
index 9adfb6b8d6..d596b6b1a8 100644
--- a/denote.el
+++ b/denote.el
@@ -162,6 +162,80 @@ the appropriate list of strings."
:group 'denote
:type 'boolean)
+(defconst denote--prompt-symbols
+ '(title keywords date file-type subdirectory)
+ "List of symbols representing `denote' prompts.")
+
+(defcustom denote-prompts '(title keywords)
+ "Specify the prompts of the `denote' command for interactive use.
+
+The value is a list of symbols, which includes any of the following:
+
+- `title': Prompt for the title of the new note.
+
+- `keywords': Prompts with completion for the keywords of the new
+ note. Available candidates are those specified in the user
+ option `denote-known-keywords'. If the user option
+ `denote-infer-keywords' is non-nil, keywords in existing note
+ file names are included in the list of candidates. The
+ `keywords' prompt uses `completing-read-multiple', meaning that
+ it can accept multiple keywords separated by a comma (or
+ whatever the value of `crm-sepator' is).
+
+- `file-type': Prompts with completion for the file type of the
+ new note. Available candidates are those specified in the user
+ option `denote-file-type'. Without this prompt, `denote' uses
+ the value of `denote-file-type'.
+
+- `subdirectory': Prompts with completion for a subdirectory in
+ which to create the note. Available candidates are the value
+ of the user option `denote-directory' and all of its
+ subdirectories. Any subdirectory must already exist: Denote
+ will not create it.
+
+- `date': Prompts for the date of the new note. It will expect
+ an input like 2022-06-16 or a date plus time: 2022-06-16 14:30.
+ Without the `date' prompt, the `denote' command uses the
+ `current-time'.
+
+The prompts occur in the given order.
+
+If the value of this user option is nil, no prompts are used.
+The resulting file name will consist of an identifier (i.e. the
+date and time) and a supported file type extension (per
+`denote-file-type').
+
+Recall that Denote's standard file-naming scheme is defined as
+follows (read the manual for the technicalities):
+
+ DATE--TITLE__KEYWORDS.EXT
+
+If either or both of the `title' and `keywords' prompts are not
+included in the value of this variable, file names will be any of
+those permutations:
+
+ DATE.EXT
+ DATE--TITLE.EXT
+ DATE__KEYWORDS.EXT
+
+When in doubt, always include the `title' and `keywords' prompts.
+
+Finally, this user option only affects the interactive use of the
+`denote' command (advanced users can call it from Lisp). For
+ad-hoc interactive actions that do not change the default
+behaviour of the `denote' command, users can invoke these
+convenience commands: `denote-type', `denote-subdirectory',
+`denote-date'."
+ :group 'denote
+ :link '(info-link "(denote) The denote-prompts option")
+ :type '(radio (const :tag "Use no prompts" nil)
+ (set :tag "Available prompts" :greedy t
+ (const :tag "Title" title)
+ (const :tag "Keywords" keywords)
+ (const :tag "Date" date)
+ (const :tag "File type extension" file-type)
+ (const :tag "Subdirectory" subdirectory))))
+
(defcustom denote-sort-keywords t
"Whether to sort keywords in new files.
@@ -646,26 +720,47 @@ Optional DEFAULT-TITLE is used as the default value."
;;;;; The `denote' command
;;;###autoload
-(defun denote (title keywords)
- "Create new note with the appropriate metadata and file name.
+(defun denote (&optional title keywords file-type subdirectory date)
+ "Create a new note with the appropriate metadata and file name.
+
+When called interactively, the metadata and file name are prompted
+according to the value of `denote-prompts'.
+
+When called from Lisp, all arguments are optional.
-This command first prompts for a file TITLE and then for one or
-more KEYWORDS (separated by the `crm-separator', typically a
-comma). The latter supports completion though any arbitrary
-string can be inserted.
+- TITLE is a string or a function returning a string.
-Completion candidates are those of `denote-known-keywords'. If
-`denote-infer-keywords' is non-nil, then keywords in existing
-file names are also provided as candidates.
+- KEYWORDS is a list of strings. The list can be empty or the
+ value can be set to nil.
-When `denote-sort-keywords' is non-nil, keywords are sorted
-alphabetically in both the file name and file contents."
+- FILE-TYPE is a symbol among those described in `denote-file-type'.
+
+- SUBDIRECTORY is a string representing the path to either the value of
+ the variable `denote-directory' or a subdirectory thereof. The
+ subdirectory must exist: Denote will not create it.
+
+- DATE is a string representing a date like 2022-06-30 or a date
+ and time like 2022-06-16 14:30. A nil value or an empty string
+ is interpreted as the `current-time'."
(interactive
- (list
- (denote--title-prompt)
- (denote--keywords-prompt)))
- (denote--prepare-note title keywords)
- (denote--keywords-add-to-history keywords))
+ (let ((args (make-vector 5 nil)))
+ (dolist (prompt denote-prompts)
+ (pcase prompt
+ ('title (aset args 0 (denote--title-prompt)))
+ ('keywords (aset args 1 (denote--keywords-prompt)))
+ ('file-type (aset args 2 (denote--file-type-prompt)))
+ ('subdirectory (aset args 4 (denote--subdirs-prompt)))
+ ('date (aset args 3 (denote--date-prompt)))))
+ (append args nil)))
+ (let* ((denote-file-type (denote--file-type-symbol (or file-type
denote-file-type)))
+ (date (if (or (null date) (string-empty-p date))
+ (current-time)
+ (denote--valid-date date)))
+ (id (format-time-string denote--id-format date))
+ (denote-directory (or subdirectory (denote-directory))))
+ (denote--barf-duplicate-id id)
+ (denote--prepare-note (or title "") keywords nil date id)
+ (denote--keywords-add-to-history keywords)))
(defalias 'denote-create-note (symbol-function 'denote))
@@ -693,14 +788,14 @@ here for clarity."
(t (user-error "`%s' is not a symbol or string" filetype))))
;;;###autoload
-(defun denote-type (filetype)
- "Like `denote' but with FILETYPE for `denote-file-type'.
-In practice, this command lets you create, say, a Markdown file
-even when your default is Org.
-
-When called from Lisp the FILETYPE must be a symbol."
- (interactive (list (denote--file-type-prompt)))
- (let ((denote-file-type (denote--file-type-symbol filetype)))
+(defun denote-type ()
+ "Create note while prompting for a file type.
+
+This is the equivalent to calling `denote' when `denote-prompts'
+is set to \\'(file-type title keywords)."
+ (declare (interactive-only t))
+ (interactive)
+ (let ((denote-prompts '(file-type title keywords)))
(call-interactively #'denote)))
(defalias 'denote-create-note-using-type (symbol-function 'denote-type))
@@ -736,30 +831,18 @@ NO-CHECK-CURRENT passes the appropriate flag to
t))
;;;###autoload
-(defun denote-date (date title keywords)
- "Like `denote', but create new note for given DATE.
+(defun denote-date ()
+ "Create note while prompting for a date.
-DATE can either be something like 2022-06-16 or that plus time:
-2022-06-16 14:30.
+The date can be in YEAR-MONTH-DAY notation like 2022-06-30 or
+that plus the time: 2022-06-16 14:30
-The hour can be omitted, in which case it is interpreted as
-00:00. Beware that you might create files with non-unique
-identifiers if they both have the same date and time. In such a
-case, Denote will refrain from creating the new note. Try with
-another DATE value where, for instance, a different time is
-specified.
-
-The TITLE and KEYWORDS arguments are the same as with `denote'."
- (interactive
- (list
- (denote--date-prompt)
- (denote--title-prompt)
- (denote--keywords-prompt)))
- (when-let ((d (denote--valid-date date))
- (id (format-time-string denote--id-format d))
- ((denote--barf-duplicate-id id)))
- (denote--prepare-note title keywords nil d id)
- (denote--keywords-add-to-history keywords)))
+This is the equivalent to calling `denote' when `denote-prompts'
+is set to \\'(date title keywords)."
+ (declare (interactive-only t))
+ (interactive)
+ (let ((denote-prompts '(date title keywords)))
+ (call-interactively #'denote)))
(defalias 'denote-create-note-using-date (symbol-function 'denote-date))
@@ -798,22 +881,18 @@ The TITLE and KEYWORDS arguments are the same as with
`denote'."
(denote--subdirs-completion-table dirs)))
;;;###autoload
-(defun denote-subdirectory (directory title keywords)
- "Like `denote' but ask for DIRECTORY to put the note in.
+(defun denote-subdirectory ()
+ "Create note while prompting for a subdirectory.
-The DIRECTORY is either the variable `denote-directory' or a
-subdirectory of it. The TITLE and KEYWORDS are the same as for
-the `denote' command.
+Available candidates include the value of the variable
+`denote-directory' and any subdirectory thereof.
-Denote does not create subdirectories."
- (interactive
- (list
- (denote--subdirs-prompt)
- (denote--title-prompt)
- (denote--keywords-prompt)))
- (let ((denote-directory directory))
- (denote--prepare-note title keywords)
- (denote--keywords-add-to-history keywords)))
+This is equivalent to calling `denote' when `denote-prompts' is set to
+\\'(subdirectory title keywords)."
+ (declare (interactive-only t))
+ (interactive)
+ (let ((denote-prompts '(subdirectory title keywords)))
+ (call-interactively #'denote)))
(defalias 'denote-create-note-in-subdirectory (symbol-function
'denote-subdirectory))
- [elpa] externals/denote 335307382f 03/39: Add internal constant for denote-prompts symbols, (continued)
- [elpa] externals/denote 335307382f 03/39: Add internal constant for denote-prompts symbols, ELPA Syncer, 2022/07/11
- [elpa] externals/denote 95feac8448 12/39: Clarify a TODO, ELPA Syncer, 2022/07/11
- [elpa] externals/denote b94537cd94 14/39: Remove else part in denote--file-name-relative-to-denote-directory, ELPA Syncer, 2022/07/11
- [elpa] externals/denote a285d4df6a 23/39: Merge pull request #42 from jeanphilippegg/refactor-denote-prompts, ELPA Syncer, 2022/07/11
- [elpa] externals/denote bfda1b829f 06/39: Make 'denote' use 'denote--prompts', ELPA Syncer, 2022/07/11
- [elpa] externals/denote f4c3f1c2d5 18/39: Expand denote-prompts doc string, ELPA Syncer, 2022/07/11
- [elpa] externals/denote 71b56a6b0f 22/39: Refine interactive spec of 'denote' command, ELPA Syncer, 2022/07/11
- [elpa] externals/denote cb863db07d 25/39: Change order of arguments in 'denote', ELPA Syncer, 2022/07/11
- [elpa] externals/denote 61f48726b0 07/39: Clarify denote-prompts empty title case, ELPA Syncer, 2022/07/11
- [elpa] externals/denote 7c36c51665 09/39: Update doc string of 'denote' command, ELPA Syncer, 2022/07/11
- [elpa] externals/denote 60915b3104 33/39: Merge branch 'refactor-denote-prompts',
ELPA Syncer <=
- [elpa] externals/denote fcd182f0ff 36/39: Add 'denote-directory' Info link to silos, ELPA Syncer, 2022/07/11
- [elpa] externals/denote 218f7132bf 15/39: Remove private denote--prompts function, ELPA Syncer, 2022/07/11
- [elpa] externals/denote 10e815c3fe 17/39: Refine denote-prompts Custom UI type, ELPA Syncer, 2022/07/11
- [elpa] externals/denote 92e15886d5 20/39: Avoid errors with string value for keywords, ELPA Syncer, 2022/07/11
- [elpa] externals/denote 5761ec5f89 34/39: BREAKING update journal samples for current 'denote', ELPA Syncer, 2022/07/11
- [elpa] externals/denote b05ea22a11 05/39: Add private function to normalise denote-prompts, ELPA Syncer, 2022/07/11
- [elpa] externals/denote d8ae24a80f 13/39: Merge branch 'main' into refactor-denote-prompts, ELPA Syncer, 2022/07/11
- [elpa] externals/denote 8ea2a7b65d 30/39: Tweak denote-prompts doc string, ELPA Syncer, 2022/07/11
- [elpa] externals/denote d1a3fe3989 31/39: Revise manual on note creation; add denote-prompts, ELPA Syncer, 2022/07/11
- [elpa] externals/denote 2c0727eb37 32/39: Add :link to manual in 'denote-prompts' definition, ELPA Syncer, 2022/07/11