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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/denote 62c6853480 22/22: MAJOR UPDATE towards version 2


From: ELPA Syncer
Subject: [elpa] externals/denote 62c6853480 22/22: MAJOR UPDATE towards version 2.0.0: Merge branch 'signature'
Date: Mon, 20 Mar 2023 05:58:02 -0400 (EDT)

branch: externals/denote
commit 62c6853480d62b00e4c838e148730d1fedf6235f
Merge: 94a3ffd442 d7dc32cb42
Author: Protesilaos Stavrou <info@protesilaos.com>
Commit: Protesilaos Stavrou <info@protesilaos.com>

    MAJOR UPDATE towards version 2.0.0: Merge branch 'signature'
    
    Signatures are an optional extension to Denote's file-naming scheme.
    They are arbitrary strings of alphanumerical characters that can be
    used to establish sequential relations between files at the level of
    their file name (e.g. 1, 1a, 1b, 1b1, 1b2, ...).
    
    Files that have the signature follow this scheme (though read the
    documentation of 'denote-prompts' for possible permutations):
    
        DATE==SIGNATURE--TITLE__KEYWORDS.EXTENSION
    
    As a reminder, Denote's default file-naming scheme is:
    
        DATE--TITLE__KEYWORDS.EXTENSION
    
    [ Denote can be used to rename any file, not just to create notes.  As
      such, the file-naming scheme is a powerful, yet low-tech invention to
      facilitate searching and filtering. ]
    
    For the time being, signatures are not added to a file's front matter
    and are not shown anywhere else beside the file name.  This is done on
    purpose to simplify the implementation and make sure we define clear
    use-cases for this feature (it is easier to add new functionality than
    refactor/break existing one).
    
    Users can create files with signatures either by (i) modifying the
    'denote-prompts' user option to affect the standard 'denote' command,
    or (ii) by generating such files on demand with the command
    'denote-signature' (alias 'denote-create-note-using-signature').
    
    Signatures are treated as quasi-identifiers when renaming files that
    include them.  This means that they are not touched by Denote.  The
    user must manually update the signature which, in theory, should not
    be done if notes already have a predefined sequence.
    
    Signatures are backward-compatible, meaning that existing users are
    not impacted by their inclusion.
    
    The signature extension was discussed at length on the GitHub mirror
    in issue 115: <https://github.com/protesilaos/denote/issues/115>.
    Thanks to Stefan Thesing, Mirko Hernandez, Noboru Ota (nobiot),
    Xiaoxing Hu, nbehrnd, Elias Storms, and 101scholar for helping me
    reason about this feature, understand its scope, and prototype its
    implementation.
    
    The inclusion of the 'signature' branch into 'main' does not mean that
    we are done with the development of this feature.  We are simply
    making it available to more users while preparing for the release of
    version 2.0.0 of Denote.
    
    Watch the video series "Denote as a Zettelkasten" produced by Stefan
    Thesing, which makes use of these signatures:
    <https://www.thesing-online.de/blog/denote-as-a-zettelkasten>.
---
 README.org | 148 ++++++++++++++++++++++++++++++++++++++++++++++-------------
 denote.el  | 152 +++++++++++++++++++++++++++++++++++++++++++++----------------
 2 files changed, 231 insertions(+), 69 deletions(-)

diff --git a/README.org b/README.org
index 7b227e52ca..6990d1d354 100644
--- a/README.org
+++ b/README.org
@@ -6,7 +6,7 @@
 #+startup:               content
 #+macro:                 stable-version 1.2.0
 #+macro:                 release-date 2022-12-16
-#+macro:                 development-version 1.3.0-dev
+#+macro:                 development-version 2.0.0-dev
 #+export_file_name:      denote.texi
 #+texinfo_filename:      denote.info
 #+texinfo_dir_category:  Emacs misc features
@@ -149,11 +149,16 @@ Obligations, Tasks, and Engagements.
 #+findex: denote-date
 #+findex: denote-subdirectory
 #+findex: denote-template
+#+findex: denote-signature
 There are five ways to write a note with Denote: invoke the ~denote~,
