emacs-elpa-diffs
[Top][All Lists]
Advanced

[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))
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]