branch: externals/denote commit 6613d3903d13a59265054e84df1690f6d3e459e2 Author: Protesilaos Stavrou <i...@protesilaos.com> Commit: Protesilaos Stavrou <i...@protesilaos.com>
Refactor denote-add-front-matter and make it interactive-only --- README.org | 53 +++++++++++++++++++++++++++------------ denote.el | 85 +++++++++++++++++++++++++++++++------------------------------- 2 files changed, 80 insertions(+), 58 deletions(-) diff --git a/README.org b/README.org index 5abc987fa5..d295150799 100644 --- a/README.org +++ b/README.org @@ -2650,29 +2650,50 @@ we shall act accordingly. :CUSTOM_ID: h:54b48277-e0e5-4188-ad54-ef3db3b7e772 :END: +[ As part of {{{development-version}}}, the ~denote-add-front-matter~ + is for interactive use only. It is no longer possible to call it + from Lisp with the arguments =FILE=, =TITLE=, =KEYWORDS=, and + =SIGNATURE=. For this purpose, use the functions + ~denote-prepend-front-matter~, ~denote-rewrite-front-matter~. ] + #+findex: denote-add-front-matter Sometimes the user needs to produce new front matter for an existing -note. Perhaps because they accidentally deleted a line and could not -undo the operation. The command ~denote-add-front-matter~ can be used +note. Perhaps because they accidentally deleted a line and could not +undo the operation. The command ~denote-add-front-matter~ can be used for this very purpose. -In interactive use, ~denote-add-front-matter~ must be invoked from a -buffer that visits a Denote note. It prompts for a title and then for -keywords. These are the standard prompts we already use for note -creation, so the keywords' prompt allows minibuffer completion and the -input of multiple entries, each separated by a comma ([[#h:17896c8c-d97a-4faa-abf6-31df99746ca6][Points of entry]]). +It inserts front matter at the top of the current file if it is a +Denote note. + +If front matter exists, fully or in part, it rewrites it. Else it +prepends a new block to the current file. + +To prepare the new front matter, it prompts for title, keywords, and +signature. It does so depending on if those are part of the current +file ([[#h:4e9c7512-84dc-4dfb-9fa9-e15d51178e5d][The file-naming scheme]]). It thus skips the prompt for any +missing file name component. -The newly created front matter is added to the top of the file. +At each prompt, it uses the current value of the given file name +component as the default text in the minibuffer. For the title in +particular, it reads from the existing front matter to get the +human-readable version. Otherwise, it reads from the file name. -This command does not rename the file (e.g. to update the keywords). To -rename a file by reading its front matter as input, the user can rely on -~denote-rename-file-using-front-matter~ ([[#h:532e8e2a-9b7d-41c0-8f4b-3c5cbb7d4dca][Renaming files]]). +It does not write the value of the given file name component if the +minibuffer input is empty. -Note that ~denote-add-front-matter~ is useful only for existing Denote -notes. If the user needs to convert a generic text file to a Denote -note, they can use one of the command which first rename the file to -make it comply with our file-naming scheme and then add the relevant -front matter. +Whatever the case, it does not rename the file upon completing the +operation. This is the task of ~denote-rename-file~ or, more probably +for this case, ~denote-rename-file-using-front-matter~, among others +([[#h:532e8e2a-9b7d-41c0-8f4b-3c5cbb7d4dca][Renaming files]]). + +[ NOTE: Please check with your minibuffer user interface how to + provide an empty input. The Emacs default setup accepts the empty + minibuffer contents as they are, though popular packages like + ~vertico~ use the first available completion candidate instead. For + ~vertico~, the user must either move one up to select the prompt and + then type =RET= there with empty contents, or use the command + ~vertico-exit-input~ with empty contents. That Vertico command is + bound to =M-RET= as of this writing on 2024-02-29 09:24 +0200. ] * Linking notes :PROPERTIES: diff --git a/denote.el b/denote.el index d5b43faf04..40f776405f 100644 --- a/denote.el +++ b/denote.el @@ -3910,37 +3910,27 @@ they have front matter and what that may be." ;;;;; Creation of front matter ;;;###autoload -(defun denote-add-front-matter (file title keywords signature) - "Insert front matter at the top of FILE. +(defun denote-add-front-matter () + "Insert front matter at the top of the current file if it is a Denote note. -When called interactively, FILE is the return value of the -function `buffer-file-name'. FILE is checked to determine -whether it is a note for Denote's purposes. +If front matter exists, fully or in part, rewrite it. Else prepend a +new block to the current file. -TITLE is a string. Interactively, it is the user input at the -minibuffer prompt. - -KEYWORDS is a list of strings. Interactively, it is the user -input at the minibuffer prompt. This one supports completion for -multiple entries, each separated by the `crm-separator' (normally -a comma). - -SIGNATURE is a string. Interactively, it is the user input at the -minibuffer prompt. +To prepare the new front matter, prompt for title, keywords, and +signature. Do it depending on if those are part of the current file. +Skip the prompt for any missing file name component. -The purpose of this command is to help the user generate new -front matter for an existing note (perhaps because the user -deleted the previous one and could not undo the change). +At each prompt, use the current value of the given file name component +as the default text in the minibuffer. For the title in particular, +read from the existing front matter to get the human-readable version. +Otherwise, read from the file name. -This command does not rename the file (e.g. to update the -keywords). To rename a file by reading its front matter as -input, use `denote-rename-file-using-front-matter'. +Do not write the value of the given file name component if the +minibuffer input is empty. -Note that this command is useful only for existing Denote notes. -If the user needs to convert a generic text file to a Denote -note, they can use one of the command which first rename the file -to make it comply with our file-naming scheme and then add the -relevant front matter. +Whatever the case, do not rename the file upon completing the operation. +This is the task of `denote-rename-file' or, more probably for this +case, `denote-rename-file-using-front-matter', among others. [ NOTE: Please check with your minibuffer user interface how to provide an empty input. The Emacs default setup accepts the @@ -3951,22 +3941,33 @@ relevant front matter. or use the command `vertico-exit-input' with empty contents. That Vertico command is bound to M-RET as of this writing on 2024-02-29 09:24 +0200. ]" - (interactive - (let* ((file buffer-file-name) - (type (denote-filetype-heuristics file)) - (default-title (or (denote-retrieve-title-or-filename file type) "")) - (default-keywords (string-join (denote-retrieve-filename-keywords-as-list file) ",")) - (default-signature (or (denote-retrieve-filename-signature file) ""))) - (list - file - (denote-title-prompt default-title "Add TITLE (empty to ignore)") - (denote-keywords-sort (denote-keywords-prompt "Add KEYWORDS (empty to ignore)" default-keywords)) - (denote-signature-prompt default-signature "Add SIGNATURE (empty to ignore)")))) - (when-let* ((denote-file-is-writable-and-supported-p file) - (id (or (denote-retrieve-filename-identifier file) "")) - (date (if (string-empty-p id) nil (date-to-time id))) - (file-type (denote-filetype-heuristics file))) - (denote--add-front-matter file title keywords signature date id file-type))) + (declare (advertised-calling-convention nil "3.1.0") + (interactive-only t)) + (interactive nil text-mode) + (let* ((file buffer-file-name) + (titlep (denote-retrieve-filename-title file)) + (keywordsp (denote-retrieve-filename-keywords file)) + (signaturep (denote-retrieve-filename-signature file)) + (file-type (denote-filetype-heuristics file)) + (default-title (when titlep (or (denote-retrieve-title-value file file-type) titlep ""))) + (default-keywords (when keywordsp (string-join (denote-retrieve-filename-keywords-as-list file) ","))) + (default-signature (or signaturep "")) + (title (if titlep + (denote-title-prompt default-title "Add TITLE (empty to ignore)") + "")) + (keywords (if keywordsp + (denote-keywords-sort (denote-keywords-prompt "Add KEYWORDS (empty to ignore)" default-keywords)) + "")) + (signature (if signaturep + (denote-signature-prompt default-signature "Add SIGNATURE (empty to ignore)") + ""))) + (when-let* ((denote-file-is-writable-and-supported-p file) + (id (denote-retrieve-filename-identifier file)) + (date (date-to-time id))) + (if (denote--file-has-front-matter-p file file-type) + (denote-rewrite-front-matter file title keywords signature date id file-type) + (denote-prepend-front-matter file title keywords signature date id file-type))))) + ;;;###autoload (defun denote-change-file-type-and-front-matter (file new-file-type)