-~denote-type~, ~denote-date~, ~denote-subdirectory~, ~denote-template~
-commands, or leverage the ~org-capture-templates~ by setting up a
-template which calls the function ~denote-org-capture~.  We explain all
-of those in the subsequent sections.
+~denote-type~, ~denote-date~, ~denote-subdirectory~,
+~denote-template~, ~denote-signature~ commands, or leverage the
+~org-capture-templates~ by setting up a template which calls the
+function ~denote-org-capture~.  We explain all of those in the
+subsequent sections.
+
+[ The ~denote-signature~ and related are part of
+{{{development-version}}}. ]
 
 ** Standard note creation
 :PROPERTIES:
@@ -237,6 +242,16 @@ The value is a list of symbols, which includes any of the 
following:
   of that KEY is used to populate the new note with content, which is
   added after the front matter ([[#h:f635a490-d29e-4608-9372-7bd13b34d56c][The 
denote-templates option]]).
 
+- =signature=: - Prompts for an arbitrary string that can be used to
+  establish a sequential relationship between files (e.g. 1, 1a, 1b,
+  1b1, 1b2, ...).  Signatures have no strictly defined function and
+  are up to the user to apply as they see fit.  One use-case is to
+  implement Niklas Luhmann's Zettelkasten system for a sequence of
+  notes (Folgezettel).  Signatures are not included in a file's front
+  matter and are not shown in the description of a link.  They are
+  reserved solely for creating a sequence in a file listing, at least
+  for the time being. [Part of {{{development-version}}}.]
+
 The prompts occur in the given order.
 
 If the value of this user option is nil, no prompts are used.  The
@@ -262,8 +277,9 @@ 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]]).
+~denote-type~, ~denote-subdirectory~, ~denote-date~,
+~denote-signature~.  They are described in the subsequent section
+([[#h:887bdced-9686-4e80-906f-789e407f2e8f][Convenience commands for note 
creation]]).
 
 *** The ~denote-templates~ option
 :PROPERTIES:
@@ -396,6 +412,18 @@ commands for note creation:
   The ~denote-create-note-with-template~ is an alias of the command
   ~denote-template~, meant to help with discoverability.
 
++ Create note with a signature :: The ~denote-signature~ command first
+  prompts for an arbitrary string to use in the optional =SIGNATURE=
+  field of the file name and then asks for a title and keywords.
+  Signatures are arbitrary strings of alphanumeric characters which
+  can be used to establish sequential relations between file at the
+  level of their file name (e.g. 1, 1a, 1b, 1b1, 1b2, ...). [Part of
+  {{{development-version}}}.]
+
+  The ~denote-create-note-using-signature~ is an alias of the command
+  ~denote-signature~ intended to make the functionality more
+  discoverable. [Also part of {{{development-version}}}.]
+
 **** Write your own convenience commands
 :PROPERTIES:
 :CUSTOM_ID: h:11946562-7eb0-4925-a3b5-92d75f1f5895
@@ -1119,14 +1147,15 @@ difference between old and new file names.
 :END:
 
 #+vindex: denote-directory
-Notes are stored the ~denote-directory~.  The default path is
+Notes are stored in the ~denote-directory~.  The default path is
 =~/Documents/notes=.  The ~denote-directory~ can be a flat listing,
 meaning that it has no subdirectories, or it can be a directory tree.
 Either way, Denote takes care to only consider "notes" as valid
 candidates in the relevant operations and will omit other files or
 directories.
 
-Every note produced by Denote follows this pattern 
([[#h:17896c8c-d97a-4faa-abf6-31df99746ca6][Points of entry]]):
+Every note produced by Denote follows this pattern by default
+([[#h:17896c8c-d97a-4faa-abf6-31df99746ca6][Points of entry]]):
 
 : DATE--TITLE__KEYWORDS.EXTENSION
 
@@ -1134,7 +1163,7 @@ The =DATE= field represents the date in year-month-day 
format followed
 by the capital letter =T= (for "time") and the current time in
 hour-minute-second notation.  The presentation is compact:
 =20220531T091625=.  The =DATE= serves as the unique identifier of each
-note.
+note and, as such, is also known as the file's ID or identifier.
 
 The =TITLE= field is the title of the note, as provided by the user.  It
 automatically gets downcased and hyphenated.  An entry about "Economics
@@ -1180,10 +1209,41 @@ invoking =M-x re-builder=).
 
 [[#h:1a953736-86c2-420b-b566-fb22c97df197][Features of the file-naming scheme 
for searching or filtering]].
 
+As an optional extension to the above, file names can include a string
+of alphanumeric characters in the =SIGNATURE= field.  Signatures have
+no clearly defined purpose and are up to the user to define.  One
+use-case is to use them to establish sequential relations between
+files (e.g. 1, 1a, 1b, 1b1, 1b2, ...).  A full file name with a
+signature looks like this:
+
+: DATE==SIGNATURE--TITLE__KEYWORDS.EXTENSION
+
+The =SIGNATURE= field is anchored by the equals sign and thus retains
+the aforementioned searching/anchoring feature of =--= and =__=.
+
+Signatures are an optional extension to Denote's file-naming scheme.
+They can be added to newly created files on demand, with the command
+~denote-signature~, or by modifying the value of the user option
+~denote-prompts~.
+
+The ~denote-prompts~ can be configured in such ways to yield the
+following file name permutations:
+
+: DATE.EXT
+: DATE--TITLE.EXT
+: DATE__KEYWORDS.EXT
+: DATE==SIGNATURE.EXT
+: DATE==SIGNATURE--TITLE.EXT
+: DATE==SIGNATURE--TITLE__KEYWORDS.EXT
+: DATE==SIGNATURE__KEYWORDS.EXT
+
+When in doubt, stick to the default design.
+
 While Denote is an Emacs package, notes should work long-term and not
 depend on the functionality of a specific program.  The file-naming
 scheme we apply guarantees that a listing is readable in a variety of
-contexts.
+contexts.  The Denote file-naming scheme is, in essence, an effective,
+low-tech invention.
 
 ** Sluggified title and keywords
 :PROPERTIES:
@@ -1208,30 +1268,38 @@ holds the relevant value.  In simple terms:
 :CUSTOM_ID: h:1a953736-86c2-420b-b566-fb22c97df197
 :END:
 
-File names have three fields and two sets of field delimiters between
-them:
+By default, file names have three fields and two sets of field
+delimiters between them:
 
 : DATE--TITLE__KEYWORDS.EXTENSION
 
-The first field delimiter is the double hyphen, while the second is the
-double underscore.  These practically serve as anchors for easier
-searching.  Consider this example:
+When a signature is present, this becomes:
+
+: DATE==SIGNATURE--TITLE__KEYWORDS.EXTENSION
+
+[ Signatures are part of {{{development-version}}}. ]
 
-: 20220621T062327--introduction-to-denote__denote_emacs.txt
+Field delimiters practically serve as anchors for easier searching.
+Consider this example:
 
-You will notice that there are two matches for the word =denote=: one in
-the title field and another in the keywords' field.  Because of the
-distinct field delimiters, if we search for =-denote= we only match the
-first instance while =_denote= targets the second one.  When sorting
-through your notes, this kind of specificity is invaluable---and you get
-it for free from the file names alone!
+: 20220621T062327==1a2--introduction-to-denote__denote_emacs.txt
 
-Users can get a lot of value out of this simple arrangement, even if
-they have no knowledge of regular expressions.  One thing to consider,
-for maximum effect, is to avoid using multi-word keywords as those get
-hyphenated like the title and will thus interfere with the above: either
-set the user option ~denote-allow-multi-word-keywords~ to nil or simply
-insert single words at the relevant prompts.
+You will notice that there are two matches for the word =denote=: one
+in the title field and another in the keywords' field.  Because of the
+distinct field delimiters, if we search for =-denote= we only match
+the first instance while =_denote= targets the second one.  When
+sorting through your notes, this kind of specificity is
+invaluable---and you get it for free from the file names alone!
+Similarly, a search for ==1= will show all notes that are related to
+each other by virtue of their signature.
+
+Users can get a lot of value out of this simple yet effective
+arrangement, even if they have no knowledge of regular expressions.
+One thing to consider, for maximum effect, is to avoid using
+multi-word keywords as those get hyphenated like the title and will
+thus interfere with the above: either set the user option
+~denote-allow-multi-word-keywords~ to nil or simply insert single
+words at the relevant prompts.
 
 * Front matter
 :PROPERTIES:
@@ -2801,6 +2869,7 @@ Everything is in place to set up the package.
   (define-key map (kbd "C-c n n") #'denote)
   (define-key map (kbd "C-c n N") #'denote-type)
   (define-key map (kbd "C-c n d") #'denote-date)
+  (define-key map (kbd "C-c n z") #'denote-signature) ; "zettelkasten" mnemonic
   (define-key map (kbd "C-c n s") #'denote-subdirectory)
   (define-key map (kbd "C-c n t") #'denote-template)
   ;; If you intend to use Denote with a variety of file types, it is
@@ -2868,13 +2937,17 @@ might change them without further notice.
 + Variable ~denote-id-regexp~ :: Regular expression to match
   ~denote-id-format~.
 
+#+vindex: denote-signature-regexp
++ Variable ~denote-signature-regexp~ :: Regular expression to match
+  the =SIGNATURE= field in a file name.
+
 #+vindex: denote-title-regexp
 + Variable ~denote-title-regexp~ :: Regular expression to match the
-  TITLE field in a file name ([[#h:4e9c7512-84dc-4dfb-9fa9-e15d51178e5d][The 
file-naming scheme]]).
+  =TITLE= field in a file name ([[#h:4e9c7512-84dc-4dfb-9fa9-e15d51178e5d][The 
file-naming scheme]]).
 
 #+vindex: denote-keywords-regexp
 + Variable ~denote-keywords-regexp~ :: Regular expression to match the
-  KEYWORDS field in a file name 
([[#h:4e9c7512-84dc-4dfb-9fa9-e15d51178e5d][The file-naming scheme]]).
+  =KEYWORDS= field in a file name 
([[#h:4e9c7512-84dc-4dfb-9fa9-e15d51178e5d][The file-naming scheme]]).
 
 #+vindex: denote-excluded-punctuation-regexp
 + Variable ~denote-excluded-punctuation-regexp~ :: Punctionation that
@@ -2900,6 +2973,10 @@ might change them without further notice.
 + Function ~denote-file-has-identifier-p~ :: Return non-nil if =FILE=
   has a Denote identifier.
 
+#+findex: denote-file-has-signature-p
++ Function ~denote-file-has-signature-p~ :: Return non-nil if =FILE=
+  has a signature. [Part of {{{development-version}}}.]
+
 #+findex: denote-file-has-supported-extension-p
 + Function ~denote-file-has-supported-extension-p~ :: Return non-nil
   if =FILE= has supported extension.  Also account for the possibility
@@ -3019,6 +3096,11 @@ might change them without further notice.
   one, refer to the ~denote-retrieve-or-create-file-identifier~
   function.
 
+#+findex: denote-retrieve-filename-signature
++ Function ~denote-retrieve-filename-signature~ :: Extract signature
+  from =FILE= name, if present, else return nil. [Part of
+  {{{development-version}}}.]
+
 #+findex: denote-retrieve-or-create-file-identifier
 + Function ~denote-retrieve-or-create-file-identifier~ :: Return
   =FILE= identifier, generating one if appropriate.  The conditions
@@ -3059,6 +3141,10 @@ might change them without further notice.
 + Function ~denote-retrieve-keywords-line~ :: Return keywords line
   from =FILE= front matter per =FILE-TYPE=.
 
+#+findex: denote-signature-prompt
++ Function ~denote-signature-prompt~ :: Prompt for signature
+  string. [Part of {{{development-version}}}.]
+
 #+findex: denote-file-prompt
 + Function ~denote-file-prompt~ :: Prompt for file with identifier in
   variable ~denote-directory~.  With optional =INITIAL-TEXT=, use it
diff --git a/denote.el b/denote.el
index da9955c9a8..9573540c36 100644
--- a/denote.el
+++ b/denote.el
@@ -223,6 +223,16 @@ The value is a list of symbols, which includes any of the 
following:
   value of that KEY is used to populate the new note with
   content, which is added after the front matter.
 
+- `signature': Prompts for an arbitrary string that can be used
+  to establish a sequential relationship between files (e.g. 1,
+  1a, 1b, 1b1, 1b2, ...).  Signatures have no strictly defined
+  function and are up to the user to apply as they see fit.  One
+  use-case is to implement Niklas Luhmann's Zettelkasten system
+  for a sequence of notes (Folgezettel).  Signatures are not
+  included in a file's front matter and are not shown in the
+  description of a link.  They are reserved solely for creating a
+  sequence in a file listing, at least for the time being.
+
 The prompts occur in the given order.
 
 If the value of this user option is nil, no prompts are used.
@@ -235,24 +245,29 @@ 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:
+Depending on the inclusion of the `title', `keywords', and
+`signature' prompts, file names will be any of those
+permutations:
 
     DATE.EXT
     DATE--TITLE.EXT
     DATE__KEYWORDS.EXT
+    DATE==SIGNATURE.EXT
+    DATE==SIGNATURE--TITLE.EXT
+    DATE==SIGNATURE--TITLE__KEYWORDS.EXT
+    DATE==SIGNATURE__KEYWORDS.EXT
 
-When in doubt, always include the `title' and `keywords' prompts.
+When in doubt, always include the `title' and `keywords'
+prompts (the default style).
 
 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', `denote-template'."
+`denote-date', `denote-template', `denote-signature'."
   :group 'denote
-  :package-version '(denote . "0.5.0")
+  :package-version '(denote . "2.0.0")
   :link '(info-link "(denote) The denote-prompts option")
   :type '(radio (const :tag "Use no prompts" nil)
                 (set :tag "Available prompts" :greedy t
@@ -261,7 +276,8 @@ convenience commands: `denote-type', `denote-subdirectory',
                      (const :tag "Date" date)
                      (const :tag "File type extension" file-type)
                      (const :tag "Subdirectory" subdirectory)
-                     (const :tag "Template" template))))
+                     (const :tag "Template" template)
+                     (const :tag "Signature" signature))))
 
 (defcustom denote-sort-keywords t
   "Whether to sort keywords in new files.
@@ -444,6 +460,9 @@ The note's ID is derived from the date and time of its 
creation.")
 (defconst denote-id-regexp "\\([0-9]\\{8\\}\\)\\(T[0-9]\\{6\\}\\)"
   "Regular expression to match `denote-id-format'.")
 
+(defconst denote-signature-regexp "==\\([[:alnum:][:nonascii:]]*\\)"
+  "Regular expression to match the SIGNATURE field in a file name.")
+
 (define-obsolete-variable-alias
   'denote--title-regexp
   'denote-title-regexp
@@ -604,6 +623,12 @@ and use one of the extensions implied by 
`denote-file-type'."
   'denote-file-has-identifier-p
   "1.0.0")
 
+(defun denote-file-has-signature-p (file)
+  "Return non-nil if FILE has a Denote identifier."
+  (when file
+    (string-match-p denote-signature-regexp
+                    (file-name-nondirectory file))))
+
 (defun denote-file-directory-p (file)
   "Return non-nil if FILE is a directory.
 Omit FILE if it matches the value of user option
@@ -1246,6 +1271,12 @@ To only return an existing identifier, refer to the 
function
   'denote-retrieve-or-create-file-identifier
   "1.0.0")
 
+(defun denote-retrieve-filename-signature (file)
+  "Extract signature from FILE name, if present, else return nil."
+  (when (denote-file-has-signature-p file)
+    (string-match denote-signature-regexp file)
+    (match-string 1 file)))
+
 (defun denote-retrieve-filename-title (file)
   "Extract title from FILE name, else return `file-name-base'.
 Run `denote-desluggify' on title if the extraction is sucessful."
@@ -1337,13 +1368,14 @@ Run `denote-desluggify' on title if the extraction is 
sucessful."
 
 ;;;;; Common helpers for new notes
 
-(defun denote-format-file-name (path id keywords title-slug extension)
+(defun denote-format-file-name (path id keywords title-slug extension 
&optional signature)
   "Format file name.
-PATH, ID, KEYWORDS, TITLE-SLUG are expected to be supplied by
-`denote' or equivalent: they will all be converted into a single
-string.  EXTENSION is the file type extension, as a string."
+PATH, ID, KEYWORDS, TITLE-SLUG, EXTENSION and optional SIGNATURE
+are expected to be supplied by `denote' or equivalent command."
   (let ((kws (denote--keywords-combine keywords))
         (file-name (concat path id)))
+    (when (and signature (not (string-empty-p signature)))
+      (setq file-name (concat file-name "==" signature)))
     (when (and title-slug (not (string-empty-p title-slug)))
       (setq file-name (concat file-name "--" title-slug)))
     (when (and keywords (not (string-blank-p kws)))
@@ -1378,13 +1410,17 @@ provided by `denote'.  FILETYPE is one of the values of
          (kws (denote--format-front-matter-keywords keywords filetype)))
     (if fm (format fm title date kws id) "")))
 
-(defun denote--path (title keywords dir id file-type)
-  "Return path to new file with ID, TITLE, KEYWORDS and FILE-TYPE in DIR."
+(defun denote--path (title keywords dir id file-type &optional signature)
+  "Return path to new file.
+Use ID, TITLE, KEYWORDS, FILE-TYPE and optional SIGNATURE to
+construct path to DIR."
   (denote-format-file-name
    dir id
    (denote-sluggify-keywords keywords)
    (denote-sluggify title)
-   (denote--file-extension file-type)))
+   (denote--file-extension file-type)
+   (when signature
+     (denote--slug-no-punct signature))))
 
 ;; Adapted from `org-hugo--org-date-time-to-rfc3339' in the `ox-hugo'
 ;; package: <https://github.com/kaushalmodi/ox-hugo>.
@@ -1428,12 +1464,13 @@ provided by `denote'.  FILETYPE is one of the values of
      (t
       (denote-date-org-timestamp date)))))
 
-(defun denote--prepare-note (title keywords date id directory file-type 
template)
+(defun denote--prepare-note (title keywords date id directory file-type 
template &optional signature)
   "Prepare a new note file.
 
 Arguments TITLE, KEYWORDS, DATE, ID, DIRECTORY, FILE-TYPE,
-and TEMPLATE should be valid for note creation."
-  (let* ((path (denote--path title keywords directory id file-type))
+TEMPLATE, and optional SIGNATURE should be valid for note
+creation."
+  (let* ((path (denote--path title keywords directory id file-type signature))
          (buffer (find-file path))
          (header (denote--format-front-matter
                   title (denote--date date file-type) keywords
@@ -1515,7 +1552,7 @@ where the former does not read dates without a time 
component."
 ;;;;; The `denote' command and its prompts
 
 ;;;###autoload
-(defun denote (&optional title keywords file-type subdirectory date template)
+(defun denote (&optional title keywords file-type subdirectory date template 
signature)
   "Create a new note with the appropriate metadata and file name.
 
 When called interactively, the metadata and file name are prompted
@@ -1542,9 +1579,11 @@ When called from Lisp, all arguments are optional.
 
 - TEMPLATE is a symbol which represents the key of a cons cell in
   the user option `denote-templates'.  The value of that key is
-  inserted to the newly created buffer after the front matter."
+  inserted to the newly created buffer after the front matter.
+
+- SIGNATURE is a string or a function returning a string."
   (interactive
-   (let ((args (make-vector 6 nil)))
+   (let ((args (make-vector 7 nil)))
      (dolist (prompt denote-prompts)
        (pcase prompt
          ('title (aset args 0 (denote-title-prompt
@@ -1556,7 +1595,8 @@ When called from Lisp, all arguments are optional.
          ('file-type (aset args 2 (denote-file-type-prompt)))
          ('subdirectory (aset args 3 (denote-subdirectory-prompt)))
          ('date (aset args 4 (denote-date-prompt)))
-         ('template (aset args 5 (denote-template-prompt)))))
+         ('template (aset args 5 (denote-template-prompt)))
+         ('signature (aset args 6 (denote-signature-prompt)))))
      (append args nil)))
   (let* ((title (or title ""))
          (file-type (denote--valid-file-type (or file-type denote-file-type)))
@@ -1572,9 +1612,10 @@ When called from Lisp, all arguments are optional.
                       (denote-directory)))
          (template (if (stringp template)
                        template
-                     (or (alist-get template denote-templates) ""))))
+                     (or (alist-get template denote-templates) "")))
+         (signature (or signature "")))
     (denote-barf-duplicate-id id)
-    (denote--prepare-note title kws date id directory file-type template)
+    (denote--prepare-note title kws date id directory file-type template 
signature)
     (denote--keywords-add-to-history keywords)))
 
 (defvar denote--title-history nil
@@ -1691,6 +1732,13 @@ packages such as `marginalia' and `embark')."
   'denote-template-prompt
   "1.0.0")
 
+(defvar denote--signature-history nil
+  "Minibuffer history of `denote-signature-prompt'.")
+
+(defun denote-signature-prompt ()
+  "Prompt for signature string."
+  (read-string "Provide signature: " nil 'denote--signature-history))
+
 ;;;;; Convenience commands as `denote' variants
 
 (defalias 'denote-create-note 'denote
@@ -1764,6 +1812,20 @@ set to \\='(template title keywords)."
 (defalias 'denote-create-note-with-template 'denote-template
   "Alias of `denote-template' command.")
 
+;;;###autoload
+(defun denote-signature ()
+  "Create note while prompting for a file signature.
+
+This is the equivalent to calling `denote' when `denote-prompts'
+is set to \\='(signature title keywords)."
+  (declare (interactive-only t))
+  (interactive)
+  (let ((denote-prompts '(signature title keywords)))
+    (call-interactively #'denote)))
+
+(defalias 'denote-create-note-using-signature 'denote-signature
+  "Alias of `denote-signature' command.")
+
 ;;;;; Other convenience commands
 
 (defun denote--extract-title-from-file-history ()
@@ -2122,10 +2184,11 @@ files)."
       current-prefix-arg)))
   (let* ((dir (file-name-directory file))
          (id (denote-retrieve-or-create-file-identifier file date))
+         (signature (denote-retrieve-filename-signature file))
          (extension (file-name-extension file t))
          (file-type (denote-filetype-heuristics file))
          (new-name (denote-format-file-name
-                    dir id keywords (denote-sluggify title) extension))
+                    dir id keywords (denote-sluggify title) extension 
signature))
          (max-mini-window-height 0.33)) ; allow minibuffer to be resized
     (when (denote-rename-file-prompt file new-name)
       (denote-rename-file-and-buffer file new-name)
@@ -2212,11 +2275,12 @@ The operation does the following:
             (dolist (file marks)
               (let* ((dir (file-name-directory file))
                      (id (denote-retrieve-or-create-file-identifier file))
+                     (signature (denote-retrieve-filename-signature file))
                      (file-type (denote-filetype-heuristics file))
                      (title (denote--retrieve-title-or-filename file 
file-type))
                      (extension (file-name-extension file t))
                      (new-name (denote-format-file-name
-                                dir id keywords (denote-sluggify title) 
extension)))
+                                dir id keywords (denote-sluggify title) 
extension signature)))
                 (denote-rename-file-and-buffer file new-name)
                 (when (denote-file-is-writable-and-supported-p new-name)
                   (if (denote--edit-front-matter-p new-name file-type)
@@ -2259,9 +2323,10 @@ proceed with the renaming."
             (keywords (denote-retrieve-keywords-value file file-type))
             (extension (file-name-extension file t))
             (id (denote-retrieve-or-create-file-identifier file))
+            (signature (denote-retrieve-filename-signature file))
             (dir (file-name-directory file))
             (new-name (denote-format-file-name
-                       dir id keywords (denote-sluggify title) extension)))
+                       dir id keywords (denote-sluggify title) extension 
signature)))
       (when (or auto-confirm
                 (denote-rename-file-prompt file new-name))
         (denote-rename-file-and-buffer file new-name)
@@ -2306,12 +2371,13 @@ their respective front matter."
         (dolist (file marks)
           (let* ((dir (file-name-directory file))
                  (id (denote-retrieve-or-create-file-identifier file))
+                 (signature (denote-retrieve-filename-signature file))
                  (file-type (denote-filetype-heuristics file))
                  (title (denote-retrieve-title-value file file-type))
                  (keywords (denote-retrieve-keywords-value file file-type))
                  (extension (file-name-extension file t))
                  (new-name (denote-format-file-name
-                            dir id keywords (denote-sluggify title) 
extension)))
+                            dir id keywords (denote-sluggify title) extension 
signature)))
             (denote-rename-file-and-buffer file new-name)))
         (revert-buffer))
     (user-error "No marked files; aborting")))
@@ -2407,6 +2473,11 @@ and seconds."
   :group 'denote-faces
   :package-version '(denote . "0.1.0"))
 
+(defface denote-faces-signature '((t :inherit font-lock-warning-face))
+  "Face for file name signature in Dired buffers."
+  :group 'denote-faces
+  :package-version '(denote . "2.0.0"))
+
 (defface denote-faces-delimiter
   '((((class color) (min-colors 88) (background light))
      :foreground "gray70")
@@ -2420,9 +2491,10 @@ and seconds."
 ;; For character classes, evaluate: (info "(elisp) Char Classes")
 (defvar denote-faces--file-name-regexp
   (concat "\\(?1:[0-9]\\{8\\}\\)\\(?2:T[0-9]\\{6\\}\\)"
-          "\\(?:\\(?3:--\\)\\(?4:[[:alnum:][:nonascii:]-]*\\)\\)?"
-          "\\(?:\\(?5:__\\)\\(?6:[[:alnum:][:nonascii:]_-]*\\)\\)?"
-          "\\(?7:\\..*\\)?$")
+          "\\(?:\\(?3:==\\)\\(?4:[[:alnum:][:nonascii:]]*?\\)\\)?"
+          "\\(?:\\(?5:--\\)\\(?6:[[:alnum:][:nonascii:]-]*?\\)\\)?"
+          "\\(?:\\(?7:__\\)\\(?8:[[:alnum:][:nonascii:]_-]*?\\)\\)?"
+          "\\(?9:\\..*\\)?$")
   "Regexp of file names for fontification.")
 
 (defconst denote-faces-file-name-keywords
@@ -2430,22 +2502,26 @@ and seconds."
      (1 'denote-faces-date)
      (2 'denote-faces-time)
      (3 'denote-faces-delimiter nil t)
-     (4 'denote-faces-title nil t)
+     (4 'denote-faces-signature nil t)
      (5 'denote-faces-delimiter nil t)
-     (6 'denote-faces-keywords nil t)
-     (7 'denote-faces-extension nil t )))
+     (6 'denote-faces-title nil t)
+     (7 'denote-faces-delimiter nil t)
+     (8 'denote-faces-keywords nil t)
+     (9 'denote-faces-extension nil t )))
   "Keywords for fontification of file names.")
 
 (defconst denote-faces-file-name-keywords-for-backlinks
-  `((,(concat "^\\(?8:.*/\\)?" denote-faces--file-name-regexp)
-     (8 'denote-faces-subdirectory nil t)
+  `((,(concat "^\\(?10:.*/\\)?" denote-faces--file-name-regexp)
+     (10 'denote-faces-subdirectory nil t)
      (1 'denote-faces-date)
      (2 'denote-faces-time)
      (3 'denote-faces-delimiter nil t)
-     (4 'denote-faces-title nil t)
+     (4 'denote-faces-signature nil t)
      (5 'denote-faces-delimiter nil t)
-     (6 'denote-faces-keywords nil t)
-     (7 'denote-faces-extension nil t)))
+     (6 'denote-faces-title nil t)
+     (7 'denote-faces-delimiter nil t)
+     (8 'denote-faces-keywords nil t)
+     (9 'denote-faces-extension nil t )))
   "Keywords for fontification of file names in the backlinks buffer.")
 
 ;;;; Fontification in Dired



reply via email to

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