protesilaos.denote/CHANGELOG.org
2026-05-20 15:41:08 +03:00

7064 lines
301 KiB
Org Mode

#+title: Change log of Denote
#+author: Protesilaos
#+email: info@protesilaos.com
#+language: en
#+options: ':t toc:nil author:t email:t num:t
#+startup: content
This document contains the release notes for each tagged commit on the
project's main git repository: <https://github.com/protesilaos/denote>.
The newest release is at the top. For further details, please consult
the manual: <https://protesilaos.com/emacs/denote>.
#+toc: headlines 1 insert TOC here, with one headline level
* Version 4.2.0 on 2026-05-20
:PROPERTIES:
:CUSTOM_ID: h:68f86f8a-928d-4a1e-b83c-62c648753965
:END:
This version brings several improvements to the core ~denote~ package
as well as all the Denote extensions I maintain. The core package is
stable, its feature set is rich, and the wider ecosystem of extensions
is growing.
Most of the changes documented herein are of interest to experienced
users who may be looking for ways to refine their workflow. I
recommend that new users start with the basics, as I explained them in
the original video demonstration of Denote or as they are documented
in the manual's section for newcomers:
- Webpage :: <https://protesilaos.com/emacs/denote#h:c54bedb4-5377-4dbd-853c-5870ace6eb33>.
- Info manual :: With the latest ~denote~ package installed, evaluate =(info "(denote) Getting started with Denote")=.
Remember that the release notes are true only at the time of
publication. The single source of truth is the official manual.
** Core Denote
:PROPERTIES:
:CUSTOM_ID: h:cc1daf10-2335-4f81-93f4-e5b29929a670
:END:
*** Overview of the new features
:PROPERTIES:
:CUSTOM_ID: h:7a5e8f4c-1d2b-4c3e-8a9d-0f1e2d3c4b5a
:END:
- The command ~denote-dired-focus~ will filter the results of an
existing ~denote-dired~ buffer. Use this to narrow down the results.
- In Org files, the =denote:= link type can now be previewed using the
built-in ~org-link-preview~ command, starting with Org version =9.8.0=.
- The command ~denote-link-or-create-with-command~ extends the
existing convenience functions of the "do or create note" kind.
- The ~denote-file-prompt~ uses completion metadata to sort by most
recently accessed, group by directory or file extension, and cover
packages that display cosmetic icons alongside completion
candidates.
- Denote now enforces a controlled vocabulary for keywords when ~denote-infer-keywords~ is set to ~nil~, such that only the ~denote-known-keywords~ are provided as an option at the relevant
prompts.
- The mechanism for integrating Denote with ~org-capture~ now supports
prompting for an signature via ~denote-org-capture-with-prompts~
(the signature is an optional, free-form component of the Denote
file-naming scheme).
- Several packages that extend Denote are documented in the manual. If
you have a package for Denote, let me know and I will write a
section about it.
*** Focus a ~denote-dired~ buffer with ~denote-dired-focus~
:PROPERTIES:
:CUSTOM_ID: h:5e4d3c2b-1a0e-9d8c-7b6a-5f4e3d2c1b0a
:END:
The command ~denote-dired~ produces a Dired listing of file names that
match the given regular expressions. Users can benefit from the Denote
file-naming scheme to, for example, include all files that have the
keyword =_emacs=. In the resulting Dired buffer, the new command
~denote-dired-focus~ can then be invoked to further narrow down the
results, such as to only show files that have =2026= in their file
(with default settings, the date is part of the Denote identifier).
I implemented this feature in response to issue 693 by 82Kang:
<https://github.com/protesilaos/denote/issues/693>.
*** Improvements to the file prompt
:PROPERTIES:
:CUSTOM_ID: h:2b1a0e9d-8c7b-6a5f-4e3d-2c1b0a987654
:END:
Various Denote commands prompt for a file name: for instance,
~denote-link~ asks which file to link to. This file prompt is now
augmented with completion metadata that transform how files look and
how the information is organised.
Before, the prompt presented full file names like:
: 20220610T043241--initial-thoughts-on-the-zettelkasten-method__notetaking.org
: 20220610T062201--define-custom-org-hyperlink-type__denote_emacs_package.md
: 20220610T162327--on-hierarchy-and-taxis__notetaking_philosophy.txt
Those same file names are now transformed to look like this:
: 2022-06-10 initial-thoughts-on-the-zettelkasten-method notetaking
: 2022-06-10 define-custom-org-hyperlink-type denote_emacs_package
: 2022-06-10 on-hierarchy-and-taxis notetaking_philosophy
The files will be grouped by file extension or directory (if they are
in a subdirectory of the ~denote-directory~). Furthermore, they will
be sorted by most recently accessed.
The underlying file names are still available except that their
presentation is modified. This means that input at the minibuffer
prompt will still match everything they contain.
This completion metadata extends to the packages ~all-the-icons~ and
~nerd-icons~, which are now instructed to add the correct file icons
to the completion candidates: an Org file will have the unicorn icon
beside it, for example.
Users who do not like the new style can revert to the plain
presentation by setting ~denote-file-prompt-extra-metadata~ to ~nil~.
Advanced users who wish to set up the ~completion-category-overrides~
may target the ~denote-file~ completion category or, anyhow, modify
the ~denote-file-prompt-extra-metadata~.
*** Link to a file or create a new note using a specific command
:PROPERTIES:
:CUSTOM_ID: h:3c2b1a0e-9d8c-7b6a-5f4e-3d2c1b0a9876
:END:
Denote provides many "convenience wrapper" commands that do something
quickly which can also be achieved with minimal configuration. For
example, the ~denote~ command may be modified to also prompt for a
file type and so the ~denote-type~ command is like ~denote~ with the
addition of the file type prompt. Users can look at the source code of
~denote-type~ to write their own small variations (the manual provides
several examples as well).
The ~denote-open-or-create-with-command~ may then use those to
implement its specified behaviour of "open an existing file or create
it using a convenience wrapper command".
Same principle for the new ~denote-link-or-create-with-command~: it
makes possible the workflow of "link to an existing file or create a
new note with the given command".
Convenience wrappers are listed in the value of the user option
~denote-commands-for-new-notes~.
Thanks to Matthew Batson for building on top of existing functionality
to contribute ~denote-link-or-create-with-command~ in pull request
674: <https://github.com/protesilaos/denote/pull/674>. Matthew has
assigned copyright to the Free Software Foundation.
*** Preview =denote:= links in Org files
:PROPERTIES:
:CUSTOM_ID: h:4d3c2b1a-0e9d-8c7b-6a5f-4e3d2c1b0a98
:END:
Starting with Org version =9.8.0= custom link types such as =denote:=
can implement their own preview mechanism. In practice, this means
that =denote:= links pointing to image files will now work as expected
with ~org-link-preview~ (remember that the Denote file-naming scheme
can be applied to any file and is in no way specific to
note-taking---I use it for documents and videos, for example).
Thanks to Samuel W. Flint for the original contribution in pull request 683:
<https://github.com/protesilaos/denote/pull/683>, with further changes
by me. The original contribution is small, meaning that Samuel does
not need to assign copyright to the Free Software Foundation.
*** Signature support in Org capture
:PROPERTIES:
:CUSTOM_ID: h:1a0e9d8c-7b6a-5f4e-3d2c-1b0a98765432
:END:
The ~denote-org-capture-with-prompts~ function now supports the
signature file name component as an additional parameter. This
function is meant to be used in tandem with the ~org-capture~
mechanism, as shown in the manual.
Thanks to Tobias Lidman-Strauss for the contribution in merge request
2 on the GitLab mirror: <https://gitlab.com/protesilaos/denote/-/merge_requests/2>.
The change is small, meaning that Tobias does not need to assign
copyright to the Free Software Foundation.
*** The ~denote-fontify-links-mode~ is only relevant for =.txt= files
:PROPERTIES:
:CUSTOM_ID: h:0e9d8c7b-6a5f-4e3d-2c1b-0a9876543210
:END:
The =denote:= links are automatically highlighted as links in Org and
Markdown bufers. Users who prefer to write notes in plain =.txt= files
must enable the ~denote-fontify-links-mode~ to get the same effect.
I have revised ~denote-fontify-links-mode~ to only work with =.txt= as
its other users were not necessary. In the process, I have deprecated
the ~denote-fontify-links-mode-maybe~ function: just use the ~denote-fonftify-links-mode~.
The keys =RET= and =C-c C-o= open the link (same keys used by Org and
Markdown modes).
*** Growing ecosystem of Denote packages
:PROPERTIES:
:CUSTOM_ID: h:9d8c7b6a-5f4e-3d2c-1b0a-9876543210fe
:END:
In the Denote manual I mention packages that build on top of Denote.
There is one section for each package. The manual now includes the
following:
- ~denote-agenda~ (by Samuel W. Flint) :: Use Denote notes as Org agenda files.
- ~denote-journal-capture~ (by Samuel W. Flint) :: Enhanced journaling workflows.
- ~denote-lint~ (Peter Smith) :: Checks for inconsistencies in Denote file names and front matter.
- ~denote-project-notes~ (by Samuel W. Flint) :: Integrate Denote with Emacs' built-in project support.
- ~denote-regexp~ (by Samuel W. Flint) :: Search and link notes using regular expressions.
- ~denote-review~ (by Matto Fransen) :: A package for reviewing notes over time.
- ~denote-sections~ (by Samuel W. Flint) :: Manage sections within Denote notes.
- ~denote-wordcloud~ (by Alexander Kuzmin) :: Generate word clouds from Denote notes.
*** Miscellaneous
:PROPERTIES:
:CUSTOM_ID: h:8c7b6a5f-4e3d-2c1b-0a98-76543210fedc
:END:
- The command ~denote-dired~ (alias ~denote-sort-dired~) is refactored
to work as intended in all cases. Thanks to kilesduli for the
contribution in pull request 666: <https://github.com/protesilaos/denote/pull/666>.
Further changes by me, including the option to maintain many
separate ~denote-dired~ buffers, which I did in response to issue
693 by 82Kang: <https://github.com/protesilaos/denote/issues/693>.
- I have revised the ~denote-grep~ mechanism and all of its ancillary
functions and variables are revised in the interest of consistency
and maintainability. Thanks to gnuhack for contributing a macro that
was meant to streamline some commands. This was done in pull request
697: <https://github.com/protesilaos/denote/pull/697>. I eventually
changed lots of things so that the macro was not relevant anymore,
though mine was a change with a wider scope.
- The Org link storage mechanism (~denote-link-ol-store~) now works
correctly within ~org-capture~ buffers, allowing for more flexible
linking workflows.
- Following non-Denote Markdown links no longer result in an error
under certain circumstances. Thanks to bplubell for the contribution
in pull request 685: <https://github.com/protesilaos/denote/pull/685>.
The change is small, meaning that its author does not need to assign
copyright to the Free Software Foundation.
- Retrieving front matter is now more reliable, even when the buffer
is unsaved. Thanks to kilesduli for the contribution in pull request
672: <https://github.com/protesilaos/denote/pull/672>. Also thanks
to Jean-Philippe Gagné Guay for reviewing the change and for
reporting a problem with an earlier version of the code in issue
670: <https://github.com/protesilaos/denote/issues/670>. Further
changes by me.
- The various Denote rename commands that affect the front matter in
files no longer change existing spacing. I did this to address the
comment posted by Morten Kjeldgaard in issue 703: <https://github.com/protesilaos/denote/issues/703>.
- Updated the documentation to explain how to automatically encrypt
new notes when using a custom file type.
- Refined the internal helper functions for directory management and
identifier validation.
- Thanks to nescias for fixing three typos in the manual. This was
sent to me as a patch, which I installed as commit =c772378=.
*** Changes to the extensions of Denote I maintain
:PROPERTIES:
:CUSTOM_ID: h:6e7f8a9b-0c1d-2e3f-4a5b-6c7d8e9f0a1b
:END:
This is about packages I maintain. Some of them were originally part
of the denote.git repository, but I moved them out into their own
packages to make everything easier to reason about.
**** ~consult-denote~ version 0.5.0
:PROPERTIES:
:CUSTOM_ID: h:1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d
:END:
- Package name (GNU ELPA): ~consult-denote~
- Official manual: <https://protesilaos.com/emacs/consult-denote>
- Change log: <https://protesilaos.com/emacs/consult-denote-changelog>
- Git repository: <https://github.com/protesilaos/consult-denote>
- Backronym: Consult-Orchestrated Navigation and Selection of
Unambiguous Targets...denote.
- References to the long-obsolete "denote-silo-extras-" prefix are
replaced by "denote-silo-". Thanks to IT Ascalium for the
contribution in pull request 20: <https://github.com/protesilaos/consult-denote/pull/20>.
The change is small, so its author does not need to assign copyright
to the Free Software Foundation.
- The ~consult-denote-file-prompt~ correctly handles relative file
paths when ~denote-directory~ is set to a list of directories. This
is what the underlying ~denote-file-prompt~ does (which I mentioned
above about its metadata). Thanks to Kai von Fintel for the
contribution in pull request 24: <https://github.com/protesilaos/consult-denote/pull/24>.
The change does not require copyright assignment.
**** ~denote-merge~ version 0.1.0
:PROPERTIES:
:CUSTOM_ID: h:c877c108-9d57-4b54-a16f-fbeb8c92fa16
:END:
- Git repository: <https://github.com/protesilaos/denote-merge>
- Official manual: <https://protesilaos.com/emacs/denote-merge>
- Backronym: Denote... Merging Eventually Reformats the Given Entries.
This is an optional extension to the ~denote~ package. It provides
commands and relevant user options to streamline the work of merging
contents from one Denote file to another. This is for users who
periodically review their notes to add, remove, or otherwise
consolidate their accumulated knowledge.
**** ~denote-journal~ version 0.3.0
:PROPERTIES:
:CUSTOM_ID: h:2b3c4d5e-6f7a-8b9c-0d1e-2f3a4b5c6d7e
:END:
- Package name (GNU ELPA): ~denote-journal~
- Official manual: <https://protesilaos.com/emacs/denote-journal>
- Git repository: <https://github.com/protesilaos/denote-journal>
- Backronym: Denote... Journaling Obviously Utilises Reasonableness
Notwithstanding Affectionate Longing.
- The user option ~denote-journal-keyword~ now supports a ~nil~ value,
allowing users to create journal entries without a specific keyword.
Thanks to nescias for sending me the patch via email, which I
installed as commit =d4cc501= in denote-journal.git. The change does
not require copyright assignment.
- Fixed an issue about how the function ~denote-directory-files~ was
used. Thanks to Donald Brady for reporting the bug in issue 656 on
the main Denote repository and to kamchy for confirming the problem:
<https://github.com/protesilaos/denote/issues/656>. The approach was
utlimately revised in denote.git courtesy of a change by
Jean-Philippe Gagné Guay in pull request 661:
<https://github.com/protesilaos/denote/pull/661>.
**** ~denote-markdown~ version 0.3.0
:PROPERTIES:
:CUSTOM_ID: h:3c4d5e6f-7a8b-9c0d-1e2f-3a4b5c6d7e8f
:END:
- Package name (GNU ELPA): ~denote-markdown~
- Official manual: <https://protesilaos.com/emacs/denote-markdown>
- Git repository: <https://github.com/protesilaos/denote-markdown>
- Backronyms: Denote... Markdown's Ambitious Reimplimentations
Knowingly Dilute Obvious Widespread Norms; Denote... Markup
Agnosticism Requires Knowhow to Do Only What's Necessary.
- The package defines a =markdown-obsidian= file type which can be
used by relevant note-creating commands, such as ~denote~ or the
convenience wrapper ~denote-type~. This file type is updated to be
more robust, in accordance with some changes in core Denote (I am
not even documenting those, as they are not intended for users).
**** ~denote-org~ version 0.3.0
:PROPERTIES:
:CUSTOM_ID: h:4d5e6f7a-8b9c-0d1e-2f3a-4b5c6d7e8f9a
:END:
- Package name (GNU ELPA): ~denote-org~
- Official manual: <https://protesilaos.com/emacs/denote-org>
- Git repository: <https://github.com/protesilaos/denote-org>
- Backronym: Denote... Ordinarily Restricts Gyrations.
- The command ~denote-org-link-to-heading~ now supports linking to the
current file when called with a prefix argument. This way, a file
can have links between its headings. Thanks to Tonus for pointing
out that it was impossible to create a link inside the current file.
This was done in issue 17: <https://github.com/protesilaos/denote-org/issues/17>.
- A helper function for retrieving the backlinks of a heading is
updated to return full file paths. Thanks to Vedang Manerikar for
the contribution in pull request 20: <https://github.com/protesilaos/denote-org/pull/20>.
Vedang has assigned copyright to the Free Software Foundation.
- Another helper function is updated to conform with changes to core
Denote with regard to how the ~denote-link-description-format~ is
handled. Thanks to Jung Han for reporting the bug in issue 21:
<https://github.com/protesilaos/denote-org/issues/21>.
**** ~denote-silo~ version 0.3.0
:PROPERTIES:
:CUSTOM_ID: h:6f7a8b9c-0d1e-2f3a-4b5c6d7e8f9a0b1c
:END:
- Package name (GNU ELPA): ~denote-silo~
- Official manual: <https://protesilaos.com/emacs/denote-silo>
- Git repository: <https://github.com/protesilaos/denote-silo>
- Backronym: Denote... Silos Insulate Localised Objects.
The minibuffer prompt for silo directories uses the corrent completion
category (consistent with what I mentioned above about completion
metadata). Thanks to Wilf-bog for reporting an error with the
completion prompt in issue 1: <https://github.com/protesilaos/denote-silo/issues/1>.
**** ~denote-sequence~ version 0.3.0
:PROPERTIES:
:CUSTOM_ID: h:5e6f7a8b-9c0d-1e2f-3a4b-5c6d7e8f9a0b
:END:
- Package name (GNU ELPA): ~denote-sequence~
- Official manual: <https://protesilaos.com/emacs/denote-sequence>
- Git repository: <https://github.com/protesilaos/denote-sequence>
- Backronym: Denote... Sequences Efficiently Queue Unsorted Entries
Notwithstanding Curation Efforts.
This package deserved its own release notes, as I did a lot of work on
it. But as this file is already long, I will focus on the essentials:
- The ~denote-sequence-scheme~ used to support a =numeric= and =alphanumeric= option. There now is a third one called =alphanumeric-delimited=. It combines features from the other two
and may be better suited for especially long/intricate sequences.
- The ~denote-sequence-reparent~ command now works recursively to
produce the desired consequences to all descendants of a given
sequence note. Thanks to Peter Prevos for the contribution in pull
request 13, which further changes by me:
<https://github.com/protesilaos/denote-sequence/pull/13>.
- The command ~denote-sequence-view-hierarchy~ produces a bespoke
buffer with all the sequence notes that form a hierarchy. The buffer
displays file titles, the concomitant sequence, and file keywords.
Each level of depth is expressed by a number of spaces, controlled
by the user option ~denote-sequence-hierarchy-indentation~. In the
hierarchy buffer, there are commands that move to the next/previous
item, or forward/backward at the same level of depth. =RET= opens
the file at point, =TAB= folds/unfolds the tree. The user option ~denote-sequence-hierarchy-move-and-open~ controls whether motion
commands should automatically open the file, which by default
happens in the other window (users who modify the variable ~denote-open-link-function~ will get the specified behaviour in this
context as well). The ~denote-sequence-view-hierarchy~ can be called
with one or two prefix arguments to limit to a given sequence prefix
and/or level of depth (something that ~denote-sequence-dired~ also
supports). In short, this is a way to visualise your sequence notes
in a buffer that has a different presentation than Dired.
- Thanks to alan-w-255 for renaming and refining a prompt that is also
used in the hierarchy feature. This was done in pull request 15:
<https://github.com/protesilaos/denote-sequence/pull/15>. The change
is small, meaning that its author does not need to assign copyright
to the Free Software Foundation. Further refinements by me.
- Thanks to Nicolas Semrau for binding =q= to ~quit-window~ in the
~denote-sequence-hierarchy-mode-map~. This was done in pull request
20: <https://github.com/protesilaos/denote-sequence/pull/20>. The
change is small, meaning that Nicolas does not need to assign
copyright to the Free Software Foundation.
- The ~denote-sequence-file-prompt-extra-metadata~ is the functional
equivalent of the aforementioned ~denote-file-prompt-extra-metadata~.
- Thanks to liyingzhi for pointing out an inaccurate comment in the
docstring of ~denote-sequence-scheme~. This was done in issue 18:
<https://github.com/protesilaos/denote-sequence/issues/18>.
- The ~denote-sequence-dired~ is updated to align with the modalities
of ~denote-dired~, as noted above. Thanks to juh for reminding me
about the need for changes in issue 14: <https://github.com/protesilaos/denote-sequence/issues/14>.
- Thanks to Stefan Monnier for pointing out a stylistic mistake in an
older version of ~denote-sequence-dired~. This was done on the
emacs-devel mailing list: <https://lists.gnu.org/archive/html/emacs-devel/2025-11/msg01119.html>.
Also thanks to Stefan for telling me about some other compiler
warnings: <https://lists.gnu.org/archive/html/emacs-devel/2025-11/msg01119.html>.
*** Git commits
:PROPERTIES:
:CUSTOM_ID: h:7b6a5f4e-3d2c-1b0a-9876-543210fedcba
:END:
#+begin_src sh
~/Git/Projects/denote $ git shortlog 4.1.0..4.2.0 --summary --numbered
184 Protesilaos
4 duli
3 Jean-Philippe Gagné Guay
3 Matthew Batson
2 alvmts
2 gnuhack
1 Alvin Hsu
1 Matto Fransen
1 Samuel W. Flint
1 Tobias Lidman-Strauss
1 bplubell
1 gvalson
1 nescias
#+end_src
* Version 4.1.0 on 2025-10-17
:PROPERTIES:
:CUSTOM_ID: h:385847d5-4990-4c1f-9869-82113fe1b47f
:END:
The overarching theme of version =4.1.0= is that of continuing to
deliver on the highly hackable/flexible/powerful potential of Denote.
All the core functionality is the same as before and you still only
need a tiny configuration to use Denote productively. We are adding
more refinements and subtle improvements under the hood, while making
it even easier for advanced users/developers to piece together a
workflow that matches their particular needs.
Since version =4.0.0=, we have moved the "Denote extras" files into
their own packages. I cover their changes further down after I
elaborate on all the changes to the core Denote package:
- [[#h:ce5befb1-0401-4b06-ad4f-64c567b15b91][~denote-journal~ version 0.2.0]]
- [[#h:1403c3b9-280d-4033-a930-5364bf7b5e90][~denote-org~ version 0.2.0]]
- [[#h:d2e18b7d-dc8d-48ad-a0d7-71f291d5aa7c][~denote-sequence~ version 0.2.0]]
Note that I write all the release notes by hand. The reason is that I
consider this process an essential part of my role as a maintainer.
Taking the time to review and document everything ensures that (i) I am
well informed about the state of the package, (ii) I did not forget
anything about this development cycle, and (iii) I take another look
at the changes we made to ensure everything is in order.
** Overview of the new features for core Denote
:PROPERTIES:
:CUSTOM_ID: h:47ec2fca-8fd4-4f96-af89-454e0a001e46
:END:
- The user option ~denote-directory~ can be assigned to a list of
directories. The original string value is also acceptable and
remains the default.
- Advanced users can define a completely custom scheme for
identifiers. This can be as simple as automatically assigned ordinal
numbers to increasingly complex patterns that may also involve user
input.
- The command ~denote-find-backlink-with-location~ is like ~denote-find-backlink~ except it also moves to the exact location of
the link in the corresponding file.
- All Denote buffer names share a common prefix, which is subject to
the user option ~denote-buffer-name-prefix~. This makes it easier to
spot them in the buffer list.
- The command ~denote-dired~ (alias ~denote-sort-dired~) can sort
files by =random= and =last-modified= in addition to the methods
that involve Denote file name components.
- The user option ~denote-query-sorting~ controls how files in all
query buffers are sorted by default. This covers backlinks, query
links for file contents, and any buffer produced by the ~denote-grep~ command. It benefits from the internal "Denote sort"
mechanism, which is also used by ~denote-dired~ and the Org dynamic
blocks of the ~denote-org~ package.
Remember that the release notes are true only at the time of
publication. The single source of truth always is the official manual.
** Set ~denote-directory~ to a list of directories
:PROPERTIES:
:CUSTOM_ID: h:60ed9223-a092-4d2a-a6b6-3ba72150648b
:END:
The user option ~denote-directory~ can optionally be bound to a list
of file system paths, each of which represents a directory root, such
as ='("/home/prot/Documents/work/" "=/home/prot/Git/hut/")= (Denote
has always supported subdirectories, even for a singular ~denote-directory~).
When creating new files, such as with the ~denote~ command, the first
directory on the list will be selected. This can be changed by
modifying the ~denote-prompts~ user option so that it asks for a
directory or subdirectory thereof. Or by writing small wrapper
commands that put files in a predefined directory, like this:
#+begin_src emacs-lisp
(defun my-denote-for-work ()
"Like `denote' but always use the ~/Documents/work/ directory."
(interactive)
(let ((denote-use-directory "~/Documents/work/"))
(call-interactively 'denote)))
#+end_src
Why have many directories as part of the ~denote-directory~? Some
users want to maintain separate directories with Denote files, while
retaining the option of establishing links between (unlike the concept
of "silos" we support, where the directories are self-contained).
Those two directories can be their own Git repositories, for example,
and have different syncing policies for access across multiple
devices.
Thanks to Jean-Philippe Gagné Guay for providing the core
functionality in pull request 609: <https://github.com/protesilaos/denote/pull/609>.
Jean-Philippe is a long-time contributor who has assigned copyright to
the Free Software Foundation. I made several changes on top, such as
to allow ~denote-dired~ (alias ~denote-sort-dired~) to work with many
directories, by finding their common root (which would ultimately be
=/=).
** Define completely custom Denote identifiers
:PROPERTIES:
:CUSTOM_ID: h:e15ef74b-d86e-4c36-812b-2ebd0f4b7dcf
:END:
The default Denote identifier should work for most people in most
cases. I have considered the Denote file-naming scheme carefully and
know it is reliable. Advanced users who have a clear use-case of
something out-of-the-ordinary can now get "Denoted" file names with
arbitrary identifiers. Since this is an advanced feature, I will not
elaborate here on the technicalities. Though I have taken the time to
write at length in the manual about it, with concrete examples ranging
from simple to more complex scenaria. Start with this introduction:
<https://protesilaos.com/emacs/denote#h:3048f558-7d84-45d6-9ef2-53055483e801>.
This feature has been discussed and requested for a long time, across
several related issues:
- <https://github.com/protesilaos/denote/issues/278>.
- <https://github.com/protesilaos/denote/issues/474>.
- <https://github.com/protesilaos/denote/issues/581>.
Thanks, in no particular order, to mentalisttraceur, juh2, Christian
Tietze, and Jean-Philippe Gagné Guay for sharing their thoughts. Also
thanks to Jean-Philippe Gagné Guay for contributing the patches that
made this possible, the last of which is in pull request 586:
<https://github.com/protesilaos/denote/issues/586>.
** Find a backlink at its exact location in the file
:PROPERTIES:
:CUSTOM_ID: h:f0388079-05f6-417b-b232-42aee3447909
:END:
Denote has two ways of working with backlinks: (i) to display them in
a dedicated buffer and (ii) to use a minibuffer prompt that supports
completion in order to pick one file out of the list. The new command
~denote-find-backlink-with-location~ is of the latter kind. Like its
more generic ~denote-find-backlink~ counterpart, it uses the
minibuffer to pick a file that links to the current one. Then, it also
moves the cursor to where the link is.
I did this is in response to issue 471 as reported by johkneisl:
<https://github.com/protesilaos/denote/issues/471>.
** Denote buffer names use the ~denote-buffer-name-prefix~
:PROPERTIES:
:CUSTOM_ID: h:9057709b-8e5f-4628-9463-8bd938a8e92e
:END:
This is a new user option that takes an arbitrary string. Its value is
="[D]"= by default. It consolidates how we name all of our buffers.
Out-of-the-box, this applies to special buffers, like those produced
by the commands ~denote-backlinks~ and ~denote-dired~. When the
optional minor mode ~denote-rename-buffer-mode~ is enabled, all
buffers whose file naming scheme is that of Denote will get the
~denote-buffer-name-prefix~ in addition to their own ~denote-rename-buffer-format~.
This is related to pull request 597 by James Kalyan:
<https://github.com/protesilaos/denote/pull/597>. James has assigned
copyright to the Free Software Foundation.
** The Denote sort mechanism can sort by =random= and =last-modified=
:PROPERTIES:
:CUSTOM_ID: h:f6ea4714-1ed4-4db7-ad4b-c040b6c60c6d
:END:
In core Denote, this is used internally by the ~denote-dired~ command
(alias ~denote-sort-dired~) and the query buffers (more in the next
section). By default, ~denote-dired~ prompts for the sort method and
whether to reverse the order. Though there are user options to tweak
its behaviour (consult the manual). The Org dynamic blocks of the
~denote-org~ package also rely on this mechanism ([[#h:1403c3b9-280d-4033-a930-5364bf7b5e90][~denote-org~ version 0.2.0]]).
** Control the default sort of files in query buffers
:PROPERTIES:
:CUSTOM_ID: h:42bd3513-98fa-4653-9e4b-b0918938ae3b
:END:
Query buffers are those of ~denote-backlinks~, ~denote-grep~, and
~denote-query-contents-link~ (in the latter case, the query buffer is
produced when you click on the link). Users can now modify how they
sort matching files via the option ~denote-query-sorting~. The sorting
methods are by any of the Denote file names components (per
~denote-sort-components~), random order, last modified, or an
arbitrary function.
Thanks to Lucas Quintana for the contribution in pull request 594:
<https://github.com/protesilaos/denote/pull/594>. Lucas has assigned
copyright to the Free Software Foundation.
** Miscellaneous for core Denote
:PROPERTIES:
:CUSTOM_ID: h:889e72d5-3532-431d-a691-2e2ca7237d58
:END:
- The ~denote-dired~ command (alias ~denote-sort-dired~) sets up its ~revert-buffer-function~ in a more robust way, such that it does not
affect the window layout under certain conditions.
- Fixed a bug with the menu entry of Denote that broke ~context-menu-mode~. It addresses issue 592, as reported by artelse:
<https://github.com/protesilaos/denote/issues/592>. Thanks to Lucas
Quintana for the patch. Lucas has assigned copyright to the Free
Software Foundation.
- Thanks to ryota for refining the documentation of the variable ~denote-use-template~ and its potential interference with ~denote-org-capture-identifiers~ in custom user code. We discussed
this in issue 545 and the patch was sent as pull request 598:
- <https://github.com/protesilaos/denote/issues/545>.
- <https://github.com/protesilaos/denote/pull/598>. The change is
small, meaning that ryota does not need to assign copyright to
the Free Software Foundation.
- An internal check to determine if a file has backlinks is now faster
than before: it exits with a non-~nil~ value as soon as it finds one
match, instead of trying to collect all the backlinks. Thanks to
Yann Dutrieux for addressing an omission of mine in the original
implementation and then for discussing with me some further
refinements. Yann's contribution was sent as pull request 637:
<https://github.com/protesilaos/denote/pull/637>.
- Thanks to Alan Schmitt and Ashish Panigrahi for fixing a couple of
typos, in pull requests 623 and 626, respectively:
- <https://github.com/protesilaos/denote/pull/623>.
- <https://github.com/protesilaos/denote/pull/626>.
** Git commits for core Denote
:PROPERTIES:
:CUSTOM_ID: h:ef286c08-8e04-4d33-b72c-696c026c8183
:END:
#+begin_src sh
~/Git/Projects/denote $ git shortlog 4.0.0..4.1.0 --summary --numbered
156 Protesilaos
29 Jean-Philippe Gagné Guay
4 Lucas Quintana
2 James Kalyan
1 Alan Schmitt
1 Ashish Panigrahi
1 Hanwen Guo
1 Ryota
1 Yann Dutrieux
#+end_src
** Changes to the extensions of Denote I maintain
:PROPERTIES:
:CUSTOM_ID: h:dec0751e-6757-46e8-9982-718cc454b1ed
:END:
This concerns all the former "Denote extras" that were shipped with
core Denote as well as ~consult-denote~.
*** ~consult-denote~ version 0.4.0
:PROPERTIES:
:CUSTOM_ID: h:52525fbf-6801-4676-91da-095a7439e582
:END:
- The commands ~consult-denote-grep~ and ~consult-denote-find~ also
work when ~denote-directory~ is set to a list value, as explained
further above ([[#h:60ed9223-a092-4d2a-a6b6-3ba72150648b][Set ~denote-directory~ to a list of directories]]).
- There is a Consult-powered counterpart to the ~denote-sequence-file-prompt~. It is for users of the ~denote-sequence~ package and comes into effect when the ~consult-denote-mode~ is enabled (that mode "Consults" all relevant
minibuffer prompts Denote uses so they get the familiar preview
functionality). The ~denote-sequence-file-prompt~ is used by
commands such as ~denote-sequence~, ~denote-sequence-find~, and ~denote-sequence-link~, among others ([[#h:d2e18b7d-dc8d-48ad-a0d7-71f291d5aa7c][~denote-sequence~ version 0.2.0]]).
- The command ~consult-denote-find~ sorts its files by default. We
discussed this with Gianluca Della Vedova and Gianluca implemented
the tweak in pull request 18:
<https://github.com/protesilaos/consult-denote/pull/18>. The change
is small, meaning that Gianluca does not need to assign copyright to
the Free Software Foundation.
*** ~denote-journal~ version 0.2.0
:PROPERTIES:
:CUSTOM_ID: h:ce5befb1-0401-4b06-ad4f-64c567b15b91
:END:
- It is now possible to specify the desired interval used by the
command ~denote-journal-new-or-existing-entry~ to determine what
"new" and "existing" mean. Users may want to, for example, maintain
one file per month, with daily entries as headings or as free-form
text. The user option ~denote-journal-interval~ specifies the
interval as a symbol among =daily=, =weekly=, =monthly=, and =yearly=. Thanks to Ning Xu for floating the idea of non-daily
journaling in issue 18: <https://github.com/protesilaos/denote-journal/issues/18>.
- Thanks to Alan Schmitt for catching a couple of errors in my
original implementation and for suggesting fixes in pull requests
20 and 21. Also thanks to Abdelhak Bougouffa for addressing
another problem in pull request 23. Further changes by me.
- <https://github.com/protesilaos/denote-journal/pull/20>.
- <https://github.com/protesilaos/denote-journal/pull/21>.
- <https://github.com/protesilaos/denote-journal/pull/23>.
- The new user option ~denote-journal-signature~ specifies a signature
that will be applied to all new journal entries. It is the
counterpart of ~denote-journal-keyword~. Possible values are ~nil~,
for no predefined signature, a string for a constant signature, and a
function that returns a string which is then used as-is. Thanks to
Halogen3576 for suggesting an option for a signature in issue 13:
<https://github.com/protesilaos/denote-journal/issues/13>.
In the case of a function value, users may wish to integrate the ~denote-journal~ package with the ~denote-sequence~ package
([[#h:d2e18b7d-dc8d-48ad-a0d7-71f291d5aa7c][~denote-sequence~ version 0.2.0]]). For example, each new journal
entry should be defined as a new parent sequence. Thus:
#+begin_src emacs-lisp
(setq denote-journal-signature
(lambda ()
(denote-sequence-get-new 'parent)))
#+end_src
- The user option ~denote-journal-keyword~ is extended to support a
function value which should return a string or list of strings.
- The integration with =M-x calendar= (when the minor mode ~denote-journal-calendar-mode~ is enabled) is more robust when
highlighting dates that have a Denote journal entry. Thanks to Alan
Schmitt for the patch that improves the check for visible dates
only. This was done in pull request 12: <https://github.com/protesilaos/denote-journal/pull/12>.
- The ~denote-journal-calendar~ face is extended to also work when
Emacs is ran in a TTY. Thanks to Ettore Berardi for the original
contribution and for discussing this with me. It was done in pull
request 14: <https://github.com/protesilaos/denote-journal/pull/14>.
The contribution is less than 15 lines of code, meaning that Ettore
does not need to assign copyright to the Free Software Foundation.
- The function ~denote-journal-path-to-new-or-existing-entry~ is
tweaked to not kill the buffer of the new file it might generate.
Thanks to jbwfu for the change in pull request 17:
<https://github.com/protesilaos/denote-journal/pull/17>. The change
is small, meaning that the author does not need to assign copyright
to the Free Software Foundation.
- Dates with a single digit in the title of a new journal entry no
longer have a space where the second digit normally is. So something
like =October 1= instead of =October 1=. Thanks to Josh Kingsley for
the patch. The change is small, meaning that Josh does not need to
assign copyright to the Free Software Foundation. It was done in
pull request 24: <https://github.com/protesilaos/denote-journal/pull/24>.
- Thanks to gk2803 for renaming a couple of old symbols to their
current names in the commentary of the package. This was done in
pull request 10: <https://github.com/protesilaos/denote-journal/pull/10>.
#+begin_src sh
~/Git/Projects/denote-journal $ git shortlog 0.1.0..0.2.0 --summary --numbered
35 Protesilaos
3 Alan Schmitt
2 Ettore Berardi
1 Abdelhak Bougouffa
1 Josh Kingsley
1 gk2803
1 jbwfu
#+end_src
*** ~denote-org~ version 0.2.0
:PROPERTIES:
:CUSTOM_ID: h:1403c3b9-280d-4033-a930-5364bf7b5e90
:END:
- A new Org dynamic block integrates with the ~denote-sequence~
package ([[#h:d2e18b7d-dc8d-48ad-a0d7-71f291d5aa7c][~denote-sequence~ version 0.2.0]]). The block is called ~denote-sequence~ and can be inserted at point with the command ~denote-org-dblock-insert-sequence~. What this block does is list
the descendants of a given sequence up to a maximum depth. The
presentation is a typographic list of lists to visualise the
hierarchy of the complete sequence, with each set of children nested
under its parent. Thanks to Peter Prevos for the original
implementation in pull request 9 and for subsequent tweaks in pull
request 13. Other changes by me are done to ensure tighter
integration with the ~denote-sequence~ package.
- <https://github.com/protesilaos/denote-org/pull/9>.
- <https://github.com/protesilaos/denote-org/pull/13>.
- All Org dynamic blocks that have a =:sort-by-component= parameter
can now sort by =random= and =last-modified=. This is made possible
by the aforementioned improvements to the core Denote sort mechanism
([[#h:f6ea4714-1ed4-4db7-ad4b-c040b6c60c6d][The Denote sort mechanism can sort by =random= and =last-modified=]]).
- The ~denote-missing-links~ Org dynamic block, which can be inserted
at point with the command ~denote-org-dblock-insert-missing-links~
takes an optional =:not-regexp= parameter. This is a regular
expression of files to omit from the results. Same for the ~denote-backlinks~ block, which can be inserted at point with the
command ~denote-org-dblock-insert-backlinks~.
- The ~denote-files-as-headings~ Org dynamic block, which can be
inserted at point with the command ~denote-org-dblock-insert-files-as-headings~
now also accepts an optional =:exclude-tags= parameter. It is either ~nil~ or non-~nil~ and determines whether the heading will have the
file's =#+filetags= as its own tags. Thanks to Matt Nolan for
suggesting this idea in issue 14: <https://github.com/protesilaos/denote-org/issues/14>.
#+begin_src sh
~/Git/Projects/denote-org $ git shortlog 0.1.0..0.2.0 --summary --numbered
42 Protesilaos
8 Peter Prevos
#+end_src
*** ~denote-sequence~ version 0.2.0
:PROPERTIES:
:CUSTOM_ID: h:d2e18b7d-dc8d-48ad-a0d7-71f291d5aa7c
:END:
- The new commands ~denote-sequence-find-next-sibling~ and ~denote-sequence-find-previous-sibling~ move to the next or previous
sibling in the given sequence. When called interactively, they work
relative to the current file. When called from Lisp, they expect a =SEQUENCE= argument and its corresponding =RELATIVES=.
- The ~denote-sequence-dired~ command is updated to (i) work with a
list value for ~denote-directory~ ([[#h:60ed9223-a092-4d2a-a6b6-3ba72150648b][Set ~denote-directory~ to a list of directories]]),
as noted further above and (ii) benefit from the refinements done to ~denote-dired~ with regard to its ~revert-buffer-function~.
- The new command ~denote-sequence-rename-as-parent~ makes it easier
to apply the Denote file-naming scheme to an existing file and make
it a new parent sequence. Thanks to Alex Carney for requesting
something along those lines in issue 4:
<https://github.com/protesilaos/denote-sequence/issues/4>.
[ Remember that Denote is highly adaptable/hackable, meaning that
many of these convenience commands build on top of the core with small
extensions to it. The body of ~denote-sequence-rename-as-parent~ is
only 4 lines long, two of which are for an error check. This is
typical of much of what we provide and is how users can always
extend Denote to do something slightly different than what we
support out-of-the-box. ]
- Made several other refinements under the hood, including the
addition of more tests. In this regard, thanks to Rory Molinari,
Peter Prevos, and Ashton Wiersdorf for fixing three bugs in pull
requests 5, 8, and 11, respectively:
- <https://github.com/protesilaos/denote-sequence/pull/5>.
- <https://github.com/protesilaos/denote-sequence/pull/8>.
- <https://github.com/protesilaos/denote-sequence/pull/11>.
#+begin_src sh
~/Git/Projects/denote-sequence $ git shortlog 0.1.0..0.2.0 --summary --numbered
61 Protesilaos
1 Ashton Wiersdorf
1 Peter Prevos
1 Rory Molinari
#+end_src
*** Changes to ~denote-markdown~
:PROPERTIES:
:CUSTOM_ID: h:6c5aa212-226f-4f14-a4e9-2d1eb00d7707
:END:
Nothing of substance.
*** Changes to ~denote-silo~
:PROPERTIES:
:CUSTOM_ID: h:f5f6675e-fbbe-45c8-9a05-dbcc611c6dab
:END:
Nothing of substance.
* Version 4.0.0 on 2025-04-15
:PROPERTIES:
:CUSTOM_ID: h:8a134846-72cc-4fbf-830d-6ca9fd0f9ec8
:END:
This is a massive release. There is one breaking change, which should
be easy to adapt to: this pertains to the reorganisation of the
project to separate the "core" of Denote from its "extensions". The
core is the ~denote~ package. Each extension now has its own package
(details below).
Other than that, this version includes lots of new features for
searching and linking as well as quality-of-life refinements. We have
generalised the infrastructure for performing queries in the
~denote-directory~ and made the buffers with the search results more
useful.
Take your time to read through this publication. I am writing it for
you. Also remember that the most up-to-date resource for anything
related to Denote is its manual. You are always welcome to contact me:
<https://protesilaos.com/contact>. Or join the development on the Git
repository.
As usual, special thanks to Jean-Philippe Gagné Guay for making high
quality contributions to Denote since the beginning of the project ~3
years ago. Those will not always be headline features, but are
important improvements to the underlying code base.
I mention contributions from Jean-Philippe and others in its context.
Though I do not cover implementation details, otherwise this document
will be the size of a book. This does not mean that they are no
important though. Please consult the Git commit log for all the
technicalities.
** All the "extras" are in separate packages, including the Org dynamic blocks
:PROPERTIES:
:CUSTOM_ID: h:26ed2af1-60c8-4217-93b3-bbe344e4eb7b
:END:
In previous versions of Denote, we included some optional extensions
as part of the ~denote~ package. These included the files
=denote-org-extras.el= (Org dynamic blocks, among others),
=denote-journal-extras.el= (streamlined for journaling),
=denote-silo-extras.el= (working with multiple Denote silos).
The files =denote-md-extras.el= (Markdown extras) and
=denote-sequence.el= (sequence notes, including Luhmann-style
alphanumeric sequences) were also part of the project during the last
development cycle, though they never made it into a tagged release.
All these are now available as standalone packages on the official GNU
ELPA archive:
- ~denote-org~ :: In the Emacs configuration file, replace all
instances of =denote-org-extras= with =denote-org=.
- ~denote-journal~ :: Replace =denote-journal-extras= with =denote-journal=.
- ~denote-silo~ :: Replace =denote-silo-extras= with =denote-silo=.
- ~denote-markdown~ :: Replace =denote-md-extras= with =denote-markdown=.
- ~denote-sequence~ :: No changes to any of the defined symbols.
Simply get the new package.
I will document each of these packages further below. The plan, going
forward, is to maintain all the packages and coordinate their new
versions.
** More things in "core"
:PROPERTIES:
:CUSTOM_ID: h:3820e9cf-f034-4c3c-a4ed-1e7d11f1cd23
:END:
While the extras are moved out to their own code repositories, all
other features are merged into =denote.el=. Those include everything
that was in =denote-sort.el= and =denote-rename-buffer.el=.
- The "sort" mechanism is mostly for package developers. We use it
extensively in our Org dynamic blocks, which are now part of the ~denote-org~ package.
- The ~denote-dired~ command (alias ~denote-sort-dired~) is the only
user-facing "sort" command we have always provided. It produces a
fully fledged Dired buffer showing the results of the given search
for file names. The matching files are sorted according to the
user's expressed preference. The details are described in the
manual.
- The ~denote-rename-buffer-mode~ and all of its user options are
unchanged. This mode automatically renames the buffer of a given
Denote file so that it is easier to read it. Again, the manual
covers the technicalities.
Users do not need to make changes, unless they are explicitly loading
=denote-sort-dired= and =denote-rename-buffer=. In that case, they may
just remove those calls: only ~denote~ needs to be loaded.
** The ~denote-query-mode~
:PROPERTIES:
:CUSTOM_ID: h:36f305e2-310d-4327-941a-ca0570b473d2
:END:
Many of the features I will describe below produce search results via
the built-in Xref mechanism. Xref performs a search with a Grep or
Grep-like program, subject to the user option ~xref-search-program~.
The buffer those search results are displayed in runs the
~denote-query-mode~. It supersedes ~denote-backlinks-mode~.
The ~denote-query-mode~ supports the following:
- Results are shown in the context, with the exact match in highlight.
- Matches are grouped by file. Each file is a "heading".
- Headings can be folded with =TAB=, just how it is done in Org buffers.
- The results can be used for further queries. Type =C-h m=
(~describe-mode~) to learn about all the relevant commands.
We have had support for Xref since the original version of Denote. It
now is more generalised to cover backlinks, query links, and
~denote-grep~ (more below).
** Use query links for file contents or file names
:PROPERTIES:
:CUSTOM_ID: h:c217a37a-db73-46bd-ab5f-3f9c54f9d53b
:END:
Denote has always provided the option to link directly to a file with
a given name by referencing its identifier. This can be done with the
command ~denote-link~, among a few others like it (always consult the
manual of Denote).
In addition to these "direct links", we also support "query links".
Those do not point to a file but instead trigger a search. The results
are placed in a buffer that uses the appropriate major mode.
There are two types of query links:
- Query file contents :: Use the command ~denote-query-contents-link~
to insert a query link at point for "file contents". It perform a
search inside files in the ~denote-directory~ and put the results in
a ~denote-query-mode~ buffer.
- Query file names :: Use the ~denote-query-filenames-link~ to insert
a query link for "file names". It performs the query against file
names (not contents!) and puts the results in a ~dired~ buffer.
The display of the buffer with the query link results is controlled by
the user option ~denote-query-links-display-buffer-action~.
Query links are styled a little bit differently than direct links.
Compare the ~denote-faces-link~ with ~denote-faces-query-link~. Both
should look okay with most themes.
Denote query links are supported as part of the =denote:= hyperlink
type. They are available in all file types we define (per the user
option ~denote-file-type~) and should, in principle, work in any
custom file type (advanced users can check the variable ~denote-file-types~).
** Backlinks now always show their context
:PROPERTIES:
:CUSTOM_ID: h:8ebc6ae8-1087-46fa-a0ec-464749f0ac4d
:END:
In the past, the command ~denote-backlinks~ would produce a bespoke
buffer showing a list of file names that included links to the current
file (any file with the Denote file-naming scheme can have backlinks,
by the way, including PDFs, videos, etc.). This buffer did not provide
any additional functionality. We used to support the option to show
results in their context via ~denote-backlinks-show-context~. Those
would be rendered in a standard Xref buffer.
The contextual results are now the default and sole option. This is
because we have expanded the functionality of those buffers to use the
~denote-query-mode~, as explained above. Plus, it makes our code base
simpler.
Users will notice how backlikns look just like a query link for file
contents. This is because backlinks are the original query links since
day one of Denote.
** Direct links to a file with matching contents
:PROPERTIES:
:CUSTOM_ID: h:a1a7b766-328d-4883-93b2-c68b49bd1aa3
:END:
The command ~denote-link-to-file-with-contents~ allows users to
produce a direct link to a file whose contents (not file name!)
includes the given query.
Similarly, the command ~denote-link-to-all-files-with-contents~
generates a typographic list (bullet list) to all files whose contents
match the given query.
The manual covers all linking commands in depth.
** The essence of ~denote-search~ is part of ~denote~
:PROPERTIES:
:CUSTOM_ID: h:5d2ac378-304c-4ea8-bbfb-b3f7b649b27d
:END:
The ~denote-search~ package by Lucas Quintana uses the infrastructure
of Denote to perform searches in file contents. We now provide its
feature set as part of core ~denote~.
We decided to do this since query links already introduced all of the
requisite generalisations to ~denote-query-mode~.
Users can rely on the commands ~denote-grep~, ~denote-grep-marked-dired-files~,
and ~denote-grep-files-referenced-in-region~.
The placement of these buffers is subject to the user option
~denote-grep-display-buffer-action~.
This functionality was introduced in two pull requests by Lucas
Quintana, 571 and 573, with further changes by me:
- <https://github.com/protesilaos/denote/pull/571>.
- <https://github.com/protesilaos/denote/pull/573>.
Lucas has assigned copyright to the Free Software Foundation.
I think this was a much-needed addition to the core of Denote. It
complements ~denote-dired~ and query links.
** Formatting of links with ~denote-link-description-format~
:PROPERTIES:
:CUSTOM_ID: h:635b7f04-891a-4a8b-b420-4e0d9dadc232
:END:
The old user option ~denote-link-description-function~ is deprecated
and superseded by the new ~denote-link-description-format~. The new
user option still accepts a custom function as its value, so the old
behaviour should be retained.
What the new ~denote-link-description-format~ supports is an easier
way to customise the description of a link by using format specifiers
for common options. For example, users who only want to see the title
of the linked file can do this:
#+begin_src emacs-lisp
(setq denote-link-description-format "%t")
#+end_src
The documentation of this user option covers all the format specifiers
and further details.
** Miscellaneous changes for all users
:PROPERTIES:
:CUSTOM_ID: h:76a56ab5-c44b-4c67-8048-25dd0dd88dcf
:END:
- The command ~denote-add-front-matter~ is superseded by ~denote-rename-file~ and related. Those renaming commands will add
missing front matter or rewrite the modified lines of existing front
matter. This is due to refinements made by Jean-Philippe Gagné Guay
to the file renaming mechanism. We discussed this deprecation in
issue 498: <https://github.com/protesilaos/denote/issues/498>. Also
thanks to Samuel Flint for reporting an earlier problem with file
name signatures: <https://github.com/protesilaos/denote/issues/492>.
- The user option ~denote-open-link-function~ specifies the function
used by Denote to open the file of a direct link.
- The user option ~denote-org-store-link-to-heading~ can now be set to
form generic context links without a =PROPERTIES= drawer and
corresponding =CUSTOM_ID=. Set the value of this variable to ='context=. Read its documentation for further details.
- Also about ~denote-org-store-link-to-heading~, we have changed its
default value to ~nil~, which is what we were doing for most of
Denote's history. This means that, by default, ~org-store-link~ and
anything building on top of it will create a link only to the
current Denote file, like =denote:IDENTIFIER=, but not to the
current heading within that file. To create links to the
file+heading, set the value of this variable to ='id=.
- The command ~denote-dired-link-marked-notes~ is an alias for
~denote-link-dired-marked-notes~.
- The user option ~denote-sort-dired-extra-prompts~ control what
~denote-dired~ (alias ~denote-sort-dired~) prompts for. It accepts
either a nil value or a list of symbols among ~sort-by-component~,
~reverse-sort~, and ~exclude-regexp~. The order those symbols appear
in the list is significant, with the leftmost coming first.
- There is a new ~denote-sort-identifier-comparison-function~ variable
which determines how identifier-based sorting should be done by
default. It complements the existing ~denote-sort-title-comparison-function~,
~denote-sort-keywords-comparison-function~, ~denote-sort-signature-comparison-function~.
Thanks to Maikol Solís for the contribution in pull request 517:
<https://github.com/protesilaos/denote/pull/517>. The change is
small, meaning that Maikol does not need to assign copyright to the
Free Software Foundation (though I believe the paperwork is done, anyway).
- Lots of refinements to the doc strings of individual variables
and/or functions as well as the manual.
- Lots of other contributions to discussions and questions on the Git
repository. Granted, these are not "changes" per se but are part of
the development effort nonetheless.
- Made ~denote-get-path-by-id~ use ~denote-get-file-extension-sans-encryption~
instead of ~denote-get-file-extension~. This fixes a bug where the
extension is duplicated if it has an encryption component. Thanks to
eum3l for the patch in pull request 562: <https://github.com/protesilaos/denote/pull/562>.
The change is small, meaning that the author does not need to assign
copyright to the Free Software Foundation.
- Same as above for ~denote--rename-file~, which was done in pull
request 557: <https://github.com/protesilaos/denote/pull/557>.
** For developers or advanced users
:PROPERTIES:
:CUSTOM_ID: h:7eaf43a6-7d62-440e-bf7c-8d9536c7d36e
:END:
The following have been added or modified.
+ NEW Function ~denote-file-has-denoted-filename-p~ :: Return non-nil
if =FILE= respects the file-naming scheme of Denote. This tests the
rules of Denote's file-naming scheme. Sluggification is ignored. It
is done by removing all file name components and validating what
remains. Thanks to Jean-Philippe Gagné Guay for the pull request
515: <https://github.com/protesilaos/denote/pull/515>.
+ NEW Functions ~denote-infer-keywords-from-files~ :: Return list of
keywords in ~denote-directory-files~. With optional
=FILES-MATCHING-REGEXP=, only extract keywords from the matching
files. Otherwise, do it for all files. Keep any duplicates. Users
who do not want duplicates should refer to the functions
~denote-keywords~.
+ MODIFIED Function ~denote-keywords~ :: Returns an appropriate list
of keyword candidates, while accounting for the value of the user
option ~denote-infer-keywords~. It now also accepts the optional =FILES-MATCHING-REGEXP= parameter.
+ MODIFIED Function ~denote-directory-files~ :: Returns a list of
absolute file paths in variable ~denote-directory~. It now accepts
the optional =EXCLUDE-REGEXP= parameter.
+ MODIFIED Function ~denote-format-file-name~ :: Formats a file name.
The way it treats its =ID= parameter has changed. Please read its
doc string. Thanks to Jean-Philippe Gagné Guay for the pull request
496: <https://github.com/protesilaos/denote/pull/496>.
+ ALIAS Function ~denote-retrieve-filename-keywords-as-list~ :: This
is a name that is easier to discover than ~denote-extract-keywords-from-path~,
because of the many other functions with the =denote-retrieve-*= prefix.
+ MODIFIED Function ~denote-retrieve-filename-identifier~ :: Extracts
the identifier from =FILE= name, if present, else returns nil. To
create a new one from a date, refer to the ~denote-get-identifier~
function. Thanks to Jean-Philippe Gagné Guay for the pull request
476: <https://github.com/protesilaos/denote/pull/476>.
+ MODIFIED Function ~denote-get-identifier~ :: Converts =DATE= into a
Denote identifier using ~denote-id-format~. If =DATE= is nil, it
returns an empty string as the identifier. Also by Jean-Philippe in
pull request 476 mentioned right above.
+ MODIFIED Function ~denote-date-prompt~ :: Prompts for a date,
expecting =YYYY-MM-DD= or that plus =HH:MM= (or even =HH:MM:SS=).
Can also use Org's more advanced date selection utility if the user
option ~denote-date-prompt-use-org-read-date~ is non-nil. It now has
the optional parameters =INITIAL-DATE= and =PROMPT-TEXT=. Thanks to
Jean-Philippe Gagné Guay for the pull request 576:
<https://github.com/protesilaos/denote/pull/576>.
- NEW Function ~denote-retrieve-groups-xref-query~ :: Accesses the
location of xrefs for =QUERY= and group them per file. Limit the
search to text files.
- NEW Function ~denote-retrieve-files-xref-query~ :: Returns sorted,
deduplicated file names with matches for =QUERY= in their contents.
Limits the search to text files.
- NEW Function ~denote-retrieve-xref-alist~ :: Returns xref alist of
files with the location of matches for =QUERY=. With optional =FILES-MATCHING-REGEXP=, it limits the list of files accordingly
(per ~denote-directory-files~). At all times, it limits the search
to text files.
+ NEW Function ~denote-prepend-front-matter~ :: Prepend front matter
to =FILE=. The =TITLE=, =KEYWORDS=, =DATE=, =ID=, =SIGNATURE=, and
=FILE-TYPE= are passed from the renaming command and are used to
construct a new front matter block if appropriate.
+ MODIFIED Function ~denote-rewrite-front-matter~ :: Rewrites front
matter of note after ~denote-rename-file~ (or related). The =FILE=, =TITLE=, =KEYWORDS=, =SIGNATURE=, =DATE=, =IDENTIFIER=, and =FILE-TYPE= arguments are given by the renaming command and are used
to construct new front matter values if appropriate. If ~denote-rename-confirmations~ contains ~rewrite-front-matter~,
prompt to confirm the rewriting of the front matter. Otherwise
produce a ~y-or-n-p~ prompt to that effect. Thanks to
Jean-Philippe Gagné Guay for the pull request 558:
<https://github.com/protesilaos/denote/pull/558>.
** Denote "extensions" that are not in the ~denote~ package anymore
:PROPERTIES:
:CUSTOM_ID: h:40e030cd-f462-44ce-add9-ab1525359ae6
:END:
*** ~denote-journal~ integrates nicely with =M-x calendar=
:PROPERTIES:
:CUSTOM_ID: h:f8ab710d-852f-4d8b-b0f8-9a24c5c83808
:END:
The ~calendar~ can now highlight days that have journal entry. It may
also be used as a date picker to view or write a journal entry for
that day.
- Thanks to Alan Schmitt for reporting an issue with the calendar
integration during development:
<https://github.com/protesilaos/denote-journal/issues/8>.
- Thanks to Vineet C. Kulkarni for tweaking the identification of the
journal keyword to be more robust:
<https://github.com/protesilaos/denote-journal/pull/4>.
- Thanks to Honza Pokorny for fixing two small issues with the path
expansion:
- <https://github.com/protesilaos/denote-journal/pull/5>
- <https://github.com/protesilaos/denote-journal/pull/7>
Other than that, the package is providing the same functionality as
the discontinued =denote-journal-extras.el=.
- Manual: <https://protesilaos.com/emacs/denote-journal>.
- GitHub: <https://github.com/protesilaos/denote-journal>.
*** ~denote-org~ is almost the same as the discontinued =denote-org-extras.el=
:PROPERTIES:
:CUSTOM_ID: h:db491fe0-0c96-4c2e-9320-dc2697106e12
:END:
The only addition to dynamic blocks the optional =:not-regexp= parameter.
This is a regular expression that can further filter the results of a
search, such that the matching items are removed from the output.
The official manual of ~denote-org~ covers the technicalities.
- Manual: <https://protesilaos.com/emacs/denote-org>.
- GitHub: <https://github.com/protesilaos/denote-org>.
Also thanks to Elias Storms for fixing a small issue with the "missing
links" Org dynamic block, in pull request 486: <https://github.com/protesilaos/denote/pull/486>
*** ~denote-silo~ is the same as the discontinued =denote-silo-extras.el=
:PROPERTIES:
:CUSTOM_ID: h:ed7c77f5-9b44-4e76-9ada-80ff0ed6d5f6
:END:
I have only made small tweaks to it, but nothing that changes the user
experience.
+ Manual: <https://protesilaos.com/emacs/denote-silo>
+ GitHub: <https://github.com/protesilaos/denote-silo>
*** ~denote-markdown~ for some Markdown-specific extras
:PROPERTIES:
:CUSTOM_ID: h:e01d236c-fb50-488f-9fb2-15e866fa122a
:END:
This package provides some convenience functions to better integrate
Markdown with Denote. This is mostly about converting links from one
type to another so that they can work in different applications
(because Markdown does not have a standardised way to define custom
link types). It also defines an "Obsidian" file type which does not
have any front matter but only uses a level 1 heading for the title of
the note.
The code of ~denote-markdown~ used to be bundled up with the ~denote~
package before version =4.0.0= of the latter and was available in the
file =denote-md-extras.el=. Users of the old code will need to adapt
their setup to use the ~denote-markdown~ package. This can be done by
replacing all instances of =denote-md-extras= with =denote-markdown=
across their configuration.
+ Manual: <https://protesilaos.com/emacs/denote-markdown>
+ GitHub: <https://github.com/protesilaos/denote-markdown>
*** Write sequence notes (or "folgezettel") with ~denote-sequence~
:PROPERTIES:
:CUSTOM_ID: h:6181df9e-790f-4fcf-8093-cefbba324cb5
:END:
Users who want their notes to have an inherent structure can use
~denote-sequence~. The idea is to have thoughts that naturally form
sequences and are named accordingly. The sequence scheme is either
numeric or alphanumeric. The manual of the package explains all the
details.
+ Manual: <https://protesilaos.com/emacs/denote-sequence>
+ GitHub: <https://github.com/protesilaos/denote-sequence>
I had a lot of fun developing this comprehensive package during the
winter holidays.
Thanks to Claudio Migliorelli, Kierin Bell, Mirko Hernandez for
helping me fix some issues during development:
- <https://github.com/protesilaos/denote/pull/518>.
- <https://github.com/protesilaos/denote/pull/528>.
- <https://github.com/protesilaos/denote/pull/540>.
- <https://github.com/protesilaos/denote/pull/541>.
- <https://github.com/protesilaos/denote-sequence/issues/2>.
** The ~consult-denote~ also gets a small update
:PROPERTIES:
:CUSTOM_ID: h:90a9287d-a7dd-4d65-9214-4be6ebdf5943
:END:
This has always been a standalone package. I made the function
~consult-denote-file-prompt~ read the special-purpose variable
~denote-file-prompt-use-files-matching-regexp~. This is related to
commit =e0f1d47= in denote.git, about issue 536 as reported by Alan
Schmitt: <https://github.com/protesilaos/denote/issues/536>. The
variable =denote-file-prompt-use-files-matching-regexp= is meant to be
~let~ bound and is for advanced users or developers.
** Feature freeze at least until the end of April 2025
:PROPERTIES:
:CUSTOM_ID: h:8624e698-90cd-429e-a072-b0fa2df76662
:END:
I will not develop new features or accept pull request for a couple of
weeks. The idea is to focus on fixing any bug reports. We can then
publish point releases quickly.
New features can be included after we are confident that the packages
we have are okay.
** Git commits
:PROPERTIES:
:CUSTOM_ID: h:5191b423-6dc5-4ca7-9bcc-39797be5707c
:END:
This is just an overview of the Git commits, though remember that
there is more that goes into a project, such as the reporting of
inconsistencies, discussion of new ideas, et cetera. Thanks to
everybody involved! Plus, some commits are large while others are
tiny.
#+begin_src
~/Git/Projects/denote $ git shortlog 3.1.0..4.0.0 --summary --numbered
470 Protesilaos
90 Jean-Philippe Gagné Guay
6 Kierin Bell
4 Alan Schmitt
3 eum3l
2 Claudio Migliorelli
2 Lucas Quintana
2 grtcdr
1 Elias Storms
1 Laurent Gatto
1 Maikol Solís
1 Octavian
1 TomoeMami
#+end_src
The following are not accurate because they only reflect the changes
after the reorganisation I made. But we have to start from somewhere.
#+begin_src
~/Git/Projects/denote-journal $ git shortlog --summary --numbered
54 Protesilaos
2 Honza Pokorny
1 Vineet C. Kulkarni
#+end_src
#+begin_src
~/Git/Projects/denote-sequence $ git shortlog --summary --numbered
22 Protesilaos
#+end_src
#+begin_src
~/Git/Projects/denote-silo $ git shortlog --summary --numbered
17 Protesilaos
#+end_src
#+begin_src
~/Git/Projects/denote-org $ git shortlog --summary --numbered
15 Protesilaos
#+end_src
#+begin_src
~/Git/Projects/denote-markdown $ git shortlog --summary --numbered
11 Protesilaos
#+end_src
* Version 3.1.0 on 2024-09-04
:PROPERTIES:
:CUSTOM_ID: h:f089ab11-4ad7-4fd9-9bf3-2deb2e070297
:END:
Denote is stable and reliable though we keep adding minor refinements
to it. Remember that many---if not all---of these are intended for
experienced users who have developed their own workflow and want to
adapt Denote to its particularities. We may call them "power users".
New users do not need to know about every single feature. A basic
configuration is enough and is why the original video I did about
Denote (from even before I published version =0.1.0=) is still relevant.
For example:
#+begin_src emacs-lisp
;; Start with something like this.
(use-package denote
:ensure t
:bind
(("C-c n n" . denote)
("C-c n r" . denote-rename-file)
("C-c n i" . denote-link) ; "insert" mnemonic
("C-c n b" . denote-backlinks))
:config
(setq denote-directory (expand-file-name "~/Documents/notes/")))
#+end_src
And here is the same idea with a little bit more convenience:
#+begin_src emacs-lisp
;; Another basic setup with a little more to it.
(use-package denote
:ensure t
:hook (dired-mode . denote-dired-mode)
:bind
(("C-c n n" . denote)
("C-c n r" . denote-rename-file)
("C-c n l" . denote-link)
("C-c n b" . denote-backlinks))
:config
(setq denote-directory (expand-file-name "~/Documents/notes/"))
;; Automatically rename Denote buffers when opening them so that
;; instead of their long file name they have a literal "[D]"
;; followed by the file's title. Read the doc string of
;; `denote-rename-buffer-format' for how to modify this.
(denote-rename-buffer-mode 1))
#+end_src
** The ~denote-sort-dired~ command is more configurable
:PROPERTIES:
:CUSTOM_ID: h:717765ae-f76f-4b41-96c0-895fe131a83d
:END:
The ~denote-sort-dired~ command asks for a literal string or regular
expression and then produces a fully fledged Dired listing of matching
files in the ~denote-directory~. Combined with the efficient Denote
file-naming scheme, this is a killer feature to collect your relevant
files in a consolidated view and have the full power of Dired available.
By default ~denote-sort-dired~ prompts for the file name component to
sort by and then asks whether to reverse the sorting or not. Users who
want a more streamlined experience can configure the user option
~denote-sort-dired-extra-prompts~.
It is possible to skip the prompts altogether and use the default
values for (i) which component to sort by and (ii) whether to reverse
the sort. To this end, users can have something like this in their
configuration:
#+begin_src emacs-lisp
;; Do not issue any extra prompts. Always sort by the `title' file
;; name component and never do a reverse sort.
(setq denote-sort-dired-extra-prompts nil)
(setq denote-sort-dired-default-sort-component 'title)
(setq denote-sort-dired-default-reverse-sort nil)
#+end_src
For me, Dired is one of the best things about Emacs and I like how it
combines so nicely with Denote file names (this is the cornerstone of
Denote, after all).
** The ~denote-sort-dired~ sorting functions are customisable
:PROPERTIES:
:CUSTOM_ID: h:7c4824c0-7f9b-46f5-98ea-4ebbab092193
:END:
Power users may want to control how the sorting works and what it is
matching on a per file-name-component basis. The user options are
these:
- ~denote-sort-title-comparison-function~.
- ~denote-sort-keywords-comparison-function~.
- ~denote-sort-signature-comparison-function~.
One use-case is to match specific patterns inside of file names, such
as Luhmann-style signatures. I wrote about this in the manual as well
as on my blog (with screenshots):
<https://protesilaos.com/codelog/2024-08-01-emacs-denote-luhmann-signature-sort/>.
Thanks to Riccardo Giannitrapani for discussing this with me and
helping me understand the use-case better. This was done via a private
channel and I am sharing it with permission.
** Show the date of each linked file in Org dynamic blocks
:PROPERTIES:
:CUSTOM_ID: h:ad222eb0-06db-4416-820c-c60f31169f66
:END:
All our Org dynamic blocks that produce links to files now read the
parameter =:include-date=. When it is set to =t=, the listed files
will include their corresponding date inside of parentheses after the
file's title.
Thanks to Sergio Rey for describing this idea to me. This was done via
a private channel and the information is shared with permission.
** Exclude specific directories from Org dynamic blocks
:PROPERTIES:
:CUSTOM_ID: h:5c0b76fc-2758-4a33-875a-fa9eee705d83
:END:
The optional Org dynamic blocks we define let users collect links to
other files (and more) in a quick and effective way. Each block
accepts parameters which control its output, such as how to sort
files.
All our dynamic blocks now accept the =:excluded-dirs-regexp=. This is
a regular expression which is matched against directory file system
paths. Matching directories and their files are not included in the
data handled by the dynamic block.
Note that we have the user option ~denote-excluded-punctuation-regexp~
which defines a global preference along the same lines.
I did a video about this feature:
<https://protesilaos.com/codelog/2024-07-30-emacs-denote-exclude-dirs-org-blocks/>.
Thanks to Claudio Migliorelli for discussing this idea with me. It was
done via a private channel and this information is shared with permission.
** New dynamic block to insert files as headings
:PROPERTIES:
:CUSTOM_ID: h:0cae3fdb-ba83-46f0-9006-13d0073ae092
:END:
We already had an Org dynamic block that would insert file contents.
Though that one inserts files as they are, optionally without their
front matter. However, users may have a workflow where they want to
eventually copy some of the block's output into the main file they are
editing, at which point it is easier for the entire inserted file to
appear as a series of headings. The =#+title= of the inserted file
becomes a top-level heading and every other heading is pushed deeper
one level.
To this end, we provide the Org dynamic block known as ~denote-files-as-headings~.
Insert it with the command ~denote-org-extras-dblock-insert-files-as-headings~
or select it with the minibuffer after calling Org's own command
~org-dynamic-block-insert-dblock~.
The top-level headings (those that were the =#+title=) can optionally
link back to the original file. Though please read the manual for all
the parameters this dynamic block takes.
** The dynamic block for backlinks can be about the current heading only
:PROPERTIES:
:CUSTOM_ID: h:6e6deff6-c02d-4157-85c0-fc405f64ad34
:END:
The Org dynamic block for backlinks can now read the optional
=:this-heading-only= parameter. When it is set to =t=, the block will
only include links that point to the specific heading inside of the
current file. Otherwise, backlinks are about the whole file.
To insert such a dynamic block, use the command
~denote-org-extras-dblock-insert-backlinks~.
** Toggle the detailed view in backlinks buffers
:PROPERTIES:
:CUSTOM_ID: h:01b4dfb0-3883-4cc8-ac41-8a7b55e42fe8
:END:
By default, the buffer produced by the command ~denote-backlinks~ has
a compact view of showing the file names linking to the current file.
With the user option ~denote-backlinks-show-context~ set to a non-nil
value, the backlinks buffer produces a detailed listing of matching
results, where the links are shown in their original context.
Users can now choose to have this on-demand by calling the command
~denote-backlinks-toggle-context~ which switches between the detailed
and compact views.
This blog post I wrote about it include screenshots:
<https://protesilaos.com/codelog/2024-07-25-emacs-denote-backlinks-context-toggle/>.
** Templates can have a function that returns a string
:PROPERTIES:
:CUSTOM_ID: h:8d0ac1eb-d057-4fce-bf60-98d5de932a0d
:END:
The ~denote-templates~ variable allows the user to specify one or more
named templates which can then be inserted during the creation of a
new note. One way to be prompted for a template among those specified
is to modify the ~denote-prompts~ user option and then use the regular
~denote~ command. Another way is to use the command ~denote-template~
(alias ~denote-create-note-with-template~), which will prompt for the
template to use.
Templates ordinarily have a string as their value, though now their
value can also be the symbol of a function. This function takes no
arguments and is expected to return a string. Denote takes care to
insert that below the front matter of the new note.
So it can look like this:
#+begin_src emacs-lisp
(setq denote-templates
`((report . "* Some heading\n\n* Another heading") ; A string with newline characters
(blog . my-denote-template-function-for-blog) ; the symbol of a function that will return a string
(memo . ,(concat "* Some heading" ; expand this `concat' into a string
"\n\n"
"* Another heading"
"\n\n"))))
#+end_src
Thanks to skissue (Ad) for the contribution in pull request 398:
<https://github.com/protesilaos/denote/pull/398>. The change is small,
meaning that its author does not need to assign copyright to the Free
Software Foundation.
Also thanks to Jean-Philippe Gagné Guay for extending this to
~denote-org-capture~. Done in pull request 399:
<https://github.com/protesilaos/denote/pull/399>. Jean-Philippe is a
long-time contributor who has assigned copyright to the Free Software
Foundation.
** The ~denote-rename-buffer-mode~ can now show if a file has backlinks
:PROPERTIES:
:CUSTOM_ID: h:b163982b-3fea-48c8-90a0-d8358e066951
:END:
This global minor mode takes care to rename the buffers of Denote
files to a pattern that is easier for users to read. As with
everything, it is highly configurable. The default value now includes
an indicator that shows if the current file has backlinks (other files
linking to it).
The exact characters used in this indicator are specified in the new
user option ~denote-rename-buffer-backlinks-indicator~. The default
value is ="<-->"=, which hopefully communicates the idea of a link
(but, yeah, symbolism is hard). Users may want to modify this to add
some fancier Unicode character.
Thanks to Ashton Wiersdorf for the original contribution in pull
request 392: <https://github.com/protesilaos/denote/pull/392>. Ashton
has assigned copyright to the Free Software Foundation.
** The ~denote-rename-buffer-format~ has changed
:PROPERTIES:
:CUSTOM_ID: h:8913785e-5c87-48ab-9df2-dafbbb9b1a5d
:END:
In the same theme as above, the user option ~denote-rename-buffer-format~
has a new default value. Before, it would only show the title of the
file. Now it shows the aforementioned ~denote-rename-buffer-backlinks-indicator~,
if there are backlinks, plus the title, plus a literal ="[D]"= prefix.
The prefix should make it easier to spot Denote files in a buffer
listing.
Read the documentation of ~denote-rename-buffer-format~ for how to
tweak this to your liking.
** New user option ~denote-kill-buffers~
:PROPERTIES:
:CUSTOM_ID: h:14177204-6269-48c1-bc65-de72b59d4e84
:END:
This controls whether and when Denote should automatically kill any
buffer it generates while creating a new note or renaming an existing
file. The manual describes the details.
By default, Denote does not kill any buffers to give users the chance
to review what is on display and confirm any changes or revert them
accordingly.
Thanks to Jean-Philippe Gagné Guay for the contribution in pull
request 426: <https://github.com/protesilaos/denote/pull/426>. This is
related to issues 273 and 413, so also thanks to Vineet C. Kulkarni
and mentalisttraceur for their participation and/or questions.
** The ~denote-journal-extras-new-or-existing-entry~ handles any filename component order
:PROPERTIES:
:CUSTOM_ID: h:0b570a97-3e0c-488f-9c9d-02d2f8ac786f
:END:
Version =3.0.0= of Denote introduced a new option to rearrange the
file name components. All Denote commands should respect it. We did,
however, have a problem with the command ~denote-journal-extras-new-or-existing-entry~
which was not recognising the date properly.
Thanks to Jakub Szczerbowski for the contribution in pull request 395:
<https://github.com/protesilaos/denote/pull/395>. The change is small,
meaning that Jakub does not need to assign copyright to the Free
Software Foundation.
While I am documenting this here, users should already have the fix as
I published a minor release for it in July (in fact, there were 8
minor releases in the aftermath of the =3.0.0= release, which
addressed several small issues).
** The ~denote-rename-file-using-front-matter~ recognises the file-at-point in Dired
:PROPERTIES:
:CUSTOM_ID: h:01f652c5-5713-4884-8a01-ee39f1388a12
:END:
This makes it consistent with how ~denote-rename-file~ works. I am
implemented this in response to issue 401 where Alp Eren Kose assumed
it was the default behaviour: <https://github.com/protesilaos/denote/issues/401>.
I think it makes sense to have it this way to avoid such confusion.
Still, it seems easier to edit the file and call ~denote-rename-file-using-front-matter~
directly, rather do an intermediate step through Dired.
** The ~denote-rename-file-using-front-matter~ does not ask to rewrite front matter
:PROPERTIES:
:CUSTOM_ID: h:337c5640-8e75-408e-b5cf-4a37ac8e249b
:END:
The workflow for this command is that the user modifies the front
matter, invokes the command, and Denote takes care to rename the file
accordingly. We had a regression were this would happen as expected,
but Denote would still prompt if it was okay to update the front
matter. That made no sense.
As with the change mentioned above, this was also fixed in a minor
release so that users would not have to wait all this time.
** The ~denote-add-links~ and ~denote-find-link~ commands always works inside a silo
:PROPERTIES:
:CUSTOM_ID: h:9c343ddb-a31a-41d5-90c2-ce54622558fa
:END:
This was always the intended behaviour, though there was an issue with
the implementation that prevented the directory-local value from being
read.
Thanks to yetanotherfossman for reporting the problem with
~denote-add-links~ in issue 386 and to Kolmas for doing the same for
~denote-find-link~:
- <https://github.com/protesilaos/denote/issues/386>.
- <https://github.com/protesilaos/denote/issues/416>.
Also thanks to Jean-Philippe Gagné Guay for following up with a change
to the code that should address the underlying problem with temporary
buffers. This was done in pull request 419:
<https://github.com/protesilaos/denote/pull/419>.
** Denote commands should work in more special Org buffers
:PROPERTIES:
:CUSTOM_ID: h:e33bea49-f2b4-43ee-96ac-d24630c9bcd7
:END:
A case we already handled was ~org-capture~ buffers. Another one is
the buffer produced by the command ~org-tree-to-indirect-buffer~.
Thanks to coherentstate for bringing this matter to my attention in
issue 418: <https://github.com/protesilaos/denote/issues/418>.
Also thanks to skissue for noting another edge case that prevented
~denote-rename-buffer-mode~ from doing the right thing. This was
reported in issue 393: <https://github.com/protesilaos/denote/issues/393>.
** Denote will not create a =CUSTOM_ID= via ~org-capture~ if not necessary
:PROPERTIES:
:CUSTOM_ID: h:c9c04d9a-776d-4b6b-826a-cd9a56f31643
:END:
If the ~org-capture~ template does not include one of the specifiers
which produce a link, then we take care to not include a =CUSTOM_ID=
in the properties of the current heading. We do this to make it
possible to link directly to a heading inside of a file (a feature
that is documented in the manual).
Before, we were creating the =CUSTOM_ID= unconditionally, which was
not the desired behaviour. Thanks to Jonas Großekathöfer for bringing
this matter to my attention in issue 404:
<https://github.com/protesilaos/denote/issues/404>.
** The prompt for selecting a silo has the appropriate metadata
:PROPERTIES:
:CUSTOM_ID: h:cc5951b1-ee87-4126-b3f2-91c32e3431ae
:END:
All the Denote minibuffer prompts have the appropriate completion
metadata to integrate with core Emacs functionalities and with
third-party packages that leverage them. One such case pertains to the
completion category our prompts report. This is used by a package such
as ~embark~ to infer the set of relevant actions to perform or by the
~marginalia~ package to produce the appropriate annotations.
Users will now notice a difference while using commands such as
~denote-silo-extras-create-note~ if they have ~marginalia-mode~
enabled: all completion candidates will have file-related annotations.
This is a small change which goes to show how the little things
contribute to a more refined experience.
** New name for option that controls where backlinks buffers are displayed
:PROPERTIES:
:CUSTOM_ID: h:3e0e2242-8802-4c63-adce-0e20d3f27ad9
:END:
The user option is now called ~denote-backlinks-display-buffer-action~.
The old name ~denote-link-backlinks-display-buffer-action~ is an alias
for it and will thus work the same way. Though you are encouraged to
rename it in your configuration as I will eventually remove those
obsolete symbols from the Denote code base.
** The ~revert-buffer~ should do the right thing in backlinks buffers
:PROPERTIES:
:CUSTOM_ID: h:2982cfcd-6bef-452d-aa0d-d8ab4e721b25
:END:
I made several tweaks to the underlying code to ensure that reverting
a backlinks buffer will always reuse the original parameters that
generated it. Backlinks buffers are produced by the ~denote-backlinks~
command, among others.
** Lots of new entries in the manual with custom code
:PROPERTIES:
:CUSTOM_ID: h:991d980b-1353-4b53-8ae4-ae09450cce05
:END:
The manual of Denote is a rich resource of knowledge for how to use
this package and how to extend it with custom code. I have written the
following entries to further help you improve your productivity:
- A custom ~denote-region~ that references the source
- Custom sluggification to remove non-ASCII characters
- Sort signatures that include Luhmann-style sequences
- Why are some Org links opening outside Emacs?
** More functions for developers or advanced users
:PROPERTIES:
:CUSTOM_ID: h:2e41930a-1907-47f2-956e-fef8b2459461
:END:
The following functions are now public, meaning that they are safe to
be used in the code of other packages or incorporated in user
configurations:
- ~denote-identifier-p~.
- ~denote-get-identifier-at-point~. I am implementing this in response
to a question by Alan Schmitt in issue 400: <https://github.com/protesilaos/denote/issues/400>.
- ~denote-org-extras-outline-prompt~.
- ~denote-silo-extras-directory-prompt~.
Consult their respective doc strings for the technicalities.
Note that the Elisp convention is that private functions (intended for
use only inside the package) have a double dash (=--=) in their name.
In principle, these are undocumented and can change at any moment
without any notice. I do try to avoid such cases and even add warnings
when I make changes to them. Still, you should not use private
functions without understanding the risks involved.
** Miscellaneous
:PROPERTIES:
:CUSTOM_ID: h:be41d902-8d65-4012-aad2-d66507d34f78
:END:
- Wrote more unit tests for various functions.
- Improve the doc strings of several symbols (everything in the Denote
code base is documented).
- Fix some typos thanks to Nicolas Semrau and bryanrinders:
- <https://github.com/protesilaos/denote/commit/e7cfd48bd63e0815718cd9f1f0465d8c1c4f4a84>.
- <https://github.com/protesilaos/denote/pull/425>.
- Commented on all sorts of issues on the GitHub repository and many
more in private.
** New release cycle starts in mid-September
:PROPERTIES:
:CUSTOM_ID: h:2b55dd84-6ebe-438d-aba8-97dd329ec34e
:END:
I have many ideas for how to further refine Denote. Maybe you do too.
Though we must all wait a couple of weeks in case someone reports a
bug. This way, it is easy to fix it and publish a new minor version.
Otherwise, we may have to bundle the fix with some in-development
feature that we have not fully tested yet.
** Git commits
:PROPERTIES:
:CUSTOM_ID: h:c0da6de0-c683-4029-9d95-06c27102dc4a
:END:
This is just an overview of the Git commits, though remember that
there is more that goes into a project, such as the reporting of
inconsistencies, discussion of new ideas, etc.. Thanks to everybody
involved!
#+begin_src
~/Git/Projects/denote $ git shortlog 3.0.0..3.1.0 --summary --numbered
104 Protesilaos
7 Jean-Philippe Gagné Guay
3 Ashton Wiersdorf
1 Ad
1 Jakub Szczerbowski
1 bryanrinders
#+end_src
* Version 3.0.0 on 2024-06-30
:PROPERTIES:
:CUSTOM_ID: h:bf5e869d-548f-4c77-bf1c-b7dcf6d1d4da
:END:
This major release comes about two years after the first version of
Denote, which was published on 2022-06-27. A lot of technicalities
have changed in the meantime, though the core idea remains the same.
In fact, the original video presentation I did is still relevant,
especially for those looking to get started with Denote (but remember
to consult the latest documentation for up-to-date information---and
ask me if you have any questions).
Version 3 iterates on refinements that we made over the life cycle of
version 2. Existing users will find that their workflow remains the
same, though they now have even more options at their disposal.
As usual, my release notes are detailed. Please take your time to read
them: they are here for you.
Special thanks to Jean-Philippe Gagné Guay, a long-time contributor to
the project, for working on some of the items covered herein. I am not
covering everything, as many important changes are not user-facing.
Please consult the Git log for further details.
** File name components can be written in any order
:PROPERTIES:
:CUSTOM_ID: h:fa0ffaf5-f762-4667-abe2-350f4ea4aac5
:END:
[ Relevant blog post: <https://protesilaos.com/codelog/2024-05-19-emacs-denote-reorder-file-name-components/>.]
Users can now change the variable ~denote-file-name-components-order~
to affect how Denote file names are constructed. By default, file
names are written using this scheme (consult the manual for the
details):
: IDENTIFIER--TITLE__KEYWORDS.EX
An optional =SIGNATURE= field can be added, thus:
: IDENTIFIER==SIGNATURE--TITLE__KEYWORDS.EXT
By modifying the ~denote-file-name-components-order~, users can
produce file names like these:
: --TITLE__KEYWORDS@@IDENTIFIER.EXT
: __SIGNATURE--TITLE__KEYWORDS@@IDENTIFIER.EXT
: __SIGNATURE--TITLE@@IDENTIFIER__KEYWORDS.EXT
Note that when the =DATE= is not the first component, it gets the =@@=
prefix to (i) remain unambiguous and (ii) make it easy to target it
directly for search purposes.
Thanks to Jean-Philippe Gagné Guay for the contribution in pull
request 360: <https://github.com/protesilaos/denote/pull/360>.
We discussed the possible delimiters for the =IDENTIFIER= in issue
332: <https://github.com/protesilaos/denote/issues/332>. Thanks to
Jean-Philippe, Nick Bell, Maikol Solis, and mentalisttraceur for their
insights. Our concern was to use characters that are stylistically
fine, while they are not special symbol in regular expressions (as
those make searching a bit less convenient).
Please remember that the file-naming scheme is the cornerstone of
Denote. If you do change how your notes are named, make sure to be
consistent throughout, otherwise you will likely make it harder for
yourself to find what you need.
** Exclude certain files from all prompts
:PROPERTIES:
:CUSTOM_ID: h:1c751e58-2f57-4aa8-9990-4ecb73054262
:END:
Sometimes users keep files in their ~denote-directory~ that they do
not want to interactive with. These can, for example, be what Org
produces when exporting to another file format or when archiving a
heading.
The user option ~denote-excluded-files-regexp~ makes is possible to
omit all those files from the relevant Denote prompts.
This is in response to requests for such a user option done by Samuel
W. Flint and zadca123 in issues 376 and 384, respectively:
- <https://github.com/protesilaos/denote/issues/376>
- <https://github.com/protesilaos/denote/issues/384>
[ Please let me know if you need this feature but do not know how to
write a regular expression. I can include concrete examples in the
manual, though I need to know about them first. ]
** Links in plain text and Markdown files are buttonised differently
:PROPERTIES:
:CUSTOM_ID: h:9f9b978f-3c2b-4b27-9ff5-ec0ac24a76d0
:END:
Before we were using the function ~denote-link-buttonize-buffer~,
which would create "buttons" for all the =denote:= links it would.
Users probably had something like this in their configuration:
#+begin_src emacs-lisp
;; DEPRECATED method
(add-hook 'text-mode-hook #'denote-link-buttonize-buffer)
#+end_src
We now provide an approach that is technically better by using Emacs'
fontification mechanism. All the user needs is to add this to their
configuration:
#+begin_src emacs-lisp
(add-hook 'text-mode-hook #'denote-fontify-links-mode-maybe)
#+end_src
The notion of "maybe" in the symbol of that function is because this
will take care to be activated only in the right context.
Thanks to Abdul-Lateef Haji-Ali for the contribution in pull request
344 (further changes by me): <https://github.com/protesilaos/denote/pull/344>.
Abdul-Lateef has assigned copyright to the Free Software Foundation.
** How to make Org export work in a Denote silo
:PROPERTIES:
:CUSTOM_ID: h:dd39bb26-a2c0-47ad-8d54-61f1ba82d3d5
:END:
[ Relevant blog post: <https://protesilaos.com/codelog/2024-06-18-emacs-denote-silos-org-export/>. ]
This is not a change in Denote per se, though I have added the
relevant details in the manual. Basically, the Org export machinery
dismisses directory-local variables, thus breaking how Denote silos
work. We can work around this by having an extra =#+bind= directive in
the front matter of each file. The manual, or the aforementioned blog
post, describe the technicalities.
** Org headings can have their own backlinks
:PROPERTIES:
:CUSTOM_ID: h:2464625e-e041-467c-a4fd-5744e3bb79c3
:END:
[ Relevant blog: <https://protesilaos.com/codelog/2024-04-21-emacs-denote-heading-backlinks/>. ]
Denote could already link to an Org heading directly. Now it can also
generate a backlinks buffer for the current heading, using the
command ~denote-org-extras-backlinks-for-heading~.
This is part of the optional extension =denote-org-extras.el= (it is
part of the Denote package, but not loaded by default if you use
something like =(require 'denote)=).
I am providing this as an option for those who absolutely need it,
though in my opinion it is better to have atomic notes, such that each
file contains information that is relevant as a whole. In this
workflow, individual headings can be added or removed, but the big
picture idea of the file remain intact.
At any rate, this change is possible due to the requisite refactoring
of the code that handles the backlinks. We can technically produce
backlinks to any pattern in files, though this may be more of interest
to developers rather than foreshadow future features in core Denote.
** Finer control over confirmations while renaming
:PROPERTIES:
:CUSTOM_ID: h:b3dc71a6-fa0b-48d1-b8a7-2842bf725092
:END:
The ~denote-rename-no-confirm~ is deprecated and superseded by the
more flexible user option ~denote-rename-confirmations~.
The command ~denote-rename-file~ (and others like it) prompts for
confirmation before changing the name of a file and updating its front
matter. The user option ~denote-rename-confirmations~ controls what
the user is prompted for, if anything. Please consult its
documentation for the technicalities.
Thanks to Jean-Philippe Gagné Guay for the contribution in pull
request 324: <https://github.com/protesilaos/denote/pull/324>.
** The user option ~denote-save-buffer-after-creation~ is renamed to ~denote-save-buffers~
:PROPERTIES:
:CUSTOM_ID: h:10883c47-0f5e-4267-a122-86906bf25a61
:END:
Please update your configuration accordingly, if you were using the
old name.
** The commands ~denote-keywords-add~ and ~denote-keywords-remove~ are replaced by ~denote-rename-file-keywords~
:PROPERTIES:
:CUSTOM_ID: h:042699ec-5516-44ca-93ee-60b32e599029
:END:
The new command can add or remove keywords. It does this by
prepopulating the minibuffer prompt with the existing keywords. Users
can then use the ~crm-separator~ (normally a comma), to write new
keywords or edit what is in the prompt to rewrite them accordingly. An
empty input means to remove all keywords.
[ 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-06-30 10:37 +0300. ]
Technically, ~denote-rename-file-keywords~ is a wrapper for
~denote-rename-file~, doing all the things that does.
** The commands ~denote-rename-file-title~ and ~denote-rename-file-signature~
:PROPERTIES:
:CUSTOM_ID: h:2c2c0f6f-413b-4492-b6a2-062034692c4c
:END:
These are like the ~denote-rename-file-keywords~ we just covered.
There are wrappers of the ~denote-rename-file~ command, which are used
to change on the file name component they reference.
If that component exists, its text is included in the minibuffer. The
user can then modify it accordingly. If there is no text, the user is
adding a new one. An empty input means to remove the title/signature
from the file altogether (again, check your minibuffer for how to
provide an empty input).
** More commands to add/remove keywords in bulk from Dired
:PROPERTIES:
:CUSTOM_ID: h:01770801-c511-46c0-9a05-890276374b63
:END:
Two new specialised commands are available to help users add or remove
keywords from many files at once. These are:
- ~denote-dired-rename-marked-files-add-keywords~
- ~denote-dired-rename-marked-files-remove-keywords~.
They complement the ~denote-dired-rename-marked-files-with-keywords~,
which we have had for a long time already, and which rewrites all the
keywords (instead of only adding/removing from the list).
All three of those commands operate only on the =KEYWORDS= component
of the file name, leaving everything else as-is (while respecting the
aforementioned ~denote-file-name-components-order~).
Thanks to Vedang Manerikar for the contribution in pull request 316:
<https://github.com/protesilaos/denote/pull/316>. Vedang has already
assigned copyright to the Free Software Foundation.
** The ~denote-org-extras-convert-links-to-file-type~ can return relative paths
:PROPERTIES:
:CUSTOM_ID: h:5f97d3f5-294d-467d-858b-281e46060625
:END:
The previous implementation would always return an absolute file path,
ignoring the Org user option ~org-link-file-path-type~. Whereas now it
will return a relative path if that user option is set to a value of
either ='adaptive= or ='relative=.
Thanks to Alexandre Rousseau for the contribution in pull request 325:
<https://github.com/protesilaos/denote/pull/325>. The change is small,
meaning that Alexandre does not need to assign copyright to the Free
Software Foundation.
** For developers or advanced users
:PROPERTIES:
:CUSTOM_ID: h:6911a5d6-6de3-4e04-b9d2-12a6526b4e97
:END:
*** The ~denote-add-prompts~ is made public
:PROPERTIES:
:CUSTOM_ID: h:28bfa74b-5a38-4f3c-a5fe-bf5a697385db
:END:
This is used to ~let~ bind any additional prompts that should be used
by the ~denote~ command. Check the source code for how we are using
this function.
*** The ~denote-select-linked-file-prompt~ is now public
:PROPERTIES:
:CUSTOM_ID: h:669f8eee-bdab-406a-aada-73ee8de9caf2
:END:
This is used internally but the commands ~denote-find-link~,
~denote-find-backlink~. Refer to the implementation of those commands
to get an idea of how to use this prompt.
*** The ~denote-retrieve-title-or-filename~ is just a wrapper
:PROPERTIES:
:CUSTOM_ID: h:414cfd70-1850-44bf-b0fe-fb3809af302e
:END:
It simply calls the ~denote-retrieve-front-matter-title-value~ or
~denote-retrieve-filename-title~. We do not want it to return the
~file-name-base~, as it used to, because this will duplicate the text
of the file name when there is no =TITLE= component, as demonstrated by
duli in issue 347: <https://github.com/protesilaos/denote/issues/347>.
*** The ~denote-file-prompt~ is more robust
:PROPERTIES:
:CUSTOM_ID: h:f7fb9e1f-e7b9-4dd1-a517-79069f28dcfe
:END:
We have made this function show relative file paths for the
convenience of the user, but we take care to internally return and
store the full file path (which is unambiguous). Thanks to Alan
Schmitt for noting that the history was not working properly. This was
done in issue 339: <https://github.com/protesilaos/denote/issues/339>.
A series of commits dealt with the implementation details, including a
contribution by Jean-Philippe Gagné Guay in pull request 342:
<https://github.com/protesilaos/denote/pull/342>. Also read 353 for a
further set of tweaks from my side: <https://github.com/protesilaos/denote/discussions/353>.
As part of these changes, the ~denote-file-prompt~ now takes a
=NO-REQUIRE-MATCH= argument. It also respects the aforementioned user
option of ~denote-excluded-files-regexp~.
*** Relevant functions conform with the ~denote-rename-confirmations~
:PROPERTIES:
:CUSTOM_ID: h:b056abdf-b9d9-4799-8e24-ae6507b4780e
:END:
These include the ~denote-rename-file-prompt~ and
~denote-rewrite-front-matter~, as well as the new
~denote-add-front-matter-prompt~.
This has the meaning of what I mentioned above. Commands that need to
deviate from the user option ~denote-rename-confirmations~ can ~let~
bind it accordingly: we even do this for some commands in =denote.el=,
because certain prompts do not make sense there.
*** All file name components can be ~let~ bound
:PROPERTIES:
:CUSTOM_ID: h:0118ad59-5fc2-4a19-8946-324410adb107
:END:
We define a new series of variables which can be set to a lexically
scoped value to control what the ~denote~ function parses. These are:
- ~denote-use-date~
- ~denote-use-directory~
- ~denote-use-file-type~
- ~denote-use-keywords~
- ~denote-use-signature~
- ~denote-use-template~
- ~denote-use-title~
Employ those for custom extensions you may have.
Thanks to Jean-Philippe Gagné Guay for adding those in pull request
365: <https://github.com/protesilaos/denote/pull/365>.
** Miscellaneous
:PROPERTIES:
:CUSTOM_ID: h:1fc6d700-e8aa-4d05-bbae-5623a9565922
:END:
- All the Org dynamic blocks defined by Denote in the optional
=denote-org-extras.el= are now autoloaded. This means that
evaluating such a code block will work even if the user has not
explicitly used something like =(require 'denote-org-extras)=.
Thanks to Julian Hoch for asking for a relevant clarification in
issue 337: <https://github.com/protesilaos/denote/issues/337>.
Thanks to Kolmas for reporting some missing autoloads in issue 371:
<https://github.com/protesilaos/denote/issues/371>.
- The value of the user option ~denote-link-backlinks-display-buffer-action~
is slightly modified to (i) make the buffer dedicated to its window
and (ii) try to preserve its size during automatic recombinations of
the frame's layout.
- There was a regression in version =2.3.0= relative to =2.2.0= where
the ~denote-link~ command would fail in Org capture buffers. Thanks
to Sven Seebeck for reporting this bug in issue 298:
<https://github.com/protesilaos/denote/issues/298>.
- The ~denote-filetype-heuristics~ function no longer chokes if it
gets a nil value (such as in Org capture buffers).
- The ~denote-journal-extras-directory~ (part of the optional
=denote-journal-extras= file) falls back to ~denote-directory~ if
its value is nil. This is what the user option
~denote-journal-extras-directory~ promises in its doc string.
- All prompts should have their scope of application in all capital
letters, such as =Select TEMPLATE key=. The idea is to make it
easier for the user to quickly spot for the prompt is about.
- The user option ~denote-link-description-function~ is documented in
the manual. Thanks to Sven Seebeck for noticing that we did not
document this for the =2.3.0= release. Thanks to Jean-Philippe Gagné
Guay for helping me refine the code. This was all done in issue 298:
<https://github.com/protesilaos/denote/issues/298>.
- As part of internal changes to how our various "rename" commands
work, Kolmas reported a regression with wrongly assigned file
extensions. This was done in issue 343:
<https://github.com/protesilaos/denote/issues/343>.
- In the =denote-org-extras.el= we now always jump to the correct Org
heading line, instead of missing it by 1 under certain conditions.
Thanks to kilesduli for bringing this matter to my attention in
issue 354: <https://github.com/protesilaos/denote/issues/354>.
** Policy for the aftermath of this release
:PROPERTIES:
:CUSTOM_ID: h:250e8abe-8e8d-41b9-a9dc-b2951a07d5bd
:END:
The next few days or weeks are reserved for bug fixes. We first want
to make sure that the current code base is rock solid, before making
any further changes. Any bugs will be addressed outright and new point
releases will be published (though those are not accompanied by a
change log entry).
** Git commits
:PROPERTIES:
:CUSTOM_ID: h:e9ea8288-99d1-407d-919a-b6024d35a501
:END:
Just an overview of what we did. Thanks again to everyone involved.
#+begin_src sh
~/Git/Projects/denote $ git shortlog 2.3.0..3.0.0 --summary --numbered
169 Protesilaos
52 Jean-Philippe Gagné Guay
3 Al Haji-Ali
2 Alan Schmitt
1 Alexandre Rousseau
1 Jianwei Hou
1 Vedang Manerikar
#+end_src
* Version 2.3.0 on 2024-03-24
:PROPERTIES:
:CUSTOM_ID: h:e9d3ebdb-8a69-47a9-a5a2-619abc44b7d2
:END:
This release brings a host of user-facing refinements to an already
stable base, as well as some impressive new features. There is a lot
to cover, so take your time reading these notes.
Special thanks to Jean-Philippe Gagné Guay for the numerous
refinements to parts of the code base. Some of these are not directly
visible to users, but are critical regardless. In the interest of
brevity, I will not be covering the most technical parts here. I
mention Jean-Philippe's contributions at the outset for this reason.
Though the Git commit log is there for interested parties to study
things further.
** Check out the ~denote-explore~ package by Peter Prevos
:PROPERTIES:
:CUSTOM_ID: h:3e49dd9d-59db-40e5-9116-ce678231b08d
:END:
This package provides several neat extensions that help you make
better sense of your knowledge base, while keeping it in good order.
The ~denote-explore~ package has commands to summarise the usage of
keywords, visualise connections between notes, spot infrequently used
keywords, and jump to previous historical entries.
- Git repository: <https://github.com/pprevos/denote-explore>.
- Documentation: <https://lucidmanager.org/productivity/denote-explore>.
Now on to Denote version =2.3.0=!
** Link to a heading inside a Denote Org file
:PROPERTIES:
:CUSTOM_ID: h:ca7baf4f-04af-4467-a1e6-20403357280f
:END:
Denote creates links to files by using their unique identifier. As Org
provides the =CUSTOM_ID= property for per-heading identifiers, we now
leverage this infrastructure to compose links that point to a file and
then to a heading therein. This only works for Org, as no other plain
text major mode has a concept of heading identifiers (and it is not
Denote's job to create such a feature).
I demonstrated the functionality in a video:
<https://protesilaos.com/codelog/2024-01-20-emacs-denote-link-org-headings/>
Technically, the =denote:= link type has the same implementation
details as Org's standard =file:= and has always had this potential to
jump to a section inside the given file.
*** The ~denote-org-store-link-to-heading~ user option
:PROPERTIES:
:CUSTOM_ID: h:a7864660-5b4c-4467-a252-9140baedeb1a
:END:
The user option ~denote-org-store-link-to-heading~ determines whether
~org-store-link~ links to the current Org heading (such links are
merely "stored" and need to be inserted afterwards with the command
~org-insert-link~). Note that the ~org-capture~ command uses the
~org-link~ internally if it has to store a link.
When its value is non-nil, ~org-store-link~ stores a link to the
current Org heading inside the Denote Org file. If the heading does
not have a =CUSTOM_ID=, it creates it and includes it in the heading's
=PROPERTIES= drawer. If a =CUSTOM_ID= exists, ~org-store-link~ use it
as-is.
This makes the resulting link a combination of the =denote:= link type,
pointing to the identifier of the current file, plus the value of the
heading's =CUSTOM_ID=, such as:
- =[[denote:20240118T060608][Some test]]=
- =[[denote:20240118T060608::#h:eed0fb8e-4cc7-478f-acb6-f0aa1a8bffcd][Some test::Heading text]]=
Both lead to the same Denote file, but the latter jumps to the heading
with the given =CUSTOM_ID=. Notice that the link to the heading also
has a different description, which includes the heading text.
The value of the =CUSTOM_ID= is determined by the Org user option
~org-id-method~. The sample shown above uses the default UUID
infrastructure.
If ~denote-org-store-link-to-heading~ is set to a nil value, the
command ~org-store-link~ only stores links to the Denote file (using
its identifier), but not to the given heading. This is what Denote was
doing in all versions prior to =2.3.0=.
Thanks to Kristoffer Balintona for discussing with me how
~org-capture~ interfaces with ~org-store-link~. I updated the
documentation accordingly. This was done in issue 267:
<https://github.com/protesilaos/denote/issues/267>.
*** Insert link to an Org file with a further pointer to a heading
:PROPERTIES:
:CUSTOM_ID: h:dd054536-8d20-4251-b23d-77fec7d7d036
:END:
As part of the optional =denote-org-extras.el= extension that comes
with the ~denote~ package, the command ~denote-org-extras-link-to-heading~
prompts for a link to an Org file and then asks for a heading therein,
using minibuffer completion. Once the user provides input at the two
prompts, the command inserts a link at point which has the following
pattern: =[[denote:IDENTIFIER::#ORG-HEADING-CUSTOM-ID]][Description::Heading text]]=.
Because only Org files can have links to individual headings, the
command ~denote-org-extras-link-to-heading~ prompts only for Org files
(i.e. files which include the =.org= extension). Remember that Denote
works with many file types.
This feature is similar to the concept of the aforementioned user
option ~denote-org-store-link-to-heading~. It is, however, interactive
and differs in the directionality of the action. With that user
option, the command ~org-store-link~ will generate a =CUSTOM_ID= for
the current heading (or capture the value of one as-is), giving the
user the option to then call ~org-insert-link~ wherever they see fit.
By contrast, the command ~denote-org-extras-link-to-heading~ prompts
for a file, then a heading, and inserts the link at point.
** Refinements galore to minibuffer prompts
:PROPERTIES:
:CUSTOM_ID: h:e509402b-a58f-4a10-b364-b158b31d1ee5
:END:
*** All commands that affect file names conform with ~denote-prompts~
:PROPERTIES:
:CUSTOM_ID: h:11f0fc1e-552b-4a02-bf01-9d8508ce68c8
:END:
The scope of the ~denote-prompts~ user option is broadened to make it
more useful. In the past, this variable would only affect the
behaviour of the ~denote~ command. For example, the user would make
the command prompt for a subdirectory, then keywords, then a title.
But all other commands were not following this setting, as they were
hardcoding the prompts for title and keywords.
Take the ~denote-subdirectory~ command as an example. It would first
prompt for a subdirectory to place the new note in, then for a title,
and then for keywords. Whereas now, it prepends the =subdirectory=
prompt to the list of ~denote-prompts~. So if the user has configured
their ~denote-prompts~ to, for example, ask for a signature and a file
type, the ~denote-subdirectory~ will do just that with the addition of
the =subdirectory= prompt.
Same idea for all commands that either create or modify file names,
wherever conformity with ~denote-prompts~ makes sense. For example,
the ~denote-rename-file~ will never ask for a =subdirectory= because
our renaming policy is to always rename in place (to avoid
mistakes---you can always move the file afterwards).
This also means that the ~denote-rename-file~ and its multi-file
counterpart, ~denote-dired-rename-files~, will only prompt for a
signature if it is part of the ~denote-prompts~. Whereas in the
previous version this was unconditional, thus burdening users who do
not need the =SIGNATURE= file name component (more about renaming
further into the release notes).
Lots of Git commits went into this redesign, per my initiave in issue
247: <https://github.com/protesilaos/denote/issues/247>. Thanks to
Vedang Manerikar for the changes to the convenience wrappers of the
~denote~ command (like ~denote-subdirectory~), which were done in pull
request 248: <https://github.com/protesilaos/denote/pull/248>.
Vedang has assigned copyright to the Free Software Foundation.
Also thanks to Max Brieiev for joining the technical discussion
therein.
The renaming commands are more intuitive now, which addresses a
discussion point raised by user babusri in issue 204:
<https://github.com/protesilaos/denote/issues/204>.
*** A simple tweak for more informative minibuffer prompts
:PROPERTIES:
:CUSTOM_ID: h:a502217d-8eff-4a6f-b66a-33e5e7ecda9d
:END:
The text of each prompt now has all capital letters for the word
referencing its scope of its application, like =TITLE=, =KEYWORDS=,
=SIGNATURE=. The idea is to make it easier to quickly scan the text,
especially while working through multiple prompts. For example, the
prompt for a title now reads:
: New file TITLE:
This paradigm is followed by all prompts. It is a small yet effective
tweak to get a better sense of context.
*** The file prompt uses relative names once again
:PROPERTIES:
:CUSTOM_ID: h:8f182ad3-c97f-45dc-a451-c552f2a7957c
:END:
In previous versions of Denote, the minibuffer prompt to pick a file
(such as a file to link to) would show relative file names: the name
without the full file system path. The functionality depended on the
built-in =project.el= library, which did not allow us to do everything
we wanted with our prompts, such as to have a dedicated minibuffer
history or to easily enable the workflow of commands like
~denote-open-or-create~.
In the previous version, I made the decision to remove the
=project.el= dependency and the concomitant presentation of relative
names in order to add the functionality we want. I did it with the
intention to find a better solution down the line. Et voilá! Relative
file names are back. We now have all the functionality we need. Sorry
if in the meantime you had to deal with those longer names! It was a
necessary intermediate arrangement for the greater good.
For the technicalities, refer to the source code of the function
~denote-title-prompt~.
*** Completion using previous inputs is now optional
:PROPERTIES:
:CUSTOM_ID: h:bcf382e4-bd00-49f3-859a-3f86e9770b77
:END:
All our minibuffer prompts have their dedicated history (you can
persist histories with the built-in ~savehist-mode~). They store
previous values, giving the user easy access to their past input
values. Some of our commands not only record a history, but also
leverage it to provide completion. These commands are named in the
variable ~denote-prompts-with-history-as-completion~. As of this
writing, they are:
- ~denote-title-prompt~
- ~denote-signature-prompt~
- ~denote-files-matching-regexp-prompt~
Users who do not want to use completion for those can set the new user
option ~denote-history-completion-in-prompts~ to a nil value.
** Renaming files got better all-round
:PROPERTIES:
:CUSTOM_ID: h:747e126a-b966-4ac8-a8ec-cf900012e37e
:END:
One of the pillars of the ~denote~ package is its ability to rename
any file to use the efficient Denote file-naming scheme (makes file
names predictable and easy to retrieve even with rudimentary tools).
To this end, we provide several commands that affect file names,
beside the commands that create new files.
As noted above, the commands which rename files to follow the Denote
file-naming scheme now conform with the user option ~denote-prompts~,
but there is more!
*** A broadened scope for the ~denote-rename-no-confirm~ option
:PROPERTIES:
:CUSTOM_ID: h:f93b8075-de2d-416e-9275-7225d03678ad
:END:
The implementation of this user option is redone (i) to save the
underlying buffer outright if the user does not want to provide their
confirmation for a rename each time and (ii) to cover all relevant
commands that perform a rename operation. The assumption is that the
user who opts in to this feature is familiar with the Denote renaming
modalities and knows they are reliable.
The default is still the same: Denote always asks for confirmation
before renaming a file, showing the difference between the old and new
names, as well as any changes to the file's contents. In this light,
buffers are not saved to give the user the chance to further inspect
the changes (such as by running ~diff-buffer-with-file~).
Commands that will now skip all confirmation prompts to rename the file
and, where relevant, save the corresponding buffer outright:
- ~denote-rename-file~
- ~denote-dired-rename-files~
- ~denote-dired-rename-marked-files-with-keywords~
- ~denote-rename-file-using-front-matter~
- ~denote-rename-add-keywords~
- ~denote-rename-remove-keywords~
- ~denote-rename-add-signature~ (new, more below)
- ~denote-rename-remove-signature~ (new, more below)
*** Rename a file by adding or removing a =SIGNATURE= component
:PROPERTIES:
:CUSTOM_ID: h:01ab0277-b4d4-433e-bd25-b9a0357412f6
:END:
The =SIGNATURE= is an optional free-form field that is part of a
Denote file name. A common use-case is to write sequence notes with
it, though Denote does not enforce any particular convention (you may
prefer to have it as a special kind of keyword for certain files that
simply stands out more due to its placement).
[ Besides, the ~denote-sort-dired~ command lets you filter and sort
files while putting them in a fully fledged Dired buffer, so
manually sequencing notes via their signature may not be needed. ]
We now provide two commands to add or remove a signature from file
names:
- The ~denote-rename-add-signature~ prompts for a file and a
signature. The default value for the file prompt is the file of the
currently open buffer or the file-at-point in a Dired buffer. The
signature is an ordinary string, defaulting to the selected file's
signature, if any.
- The ~denote-rename-remove-signature~ uses the same file prompt as
above. It performs its action only if the selected file has a
signature. Otherwise, it does nothing.
Files that do not have a Denote file name are renamed accordingly.
Though for such cases it is better to use ~denote-rename-file~ or
~denote-dired-rename-files~ as they are more general.
*** Use the ~denote-after-rename-file-hook~ for optional post-rename operations
:PROPERTIES:
:CUSTOM_ID: h:57f4f60c-7873-4542-a7a5-5c997cdbd137
:END:
All renaming commands run the ~denote-after-rename-file-hook~ after a
successful operation. This is meant for users who want to do something
specific after the renaming is done.
** More optional features of the =denote-org-extras.el=
:PROPERTIES:
:CUSTOM_ID: h:a0a2753e-5be9-4776-9f3f-e3b7556c13c1
:END:
I already covered the ~denote-org-extras-link-to-heading~, though the
file =denote-org-extras.el= has some more optional goodies for those
who work with Org files.
*** Create a note from the current Org subtree
:PROPERTIES:
:CUSTOM_ID: h:fbf1e574-e9aa-4c67-8034-27341d7a5536
:END:
In Org parlance, an entry with all its subheadings and other contents
is a "subtree". Denote can operate on the subtree to extract it from
the current file and create a new file out of it. One such workflow is
to collect thoughts in a single document and produce longer standalone
notes out of them upon review.
The command ~denote-org-extras-extract-org-subtree~ (part of the
optional =denote-org-extras.el= extension) is used for this purpose.
It creates a new Denote note using the current Org subtree. In doing
so, it removes the subtree from its current file and moves its
contents into a new file.
The text of the subtree's heading becomes the =#+title= of the new
note. Everything else is inserted as-is.
Read the documentation string of ~denote-org-extras-extract-org-subtree~
or consult the manual for further details.
*** Convert =denote:= links to =file:= links
:PROPERTIES:
:CUSTOM_ID: h:042e26e8-e3e0-4c57-9855-6b363671ae9a
:END:
Sometimes the user needs to translate all =denote:= link types to
their =file:= equivalent. This may be because some other tool does not
recognise =denote:= links (or other custom links types---which are a
standard feature of Org, by the way). The user thus needs to (i)
either make a copy of their Denote note or edit the existing one, and
(ii) convert all links to the generic =file:= link type that
external/other programs understand.
The optional extension =denote-org-extras.el= contains two commands
that are relevant for this use-case:
+ Convert =denote:= links to =file:= links :: The command
~denote-org-extras-convert-links-to-file-type~ goes through the
buffer to find all =denote:= links. It gets the identifier of the
link and resolves it to the actual file system path. It then
replaces the match so that the link is written with the =file:= type
and then the file system path. The optional search terms and/or link
description are preserved.
+ Convert =file:= links to =denote:= links :: The command ~denote-org-extras-convert-links-to-denote-type~ behaves like the
one above. The difference is that it finds the file system path and
converts it into its identifier.
*** The Denote Org dynamic blocks are now in =denote-org-extras.el=
:PROPERTIES:
:CUSTOM_ID: h:51d72c47-d434-4954-98d6-2db7a7ea6812
:END:
As part of this version, all our dynamic blocks are defined in the
file =denote-org-extras.el=. The file which once contained these block
definitions, =denote-org-dblock.el=, now only has aliases for the new
function names and dipslays a warning about its deprecation.
There is no need to ~require~ the ~denote-org-extras~ feature because
all of Denote's Org dynamic blocks are autoloaded (meaning that they
work as soon as they are used). For backward compatibility, all
dynamic blocks retain their original names as an alias for the newer
one.
We will not remove =denote-org-dblock.el= anytime soon to avoid any
potential breakage with people's existing notes. Though if you are new
to this functionality, you better avoid the deprecated symbols.
*** Org dynamic block to only insert missing links
:PROPERTIES:
:CUSTOM_ID: h:45176e63-c609-40f6-a11d-1cc0c28460dd
:END:
The =denote-missing-links= block is available with the command
~denote-org-extras-dblock-insert-missing-links~. It is like the
=denote-links= block (documented at length in the manual), except it
only lists links to files that are not present in the current buffer.
The parameters are otherwise the same:
: #+BEGIN: denote-missing-links :regexp "YOUR REGEXP HERE" :sort-by-component nil :reverse-sort nil :id-only nil
:
: #+END:
Remember to type =C-c C-x C-u= (~org-dblock-update~) with point on the
=#+BEGIN= line to update the block.
This brings back a feature that was deprecated in version 2.2.0, but
makes changes to it so that (i) it is more limited in scope and (ii)
available as a standalone Org dynamic block.
Thanks to Stephen R. Kifer, Peter Prevos, and Elias Storms for the
discussion which made it clear to me that users do have a need for
such functionality. This was done in the now-defunct mailing list:
<https://lists.sr.ht/~protesilaos/denote/%3C1db2104e-70bd-47f9-a7ed-b8d4bb370a7f%40app.fastmail.com%3E>.
Also thanks to Vedang Manerikar for fixing an edge case bug. This was
done in pull request 260: <https://github.com/protesilaos/denote/pull/260>.
Org dynamic blocks are a powerful feature which also showcases how far
we can go with Denote's efficient file-naming scheme.
** Quality-of-life improvements
:PROPERTIES:
:CUSTOM_ID: h:08f27f36-0ed2-4a5e-b02b-f0075c6e904f
:END:
Here I include other changes we made to existing functionality.
*** BREAKING User-defined sluggification of file name components
:PROPERTIES:
:CUSTOM_ID: h:240b80e7-242c-46fb-83d2-1ba36bdcaf66
:END:
In the previous version, we introduced the user option
~denote-file-name-letter-casing~. This was used to control the letter
casing of file name components, but was ultimately not flexible enough
for our purposes. We are thus retiring it and replacing it with the
more powerful, but also more advanced, user option
~denote-file-name-slug-functions~.
For existing users of the deprecated functionality, you can still
preserve the input of a prompt verbatim with something like this:
#+begin_src emacs-lisp
(setq denote-file-name-slug-functions
'((title . denote-sluggify-title)
(keyword . identity)
(signature . denote-sluggify-signature)))
#+end_src
The manual explains the details and shows ready-to-use code samples.
Remember that deviating from the default file-naming scheme of Denote
will make things harder to use in the future, as files will have
permutations that create uncertainty. The sluggification scheme and
concomitant restrictions we impose by default are there for a very
good reason: they are the distillation of years of experience. Here we
give you what you wish, but bear in mind it may not be what you need.
You have been warned.
Thanks to Jean-Philippe Gagné Guay for introducing this variable,
among other tweaks, in pull request 217: <https://github.com/protesilaos/denote/pull/217>.
Jean-Philippe has assigned copyright to the Free Software Foundation.
*** Option to automatically save the buffer of a new note
:PROPERTIES:
:CUSTOM_ID: h:3e1249f1-ac26-4187-9ddd-7391b4e5131f
:END:
The user option ~denote-save-buffer-after-creation~ controls whether
commands that create new notes save their buffer right away.
The default behaviour of commands such as ~denote~ (or related) is to
not save the buffer they create. This gives the user the chance to
review the text before writing it to a file. The user may choose to
delete the unsaved buffer, thus not creating a new file on disk.
If ~denote-save-buffer-after-creation~ is set to a non-nil value, such
buffers are saved automatically and so the file is written to disk.
*** The ~denote-menu-bar-mode~ and the placement of the Denote submenu
:PROPERTIES:
:CUSTOM_ID: h:c8336927-cf6b-4770-b041-123bf9186e57
:END:
The command ~denote-menu-bar-mode~ toggles the inclusion of the
submenu with the Denote entries in the Emacs menu bar (which is on
display when ~menu-bar-mode~ is enabled).
This submenu is now shown after the =Tools= entry.
Thanks to Joseph Turner for sending me the relevant patches. Joseph
has assigned copyright to the Free Software Foundation.
*** The =C-c C-o= works in ~markdown-mode~ for Denote links
:PROPERTIES:
:CUSTOM_ID: h:1c884b19-7ab7-4eb5-a332-815d25f7373c
:END:
In files whose major mode is ~markdown-mode~, the default key binding
=C-c C-o= (which calls the command ~markdown-follow-thing-at-point~)
correctly resolves =denote:= links. This method works in addition to
the =RET= key, which is made available by the buttonization that we
also provide. Interested users can refer to the function
~denote-link-markdown-follow~ for the implementation details.
Thanks to user pmenair for noting a case where this was breaking
general Markdown linking functionality. This was done in issue 290:
<https://github.com/protesilaos/denote/issues/290>.
*** More fine-grained control of Denote faces for dates/identifiers
:PROPERTIES:
:CUSTOM_ID: h:c6f739ef-ea26-41b8-84e6-c87c4622cdba
:END:
We now define more faces for fine-grained control of the identifier in
Dired. Thanks to mentalisttraceur for suggesting the idea in issue
276: <https://github.com/protesilaos/denote/issues/276>.
Before you ask, no, none of my themes will cover those faces because
extra colouration is something only the user can decide if they want
or not. In the above link I provide a sample with a screenshot (apart
from the ~modus-themes~, my ~ef-themes~ and ~standard-themes~ have
similar functionality):
#+begin_src emacs-lisp
(defun my-modus-themes-denote-faces (&rest _)
(modus-themes-with-colors
(custom-set-faces
`(denote-faces-year ((,c :foreground ,cyan)))
`(denote-faces-month ((,c :foreground ,magenta-warmer)))
`(denote-faces-day ((,c :foreground ,cyan)))
`(denote-faces-time-delimiter ((,c :foreground ,fg-main)))
`(denote-faces-hour ((,c :foreground ,magenta-warmer)))
`(denote-faces-minute ((,c :foreground ,cyan)))
`(denote-faces-second ((,c :foreground ,magenta-warmer))))))
(add-hook 'modus-themes-post-load-hook #'my-modus-themes-denote-faces)
#+end_src
*** New convenience command for users of the optional =denote-journal-extras.el=
:PROPERTIES:
:CUSTOM_ID: h:9e7bff88-a6ad-45e7-b802-0493153e0e20
:END:
The command ~denote-journal-extras-link-or-create-entry~ links to the
journal entry for today or creates it in the background, if missing,
and then links to it from the current file. If there are multiple
journal entries for the same day, it prompts to select one among them
and then links to it. When called with an optional prefix argument
(such as =C-u= with default key bindings), the command prompts for a
date and then performs the aforementioned. With a double prefix
argument (=C-u C-u=), it also produces a link whose description
includes just the file's identifier.
Thanks to Alan Schmitt for contributing this command, based on
previous discussions. It was done in pull request 243:
<https://github.com/protesilaos/denote/pull/243>.
** For developers or advanced users
:PROPERTIES:
:CUSTOM_ID: h:03778c8c-60aa-449c-96df-7e41916668a6
:END:
These has new parameters or are new symbols altogether. Please read
their respective doc string for the details.
+ Function ~denote-convert-file-name-keywords-to-crm~.
+ Function ~denote-valid-date-p~.
+ Function ~denote-parse-date~.
+ Function ~denote-retrieve-title-or-filename~.
+ Function ~denote-get-identifier~.
+ Function ~denote-signature-prompt~.
+ Function ~denote-file-prompt~.
+ Function ~denote-keywords-prompt~.
+ Function ~denote-title-prompt~.
+ Function ~denote-rewrite-front-matter~.
+ Function ~denote-rewrite-keywords~.
+ Function ~denote-update-dired-buffers~.
+ Function ~denote-format-string-for-org-front-matter~.
+ Function ~denote-format-string-for-md-front-matter~.
+ Variable ~denote-link-signature-format~.
+ Function ~denote-link-description-with-signature-and-title~.
+ Variable ~denote-link-description-function~.
** Miscellaneous
:PROPERTIES:
:CUSTOM_ID: h:040f2678-674d-4e99-b428-659cd3a3b7c3
:END:
- The ~denote-sort-dired~ function no longer errors out when there is
no match for the given search terms. Thanks to Vedang Manerikar for
the initial patch! This was done in the now-defunct mailing list:
<https://lists.sr.ht/~protesilaos/denote/patches/47625>. Further
changes by me.
- The ~denote-keywords-sort~ function no longer tries to sort keywords
that are not a list. Thanks to Ashton Wiersdorf for the patch. The
change is small. As such, Ashton does not need to assign copyright
to the Free Software Foundation.
- Documented in the manual that custom convenience commands can be
accessed by the ~denote-command-prompt~. Thanks to Glenna D. for
clarifying the language.
- The ~denote-user-enforced-denote-directory~ is obsolete. Those who
used it in their custom code can simply ~let~ bind the value of the
variable ~denote-directory~. Thanks to Jean-Philippe Gagné Guay for
making the relevant changes (the Git history is not direct here and
I cannot quickly find the pull request---the commit is =a48a1da=).
- The ~denote-link-return-links~ no longer keeps buffers around.
Thanks to Matteo Cavada for the patch. This was done in pull request
252: <https://github.com/protesilaos/denote/pull/252>. The change is
small and so Matteo does not need to assign copyright to the Free
Software Foundation.
- Thanks to user jarofromel (recorded in Git as "random" author) for
fixing a mismatched parenthesis in ~denote-parse-date~. This was
done in pull request 258: <https://github.com/protesilaos/denote/pull/258>.
- The ~denote-rename-buffer-mode~ now works as expected with
non-editable files, like PDFs. Thanks to Alan Schmitt for bringing
this matter to my attention and then refining the implementation
details in pull request 268: <https://github.com/protesilaos/denote/pull/268>.
- All the Denote linking functions can be used from any file outside
the ~denote-directory~ (links are still resolved to files inside the ~denote-directory~). Thanks to Jean-Philippe Gagné Guay for the
contribution in pull request 236: <https://github.com/protesilaos/denote/pull/236>.
- We removed all glue code that integrated Denote with the built-in ~ffap~, ~xref~, and ~project~ libraries. We may reconsider how best
to organise such features in the future. Thanks to Noboru Ota
(nobiot), who originally contributed those extensions, for
suggesting their removal from our code base. We did this by
evaluating all use-cases. The discussion with Noboru happened in
issue 264: <https://github.com/protesilaos/denote/issues/264>. Also
thanks to Jean-Philippe Gagné Guay and Alan Schnmitt for checking
the impact of this on how we generate backlinks. The latest
iteration of this was done in pull request 294, by Jean-Philippe:
<https://github.com/protesilaos/denote/pull/294>.
- While renaming files, signatures no longer lose consecutive spaces.
Thanks to Wesley Harvey for the contribution in pull request 207:
<https://github.com/protesilaos/denote/pull/207>. The change is
within the ~15 line limit and so Wesley does not need to assign
copyright to the Free Software Foundation.
- All of the above and lots more are documented at length in the
manual. This is a big task in its own right (as are release notes,
by the way), though it ensures we keep a high standard for the
entire package and can communicate all our knowledge to the user.
** No more SourceHut
:PROPERTIES:
:CUSTOM_ID: h:9a0d6afc-95e0-490e-a573-5a50fe7bdf28
:END:
Development continues on GitHub with GitLab as a mirror. I explained
my reasons here: <https://protesilaos.com/codelog/2024-01-27-sourcehut-no-more/>.
This is a change that affects all my Emacs packages.
** Forward guidance for Denote version 3.0.0
:PROPERTIES:
:CUSTOM_ID: h:61fb340e-5c7c-4a4b-927c-63faf4759a09
:END:
We will not any new features until mid-April or a bit later if
necessary. This gives users enough time to report any potential issues
with version =2.3.0=. If there are any bugs, they will be fixed right
away and new minor releases will be introduced (though without release
notes).
Once we are done with this release cycle, we want to prepare for the
next major version of Denote. The plan is to make the placement of
file name components entirely customisable, among many other power
user features. Though the defaults will remain intact.
For the immediate future, please prioritise bug reports/fixes. Then
see you around for another round of hacking. The Denote code base is a
pleasure to work with due to how composable everything is. I happy to
make it even better for developers and users alike.
** Git commits
:PROPERTIES:
:CUSTOM_ID: h:a6fd8e16-ded9-49cf-afbb-6e1373c3c43d
:END:
Just an overview of what we did. Thanks again to everyone involved.
#+begin_src sh
~/Git/Projects/denote $ git shortlog 2.2.0..2.3.0 --summary --numbered
246 Protesilaos
46 Jean-Philippe Gagné Guay
6 Vedang Manerikar
3 Joseph Turner
2 Alan Schmitt
2 Max
2 Peter Prevos
1 Ashton Wiersdorf
1 Glenna D.
1 Matteo Cavada
1 mattyonweb
1 random
1 wlharvey4
#+end_src
** All contributions are valuable
:PROPERTIES:
:CUSTOM_ID: h:967372fa-933b-40d2-b1a8-546d1a50d35d
:END:
I encourage you to provide feedback on any of the functionality of the
Denote package. You do not need to be a developer or indeed an expert
in Emacs. When you have an idea in mind on how you use Denote, or you
think something could be done differently, please speak your mind. I
do listen to feedback and am interested in further improving this
package. Everybody is welcome!
* Version 2.2.0 on 2023-12-10
:PROPERTIES:
:CUSTOM_ID: h:8efed390-cfa0-420d-b300-0cb76bf2c9f9
:END:
The present version covers four broad themes:
1. Denote rename commands are more user-friendly and featureful.
2. An optional sorting facility makes it possible to produce a
filtered and sorted Dired buffer with Denote files.
3. The optional Denote Org dynamic blocks have received a lot of attention.
4. Bug fixes and internal refinements.
[ Remember that you do not need to be a programmer to contribute to
Denote. Report a bug, make a suggestion, or just describe how you
want to use this package. Every idea counts and we may implement it
if we can. ]
** The rename commands can remove a Denote file name component
:PROPERTIES:
:CUSTOM_ID: h:54d803d8-4863-4160-bb2f-3302fb8bff23
:END:
The commands we provide to rename files using the Denote file-naming
scheme---~denote-rename-file~, ~denote-dired-rename-files~, and
~denote-dired-rename-marked-files-with-keywords~---can now remove
Denote file name components. This is done by providing an empty string
at the relevant prompt.
For example, to remove the =TITLE= component from a file called
=20231209T110322==sig--title__keywords.ext= we provide an empty string
at the title prompt. The end result will look something like this:
=20231209T110322==sig__keywords.ext=.
All prompts now include a hint that leaving them empty will ignore the
given field if it does not exist or remove it if it does exist.
Note that you must *check how to input an empty string* with your
minibuffer user interface of choice. For instance, with the ~vertico~
package you can do that with the =M-RET= key binding or by selecting
the prompt line directly (notice the counter showing something like
=*/5= instead of =1/5=). Please make sure to consult the documentation
of the package you are using as this behaviour is not controlled by
Denote. Vertico, and others like it, selects the first candidate if
you type =RET= without any input, which is not the same as an empty
string---it is the first candidate.
Also read the Denote manual on the matter of [[https://protesilaos.com/emacs/denote#h:532e8e2a-9b7d-41c0-8f4b-3c5cbb7d4dca][Renaming files]]. In short,
we use this facility to name all our files, regardless of file type,
in a consistent way that makes them easier to find (I do this with my
videos, for example, and I do it across my filesystem for all personal
files).
** The file-to-be-renamed is easier to read in the minibuffer
:PROPERTIES:
:CUSTOM_ID: h:69d85d3b-0200-4cc1-baff-9d59aa0ff57b
:END:
The commands ~denote-rename-file~ and ~denote-dired-rename-files~
show the name of the file they are operating on in the minibuffer
prompt. This is now produced relative to the current directory,
meaning that instead of =/some/rather/long/path/to/file-name.txt=
Denote only displays =file-name.txt=.
Our rename commands never move files to another directory, anyway, so
we do not need to remind the user of the entire file system path.
To make things easier for users/themes, file names highlighted in
Denote prompts are fontified with either of following faces,
depending on the specifics of the case:
- ~denote-faces-prompt-old-name~
- ~denote-faces-prompt-new-name~
- ~denote-faces-prompt-current-name~
These faces inherit the attributes of basic faces, so they should look
decent without further tweaks across all themes.
** Prompts for title, keywords, and signature accept an empty string
:PROPERTIES:
:CUSTOM_ID: h:5897bcc1-4637-4268-8518-8404d939b4b9
:END:
The prompts defined by Denote that apply to file name components all
accept an empty string. This has the effect of skipping the given
component. For example, we can create a file without a title and
keywords, with the following sequence of actions (I assume you are
using ~vertico~ for the minibuffer user interface):
- Type =M-x denote=.
- Type =M-RET= at the title prompt to input an empty string.
- Now type =M-RET= at the keywords prompt for another empty string.
The resulting file name is something like =20231209T110950.org=.
** Dired with sorting and filtering
:PROPERTIES:
:CUSTOM_ID: h:05aa437b-2fc8-4e01-ac38-ab77baad83af
:END:
The new optional =denote-sort.el= library provides facilities to sort
Denote files by any of their file name components. Users can benefit
from this facility to produce a filtered and sorted listing of Denote
files with the command ~denote-sort-dired~.
~denote-sort-dired~ produces a fully fledged Dired buffer. It asks for a
regular expression that matches file names in the ~denote-directory~.
It then prompts for a sort key and finally checks with the user
whether to reverse the order or not.
[ Do not be discouraged by the term "regular expression". Ordinary
words work fine. Plus, with Denote's file-naming scheme we have
semantics such as =_keyword=, =-title=, ~=signature~, as explained
in the manual. This is the whole point of using a thoughtful naming
scheme. ]
The resulting Dired listing is flat, meaning that files inside of
subdirectories are bundled together with those present at the root of
the ~denote-directory~. In this case, files inside of a subdirectory
include the directory component as a prefix. So we have something like
this:
#+begin_example
test-subdir/20230320T105950--a-new-note__testing.txt
20231202T095629--rename-works-as-intended__one_test_two.org
#+end_example
I think this is a killer feature, as the fully fledged Dired buffer
allows us to perform all supported operations on our Denote
sorted+filtered files (e.g. change file permissions, move files to
another directory, or open them in an external application).
I recorded a video to show how this works:
<https://protesilaos.com/codelog/2023-12-04-emacs-denote-sort-mechanism/>.
[ Remember that we can rename any file using the Denote file-naming
scheme, meaning that our files can include stuff like PDFs and
videos. Combine this with the concept of "silos", which is covered
in the Denote manual, to organise your long-term storage and
retrieve it efficiently. ]
** Combine contents of files with an Org dynamic block
:PROPERTIES:
:CUSTOM_ID: h:d41009c1-9833-4b28-8240-9666bfd26559
:END:
The new =denote-files= Org dynamic block produces a continuous stream
of file contents. It joins together the contents of files inside the
~denote-directory~ whose name matches the given regular expression.
Optional parameters control whether to include links to those files,
omit their front matter, sort by a given file name component, or tweak
the separator between each file's contents.
I produced a video to demonstrate the functionality:
<https://protesilaos.com/codelog/2023-11-25-emacs-denote-org-dynamic-blocks/>.
Use the command ~denote-org-dblock-insert-files~ to insert such a
block directly at point. Read the Denote manual for the
technicalities: [[https://protesilaos.com/emacs/denote#h:f15fa143-5036-416f-9bff-1bcabbb03456][Org dynamic block to insert file contents]].
[ Videos I do will eventually be out-of-date. The manual is the source
of truth. ]
Bear in mind that this feature is not "transclusion". We are simply
printing a copy of the contents of the files in the current buffer.
Changes made to this copy are not reflected in the original files.
The =denote-files= Org dynamic block is an excellent way to quickly
collect your thoughts on a given topic. Although dynamic blocks are a
feature of Org, the contents of the files do not need to be in Org
syntax (I write most of my notes in plain text (=.txt=)).
Thanks to Claudiu Tănăselia for proposing this idea and discussing it
with me. This was done via a private channel and the information is
shared with permission.
** Sort parameters are used in all Denote Org dynamic blocks
:PROPERTIES:
:CUSTOM_ID: h:7b51fe38-302e-488d-9816-7015a8071ddb
:END:
All Denote Org dynamic blocks make use of =denote-sort.el= (described
further above). It powers the =:sort-by-component= and =:reverse-sort=
parameters.
Thanks to Glenna D. for suggesting this feature and discussing it with
me. This was done via a private channel and the information is shared
with permission. It is what inspired me to start work on
=denote-sort.el=, which I then extended to cover Dired, as noted
above.
** The =:missing-only= parameter is removed from Org dynamic blocks
:PROPERTIES:
:CUSTOM_ID: h:2bd26aef-70ad-4d83-a4ab-c75a893a733a
:END:
I am removing it because the underlying functionality of
~denote-add-missing-links~ was not always reliable.
** Files with signature are linked appropriately in Org dynamic blocks
:PROPERTIES:
:CUSTOM_ID: h:144436eb-e674-4052-ac0a-d582b6aa2f53
:END:
In general, we provide the command ~denote-link-with-signature~ to let
the user pick a file that has a signature and link to it. The
description of such a link contains the signature text as well as the
file title. The ~denote-link-with-signature~ is distinct from the
standard ~denote-link~, as it allows the user to express intent about
the inclusion of the signature.
In Org dynamic blocks for links/backlinks, we make this happen
automatically since there can be no manual intervention to express
intent on a link-by-link basis.
** Fontification in Dired can now extend to subdirectories
:PROPERTIES:
:CUSTOM_ID: h:46e08576-4c17-4b1e-a268-e0223250e7c1
:END:
The user option ~denote-dired-directories~ activates the
~denote-dired-mode~ in the specified list of directories when the user
sets this in their init file:
#+begin_src emacs-lisp
(add-hook 'dired-mode-hook #'denote-dired-mode-in-directories)
#+end_src
The new user option ~denote-dired-directories-include-subdirectories~
extends the reach of this feature to all subdirectories thereof.
Thanks to Henrik Hörmann for discussing this with me and contributing
a patch. This was originally done in pull request 191 on the GitHub
mirror: <https://github.com/protesilaos/denote/pull/191>. Subsequent
refinements by me.
** Signatures are sluggified as intended
:PROPERTIES:
:CUSTOM_ID: h:73e1efaa-2c22-48ee-be46-072b55177c99
:END:
The file name signature component is now sluggified properly. This
means that multiple words are separated by the equals sign, in
accordance with the Denote file-naming scheme where a word separator
is the same as the given field separator (this is the low-tech feature
that makes Denote files so easy to retrieve without fancy extras).
Vedang Manerikar fixed two relevant bugs in the "rename" commands,
while I rewrote internal functions and tests in the interest of consistency. Vedang's patches: <https://lists.sr.ht/~protesilaos/denote/patches/46790>.
[ The "signature" is a free form component of the file name. Users can
add anything they want there, such as to use it as a "category" that
is different from "tags/keywords", or to introduce sequences in
their notes, or to just have an extra marker for files they need to
spot quickly. ]
** For developers
:PROPERTIES:
:CUSTOM_ID: h:79f2fd7e-d5a7-4c78-bce7-f8d21e86e32c
:END:
There is a section in the manual titled "For developers or advanced
users". There we document functions or variables that are
public-facing, meaning that we test and document their behaviour and
encourage others to use them for code they write on top of Denote.
Refer to this section if you are looking to extend Denote. Though you
can also just check the source code, which is designed to be readable
and hackable.
- The ~denote-directory-files~ function gains new functionality that
subsumes that of the now-deprecated functions
~denote-directory-files-matching-regexp~, ~denote-all-files~,
~denote-directory-text-only-files~. Thanks to Jean-Philippe Gagné
Guay for the contribution, which was done in pull request 195 on the
GitHub mirror: <https://github.com/protesilaos/denote/pull/195>.
- The font-lock keywords we define are consolidated into a single
variable: ~denote-faces-file-name-keywords~ instead of being split
into two variables. This means that we cover all our fontification
needs in the backlinks buffer as well as the ~denote-dired-mode~
with this one point of entry. It also works for ~denote-sort-dired~,
which can include files with their subdirectory component in the
same flat listing.
- Use the function ~denote-retrieve-filename-keywords~ to extract
keywords from the file name alone, without going into the file
contents.
- The ~denote-retrieve-filename-title~ function now returns an empty
string if no title is present. Its behaviour is thus consistent with ~denote-retrieve-filename-keywords~ and ~denote-retrieve-filename-signature~.
- The ~denote-retrieve-filename-title~ will now use the ~file-name-base~ function as a fallback subject to a non-nil
optional argument. This case come into effect when the file does not
have a title component. The new optional argument allows the caller
to handle such cases as they see fit.
- The ~denote-signature-prompt~ and ~denote-title-prompt~ functions
accept an optional =DEFAULT-SIGNATURE= or =DEFAULT-TITLE= argument.
Internally, this is used as the =INITIAL-INPUT= of ~completing-read~
instead of the =DEF= argument. This matters because we want the
prompt to return an empty string if there is no input, whereas the
presence of =DEF= means that =DEF= is returned when the prompt is
empty.
- All our functions that interactively match file names with a regular
expression now use the ~denote-files-matching-regexp-prompt~
function. When called from Lisp, it takes a =REGEXP= argument as
well as an optional =PROMPT-TEXT=.
For the purposes of this release cycle, I am not documenting the
points of entry provided by =denote-sort.el=. It is a new feature that
I may eventually incorporate in =denote.el=. If you are interested in
the functionality (e.g. to have more elaborate sorting algorithms),
please take a look at the source code and then let us discuss the
implementation details.
** Miscellaneous
:PROPERTIES:
:CUSTOM_ID: h:ce5c7865-9ec1-49ba-9388-5a251ab56735
:END:
- Rewrote the manual on the topic of Org dynamic blocks. Same idea for
practically the entirety of =denote-org-dblock.el=.
- Marked the interactive specification of a few commands with the
major mode they belong to. This means that =M-X= (note the capital
X), which calls ~execute-extended-command-for-buffer~ by default,
will only show those commands in the relevant context.
- Made internal refinements and simplified the implementation of a few
functions. This is important work to keep the code base clean and
easy to read/maintain. Thanks to Jean-Philippe Gagné Guay for the
contribution. It was done in pull request 193 on the GitHub mirror:
<https://github.com/protesilaos/denote/pull/193>.
- Improved the doc string of the ~denote-format-file-name~ function.
Also introduced a unit test for it to be sure it does what we expect
(I eventually want to have tests for everything we do, but this is a
long-term project).
** Git commits
:PROPERTIES:
:CUSTOM_ID: h:6830d3f3-130c-4346-b3ca-a3d4b0e9f974
:END:
Just an overview of what we did. Thanks again to everyone involved.
#+begin_src sh
~/Git/Projects/denote $ git shortlog 2.1.0..2.2.0 --summary --numbered
125 Protesilaos
17 Jean-Philippe Gagné Guay
2 Vedang Manerikar
1 Henrik Hörmann
#+end_src
** Policy for the next development cycle
:PROPERTIES:
:CUSTOM_ID: h:cb0cae4f-c9a1-40b3-98ae-781a57270d4e
:END:
I will give a ~1 week pause on Denote development before making any
feature changes. This is to ensure that we catch possible bugs and
push fixes right away. If there are other changes in place, it is not
possible to make point updates of this sort, as we must first wait for
the new features to be tested in real-world scenaria.
* Version 2.1.0 on 2023-11-12
:PROPERTIES:
:CUSTOM_ID: h:167beb8f-14be-40de-a1f2-d13910924c00
:END:
The general theme of this release is improvements to the quality of
life with Denote. While these release notes and the overall
documentation are comprehensive, make no mistake: Denote can be used
with =M-x denote=, =M-x denote-link=, =M-x denote-backlinks=, =M-x
denote-rename-file=. These have been rock solid from the beginning.
Everything else is for more specialised workflows.
I hope to produce a companion video to this changelog in the coming
days. Though I am still reeling from the injury to my left hand (I
wrote all this to not delay the package any longer). Please check back
in my website's coding blog section to find the follow-up video:
<https://protesilaos.com/codelog>.
[ Remember to consult the manual whenever you have a question about
Denote. It is comprehensive and, in my opinion, a paradigm of how
free software should be done for the benefit of users. I document
everything in detail and am eager to continue this way. If something
is unclear, contact me in person, use the mailing list, or open an
issue on the GitHub/GitLab mirror. I do not check other fora or
media and will thus not help you there. If you are writing custom
code, remember to read the doc strings. I write them for you too. ]
** Deprecated the ~denote-allow-multi-word-keywords~
:PROPERTIES:
:CUSTOM_ID: h:a086d1d2-adb3-4151-a7af-813d79b4b3dc
:END:
This user option enabled the use of keywords that consisted of
multiple words. Those would be separated by hyphens. Such keywords do
not work as Org =#+filetags= and also mess up with the neat search
semantics of Denote's file-naming scheme where a hyphen prefix
anchors the query to the =TITLE= component of the name.
Users who absolutely need multi-word keywords are encouraged to use
the new ~denote-file-name-letter-casing~ option. More below.
** Control the letter casing of file name components
:PROPERTIES:
:CUSTOM_ID: h:29319b8a-698b-4a1c-bab4-7b106a623de8
:END:
By default, Denote downcases all components of the file name. The user
option ~denote-file-name-letter-casing~ provides granular control over
this behaviour.
The value it accepts is an alist where each element is a cons cell of
the form =(COMPONENT . METHOD)=. The manual, or the variable's doc
string, cover the details. The gist is that we can now instruct Denote
to accept input verbatim, such as because we want to apply a
=camelCase= convention or variants thereof.
Here is an example, where we downcase the title, but preserve the
letter casing of the signature and keyword components with this:
#+begin_src emacs-lisp
(setq denote-file-name-letter-casing
'((title . downcase)
(signature . verbatim)
(keywords . verbatim)
(t . downcase)))
#+end_src
Users of the now-deprecated ~denote-allow-multi-word-keywords~ are
encouraged to implement a letter casing convention with the help of
this new user option.
Relevant sections in the manual:
- The file-naming scheme:
<https://protesilaos.com/emacs/denote#h:4e9c7512-84dc-4dfb-9fa9-e15d51178e5d>.
- Contol the letter casing of file names:
<https://protesilaos.com/emacs/denote#h:6ae1ab8c-5e36-4216-8e93-f37f4447582c>
** The ~denote-dired-mode~ should now work while toggling ~wdired~
:PROPERTIES:
:CUSTOM_ID: h:18a3b515-9306-4911-ba2d-73e36efbdd32
:END:
The writable version of Dired would break the colouration applied by
~denote-dired-mode~. I have arranged for this to not happen anymore,
although it means that I had to add an advice to relevant wdired
symbols because no proper hook is on offer.
** The "do or create" commands are more intuitive to use
:PROPERTIES:
:CUSTOM_ID: h:5bcdc4b8-ecba-44d7-accc-0b26657aa29b
:END:
Denote provides several commands with a "do or create" logic. For
example, the ~denote-open-or-create~ prompts for a file to visit: if
something matches the user's input, it is visited in a buffer,
otherwise a new note is created with the given input. Same for
~denote-link-or-create~, mutatis mutandis.
Before, the "... or create" step did not make it obvious how the
previous search terms could be reused. Whereas now those are set as
the default minibuffer value at the title prompt, meaning that typing
=RET= at the empty prompt will use that value, while =M-n=
(~next-history-element~ with default settings) will put the text into
the prompt for further editing.
I will answer this because I get asked about it: we still refrain from
creating the new note outright because the search terms are not
necessarily suitable for a new title. Remember that Denote's file name
is optimised for searching: =-word= is specific to the title, =_word=
to the keywords, and ==word= to the signature. Combine this with the
~orderless~ package and you frequently type something like =_jou -he=
to match a file with the =journal= keyword and the word =hesitation=
in its title.
*IMPORTANT NOTE:* some minibuffer completion User Interfaces preselect
the first completion candidate, which is not always the same as the
default value. Check with your UI of choice how to pass a default
value and/or provide an empty input. For example, with the ~vertico~
package one can move up from the first candidate to select the prompt
itself (the counter switches from =1/N= to =*/N=).
Relevant sections in the manual:
- Open an existing note or create it if missing:
<https://protesilaos.com/emacs/denote#h:ad91ca39-cf10-4e16-b224-fdf78f093883>.
- Link to a note or create it if missing:
<https://protesilaos.com/emacs/denote#h:9e41e7df-2aac-4835-94c5-659b6111e6de>.
*** New "... or create with command" features for more flexibility
:PROPERTIES:
:CUSTOM_ID: h:6f475151-9d64-4dfb-8c59-694c93d56ce8
:END:
As part of the wider "do or create" feature set, Denote provides the
option to run a specific note-creating command instead of just using
the standard ~denote~ one. For example, it is possible to call the
~denote-subdirectory~ command to pick a subdirectory of the
~denote-directory~ for the new note. Commands providing this facility
are ~denote-open-or-create-with-command~ and ~denote-link-after-creating-with-command~.
Thanks to Vedang Manerikar for fixing a broken ~if~ clause during
development: <https://lists.sr.ht/~protesilaos/denote/patches/46087>.
** The title and signature prompts use minibuffer completion
:PROPERTIES:
:CUSTOM_ID: h:429847c8-ebf4-4b23-a597-5276309ef61a
:END:
All Denote minibuffer prompts come with their own history. This means
that =M-p= (~previous-history-element~) and =M-n=
(~next-history-element~) always return relevant input.
The title and signature prompts now reuse their input history to
provide completion. This means that the user can quickly access
previous inputs, either to pass them directly or edit them further
before inputting them.
[ Use the built-in ~savehist-mode~ to persist histories across sessions. ]
Remember to check with your minibuffer UI on how to input empty
values at the prompt, should you ever need to do so.
For posterity, I first implemented this in commit =0d855bb=. However,
it did not work with the default minibuffer because the =SPC= key
performs completion (popping up the Completions buffer). So users
could not easily input an arbitrary string for the title/signature. I
thus reverted that commit in =9f692cb=.
[ The bug was reported by Suhail Singh on the mailing list:
<https://lists.sr.ht/~protesilaos/denote/%3C652d82c0.c80a0220.e6282.dc47%40mx.google.com%3E#%3C65392fa6.050a0220.da61c.0ac8@mx.google.com%3E>. ]
Stefan Monnier suggested the use of the ~minibuffer-with-setup-hook~,
which lets us disable =SPC= completion for the purposes of these
functions. This is most welcome as the functionality is nice to have.
Stefan's feedback was provided on the emacs-devel mailing list:
<https://lists.gnu.org/archive/html/emacs-devel/2023-10/msg00631.html>.
** Create a note with the region's contents
:PROPERTIES:
:CUSTOM_ID: h:ae798d1f-6fa2-4d99-91c9-0d5eb18b1bb0
:END:
The command ~denote-region~ takes the contents of the active region
and then prompts for a title and keywords. Once a new note is
created, it inserts the contents of the region therein. This is
useful to quickly elaborate on some snippet of text or capture it for
future reference.
It also provides the ~denote-region-after-new-note-functions~ abnormal
hook. Read the manual for more:
<https://protesilaos.com/emacs/denote#h:2f8090f1-50af-4965-9771-d5a91a0a87bd>.
** Comprehensive refinements to the ~denote-rename-buffer-mode~
:PROPERTIES:
:CUSTOM_ID: h:91b3ba9f-8b10-4f1c-a08b-70f5e7140923
:END:
This is an opt-in feature that automatically renames the buffer of
newly visited Denote files according to the user's preferences. Not to
be confused with renaming files: buffers are internal to Emacs. Enable
it at startup by adding this to your configuration file:
#+begin_src emacs-lisp
(denote-rename-buffer-mode 1)
#+end_src
Relevant entries in the manual:
- Automatically rename Denote buffers:
<https://protesilaos.com/emacs/denote#h:3ca4db16-8f26-4d7d-b748-bac48ae32d69>.
- The ~denote-rename-buffer-format~ option:
<https://protesilaos.com/emacs/denote#h:35507c18-35b1-41b9-9d80-52f54fcef3cb>.
*** The ~denote-rename-buffer-format~ option
:PROPERTIES:
:CUSTOM_ID: h:beeafe57-f110-4c11-87e7-10f682ca2386
:END:
The user option ~denote-rename-buffer-format~ controls how the
function ~denote-rename-buffer~ chooses the name of the
buffer-to-be-renamed. This function is the one used by the
~denote-rename-buffer-mode~.
Users may want, for example, to include some text that makes Denote
buffers stand out, such as a =[D]= prefix. Examples:
#+begin_src emacs-lisp
;; Use the title (default)
(setq denote-rename-buffer-format "%t")
;; Use the title and keywords with some emoji in between.
(setq denote-rename-buffer-format "%t 🤨 %k")
;; Use the title with a literal "[D]" before it
(setq denote-rename-buffer-format "[D] %t")
#+end_src
Users who need yet more flexibility are best served by writing their
own function and assigning it to the ~denote-rename-buffer-function~
(in such a case, please contact me as I am curious to know what the
underlying need is).
The manual or doc string of ~denote-rename-buffer-format~ cover the
technicalities of the available format specifiers.
Thanks to Jean-Philippe Gagné Guay for intermediately refining parts
of the code. This was done in pull request 177 on the GitHub mirror:
<https://github.com/protesilaos/denote/pull/177>.
Thanks to Vedang Manerikar for ensuring that the string of the buffer
is trimmed so that it never starts with an empty space (those buffers
count as "internal" to Emacs and are not shown to the user):
<https://lists.sr.ht/~protesilaos/denote/patches/46243>.
*** The ~denote-rename-buffer-mode~ also works with unsaved buffers
:PROPERTIES:
:CUSTOM_ID: h:e65bb546-af22-45fb-a918-d0e621b0e415
:END:
Internal refinements to a Denote Lisp macro make this minor mode also
work with new and unsaved Denote buffers. Whereas before only the
buffers of existing files would be renamed.
** Denote's renaming facilities are better than ever
:PROPERTIES:
:CUSTOM_ID: h:703b9021-f917-4b3f-9406-14992b2a4fe8
:END:
Denote's value proposition is its efficient file-naming scheme that
makes it easier to retrieve files even with rudimentary search tools.
We provide several commands to rename existing files according to this
scheme. The underlying file type does not matter (e.g. I use Denote to
name my video files).
Relevant sections in the manual:
- Renaming files:
<https://protesilaos.com/emacs/denote#h:532e8e2a-9b7d-41c0-8f4b-3c5cbb7d4dca>.
- Front matter:
<https://protesilaos.com/emacs/denote#h:13218826-56a5-482a-9b91-5b6de4f14261>.
*** Rename like an expert with ~denote-rename-no-confirm~
:PROPERTIES:
:CUSTOM_ID: h:8798dd8c-819d-4fda-9865-77d9734da28c
:END:
By default, the ~denote-rename-file~ command asks for a final
confirmation before carrying out its function. The new user option
~denote-rename-no-confirm~ can be bound to a non-nil value to skip
that step.
This only applies to ~denote-rename-file~. Other commands that rename
files in bulk never prompt for such confirmation (it would make them
cumbersome to use, plus it is assumed that the user who performs a
batch operation understands the implications).
*** The ~denote-rename-file~ command prompts for a signature
:PROPERTIES:
:CUSTOM_ID: h:e4e7e3d8-40e3-4f58-a19f-df34ccbfdbbd
:END:
This command used to only ask for a title and keywords. Now it allows
to use a signature as well. An empty input means that the signature is
ignored. AGAIN, please check with your minibuffer completion UI on how
to input an empty value, otherwise you will not get what you expect.
*** Rename mutliple files sequentially with ~denote-dired-rename-files~
:PROPERTIES:
:CUSTOM_ID: h:dcb623aa-fc4d-4d84-80e4-a540b6dbb144
:END:
This provides the same interface as ~denote-rename-file~, only it
works over a list of marked Dired files.
Internally, the prompts for title, keywords, and signature are
improved to display the underlying file that is affected by the
current operation. As the user renames files, the prompts reflect
which one is current.
*** The name of ~denote-dired-rename-marked-files~ has changed
:PROPERTIES:
:CUSTOM_ID: h:f9a16fc1-840d-400f-a5ae-a7791fac441f
:END:
It is now called ~denote-dired-rename-marked-files-with-keywords~ to
better communicate what it does. In short, this is a quick way to add
the given keywords to a list of files, converting them to the Denote
file-naming scheme in case they are not already using it. For the full
interactive power, use the aforementioned ~denote-dired-rename-files~.
*** The ~denote-rename-file-using-front-matter~ can be used without saving its buffer
:PROPERTIES:
:CUSTOM_ID: h:bfc194c2-5980-482a-aa1c-feb4ced992d1
:END:
This is now possible because of changes to underlying functions (a
Denote Lisp macro---not to bother you with technicalities).
Same principle for ~denote-rename-file-using-front-matter~.
*** The name of ~denote-change-file-type~ has changed
:PROPERTIES:
:CUSTOM_ID: h:3bf4b6c4-8399-4d5d-8df1-6495f5bfc579
:END:
It is now called ~denote-change-file-type-and-front-matter~ to avoid
confusion as to whether Denote converts files from one format to
another (there are specialised tools for that).
*** Renaming a file returns the new file path for programmatic use
:PROPERTIES:
:CUSTOM_ID: h:1d7bffd1-e422-420d-b453-9a36dd8508f7
:END:
Thanks to mentalisttraceur for requesting this feature in issue 183 on
the GitHub mirror: <https://github.com/protesilaos/denote/issues/183>.
** Link to a file with a signature
:PROPERTIES:
:CUSTOM_ID: h:b154ef64-c3b4-4e15-b533-c59d5b2ebf6b
:END:
The ~denote-link-with-signature~ command prompts for a file that has a
=SIGNATURE= component and links to it. The link's description includes
the text of the signature as well as the title.
Thanks to Mark Olson for mentioning this idea. It was done in issue
167 on the GitHub mirror: <https://github.com/protesilaos/denote/issues/167>.
I implemented it live, while also refactoring relevant parts of the
code to be more abstract/reusable:
<https://protesilaos.com/codelog/2023-09-25-emacs-live-mostly-denote/>.
Thanks to Alan Schmitt for spotting and fixing a regression caused by
the above:
<https://lists.sr.ht/~protesilaos/denote/%3Cm2cyy5rt68.fsf%40mac-03220211.irisa.fr%3E>.
** Renaming GPG or Age encrypted file works as expected
:PROPERTIES:
:CUSTOM_ID: h:9ceaf432-797c-46e5-aaf8-d7180ad66689
:END:
Emacs can seamlessly visit a =.gpg= or =.age= file. Denote has nothing
to do with encryption, though it takes care to recognise the
underlying file type and to perform its work accordingly. However,
prior versions of Denote contained a bug in how file extensions were
handled: it would keep the encryption extension but remove the file
type extension before it (so ".org.gpg" would wrongly become ".gpg").
Thanks to Jens Östlund for reporting a bug with ~denote-keywords-add~
on an encrypted file, which prompted me to investigate this further
and fix the issue holistically. This was done in issue 172 on the
GitHub mirror: <https://github.com/protesilaos/denote/issues/172>.
Interested parties are advised to check the two new public functions,
~denote-get-file-extension~ and ~denote-get-file-extension-sans-encryption~,
for the implementation details. In short, we had a problem with all
operations that needed to retrieve the file extension when that
included an encryption component.
** The optional ~denote-journal-extras~
:PROPERTIES:
:CUSTOM_ID: h:54723661-31f8-4cab-9be5-4cab19e44dc7
:END:
The manual of Denote has long provided code samples to achieve
particularised results. Among those were snippets to streamline the
use of Denote for journaling.
To make things even easier for users, we now have the
=denote-journal-extras.el=. It consolidates the rich corpus of
documented snippets into an easy-to-use and formally maintained
package. Thanks to Vedang Manerikar for providing the impetus for this
process. This was done on the mailing list:
<https://lists.sr.ht/~protesilaos/denote/patches/43255#%3C20230803170935.60833-2-ved.manerikar@gmail.com%3E>.
The new file is optional. It can be loaded thus:
#+begin_src emacs-lisp
(require 'denote-journal-extras)
#+end_src
The main idea is to quickly create journal entries. Check the manual
for the details, including the commands to use and the variables to
configure: <https://protesilaos.com/emacs/denote#h:4a6d92dd-19eb-4fcc-a7b5-05ce04da3a92>.
Thanks to Kostas Andreadis for working on a comment I had included in
a working state of the code about the inclusion of templates. Kostas
made it possible to use the Denote template prompt (per the
~denote-templates~ user option) as part of the creation of a new
journal entry. This was done in pull request 173 on the GitHub mirror:
<https://github.com/protesilaos/denote/pull/173>. The change is less
than 15 lines and thus Kostas does not need to assign copyright to the
Free Software Foundation.
Also thanks to TJ Stankus for reporting a case where
~denote-journal-extras-title-format~ did not accept a ~nil~ value (as
it should). This was done in issue 176 on the GitHub mirror:
<https://github.com/protesilaos/denote/issues/176>.
** The optional ~denote-silo-extras~
:PROPERTIES:
:CUSTOM_ID: h:618495d2-0c5b-48b4-af88-56f3d969697c
:END:
This is the same idea as with the =denote-journal-extras.el=: we had
the code in the manual and are now formally distributing it. Thanks
again to Vedang Manerikar for initiating this process. It was done on
the mailing list:
<https://lists.sr.ht/~protesilaos/denote/patches/43255>.
Use this optional feature with:
#+begin_src emacs-lisp
(require 'denote-silo-extras)
#+end_src
Consult the manual for the details:
<https://protesilaos.com/emacs/denote#h:e43baf95-f201-4fec-8620-c0eb5eaa1c85>.
** The infrastructure for unique identifiers is more robust
:PROPERTIES:
:CUSTOM_ID: h:1d538d7f-52e6-4653-b057-c62606752934
:END:
For Denote version =2.0.0= I introduced a general scheme intended to
avoid scenaria where duplicate identifiers could be created (thus
breaking a premise of Denote). Jean-Philippe Gagné Guay iterated over
the code to make it more robust and to fix some of the cases I had not
accounted for. This was done in pull request 159 on the GitHub mirror:
<https://github.com/protesilaos/denote/pull/159>. Same idea in pull
request 187: <https://github.com/protesilaos/denote/pull/187>.
** For developers or advanced users
:PROPERTIES:
:CUSTOM_ID: h:9031dc82-ab75-438c-a2c8-a1250ae48671
:END:
Denote has a clean code base with small and composable functions. This
encourages hackability. Each definition in the source is documented,
while the manual provides an overview of every public symbol.
- Added :: ~denote-get-file-extension~, ~denote-get-file-extension-sans-encryption~, ~denote-keywords-combine~, ~denote-retrieve-keywords-value-as-string~, ~denote-title-prompt-current-default~, ~denote-command-prompt~.
- Refactored :: ~denote-all-files~, ~denote-signature-prompt~, ~denote-file-prompt~, ~denote-title-prompt~, ~denote-rewrite-front-matter~.
Please read their documentation strings for the details. Or check the
manual: <https://protesilaos.com/emacs/denote#h:c916d8c5-540a-409f-b780-6ccbd90e088e>.
** Check out the ~denote-explore~ package by Peter Prevos
:PROPERTIES:
:CUSTOM_ID: h:759d0276-17e8-4461-9ee4-b4d07840dd7a
:END:
Peter posted this on the mailing list and I asked if it was okay to
mention it in the release notes of Denote. If you have a relevant
announcement to make, consider sending it to our mailing list.
#+begin_quote
Hi folks,
I have just updated the denote-explore package:
https://github.com/pprevos/denote-explore
It does three things:
1. Summary statistics: Count and visualise keywords and note types
2. Random walks: Generate new ideas using serendipity
3. Network visualisation: Visualise your Denote network of links
It contains a rudimentary network visualisation function, relying
on the R language. I will need some D3.js expertise to improve the
visualisation.
There should be a way to generate the basic network structure just
using Elisp and feeding a JSON to D3.js.
Regards
P:)
#+end_quote
** Miscellaneous
:PROPERTIES:
:CUSTOM_ID: h:01dc6bb0-53ac-43e1-b12e-484c99a6c2a7
:END:
- During this release cycle, I made lots of changes that in one way or
another related to the ~denote-file-prompt~. It was relying on a =project.el= mechanism that did not allow us to do everything we
needed. I have thus arranged for it to use the standard ~completing-read~ mechanism. There are subtle differences in
behaviour, though the core idea is the same. This change fixes a few
not-so-obvious bugs. Interested parties are advised to refer to the
message in commit =50d1bbdf1e8ffe0f449f2f5da02f9b70322fff7d=.
- All commands that use the ~denote~ function internally (i.e.
anything that creates a new note) call the ~denote-after-new-note-hook~ as part of their work. This hook is
mostly intended for advanced users who want to do something after a
new note is produced.
- The ~menu-bar-mode~ submenu of Denote is now positioned where it
should be after the "Tools". Thanks to Noboru Ota for the patch:
<https://lists.sr.ht/~protesilaos/denote/patches/44738>.
- The ~menu-bar-mode~ entry of Denote includes the new commands. This
is a nice way to discover more of what Denote can do.
- The commands ~denote-backlinks-prev~ and ~denote-backlinks-next~ are
only meant to be used inside the Denote backlinks buffer. As such,
they now produce an error when called elsewhere (I wish I could hide
them from =M-x= altogether).
- The ~denote-extract-keywords-from-front-matter~ always returns a
list, thus avoiding an erroneous case. Thanks to Vedang Manerikar
for fixing the bug: <https://lists.sr.ht/~protesilaos/denote/patches/46420>.
- The =T= in the Denote identifier component now has its own face: ~denote-faces-time-delimiter~. This is used by the backlinks buffer
and the ~denote-dired-mode~. The idea is to introduce a subtle
distinction between the date and time constituents of the
identifier. Those who want the =T= to be the same colour as the rest
of the identifier, can make the ~denote-faces-time-delimiter~
inherit the ~denote-faces-date~. For example:
#+begin_src emacs-lisp
(set-face-attribute 'denote-faces-time-delimiter nil :inherit 'denote-faces-date)
#+end_src
Thanks to Jean-Charles Bagneris for sending this patch:
<https://lists.sr.ht/~protesilaos/denote/patches/43072>.
- Fixed a ~nil~ file expansion in the function ~denote--extract-title-from-file-history~. Thanks to ezchi for
bringing this matter to my attention. It was done in issue 166 on
the GitHub mirror:
<https://github.com/protesilaos/denote/issues/166>.
- A link can be created from inside an ~org-capture~ buffer. This
means that we can call ~denote-link~ (and related) while capturing a
new note with ~org-capture~. Thanks to Peter Smith for reporting the
bug in issue 186 on the GitHub mirror:
<https://github.com/protesilaos/denote/issues/186>.
- We stopped using ~vc-rename-file~ to rename files. The reason is
that it requires the buffer to be saved, but we do not want that
after modifying the front matter because we want to give the user a
chance to confirm what happened. Thanks to Frédéric Willem for
reporting the problem in issue 185 on the GitHub mirror:
<https://github.com/protesilaos/denote/issues/185>.
- Thanks to Ivan Sokolov for removing a double negative logic in a
snippet. This was done in pull request 162 on the GitHub mirror:
<https://github.com/protesilaos/denote/pull/162>.
** Git commits
:PROPERTIES:
:CUSTOM_ID: h:d8f30943-70dd-45fe-8cf1-4c3918152aeb
:END:
Just an overview of what we did. Every contribution matters.
#+begin_src
~/Git/Projects/denote $ git shortlog 2.0.0..2.1.0 --summary --numbered
153 Protesilaos
15 Jean-Philippe Gagné Guay
5 Vedang Manerikar
1 Alan Schmitt
1 Ivan Sokolov
1 Jean-Charles Bagneris
1 Kostas Andreadis
1 Noboru Ota
1 Peter Prevos
#+end_src
* Version 2.0.0 on 2023-07-21
:PROPERTIES:
:CUSTOM_ID: h:3f17bf03-4c47-4410-abf8-1db4a0ac7775
:END:
This is the second major version of Denote, close to one year after
its initial release. The video demo I did back then remains relevant,
even though lots of details have changed.
** Notes have a new optional SIGNATURE field
:PROPERTIES:
:CUSTOM_ID: h:a3a9e14d-4132-47c0-a23c-cb008a141668
:END:
It is now possible to create notes that include a =SIGNATURE= field in
their file name. Either use the convenience command ~denote-signature~
or configure the user option ~denote-prompts~ to affect what the ~denote~
command should prompt for.
Signatures are arbitrary strings of characters that enable the user to
further qualify their documents. One possible workflow is to write
relational notes, such that =1a1= is the first extension of another
note with a =1a= signature.
The design of the =SIGNATURE= field is consistent with the Denote
file-naming scheme. The field separator is the double equals sign
(~==~), while words that comprise the signature are joined together by
a single equals sign. As such, the user can prefix a search with an
equals sign to match words in the =SIGNATURE=, just as they would use
dashes for the =TITLE= and underscores for the =KEYWORDS=.
[ Read the manual for the technicalities of the Denote file-naming
scheme. This is not limited to "notes": any file can be named
accordingly (I do it with my videos, for example). ]
Signatures are not included in a file's front matter. This is a
strategic decision to preserve backward compatibility, while not
introducing a feature that has not enjoyed widespread usage. I want
to make signatures behave the same as the rest of the file name
fields, though I am interested to learn how users employ them in their
workflow.
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.
Also thanks to Alfredo Borrás and Jeremy Friesen for discussing with
me the field delimiter of signatures on the mailing list:
<https://lists.sr.ht/~protesilaos/denote/%3C2A597B4E-5F18-4D97-9457-B3C859DAA020%40zoho.eu%3E>.
Thanks to Kai von Fintel for doing the same on the GitHub mirror in
issue 147: <https://github.com/protesilaos/denote/issues/147>.
Read the original announcement:
<https://protesilaos.com/codelog/2023-03-20-emacs-denote-signature-feature/>.
As part of the development, I fixed a case where
~denote-rename-file-using-front-matter~ would fail if it could not
find a signature
The idea is that we want the command to behave the way it always did
when the file has no signature and to preserve the signature when it
is present.
Thanks to relict for reporting the issue on the mailing list:
<https://lists.sr.ht/~protesilaos/denote/%3C87zg86lru9.fsf%40kotlak.com%3E>.
** The rename commands avoid creating duplicate identifiers
:PROPERTIES:
:CUSTOM_ID: h:d24645a3-ad02-450c-b3d7-af7802aa0b26
:END:
Denote provides commands to rename an existing file to one that
follows the Denote file-naming scheme (videos, PDFs, other text
documents, ...). Check, for example, the ~denote-rename-file~ and
~denote-dired-rename-marked-files~. The idea is to make everything
easier to search.
In prior versions, these commands could produce duplicate identifiers
if the modification date of the underlying files was the same. Such a
scenario occurs when the files are modified programmatically, as with
the =touch= command or the various =git= operations.
Denote will now take care to increment the identifier until it becomes
unique within the current scope.
Thanks to Felipe Balbi for reporting this bug in issue 105 on the
GitHub mirror: <https://github.com/protesilaos/denote/issues/105>.
Thanks to Vedang Manerikar and Jean-Charles Bagneris for commenting on
this feature on the mailing list:
<https://lists.sr.ht/~protesilaos/denote/%3C87v8emeus0.fsf%40protesilaos.com%3E>.
Thanks to Ashton Wiersdorf for noticing a mistake I made that caused a
regression in ~denote-rename-file~:
<https://lists.sr.ht/~protesilaos/denote/%3Cm2lefbbzl1.fsf%40wiersdorfmail.net%3E>.
*** Optional arguments affect ~denote-dired-rename-marked-files~
:PROPERTIES:
:CUSTOM_ID: h:6ea998be-83dd-4c67-945c-11011372818f
:END:
The ~denote-dired-rename-marked-files~ now accepts two optional
arguments. When called interactively, these are interpreted as a
single or double universal prefix argument (=C-u= by default, though
do =M-x where-is= and search for ~universal-argument~).
The first argument, named =SKIP-FRONT-MATTER-PROMPT=, skips the "yes
or no" prompt requested at the outset of the operation, passing to it
an affirmative response. Thanks to Jay Rajput for asking the question
that inspired me to implement this. It was done in issue 155 on the
GitHub mirror: <https://github.com/protesilaos/denote/issues/155>.
The second argument, named =NO-UNIQUE-ID-CHECK=, will not perform any
checks for potential duplicate identifiers. The default is to check
for duplicates and increment them such that they become unique. The
reason this optional argument exists is for those who want to speed up
the process, perhaps because they know ahead of time all identifiers
will be unique or do not care about them.
Thanks to Bruno Boal for refining how the prefix argument is
processed. The patch was sent via a private channel. The change is
small and thus does not require copyright assignment to the Free
Software Foundation.
** Menu entries help users discover Denote
:PROPERTIES:
:CUSTOM_ID: h:651e5561-f9ce-41f6-bad3-d54ce2dcff04
:END:
Users of ~menu-bar-mode~ and/or ~context-menu-mode~ will now find a
submenu with points of entry to Denote. Refer to the publication I
made on my website, as it includes a picture:
<https://protesilaos.com/codelog/2023-03-31-emacs-denote-menu/>. I
will save the thousand words for the following sections. 🙃
There is a known issue where the ~menu-bar-mode~ entry is positioned
before the =File= submenu. Apparently, there exists an inelegant way
to place the menu elsewhere, but I am not willing to maintain hacks
for missing functionality. If someone knows a clear way to put the
submenu elsewhere, please contact me: I want it to be after =Tools=.
Thanks to Kai von Fintel and Noboru Ota (nobiot) for discussing the
placement of the submenu:
<https://lists.sr.ht/~protesilaos/denote/%3C2B60992C-0FC9-42CC-B669-69A544450FEF%40mit.edu%3E>.
** "Link" commands have simpler names
:PROPERTIES:
:CUSTOM_ID: h:acf95a79-3c45-423d-a88f-d6eed7fa5387
:END:
Originally, Denote was organised as a collection of several files,
each of which had its own prefix like =denote-dired.el=, and
=denote-link.el=. This arrangement was deemed surplus to requirements
and all core code was consolidated in =denote.el=. An artefact of
that design was the presence of symbols that retained their admittedly
awkward names, like the command ~denote-link-backlinks~ or
~denote-link-add-missing-links~.
All such commands are deprecated. They are replaced with more
discoverable names. The deprecation is done in such a way that the
old names are aliases for the new ones, but the user is warned not to
rely on them.
The new names in detail:
| Old name 🤨 | New name 🤩 |
|-------------------------------------+---------------------------------------------------------------|
| ~denote-link-add-links~ | ~denote-add-links~ |
| ~denote-link-add-missing-links~ | ~denote-add-missing-links~ |
| ~denote-link-backlinks~ | ~denote-backlinks~ |
| ~denote-link-find-file~ | ~denote-find-link~ |
| ~denote-link-insert-link~ | ~denote-insert-link~ (alias for ~denote-link~) |
| ~denote-link-show-backlinks-buffer~ | ~denote-show-backlinks-buffer~ (alias for ~denote-backlinks~) |
** Denote buffers can have shorter names
:PROPERTIES:
:CUSTOM_ID: h:98f6b10a-ea29-49d1-8d3f-e2f0409f4c8f
:END:
The Denote file-naming scheme is designed to be a low-tech way of
embedding information in files, making them easier to find. A
downside is that the names are longer than =blah.txt= and so the
default Emacs behaviour is to derive a buffer name from the file name.
The new optional =denote-rename-buffer.el= provides a minor mode to
automatically rename the buffer of an existing file, such that it
reflects the file's =TITLE= field. Users must enable
~denote-rename-buffer-mode~.
The renaming procedure is controlled by the user option
~denote-rename-buffer-function~. By default, it provides the means to
rename using (i) the title, (ii) the identifier, or (iii) a custom
function that returns a string. Experienced users can refer to
~denote-rename-buffer-with-title~ to draw inspiration on the design of
such a function.
Thanks to Morgan Davidson for asking a question that inspired me to
implement this feature. The discussion took place in issue 151 on the
GitHub mirror <https://github.com/protesilaos/denote/issues/151>.
** Silos work as directory trees
:PROPERTIES:
:CUSTOM_ID: h:113820c4-7a6f-4126-9a44-92bfa59744e2
:END:
Denote provides a feature to isolate files in to their own silos, each
of which functions as its own ~denote-directory~ variable. The
technicalities are explained in the manual. Silos have proven to be a
valuable aspect of file management and I have thus expanded their
scope to work as fully fledged directory trees. This means that we no
longer assume a silo to be a flat directory listing, but instead
recognise any subdirectories inside of it.
Thanks to relict007, Hilde Rhyne, Mirko Hernández, Noboru Ota
(nobiot), Alan Schmitt, hapst3r, and Hilde Rhyne for their
participation in the relevant discussions:
- <https://lists.sr.ht/~protesilaos/denote/%3C87fsb72nge.fsf%40protesilaos.com%3E>
- <https://lists.sr.ht/~protesilaos/denote/%3C80CBB671-D812-4EA8-8C80-85F9F4144051%40disroot.org%3E>
- <https://lists.sr.ht/~protesilaos/denote/%3C87pma6t59i.fsf%40kotlak.com%3E>
- <https://github.com/protesilaos/denote/issues/129> (GitHub mirror)
- <https://lists.sr.ht/~protesilaos/denote/%3CB124A5AF-9968-4F7E-9F4B-2BC763E0BFCF@disroot.org%3E#%3Cm0sff0nnhb.fsf@disroot.org%3E>.
** Keywords do not accept multiple words by default
:PROPERTIES:
:CUSTOM_ID: h:08f23806-9570-4031-86e4-810b3e93be81
:END:
The idea is to have short keywords and then use more than one, if
necessary. We do not want to encourage the habit of long keywords
that become overly specific, while we want to avoid the use of
dashes as delimited in the file name's =KEYWORDS= field.
Technically, this changes the default value of the user option
~denote-allow-multi-word-keywords~. Users who preferred the old
behaviour can simply toggle it on.
** Pass arguments to Org capture
:PROPERTIES:
:CUSTOM_ID: h:58ff6dd3-693a-4437-9217-8e876d92c975
:END:
Denote is not an extension of Org mode, though it can integrate with
~org-capture~. I now make it possible to design a capture template
that uses specific prompts. Consult the section in the manual titled
"Create note with specific prompts using Org capture".
Thanks to Aditya Yadav for asking about this in issue 132 on the
GitHub mirror: <https://github.com/protesilaos/denote/issues/132>.
** Change an existing note's file type
:PROPERTIES:
:CUSTOM_ID: h:e1e874e3-d8ad-4685-aa62-59ad07078db2
:END:
The command ~denote-change-file-type~ changes the file type of an
existing note. The available options are those among
~denote-file-type~. Thanks to Jean-Philippe Gagné Guay for the
contribution, which was done in pull request 137 on the GitHub mirror:
<https://github.com/protesilaos/denote/pull/137>.
** Denote dynamic blocks can now parse ~rx~ notation
:PROPERTIES:
:CUSTOM_ID: h:fe595ee7-8ba6-4ca3-aa66-35aa4e5ca0f5
:END:
Denote can leverage the Org feature of "dynamic blocks" to produce
lists of links/backlinks. This is especially useful for metanotes
(read the Denote manual---I document everything for a reason).
Before, regular expressions were implemented only as strings while now
they can also be written using the ~rx~ notation. Thanks to Mirko
Hernandez for proposing this feature and discussing it with me in
issue 122 on the GitHub mirror:
<https://github.com/protesilaos/denote/issues/122>.
Thanks to Elias Storms, the author of =denote-org-dblock.el=, for
iterating on this functionality. This was done in pull request 130 on
the GitHub mirror: <https://github.com/protesilaos/denote/pull/130>.
** Made links to non-note files works as intended
:PROPERTIES:
:CUSTOM_ID: h:431a8952-0d71-4ba6-b6ae-85e5f7d520b9
:END:
The function ~denote-get-path-by-id~ is refactored to accept any file
with an identifier. This always was its intended purpose. The user
was always able to create =denote:= Org link types to, for example,
=jpg= files but ~denote-get-path-by-id~ was refusing to resolve the
otherwise valid path. Thanks to user relict007 for reporting the
problem and discussing it with me in issue 135 on the GitHub mirror:
<https://github.com/protesilaos/denote/issues/135>.
The change was not trivial. It was followed up by a patch from Noboru
Ota (nobiot) which elaborated on the conditionality. Quoting from
commit =9ce9a24=:
#+begin_quote
fix(denote-get-path-by-id): #135
Reference: https://github.com/protesilaos/denote/issues/135
This patch change function 'denote-get-path-by-id' to allow for the following:
- A single ID points to multiple files with different extensions
- Denote needs to find a single file out of the multiple files
- This is not necessarily a user error (export an Org file to an HTML)
- Denote should let user decide their "primary" file extension
The case the patch is intended to fix goes something like this:
- You have 20230216__mynotes--tag.org.
- You export it to 20230216__mynotes--tag.html.
- Both files are in denote-directory
- This means you have two files with the same ID with different
extensions denote-link-find-file, denote-link-find-backlink, and xref
integration might find the html file INSTEAD OF the .org file
This is because html is earlier in the alphabetical order than
org. Because the function uses seq-find, it will find the .html file
first and returns it.
#+end_quote
** The ~denote-rename-file-using-front-matter~ works with empty keywords
:PROPERTIES:
:CUSTOM_ID: h:b00f228d-7f84-4d84-8d5f-ac90ea6b1065
:END:
Keywords are an optional field in the Denote file-naming scheme.
However, an earlier version of the command mentioned in this heading
was considering them mandatory and would refuse to proceed if the
keywords were nil. Thanks to Eduardo Grajeda for fixing this:
<https://lists.sr.ht/~protesilaos/denote/patches/39896>.
The change is within the ~15 line limit and does not require copyright
assignment to the Free Software Foundation.
** The ~denote-title-prompt~ has its own history
:PROPERTIES:
:CUSTOM_ID: h:91f370f4-9fd1-461b-8ba4-fd9ba2d9c7a8
:END:
Denote implements minibuffer histories for all its relevant functions.
This makes it easier for users to retrieve their previous inputs and
to not get irrelevant ones.
Before, the ~denote-title-prompt~ was not using its own history but
was instead relying on another one that was intended only for file
paths, thus mixing unrelated inputs.
Thanks to Jonathan Sahar for bringing this matter to my attention.
This was done in issue 144 on the GitHub mirror:
<https://github.com/protesilaos/denote/issues/144>.
** For developers or advanced users
:PROPERTIES:
:CUSTOM_ID: h:dcc52671-2127-47e0-9167-003f40ca3a54
:END:
*** Made it possible to add predicates for recursive file listing
:PROPERTIES:
:CUSTOM_ID: h:62546ec1-6ec8-41c7-9a18-10a531b534ce
:END:
The helper function ~denote--directory-all-files-recursively~ accepts
predicates to help speed up its work.
Thanks to Wade Mealing for reporting the issue about the performance
of the built-in function ~directory-files-recursively~ in large,
nested directories. And thanks to Graham Marlow for the patch, which
was prepared as part of an extended discussion with me:
- <https://lists.sr.ht/~protesilaos/denote/patches/40370>
- <https://lists.sr.ht/~protesilaos/denote/%3C20230414000311.1981-1-graham%40mgmarlow.com%3E#%3C76ed9fe2-d597-f7b9-5e59-717aeb77c3c3@mgmarlow.com%3E>
- <https://lists.sr.ht/~protesilaos/denote/patches/40384>
- <https://lists.sr.ht/~protesilaos/denote/%3C87edonhvy0.fsf%40protesilaos.com%3E>
- <https://lists.sr.ht/~protesilaos/denote/%3C76ed9fe2-d597-f7b9-5e59-717aeb77c3c3%40mgmarlow.com%3E>
- <https://lists.sr.ht/~protesilaos/denote/%3C87zg75q4er.fsf%40protesilaos.com%3E>
- <https://lists.sr.ht/~protesilaos/denote/%3CCAO4UgPQtxhhqW0tB7eZnVh4nF9vLvnVGx+5oB_78_dg32URSLA%40mail.gmail.com%3E>
*** New public symbols
:PROPERTIES:
:CUSTOM_ID: h:ed723274-a78e-4cfd-9655-c3bfe0fb1e68
:END:
The following are now public symbols that we commit to support and
document henceforth:
+ Function ~denote-file-type-extensions~ :: Return all file type
extensions in ~denote-file-types~.
+ Variable ~denote-encryption-file-extensions~ :: List of strings
specifying file extensions for encryption.
+ Function ~denote-file-type-extensions-with-encryption~ :: Derive
~denote-file-type-extensions~ plus ~denote-encryption-file-extensions~.
+ Function ~denote-link-return-links~ :: Return list of links in
current or optional =FILE=. Also see ~denote-link-return-backlinks~.
+ Function ~denote-link-return-backlinks~ :: Return list of links in
current or optional =FILE=. Also see ~denote-link-return-links~.
+ Function ~denote-rewrite-front-matter~ :: Rewrite front matter of
note after ~denote-rename-file~ (or related) The =FILE=, =TITLE=, =KEYWORDS=, and =FILE-TYPE= arguments are given by the renaming
command and are used to construct new front matter values if
appropriate.
+ Function ~denote-rewrite-keywords~ :: Rewrite =KEYWORDS= in =FILE=
outright according to =FILE-TYPE=. Do the same as
~denote-rewrite-front-matter~ for keywords, but do not ask for
confirmation. This is for use in ~denote-keywords-add~,
~denote-keywords-remove~, ~denote-dired-rename-marked-files~, or
related.
I am publicising the ~denote-link-return-links~ and its counterpart in
response to the mailing list thread started by relict007:
<https://lists.sr.ht/~protesilaos/denote/%3C87a5ygk6yi.fsf@kotlak.com%3E>.
relict007 is the developer of the ~denote-cache~ package (in
progress): <https://git.sr.ht/~relict007/denote-cache>.
Similarly, the ~denote-rewrite-keywords~ is made public upon the
request of Alan Schmitt:
<https://lists.sr.ht/~protesilaos/denote/%3Cm2ttzgn2wu.fsf%40m4x.org%3E>.
** Miscellaneous
:PROPERTIES:
:CUSTOM_ID: h:918087e6-8cd5-4d4f-a11a-b465dcbd9fe3
:END:
- Revised ~denote-link-return-{links,backlinks}~ to not produce a
~user-error~. The errors are reserved for the interactive
functions. The others are for developers. Thanks to Elias Storms for
bringing this matter to my attention:
<https://github.com/protesilaos/denote/commit/694c1517be73949edbc3993c105c764da8e2571f#commitcomment-112677876>.
- Refrained from trying to find forward links in non-text-files. If a
file extension is not in ~denote-file-types~, we have no way of
parsing or finding outgoing links in it. This change checks for the
file extension early on in 'when-let*' block and avoids opening the
file which is a relatively costly operation (and would fail finding
links anyway). Thanks to relict007 for the patch. This was done on
the mailing list:
<https://lists.sr.ht/~protesilaos/denote/%3C87r0riffdx.fsf%40kotlak.com%3E>
The change is small and thus does not require copyright assignment
to the Free Software Foundation.
- Explained how to troubleshoot Denote. Refer to the section in the
manual titled "Troubleshoot Denote in a pristine environment."
While this is about Denote, the skills apply to all Emacs packages.
- Ensured backlinks get correct ~denote-directory~ path. The
backlinks buffer will now get the correct path when it is generated
inside a silo. This is related to issue 129 reported by hapst3r on
the GitHub mirror: <https://github.com/protesilaos/denote/issues/129>.
The change is necessary because =.dir-locals.el= do not work for
buffers, so we must get the value from the file that calls
~denote-link-backlinks~.
- Added missing underscore from examples in exporting section. Thanks
to Peter Prevos for bringing this matter to my attention:
<https://lists.sr.ht/~protesilaos/denote/%3C87fs8b85tq.fsf%40prevos.net%3E#%3C87lehiuxfo.fsf@protesilaos.com%3E>.
- Made the command ~denote-open-or-create~ work with an empty
~denote-directory~. The ~denote-file-prompt~ would throw an error
before. The correct behaviour is to proceed to the "Create" phase
if the ~denote-directory~ is empty. Thanks to user drcxd for
reporting the bug in issue 131 on the GitHub mirror and for testing
my sample code: <https://github.com/protesilaos/denote/issues/131>.
- Documented how to use tree-based file prompt on demand. This is my
solution to a request made by Mirko Hernandez on the possible use of
the old Denote file prompt. It is better not to introduce a user
option for this case, nor to keep multiple variants of the
~denote-file-prompt~ in denote.el, as we want to keep things simple.
Mirko's feedback was provided in issue 121 on the GitHub mirror:
<https://github.com/protesilaos/denote/issues/121>.
- Added the variable ~denote-user-enforced-denote-directory~. This is
intended for users who write custom code to extend Denote. The
value of this variable should be ~let~ bound around calls to the
function ~denote-directory~, thus overriding its return value. This
was discussed on the mailing list and then introduced by Vedang
Manerikar in commit =977c757=, with further changes by me in
=20ddc97=: <https://lists.sr.ht/~protesilaos/denote/patches/41776>.
Vedang has assigned copyright to the Free Software Foundation.
- Fixed ~my-denote-org-extract-subtree~ section of the documentation.
This is part of some sample code that is not part of =denote.el=,
but we provide as a convenience/inspiration for interested parties.
The provided function did not work correctly.
1. Tags are extracted before deleting the region from the source file.
2. The function ~org-end-of-subtree~ is called to calculate the
point we should delete up to. The previously used function
~org-entry-end-position~ ends at the first sub-heading under the
tree, which is not what we want. Instead, we want to cut the
whole subtree.
3. The date information available in the subtree is retained. We
look for three common places for this information: the =CREATED=
or =DATE= properties in the =PROPERTIES= drawer, and the =CLOSED=
cookie at the element level itself.
Thanks to Vedang Manerikar for the contribution:
<https://lists.sr.ht/~protesilaos/denote/%3CCABzEscbPx24LCUCc7JsMmQtVGwhou5fUH_5h+%3Dt%3Dqi4396NqNQ%40mail.gmail.com%3E>
- Removed the dependency on the built-in ~xdg~ library and updated the
default value of the user option ~denote-directory~. The reason is
that XDG is a Linux standard that does not work on other operating
systems, according to private feedback I received.
- Fixed a regression for =M-p= (~previous-history-element~) in "do or
create" commands. Read the doc string of the commands ~denote-open-or-create~ or ~denote-link-or-create~ for how this is
supposed to work. In short:
- Invoke the "do or create" command.
- Type something that does not match a file.
- In the following title prompt, hit =M-p= to bring back the last input.
I realised there was a regression when I read issue 152 on the
GitHub mirror, which was created by user "ustcpxy":
<https://github.com/protesilaos/denote/issues/152>. The issue is
about skipping the file title prompt.
- Simplified the internal ~denote--buffer-file-names~. Thanks to Adam
Růžička for noting that my change was not compatible with older
Emacs versions, and for preparing the change. This was discussed in
pull request 158 on the GitHub mirror, with my suggestion to not use ~seq-filter~ as it affected the return value:
<https://github.com/protesilaos/denote/pull/158>. The change is
below the 15 line limit, meaning that Adam does have to assign
copyright to the Free Software Foundation.
- Documented custom code in the manual on how to interactively select
a silo. I am providing this in response to a request from GitHub
user rbenit68. The discussion took place in issue 127 on the GitHub
mirror, with the participation of Mirko Hernandez:
<https://github.com/protesilaos/denote/issues/127>. The custom code
I provide is the expanded version of an idea put forth by Mirko, to
whom I am thankful.
- Fixed an outdated reference in the ~denote-file-types~ doc string.
Thanks to user doolio for spotting the error and reporting it in
issue 139 on the GitHub mirror:
<https://github.com/protesilaos/denote/issues/139>.
- Cited in the manual's section "Publications about Denote" an article
by Mohamed Suliman titled /Managing a bibliography of BiBTeX entries
with Denote/ (2022-12-20):
<https://www.scss.tcd.ie/~sulimanm/posts/denote-bibliography.html>.
If you have published something related to Denote, please let me
know and I will add to the list.
- Cited the essay by Summer Emacs titled /An explanation of how I use
Emacs/ (2023-05-04):
<https://github.com/summeremacs/howiuseemacs/blob/main/full-explanation-of-how-i-use-emacs.org>
- Cited the video series by Stefan Thesing titled /Denote as a
Zettelkasten/: <https://www.thesing-online.de/blog/denote-as-a-zettelkasten/>.
- Added link to Karl Voit's work in the manual's section "Alternative
implementations and further reading." Thanks to Norwid Behrnd for
the contribution in pull request 123 on the GitHub mirror:
<https://github.com/protesilaos/denote/pull/123>.
- Fixed the broken link to jao's blog. Thanks to Tomasz Hołubowicz
for the contribution, which was done in pull request 145 on the
GitHub mirror: <https://github.com/protesilaos/denote/pull/145>.
- Authored lots of other ancillary changes/features to the code base
or the manual (yes, this change log is how I "cut the long story
short").
* Version 1.2.0 on 2022-12-12
:PROPERTIES:
:CUSTOM_ID: h:92478a05-4a69-413c-8d95-1dacbcf6af2c
:END:
** Denote now requires Emacs version 28.1 or higher
:PROPERTIES:
:CUSTOM_ID: h:bc0e173a-3b9f-427c-9fb0-d435a5ef127e
:END:
With the help of Noboru Ota (nobiot), we realised that Denote was
broken on Emacs 27 for quite a while. The fact that we received no
feedback about it suggests that this change is the best course of
action going forward. Discussion:
<https://lists.sr.ht/~protesilaos/denote/%3C86r0yvzm12.fsf%40nobiot.com%3E#%3C86sfja78ik.fsf@nobiot.com%3E>
Emacs 27 lacks certain Xref facilities that we need for the
backlinking facility. It was holding us back for no good reason,
while also adding to the maintenance burden.
If you are using Denote on Emacs 27 and things are working for you,
there is no need to update the package. Do it when you also upgrade
Emacs to a newer version.
** Display context in backlinks' buffer
:PROPERTIES:
:CUSTOM_ID: h:dafbdbae-36f1-487a-94c8-2762568a766e
:END:
By default, the generic backlinks' buffer, which can be displayed with
the command ~denote-link-backlinks~ (alias ~denote-link-show-backlinks-buffer~),
only shows the file names of the linked notes.
We have made it possible to produce a more informative view by showing
the context of the link and also listing all links per file. This is
done by setting the user option ~denote-backlinks-show-context~ to a
non-nil value.
To illustrate the difference, this is the default backlinks' buffer:
#+begin_example
Backlinks to "On being honest" (20220614T130812)
------------------------------------------------
20220614T145606--let-this-glance-become-a-stare__journal.txt
20220616T182958--feeling-butterflies-in-your-stomach__journal.txt
#+end_example
And this is the one with ~denote-backlinks-show-context~ enabled:
#+begin_example
Backlinks to "On being honest" (20220614T130812)
------------------------------------------------
20220614T145606--let-this-glance-become-a-stare__journal.txt
37: growing into it: [[denote:20220614T130812][On being honest]].
64: As I said in [[denote:20220614T130812][On being honest]] I have never
20220616T182958--feeling-butterflies-in-your-stomach__journal.txt
62: indifference. In [[denote:20220614T130812][On being honest]] I alluded
#+end_example
Granted, here we show plain text though in Emacs the results have the
appropriate colours of the active theme and are easier to read.
Thanks to Noboru Ota (nobiot) for implementing this feature. We
discussed it at length on the mailing list:
<https://lists.sr.ht/~protesilaos/denote/%3C86r0yvzm12.fsf%40nobiot.com%3E>.
Noboru has assigned copyright to the Free Software Foundation.
** Dynamic Org blocks for lists of Denote links
:PROPERTIES:
:CUSTOM_ID: h:f7904a57-22c0-446f-b7e3-7a736332002c
:END:
Denote now includes the ~denote-org-dblock~ library. Activate it
thus:
#+begin_src emacs-lisp
;; Register Denote's Org dynamic blocks
(require 'denote-org-dblock)
#+end_src
A dynamic block gets its contents by evaluating a given function,
depending on the type of block. The type of block and its parameters
are stated in the opening =#+BEGIN= line of the block. Typing =C-c
C-c= with point on that line runs the function, with the given
arguments, and populates the block's contents accordingly.
What Denote has is ways to write blocks that produce a list of links
matching a given regular expression while conforming with some other
parameters. The manual explains how to use this powerful feature
(which is necessarily specific to the Org file type):
<https://protesilaos.com/emacs/denote#h:8b542c50-dcc9-4bca-8037-a36599b22779>.
Thanks to Elias Storms for authoring ~denote-org-dblock~ and for
discussing this issue at length with me on the mailing list:
<https://lists.sr.ht/~protesilaos/denote/%3Cm2sfisexx7.fsf%40MBA21.fritz.box%3E>.
Elias has assigned copyright to the Free Software Foundation.
** Integration with the built-in project.el and xref.el libraries
:PROPERTIES:
:CUSTOM_ID: h:e8a7d08c-cdf0-4207-92c1-391415b8371f
:END:
Denote was already using Xref internally but has now gained more
capabilities which help it find files more effectively. With the help
of Emacs' standard project library, all file-related prompts (e.g. to
add a link) search all items in the ~denote-directory~ regardless of
whether the user is in a subdirectory or not.
All Denote commands benefit from this refactoring. One such request
to "Make ~denote-open-or-create~ work better across subfolders" was
made in issue 114 on the GitHub mirror:
<https://github.com/protesilaos/denote/issues/114>.
Thanks to Noboru Ota (nobiot) for introducing this feature together
with a new system of "modules" for incorporating additional built-in
functionality:
- <https://lists.sr.ht/~protesilaos/denote/%3C86a64ooxyi.fsf%40nobiot.com%3E>
- <https://lists.sr.ht/~protesilaos/denote/%3C86k03f4iq6.fsf%40nobiot.com%3E>
I will not document the new user option ~denote-modules~ right now as
my ongoing job search prevented me from exploring the full potential
of this feature. I promise to do it for the next version of Denote
and update the manual accordingly. Nevertheless, the doc string of
~denote-modules~ already provides all one needs to get started.
** Re-use last input in "do or create" commands
:PROPERTIES:
:CUSTOM_ID: h:5a003d44-7ad0-4c92-b908-ec7cf016b2dd
:END:
The commands ~denote-open-or-create~, ~denote-link-or-create~ first
prompt for an existing note. If they find it, they act on it,
otherwise they prompt for the creation of a new note to operate on.
At the first prompt, it is common to use regular expressions and
out-of-order pattern matching (such as with the ~orderless~ package),
so the input can be something like =_test ^2022 some title=, which we
obviously don't want to automatically reuse as the new note's actual
title.
To this end, and to accommodate all workflows, we leverage Emacs'
minibuffer history to make the last input accessible with =M-p= at the
minibuffer prompt (=M-x previous-history-element=). The text is
available for further editing before it is submitted as the new note's
title. Simple, effective, and flexible!
Thanks to Guo Yong for starting the discussion that led me to this
improvement:
<https://lists.sr.ht/~protesilaos/denote/%3CNF6pFBq--3-9%40tutanota.com%3E>.
** Add support for any file type
:PROPERTIES:
:CUSTOM_ID: h:e73a4e76-6c00-4691-8893-8f885c26f306
:END:
Denote provides the user option ~denote-file-type~ which specifies the
file type to use for new notes. Options include Org mode (the
default), Markdown+YAML, Markdown+TOML, and plain text. Furthermore,
there exists the convenience command ~denote-type~ (alias
~denote-create-note-using-type~) which prompts for a file type to use
when creating a new note (I normally write in plain text, but
sometimes switch to Org or Markdown).
The variable ~denote-file-types~ (which is NOT a user option)
specifies all the parameters of what a "file type" means, such as how
to format its front matter, what style of date+time to use, which file
type extension to write, how to rename the file, what style of link to
apply, and so on. Advanced users can now edit this variable to either
register new file types or redefine the behaviour of existing ones.
Read this comprehensive guide on how to do it:
<https://protesilaos.com/codelog/2022-10-30-demo-denote-custom-file-type/>.
I repeat: this is for advanced users or, anyhow, for those who are
prepared to maintain some custom code in their setup. The guide is
accessible though and I am always willing to help anyone in need of
assistance.
A relevant request for such a feature can be found in issue 86 on the
GitHub mirror: <https://github.com/protesilaos/denote/issues/86>.
The ~denote-file-types~ were introduced by Jean-Philippe Gagné Guay in
pull request 89 at the GitHub mirror and were part of Denote version
0.6.0: <https://github.com/protesilaos/denote/pull/89>. I have made
lots of changes since then to make all parts of Denote work with it
and to parameterise its various facets.
** Exclude certain directories from all operations
:PROPERTIES:
:CUSTOM_ID: h:04f42aab-d8fe-4c4a-b865-3bb0655e2631
:END:
The user option ~denote-excluded-directories-regexp~ instructs all
Denote functions that read or check file/directory names to omit
directories that match the given regular expression. The regexp needs
to match only the name of the directory, not its full path.
Affected operations include file prompts and functions that return the
available files in the ~denote-directory~. File prompts are used by
several commands, such as ~denote-link~ and ~denote-subdirectory~.
Functions that check for files include ~denote-directory-files~ and
~denote-directory-subdirectories~.
Thanks to Graham Marlow for the contribution which was done in pull
request 112 on the GitHub mirror:
<https://github.com/protesilaos/denote/pull/112>.
The original contribution, with the subsequent tweaks I made to it, is
within the eligible line count and thus does not require copyright
assignment to the Free Software Foundation.
** Exclude certain keywords from being inferred
:PROPERTIES:
:CUSTOM_ID: h:226ba85e-1f5e-45f5-956a-f5e8a95c397e
:END:
The user option ~denote-excluded-keywords-regexp~ omits keywords that
match a regular expression from the list of inferred keywords.
Keywords are inferred from file names and provided at relevant prompts
as completion candidates when the user option ~denote-infer-keywords~
is non-nil.
Thanks to Stefan Thesing for proposing this idea in issue 115 on the
GitHub mirror: <https://github.com/protesilaos/denote/issues/115>.
[ Other people participate in that thread and there may be something
more coming out of it. ]
** Use the ~citar-denote~ package for bibliography notes
:PROPERTIES:
:CUSTOM_ID: h:ff16633f-5fb8-4935-9e2f-044ec998d3f7
:END:
Peter Prevos has produced the ~citar-denote~ package which makes it
possible to write notes on BibTeX entries with the help of the ~citar~
package. These notes have the citation's unique key associated with
them in the file's front matter. They also get a configurable keyword
in their file name, making it easy to find them in Dired and/or
retrieve them with the various Denote methods.
With ~citar-denote~, the user leverages standard minibuffer completion
mechanisms (e.g. with the help of the ~vertico~ and ~embark~ packages)
to manage bibliographic notes and access those notes with ease. The
package's documentation covers the details: <https://github.com/pprevos/citar-denote/>.
Thanks to Peter Prevos for developing this package and for mentioning
it on the Denote mailing list:
<https://lists.sr.ht/~protesilaos/denote/%3C877cz0e96r.fsf%40prevos.net%3E>.
** New functions and variables for developers
:PROPERTIES:
:CUSTOM_ID: h:5cc2076d-d4d2-45be-b28e-9ec67eca82b4
:END:
Developers or users who maintain custom code now have access to:
+ Function ~denote-keywords-sort~
+ Function ~denote-keywords-prompt~
Plus all the following which are related to the aforementioned ~denote-file-types~:
+ Variable ~denote-org-link-format~
+ Variable ~denote-md-link-format~
+ Variable ~denote-id-only-link-format~
+ Variable ~denote-org-link-in-context-regexp~
+ Variable ~denote-md-link-in-context-regexp~
+ Variable ~denote-id-only-link-in-context-regexp~
+ Function ~denote-date-org-timestamp~
+ Function ~denote-date-rfc3339~
+ Function ~denote-date-iso-8601~
Again, users can implement support for ANY FILE TYPE and use it to
write notes in, either as their default choice or on-demand. If
anything, this highlights the flexibility of Denote.
** Miscellaneous
:PROPERTIES:
:CUSTOM_ID: h:acbb0cf7-ad17-495e-85d2-821cbbfc3158
:END:
+ Added the ~denote-keywords-sort~ function. The intent is to
abstract the task of sorting the keywords. Before, it was handled
by the ~denote-keywords-prompt~, which meant that keywords were not
sorted when the ~denote~ function was called from Lisp. Thanks to
Florian for bringing this matter to my attention, providing relevant
feedback, and fixing an omission of mine in ~denote-rename-file~:
<https://lists.sr.ht/~protesilaos/denote/%3C166689879712.8.6808878344988686135.71824507%40aboulafia.org%3E>.
+ Expanded the manual's entry on directory "silos" to include more
code examples. Thanks to Viktor Haag for asking a question on the
mailing list that inspired me to produce this entry:
<https://lists.sr.ht/~protesilaos/denote/%3CCANnkwC6NLd0VneUEqFrjh7TCUBLBgEtLCcPwM37JDvJXJCShVQ%40mail.gmail.com%3E>.
+ Included a section in the manual with a non-exhaustive list of
references to publications about Denote. As of this writing, it
includes entries from David Wilson (SystemCrafters), Jack Baty,
Jeremy Friesen, and Peter Prevos. If you have an article about
Denote, please contact me about it directly or on the Denote mailing
list and I will add it to the manual.
+ Tweaked how Org's HTML export produces links in order to avoid
broken subdirectory paths. Thanks to Thibaut Benjamin for the
contribution, which was done in pull request 116 on the GitHub
mirror: <https://github.com/protesilaos/denote/pull/116>.
The change concerns a single line and thus Thibaut requires no
copyright assignment to the Free Software Foundation.
+ Expanded the manual where necessary.
* Version 1.1.0 on 2022-10-20
:PROPERTIES:
:CUSTOM_ID: h:8e0f536a-ab3b-4cab-82f7-529bc0e40dbd
:END:
** New commands or refinements to common use-cases
:PROPERTIES:
:CUSTOM_ID: h:5665e7ec-4f3a-4de3-8cb0-63d25a0db8c1
:END:
+ The ~denote-link-add-missing-links~ is a companion to what we
already provide to produce a list of links to Denote files matching
a regular expression (the ~denote-link-add-links~). This new
command adds links that are not already present in the current file.
So if you have a metanote that references, say, your journal entries
but have not updated it in a month, you can revisit the metanote,
invoke ~denote-link-add-missing-links~, and then type the search
terms (e.g. =_journal=) to include what remains.
Thanks to Elias Storms for the initial contribution, which was done
in pull request 108 on the GitHub mirror:
<https://github.com/protesilaos/denote/pull/108>.
Elias has assigned copyright to the Free Software Foundation. It is
required for changes that exceed 15 lines in total.
+ The ~denote-link-find-backlink~ provides a minibuffer interface that
shows all backlinks to the current note. It complements the
existing ~denote-link-backlinks~ command (which also has the alias
~denote-link-show-backlinks-buffer~). Each command has its own
niche: the minibuffer lets the user leverage powerful pattern
matching styles, such as those provided by the =orderless= package,
while the bespoke buffer provides an easy overview of what links to
the current note.
Thanks to Elias Storms for the original patch:
<https://lists.sr.ht/~protesilaos/denote/%3Cm2fsg6o2t6.fsf%40MBA21.fritz.box%3E#%3Cm2pmfam7yi.fsf@MBA21.fritz.box%3E>.
+ The ~denote-keywords-add~ and ~denote-keywords-remove~ are two
commands that interactively operate on the current note's front
matter to add or remove keywords. They use the familiar keywords'
prompt which means, among others, that they can read more than one
keyword at a time. To specify multiple keywords, separate each
input with a comma (or whatever the value of ~crm-separator~ is,
which should be a comma unless something out-of-the-ordinary is in
force).
Thanks to Elias Storms for the original patch, which was done as
part of a discussion on the mailing list and then iterated on:
<https://lists.sr.ht/~protesilaos/denote/%3Cm24jwvpbt2.fsf%40MBA21.fritz.box%3E#%3Cm28rlik0tc.fsf@MBA21.fritz.box%3E>.
+ The ~denote-link~ command will now recognise an active region and
use its text as the description of the inserted link. The default
behaviour is to use the file's title from its front matter or file
name. Thanks to Charanjit Singh for the original contribution,
which was done as part of pull request 109 on the GitHub mirror:
<https://github.com/protesilaos/denote/pull/109>. A subsequent
tweak was implemented in pull request 110, following a discussion
with me: <https://github.com/protesilaos/denote/pull/110>.
Charanjit's contribution is below the ~15 line threshold and thus
does not require copyright assignment to the Free Software
Foundation.
+ The renaming operations are now aware of the underlying version
control system and will use the appropriate command when a VCS is
available. In practice, renaming a file under, say, Git will
register it as a "rename" instead of two separate actions of
deletion and addition.
Thanks to Florian for the patch. It was discussed on the mailing
list and then underwent some changes:
<https://lists.sr.ht/~protesilaos/denote/%3C166547153518.8.941129310186454444.68125516@aboulafia.org%3E>.
+ The ~denote-rename-file-using-front-matter~ no longer fails to carry
out its intended task when the front matter has no keywords. If no
keywords are available, this is interpreted as a request to remove
the KEYWORDS component of the file name. This was always
technically possible and could be achieved with various permutations
of the user option ~denote-prompts~ (as explained in its doc string
or the manual). Denote only needs an identifier in the file name to
establish unique links (although I strongly encourage you to stick
to the standard file-naming scheme as it is informative, reliable,
and can work even if you access your data without Emacs).
** For more advanced use-cases
:PROPERTIES:
:CUSTOM_ID: h:505c84dd-2959-4bd4-8af4-78d75592a6d5
:END:
+ The variable ~denote-file-types~ has been tweaked to respond
directly to changes in its value done with ~setq~. Thanks to Noboru
Ota for the patch: <https://lists.sr.ht/~protesilaos/denote/%3C86k05gsqsg.fsf%40nobiot.com%3E>.
Noboru has assigned copyright to the Free Software Foundation.
+ The =:front-matter= property of the ~denote-file-types~ now accepts
a nil value. Denote could always work without front matter, but
this was not implemented flexibly in the ~denote-file-types~.
Thanks to Noboru Ota (nobiot) for pointing this out on the mailing
list: <https://lists.sr.ht/~protesilaos/denote/%3C86k05gsqsg.fsf%40nobiot.com%3E>.
+ The ~denote-file-prompt~ function now reads an optional =INITIAL-TEXT= argument. This is a string that prepopulates the
minibuffer. It is useful for custom commands the user may have
where, for example, there is a need to automatically filter to
entries matching =_journal=. Thanks to Alan Schmitt for suggesting
the idea: <https://lists.sr.ht/~protesilaos/denote/%3C87pmf676n1.fsf@m4x.org%3E>.
+ The ~denote-rename-file-using-front-matter~ accepts an optional
=AUTO-CONFIRM= argument. It can either be passed interactively or
via Lisp. The doc string (or the manual) explains the details.
Thanks to Elias Storms for the initial patch:
<https://lists.sr.ht/~protesilaos/denote/%3Cm2a667aeku.fsf%40gmail.com%3E>.
+ The ~denote-prompt-for-date-return-id~ function uses the familiar ~denote-date-prompt~ and returns the appropriate identifier. It is
used internally by some of our function, but we also provide it for
anyone who wants to write their own custom code.
+ The ~denote-retrieve-or-create-file-identifier~ function reads and
option =DATE= argument to its mandatory =FILE= argument. If =FILE=
does not have an identifier and optional =DATE= is non-nil, the
function invokes the ~denote-prompt-for-date-return-id~, as
mentioned above.
+ The ~denote-rename-file~ command accepts an optional =DATE=
argument. It functionally does what is described right above, with
the exception that this is for an interactive function (a
"command"). Read the detailed doc string or the manual for
everything that pertains to this powerful command.
Thanks to Florian for suggesting the idea on the mailing list:
<https://lists.sr.ht/~protesilaos/denote/%3C166521684647.7.5483179875879361874.67576870%40aboulafia.org%3E>.
+ The ~denote-directory-text-only-files~ function filters the
~denote-directory-files~ to only return a list of text files. This
leaves out, say, mp3 files. The function is used internally, though
it may also prove useful in custom user code.
** Miscellaneous refinements
:PROPERTIES:
:CUSTOM_ID: h:0531047f-ef15-412e-b265-886c55526d57
:END:
+ Implemented a ~revert-buffer-function~ for the backlinks' buffer,
which is produced by the command ~denote-link-backlinks~. This
revert function is what the =g= key invokes with the default key
bindings (the command is ~revert-buffer~). It produces the buffer
anew, updating the list of backlinks accordingly.
+ Documented how to speed up the creation of the backlinks' buffer.
As this depends on the built-in =xref= library, the change is done
by specifying the value of the user option ~xref-search-program~ in
Emacs 28 or higher. For example:
#+begin_src emacs-lisp
(setq xref-search-program 'ripgrep)
#+end_src
For something more elaborate:
#+begin_src emacs-lisp
;; Prefer ripgrep, then ugrep, and fall back to regular grep.
(setq xref-search-program
(cond
((or (executable-find "ripgrep")
(executable-find "rg"))
'ripgrep)
((executable-find "ugrep")
'ugrep)
(t
'grep)))
#+end_src
+ Removed some minor duplication of effort in how the buttonisation of
links is done (what makes them clickable).
+ Made refinements to the definition of functions such as ~denote-link-add-links~. There should be no noticeable change for
users, though this shows we care about code quality.
+ With Eshel Yaron, we tried to remove the empty indices for functions
and variables from the HTML version of the manual. These indices
are useful in the Info version, which can be accessed directly from
Emacs when the =denote= package is installed (for example, evaluate
=(info "(denote) Top")=), but they do not work with HTML. Alas,
what we tried to do did not work. Maybe Org has a way to control
what is exported where. We shall see. At any rate, thanks to Eshel
for the effort: <https://lists.sr.ht/~protesilaos/denote/patches/36028>.
+ All code that integrates the =denote:= custom hyperlink type with
Org's link facility is now assigned =autoload= cookies. These are
done to ensure that =denote= is loaded and is available in cases
where Org needs to access a =denote:= link at some early stage
(e.g. at startup before using Denote). Thanks to Sven Seebeck for
reporting the problem: <https://lists.sr.ht/~protesilaos/denote/%3C87r0zovwix.fsf%40svenseebeck.me%3E>.
Although Sven could not reproduce a bug reliably, I believe this
prevents such an eventuality.
+ Expanded or otherwise updated the manual to account for all of the
above, where appropriate.
* Version 1.0.0 on 2022-09-30
:PROPERTIES:
:CUSTOM_ID: h:053975d7-3fe2-49e5-96a0-336483e5861c
:END:
This is the first major release of Denote. A part of the changes
documented herein is for advanced users or developers who wish to
extend Denote with their custom code. Though we first cover what
applies to everyone.
** Changes for all users
:PROPERTIES:
:CUSTOM_ID: h:25692d4f-08da-4938-a81e-54070d91f51a
:END:
+ The custom Org hyperlink type of =denote:= can be visited from
outside the ~denote-directory~. We now provide the necessary glue
code that Org needs to store these =denote:= links. Storing them
can be done with an ~org-capture~ template or via the command ~org-store-link~. Use this to, for example, capture a TODO that
references one of your notes. =denote:= links work for as long as the referenced file is somewhere
in the ~denote-directory~ or one of its subdirectories.
Thanks to Marc Fargas for the contribution. Marc did not need to
assign copyright to the Free Software Foundation, as the patch was
within the ~15 line limit that is permissible.
The contribution was discussed on the mailing list:
<https://lists.sr.ht/~protesilaos/denote/patches/35137>. A prior
exchange took place in issue 104 over at the GitHub mirror:
<https://github.com/protesilaos/denote/issues/104>.
Some further tweaks were made to the relevant function. Thanks to
Elias Storms for reporting on the mailing list a bug which revealed
a regression I introduced to the Org link storing mechanism:
<https://lists.sr.ht/~protesilaos/denote/%3C15D55F4B-64D1-4083-AD5E-B5BACA8F1909%40ap.be%3E>.
+ Following from above, the command ~denote-link-find-file~ finds
files reliably, regardless of where the link is stored. All it
needs is for the target file to be inside the ~denote-directory~.
I discovered this while exchanging views with Marc Fargas regarding
the aforementioned patch: <https://lists.sr.ht/~protesilaos/denote/patches/35137>.
+ The command ~denote-link-buttonize-buffer~, which "buttonizes" =denote:= links in plain text and Markdown files, now performs its
task regardless of where the current file is stored. Those links
work for as long as the file they reference is somewhere inside the ~denote-directory~.
+ The commands ~denote-link-after-creating~, ~denote-link-or-create~
provide a convenience for users who need to create link to notes
that may not exist yet. The idea is that one is expounding on a
given topic and wants to create a link to a relevant issue. They
are not sure if they have written anything about it yet, so they
invoke the relevant command. Consult their doc strings or read the
manual: <https://protesilaos.com/emacs/denote#h:9e41e7df-2aac-4835-94c5-659b6111e6de>.
Thanks to user sienic for suggesting the idea and for testing the
prototypes. And thanks to Juanjo Presa for participating in the
discussion to share the view that this functionality should be part of
denote.el. This happened in issue 96 over at the GitHub mirror:
<https://github.com/protesilaos/denote/issues/96>.
+ The command ~denote-open-or-create~ offers the convenience of
visiting a file, if it exists, else prompting for its creation.
Thanks to Alan Schmitt for the contribution. The patch was sent on
the mailing list: <https://lists.sr.ht/~protesilaos/denote/%3C87fsgvddny.fsf%40protesilaos.com%3E>.
It is within the limit of what is allowed without assigning
copyright to the Free Software Foundation, though Alan has done the
relevant paperwork.
+ The manual expands on two sections: (1) Variants of
~denote-open-or-create~, (2) Variants of ~denote-link-or-create~.
They show how one can use the above "do or create" commands with
different permutations of the Denote prompts for new note creation.
+ The manual includes a section titled "Create a note with the
region's contents". Quote:
#+begin_quote
Sometimes it makes sense to gather notes in a single file and later
review it to make multiple notes out of it. With the following
code, the user marks a region and then invokes the command
~my-denote-create-new-note-from-region~: it prompts for a title and
keywords and then uses the region's contents to fill in the newly
created note.
#+end_quote
This is not part of denote.el, though we provide it in the manual
for users that may need it. Thanks to sundar bp for suggesting the
idea. This was done via a private channel and the information is
shared with permission.
+ The manual has another entry titled "Split an Org subtree into its
own note", which is similar to the above idea of using the region's
contents but has some extra niceties provided by Org. Quote:
#+begin_quote
With Org files in particular, it is common to have nested headings which
could be split off into their own standalone notes. In Org parlance an
entry with all its subheadings is a "subtree". With the following code,
the user places the point inside the heading they want to split off and
invokes the command ~my-denote-split-org-subtree~. It will create a
note using the heading's text and tags for the new file. The contents
of the subtree become the contents of the new note and are removed from
the old one.
#+end_quote
Thanks to Sven Seebeck for suggesting the idea and for testing my
prototypes. This information is shared with permission, as it was
provided via a private channel.
+ The manual describes how a user can leverage the built-in
~dired-virtual-mode~ to perform arbitrary sorting of their list of
notes. It also includes code for Eshell to quickly "export" a
command's output into a dedicated buffer (which can then be used to
derive a "virtual" Dired). Thanks to Yi Liu for asking the question
that inspired this entry:
<https://lists.sr.ht/~protesilaos/denote/%3C1C75FF01-EC76-49DF-9AEB-ED718A2795FF@gmail.com%3E>.
+ The ~denote-faces-broken-link~ has been removed. It was used for
Org links. The idea was to apply a different style if the link was
broken. However, the way fontification works means that there may
be a performance penalty as Org tries to check again and again if
the link is broken or note. As =denote:= links are robust (unless
the user tries to break them), this penalty is unacceptable. Thanks
to Peter Prevos for reporting the issue and discussing it with me on
the mailing list:
<https://lists.sr.ht/~protesilaos/denote/%3C87k05umyyo.fsf%40prevos.net%3E>.
+ The "denote" group in Custom UI buffers now provides a link to the
Info manual that is shipped with the package. To read the manual,
evaluate =(info "(denote) Top")=. Else visit the official web page:
<https://protesilaos.com/emacs/denote>.
+ Fixed a case where an internal check for a note would throw an error
if the buffer was not visiting a file. Thanks to Hilde Rhyne was
the patch: it is below the ~15 line threshold and thus does not
require copyright assignment to the Free Software Foundation. The
issue was discussed on the mailing list and was pushed to users as
version =0.6.1=:
<https://lists.sr.ht/~protesilaos/denote/%3Cm035d7nq22.fsf%40disroot.org%3E>.
+ When linking to a file that has no front matter, Denote tries to use
the TITLE component of the file name (per our file-naming scheme) as
the link's descriptive text. We now make this look a bit better, by
capitalising only the first letter while dehyphenating the text,
converting =this-is-a-test= to =This is a test=. Before, we would
capitalise all words. Thanks to Clemens Radermacher for the patch.
It was sent via a private channel. Clemens has assigned copyright
to the Free Software Foundation.
** Changes for developers or advanced users
:PROPERTIES:
:CUSTOM_ID: h:165cd056-5e27-4536-b8ac-57f88c927a43
:END:
Lots of functions and variables which once were for "private" use (the
presence of double hyphens in the symbol) are now made public.
Concretely this means that they no longer have double hyphens in their
name and we pledge to support them henceforth. "Support" means that
we (i) consider them stable, (ii) document them properly, (iii) will
record any changes made to them such as in a change log, a blog post
on my website, and via ~make-obsolete~.
The manual provides a complete reference of what is on offer. The
section is titled "For developers or advanced users":
<https://protesilaos.com/emacs/denote#h:c916d8c5-540a-409f-b780-6ccbd90e088e>.
Normally, we do not support private forms and can delete/modify them
without notice. However, I decided to write obsoletion aliases for
all forms I made public or otherwise revised, in an effort not to
break any existing custom code. The following table covers all
obsolete symbols and their new counterparts. PLEASE UPDATE YOUR CODE
as those aliases will be removed in the near future.
| Index | Old symbol | New symbol |
|-------+------------------------------------------------+---------------------------------------------------|
| 1 | denote--id-format | denote-id-format |
| 2 | denote--id-regexp | denote-id-regexp |
| 3 | denote--title-regexp | denote-title-regexp |
| 4 | denote--keywords-regexp | denote-keywords-regexp |
| 5 | denote--punctuation-regexp | denote-excluded-punctuation-regexp |
| 6 | denote-punctuation-excluded-extra-regexp | denote-excluded-punctuation-extra-regexp |
| 7 | denote--sluggify | denote-sluggify |
| 8 | denote--sluggify-and-join | denote-sluggify-and-join |
| 9 | denote--sluggify-keywords | denote-sluggify-keywords |
| 10 | denote--desluggify | denote-desluggify |
| 11 | denote--only-note-p | denote-file-is-note-p |
| 12 | denote--file-has-identifier-p | denote-file-has-identifier-p |
| 13 | denote--file-supported-extension-p | denote-file-has-supported-extension-p |
| 14 | denote--writable-and-supported-p | denote-file-is-writable-and-supported-p |
| 15 | denote--file-name-relative-to-denote-directory | denote-get-file-name-relative-to-denote-directory |
| 16 | denote-link--id-from-string | denote-extract-id-from-string |
| 17 | denote--directory-files | denote-directory-files |
| 18 | denote--subdirs | denote-directory-subdirectories |
| 19 | denote--get-note-path-by-id | denote-get-path-by-id |
| 20 | denote--directory-files-matching-regexp | denote-directory-files-matching-regexp |
| 21 | denote--retrieve-read-file-prompt | denote-file-prompt |
| 22 | denote--extract-keywords-from-path | denote-extract-keywords-from-path |
| 23 | denote--keywords-prompt | denote-keywords-prompt |
| 24 | denote--retrieve-filename-identifier | denote-retrieve-filename-identifier |
| 25 | denote--file-name-id | denote-retrieve-or-create-file-identifier |
| 26 | denote--retrieve-filename-title | denote-retrieve-filename-title |
| 27 | denote--retrieve-title-value | denote-retrieve-title-value |
| 28 | denote--retrieve-title-line | denote-retrieve-title-line |
| 29 | denote--retrieve-keywords-value | denote-retrieve-keywords-value |
| 30 | denote--retrieve-keywords-line | denote-retrieve-keywords-line |
| 31 | denote--format-file | denote-format-file-name |
| 32 | denote--barf-duplicate-id | denote-barf-duplicate-id |
| 33 | denote--title-prompt | denote-title-prompt |
| 34 | denote--file-type-prompt | denote-file-type-prompt |
| 35 | denote--date-prompt | denote-date-prompt |
| 36 | denote--subdirs-prompt | denote-subdirectory-prompt |
| 37 | denote--template-prompt | denote-template-prompt |
| 38 | denote--filetype-heuristics | denote-filetype-heuristics |
| 39 | denote--rename-file | denote-rename-file-and-buffer |
| 40 | denote--rename-file-prompt | denote-rename-file-prompt |
If you are writing code that extends Denote and feel that something is
either missing or has remained private, please contact us on the
mailing list, the GitHub/GitLab mirror, or send me an email directly.
I always respond in a timely fashion.
** Open to everyone
:PROPERTIES:
:CUSTOM_ID: h:27a391cf-8d5e-4d19-942f-46fc52dea80c
:END:
The most common feedback I get about Denote is that its documentation
is good. As you can tell from these change logs, the plan is to
continue on this path.
Please note that the communication channels for Denote (mailing list,
mirrors, my personal email) are open to users of all levels. Do not
hesitate to contact us/me.
Thanks again to everyone for their contributions, direct or indirect,
either in the form of code or the discussion of ideas. Quoting from
the "Acknowledgements" section of the manual (all my packages have
such a section):
#+begin_quote
Denote is meant to be a collective effort. Every bit of help matters.
+ Author/maintainer :: Protesilaos.
+ Contributions to code or the manual :: Abin Simon, Alan Schmitt,
Benjamin Kästner, Clemens Radermacher, Colin McLear, Damien Cassou,
Eshel Yaron, Hilde Rhyne, Jack Baty, Jean-Philippe Gagné Guay, Jürgen
Hötzel, Kaushal Modi, Kyle Meyer, Marc Fargas, Peter Prevos, Philip
Kaludercic, Quiliro Ordóñez, Stefan Monnier.
+ Ideas and/or user feedback :: Abin Simon, Alan Schmitt, Alfredo
Borrás, Benjamin Kästner, Colin McLear, Damien Cassou, Elias Storms,
Frank Ehmsen, Hanspeter Gisler, Jack Baty, Juanjo Presa, Kaushal
Modi, M. Hadi Timachi, Paul van Gelder, Peter Prevos, Shreyas
Ragavan, Summer Emacs, Sven Seebeck, Taoufik, Yi Liu, Ypot, atanasj,
hpgisler, pRot0ta1p, sienic, sundar bp.
Special thanks to Peter Povinec who helped refine the file-naming
scheme, which is the cornerstone of this project.
Special thanks to Jean-Philippe Gagné Guay for the numerous
contributions to the code base.
#+end_quote
* Version 0.6.0 on 2022-08-31
:PROPERTIES:
:CUSTOM_ID: h:50aba79a-d702-42b4-a2a5-7fa29033f904
:END:
Denote is in a stable state. I consider it feature-complete, without
prejudice to possible refinements to its existing feature set. The next
version shall be =1.0.0=.
** User-facing changes
:PROPERTIES:
:CUSTOM_ID: h:566a770b-399e-47a6-9aa4-326fd6ade9a7
:END:
+ The Denote linking facility can now link to any file that has the
Denote file-naming scheme. Before, we limited this feature to what we
consider "note" files, else the supported plain text formats (per
~denote-file-type~). Thanks to Peter Prevos for the discussion on the
mailing list: <https://lists.sr.ht/~protesilaos/denote/%3C87fsi1m5ze.fsf%40prevos.net%3E>.
+ Date prompts may optionally use the familiar Org date-selection
mechanism that leverages the calendar. This feature is subject to the
user option ~denote-date-prompt-use-org-read-date~. A date prompt is
used by the ~denote-date~ command or, optionally, by the ~denote~
command when the user option ~denote-prompts~ is configured
accordingly. The manual elaborates on the specificities. Thanks to
Jean-Philippe Gagné Guay for the contribution in pull request 97 at
the GitHub mirror: <https://github.com/protesilaos/denote/pull/97>.
+ Leading empty spaces at the ~denote~ =TITLE= prompt no longer produce
hyphens: they are simply ignored to keep file names consistent.
Thanks to Peter Prevos for the contribution in pull request 99 at the
GitHub mirror: <https://github.com/protesilaos/denote/pull/99>.
[ Peter has started the process for copyright assignment to the Free
Software Foundation, though the total contributions are still within
the permitted boundaries. ]
+ When linking to files that have no front matter, the link's anchor
text (the human-readable part) is derived from the file name =TITLE=
component. We apply a de-hyphenation and capitalisation of its
constituent words. This is not always perfect, but it is better than
something like =this-is-the-title=. Thanks to Peter Prevos for the
original idea in pull request 93 at the GitHub mirror:
<https://github.com/protesilaos/denote/pull/93>.
+ The active region is now used as the default value of the ~denote~
command =TITLE= prompt. The idea behind this Do-What-I-Mean-flavoured
patch is to be able to take a note about a subject that appears in a
buffer by simply marking it before invoking the ~denote~ command.
Thanks to Eshel Yaron for the patch: <https://lists.sr.ht/~protesilaos/denote/patches/34870>.
It is below the ~15 line threshold that thus requires no copyright
assignment to the Free Software Foundation.
+ The ~denote-rename-file-using-front-matter~ command now offers to save
the buffer if appropriate. In the past, it would simply produce an
error asking the user to save the buffer. Thanks to Peter Prevos for
the contribution in pull request 103 at he GitHub mirror:
<https://github.com/protesilaos/denote/pull/103>.
+ Fixed the text of the confirmation prompt in the command
~denote-migrate-old-markdown-yaml-tags~. Thanks to Abin Simon for the
patch: <https://lists.sr.ht/~protesilaos/denote/patches/34632>.
This patchset also fixes (i) how a tag is identified for the purposes
of migrating old to new front matter, (ii) the regular expression for
Org front matter keywords
[ The total changes are below the ~15 line threshold and thus do not
require copyright assignment to the Free Software Foundation. ]
+ Fixed a bug that prevented the creation of new notes. Thanks to
Juergen Hoetzel for the contribution in pull request 84 at the GitHub
mirror: <https://github.com/protesilaos/denote/pull/84>. This was
done immediately after the release of version =0.5.0= on 2022-08-10
and was provided to users as version =0.5.1=
[ The change is below the ~15 line threshold. ]
** Internal refinements
:PROPERTIES:
:CUSTOM_ID: h:9374b533-faaa-4ab4-b668-f74b5eae7ab5
:END:
These make the code simpler and more predictable. As the individual
changes are not user-facing, I invite interested parties to consult the
Git log. Special thanks to Jean-Philippe Gagné Guay for the multiple
contributions (and relevant discussions) over at the GitHub mirror:
- <https://github.com/protesilaos/denote/pull/88>
- <https://github.com/protesilaos/denote/pull/89>
- <https://github.com/protesilaos/denote/pull/91>
- <https://github.com/protesilaos/denote/pull/94>
- <https://github.com/protesilaos/denote/pull/101>
- <https://github.com/protesilaos/denote/pull/102>
[ Jean-Philippe has assigned copyright to the Free Software Foundation.
It is required for non-trivial changes. ]
** For advanced users
:PROPERTIES:
:CUSTOM_ID: h:c6fc05a2-ff31-4a0c-91a1-f64d2cfd6a16
:END:
The variable ~denote-file-types~ is an alist of plists which
substantiates the supported file types (per the user option
~denote-file-type~). Properties pertain to the formatting of front
matter and the retrieval of relevant values. The doc string of
~denote-file-types~ explains the details, while the default value uses
the ancillary functions we define. Thanks to Jean-Philippe Gagné Guay
for the relevant contributions in pull request 89 at the GitHub mirror:
<https://github.com/protesilaos/denote/pull/89>.
* Version 0.5.0 on 2022-08-10
:PROPERTIES:
:CUSTOM_ID: h:80b9daaa-c3c8-4457-b109-966bb6a99832
:END:
The general theme of this release is to refine what we already offer.
As I explained in some discussions, Denote is feature-complete. We can
always improve the code or add some ancillary function/command/variable,
though all the main ideas have already been implemented. Additional
functionality can be provided by other packages: I remain at the
disposal of anyone willing to write such a package.
The present release covers more than 150 commits since version 0.4.0 on
2022-07-25.
All release notes: <https://protesilaos.com/emacs/denote-changelog>.
** Templates for new notes
:PROPERTIES:
:CUSTOM_ID: h:0878125f-8392-48e6-aeff-1469eb1e18fc
:END:
We now provide the ~denote-templates~ user option. A "template" is
arbitrary text that Denote will add to a newly created note right below
the front matter.
Templates are expressed as a =(KEY . STRING)= association.
- The =KEY= is the name which identifies the template. It is an
arbitrary symbol, such as =report=, =memo=, =statement=.
- The =STRING= is ordinary text that Denote will insert as-is. It can
contain newline characters to add spacing. The manual of Denote
contains examples on how to use the ~concat~ function, beside writing
a generic string:
<https://protesilaos.com/emacs/denote#h:f635a490-d29e-4608-9372-7bd13b34d56c>.
The user can choose a template either by invoking the new command
~denote-template~ or by changing the user option ~denote-prompts~ to
always prompt for a template when calling the ~denote~ command.
Thanks to Jean-Philippe Gagné Guay for refinements to this facility.
Done in pull request 77 on the GitHub mirror:
<https://github.com/protesilaos/denote/pull/77>.
[ Jean-Philippe has assigned copyright to the Free Software Foundation. ]
** Revised format for Org =#+filetags= entry
:PROPERTIES:
:CUSTOM_ID: h:17688b79-cb1b-4a59-831e-fbf2a81245d3
:END:
Denote used to format tags in Org files by separating them with two
spaces:
#+begin_example
#+filetags: tag1 tag2
#+end_example
While this worked for some obvious use-cases, it is not supported by
Org. The Org documentation stipulates that tags be separated by the
colon sign. The above would then be written thus:
#+begin_example
#+filetags: :tag1:tag2:
#+end_example
Denote now conforms with Org's specifications. To help users update
their existing notes, we provide the ~denote-migrate-old-org-filetags~
command. It will perform the conversion in all Org files that had the
old notation. As with all Denote operations that rewrite file contents,
it DOES NOT SAVE BUFFERS. The user is expected to review the changes,
such as by using ~diff-buffer-with-file~. Multiple buffers can be saved
with ~save-some-buffers~ (check its doc string).
This command is provided for the convenience of the user. It shall be
deprecated and eventually removed from future versions of Denote.
If you need help with any of this, please do not hesitate to contact me
either in private or in one of Denote's official channels (mailing list,
GitHub/GitLab mirror).
Thanks to Alan Schmitt for bringing this matter to my attention:
<https://lists.sr.ht/~protesilaos/denote/%3C871qu0jw5l.fsf%40protesilaos.com%3E>.
Also thanks to Jean-Philippe Gagné Guay for commenting on it as it
helped me decide to include the command in =denote.el=:
<https://github.com/protesilaos/denote/pull/83#issuecomment-1210167133>.
** Revised format for Markdown+YAML =tags:= entry
:PROPERTIES:
:CUSTOM_ID: h:205a09cf-0159-425e-a6b3-41700fa3ad31
:END:
This is the same idea as above. Before, we were making the mistake of
using incorrect YAML notation:
#+begin_src yaml
tags: tag1 tag2
#+end_src
Now we do:
#+begin_src yaml
tags: ["tag1", "tag2"]
#+end_src
This is how the TOML variant always worked.
For the user's convenience, we provide a command to migrate from the old
to the new syntax: ~denote-migrate-old-markdown-yaml-tags~.
** Changes to file renaming and front matter rewriting
:PROPERTIES:
:CUSTOM_ID: h:15ecb4e8-d1ce-4e42-b74d-a3a046d93220
:END:
Denote adds "front matter" to newly created notes which includes data
such as the title and keywords/tags of the document. Strictly speaking,
the front matter is not required by Denote. It is provided for the
user's convenience, such as for readability or if they want to use the
note with other programs (e.g. Org export, a blog with Hugo/Jekyll,
...).
Denote provides commands which help the user rename their notes, by
changing the file name's =TITLE= and/or =KEYWORDS= components (per
Denote's file-naming scheme). These commands also operate on the front
matter to keep the data between file name and file contents in sync
(again, for the user's convenience).
For this release we have consolidated and refined our offerings in order
to improve their ergonomics. All changes are the result of fruitful
discussions on the mailing list and the issue tracker of the GitHub
mirror:
- <https://lists.sr.ht/~protesilaos/denote/%3C87k081l6vw.fsf%40silverstone.mail-host-address-is-not-set%3E>
- <https://lists.sr.ht/~protesilaos/denote/%3C878rogw5kk.fsf%40protesilaos.com%3E>
- <https://lists.sr.ht/~protesilaos/denote/%3C87fsiljv1s.fsf%40hu.mail-host-address-is-not-set%3E>
- <https://lists.sr.ht/~protesilaos/denote/%3C87r122afe3.fsf%40hu.mail-host-address-is-not-set%3E>
- <https://github.com/protesilaos/denote/issues/74>
Thanks to (A-Z) Hanspeter Gisler, Jean-Philippe Gagné Guay, and Peter
Prevos for their participation.
Also thanks to Jean-Philippe Gagné Guay for relevant code contributions
(please consult the Git log for the minutiae):
- <https://github.com/protesilaos/denote/pull/66>
- <https://github.com/protesilaos/denote/pull/67>
- <https://github.com/protesilaos/denote/pull/69>
- <https://github.com/protesilaos/denote/pull/75>
- <https://github.com/protesilaos/denote/pull/76>
*** Renaming a single file
:PROPERTIES:
:CUSTOM_ID: h:1d695e54-1481-42dd-916b-c0542c48aa6f
:END:
The commands ~denote-dired-rename-file-and-add-front-matter~ and
~denote-dired-rename-file~ are deprecated and superseded by the new
~denote-rename-file~. Please update any key bindings in your setup.
The difference between the old commands and the new ~denote-rename-file~
is that the latter will now insert front matter to supported file types
(per ~denote-file-type~) if they have none. This basically means that,
e.g., renaming a generic Org/Markdown/Plain text file with
~denote-rename-file~ will update its file name to comply with Denote's
file-naming scheme and also add the appropriate front matter (it
"converts" it to a Denote note). If front matter exists, this command
will rewrite it to reflect the changes to the file name's =TITLE= and/or
=KEYWORDS=.
Consult the manual for the details:
<https://protesilaos.com/emacs/denote#h:7cc9e000-806a-48da-945c-711bbc7426b0>.
Or, if the new version of the GNU ELPA package is installed, evaluate:
#+begin_src emacs-lisp
(info "(denote) Rename a single file")
#+end_src
The user option ~denote-dired-rename-expert~ is obsolete. Denote always
asks for confirmation when renaming a single file. This is because the
user can rely on batch-renaming commands which ask for confirmation only
once per batch.
*** Renaming multiple files at once
:PROPERTIES:
:CUSTOM_ID: h:82455fb4-576b-4753-af66-ac48fd158327
:END:
The command ~denote-dired-rename-marked-files-and-add-front-matter~ is
deprecated and its functionality is absorbed by the existing
~denote-dired-rename-marked-files~ command. The deprecated command was
used to insert front matter to supported file types (per
~denote-file-type~) that had none. We now handle this internally, thus
streamlining the experience for the user.
Refer to the manual for the details:
<https://protesilaos.com/emacs/denote#h:1b6b2c78-42f0-45b8-9ef0-6de21a8b2cde>
Assuming the latest Info manual is installed, evaluate:
#+begin_src emacs-lisp
(info "(denote) Rename multiple files at once")
#+end_src
*** Renaming a single file based on its front matter
:PROPERTIES:
:CUSTOM_ID: h:d913e369-9325-46c4-985b-cf5b3e35372b
:END:
Introduced the ~denote-rename-file-using-front-matter~ command. This is
new functionality we provide which uses the front matter as input to
perform a rename of the file. The aforementioned offerings prompt for
input via the minibuffer and propagate the changes firstly to the file
name and subsequently to the front matter. Whereas with the command
~denote-rename-file-using-front-matter~, the user can edit the front
matter manually and then invoke the command to pass the changes to the
file name, subject to a confirmation. Relevant entries are the title
and tags/filetags (depending on the file type). The date and the
identifier are not pertinent. Identifiers in file names are NEVER
rewritten by Denote.
Consult the manual:
<https://protesilaos.com/emacs/denote#h:3ab08ff4-81fa-4d24-99cb-79f97c13a373>.
With the latest package, evaluate:
#+begin_src emacs-lisp
(info "(denote) Rename a single file based on its front matter")
#+end_src
*** Renaming multiple files based on their front matter
:PROPERTIES:
:CUSTOM_ID: h:4efc6c14-fd71-4bd8-8bb1-e8e720b98eff
:END:
The command ~denote-dired-rename-marked-files-using-front-matter~
completes the set of features we provide for syncing between file name
and front matter. It applies to all marked files in a Dired buffer.
Read the manual to understand how the command works and what it does
exactly: <https://protesilaos.com/emacs/denote#h:ea5673cd-e6ca-4c42-a066-07dc6c9d57f8>.
Or evaluate:
#+begin_src emacs-lisp
(info "(denote) Rename multiple files based on their front matter")
#+end_src
*** Add missing front matter on demand
:PROPERTIES:
:CUSTOM_ID: h:32a103be-71a2-48e4-a18e-7727c04545ed
:END:
Sometimes the user may have incomplete front matter, perhaps due to a
mistake that was saved on disk. The command ~denote-add-front-matter~
appends a new front matter block to the current note.
Read:
<https://protesilaos.com/emacs/denote#h:54b48277-e0e5-4188-ad54-ef3db3b7e772>
Or evaluate:
#+begin_src emacs-lisp
(info "(denote) Regenerate front matter")
#+end_src
** Faces for Denote links
:PROPERTIES:
:CUSTOM_ID: h:507fb46c-a2e9-48a7-8cd2-53c5fc73394d
:END:
We provide the ~denote-faces-link~ and the ~denote-faces-broken-link~.
The latter is only relevant for Org, as Emacs' standard button mechanism
does not have a way to apply a face dynamically.
This is a change for themes/tinkerers who need to differentiate
=denote:= links from other links. Otherwise, the presentation is the
same as before.
Thanks to Peter Prevos for asking about it on the mailing list:
<https://lists.sr.ht/~protesilaos/denote/%3C03618bb20d3eaba78c32cd0cb63bfc71%40prevos.net%3E>.
** Use of XDG path in ~denote-directory~
:PROPERTIES:
:CUSTOM_ID: h:efa3049e-f1fa-48ff-af7d-d16edc677704
:END:
The default value of the ~denote-directory~ user option used to be
=~/Documents/notes= (subject to some conversion via Elisp). Denote now
conforms with the freedesktop.org specifications by using the =XDG=
directory for =DOCUMENTS= instead of =~/Documents=:
<https://www.freedesktop.org/wiki/Software/xdg-user-dirs/>.
Users who already bind the ~denote-directory~ are not affected by this
change. Same for those who do not tinker with =XDG= environment
variables and/or do not use some exotic setup.
Thanks to Philip Kaludercic for the patch:
<https://lists.sr.ht/~protesilaos/denote/patches/34561#%3C20220809115824.43089-1-philipk@posteo.net%3E>
** Bespoke major-mode for the backlinks' buffer
:PROPERTIES:
:CUSTOM_ID: h:feb9a0ed-ba15-486e-ae11-5b222b00bc31
:END:
The backlinks' buffer now uses the ~denote-backlink-mode~ instead of the
generic ~special-mode~. The former derives from the latter. It binds
keys to move between links with =n= (next) and =p= (previous). These
are stored in the ~denote-backlink-mode-map~ (use =M-x describe-mode=
(=C-h m=) in an unfamiliar buffer to learn more about it).
Thanks to Philip Kaludercic for the patch:
<https://lists.sr.ht/~protesilaos/denote/patches/34561#%3C20220809115824.43089-2-philipk@posteo.net%3E>
** Changes to the manual
:PROPERTIES:
:CUSTOM_ID: h:80217a39-86b8-4310-b7c4-dcc14e0b98fd
:END:
+ Documented all of the aforementioned. Improved how information is
presented and, generally, iterated on an already comprehensive
document.
+ Introduced a node which explains how to tweak the front matter:
<https://protesilaos.com/emacs/denote#h:7f918854-5ed4-4139-821f-8ee9ba06ad15>.
Or evaluate:
#+begin_src emacs-lisp
(info "(denote) Change the front matter format")
#+end_src
+ Updated the reference to =consult-notes=. This is a package that uses
the =consult= interface to provide access and search facilities for
notes. It can integrate with Denote. Thanks to Colin McLear for the
change in pull request 70 on the GitHub mirror:
<https://github.com/protesilaos/denote/pull/70>.
[ The change is below the ~15 line threshold and thus does not require
copyright assignment to the Free Software Foundation. ]
** Internal restructuring
:PROPERTIES:
:CUSTOM_ID: h:5d09d0af-3c25-4419-8448-90b8e1adab0d
:END:
+ All Denote code is consolidated in =denote.el=. We no longer maintain
separate files like =denote-link.el=, =denote-dired.el=, etc. Users
who had ~require~ calls to such libraries must remove them and only
keep:
#+begin_src emacs-lisp
(require 'denote)
#+end_src
+ User options that have an entry in the manual will now provide a link
to it via their Help buffer and/or the Custom UI. This is done by
adding the =:link= attribute to their declaration.
Furthermore, user options and faces now specify the version of Denote
that last affected their value (e.g. ~denote-directory~, which was
mentioned above for the XDG spec, now informs the user that it changed
for version =0.5.0=).
[ I learnt these by developing the =modus-themes=. ]
+ The variables ~denote-last-title~, ~denote-last-keywords~, ~denote-last-buffer~, and ~denote-last-front-matter~ are all obsolete.
These were used prior to version =0.1.0= to help with development but
are now deemed surplus to requirements.
+ Lots of changes were made to private functions, variables, doc
strings, and comments, in the interest of simplifying the code and/or
ensuring consistency in how operations are carried out. Though
everything is the same for the end-user.
Thanks to Jean-Philippe Gagné Guay for the numerous contributions on the
GitHub mirror. They are important for Denote, though the user does not
need to know what is happening internally (consult the Git log for the
details):
- <https://github.com/protesilaos/denote/pull/65>
- <https://github.com/protesilaos/denote/pull/72>
- <https://github.com/protesilaos/denote/pull/73>
- <https://github.com/protesilaos/denote/pull/78>
- <https://github.com/protesilaos/denote/pull/80>
- <https://github.com/protesilaos/denote/pull/81>
- <https://github.com/protesilaos/denote/pull/82>
- <https://github.com/protesilaos/denote/pull/83>
** Discussions
:PROPERTIES:
:CUSTOM_ID: h:79089c06-9e0c-49cc-9d53-a1a2fd72fb65
:END:
*** Encrypting Denote notes
:PROPERTIES:
:CUSTOM_ID: h:87e4556a-4864-4955-a98c-62b2e6a509c3
:END:
Paul van Gelder asked about this on the mailing list. I provided
guidelines on what can be done, though did not record anything in the
manual: I prefer to elicit more feedback from users. The gist is that
Emacs already has all the requisite functionality, though encryption per
se is outside the scope of Denote:
<https://lists.sr.ht/~protesilaos/denote/%3C1123434736.64290.1658954014673%40kpc.webmail.kpnmail.nl%3E>.
Denote's relevant internal mechanisms will recognise files ending in
=.gpg= (e.g. for fontification in Dired).
*** Visualise usage of Denote keywords
:PROPERTIES:
:CUSTOM_ID: h:d94ee5e3-0a54-404c-b44b-34edc3703fbc
:END:
Peter Prevos shared a proof-of-concept way to visualise keywords in the
~denote-directory~ and show usage statistics:
<https://lists.sr.ht/~protesilaos/denote/%3Ce9e5d6ae85984b51067b47f4d8e134fa%40prevos.net%3E>.
We do not include this information in the manual, as we wait for the
fully fledged code. Though do give it a try if you are interested and,
perhaps, share your thoughts for Peter's consideration.
*** Conflict between ~denote-dired-mode~ and ~diredfl-mode~
:PROPERTIES:
:CUSTOM_ID: h:0cbf504c-676c-436e-8ae8-e7115368e691
:END:
Hilde Rhyne shared a workaround they have to disable ~diredfl-mode~ in
the buffers where ~denote-dired-mode~ is enabled. The conflict between
the two is a known issue that is acknowledged in the manual:
<https://lists.sr.ht/~protesilaos/denote/%3Cm0tu6q6bg0.fsf%40disroot.org%3E>.
I think we need a proper solution in the code we provide, so this
workaround is not mentioned in the manual.
*** Why doesn't Denote provide a search facility?
:PROPERTIES:
:CUSTOM_ID: h:068108f4-a4fa-4ff8-be49-f1f10a862451
:END:
There was a discussion started by Fourchaux, with the participation of
basaran and Andre0991 on the GitHub mirror:
<https://github.com/protesilaos/denote/issues/71>.
The gist of my answer is that Denote does not need to provide such a
facility because notes are ordinary files: whatever the user already has
for them should apply to Denote. If the user has nothing to search
through files, they anyhow need something that works outside the
confines of Denote: a =denote-SEARCH= command is not an adequate
solution.
Emacs has numerous built-in commands, such as ~grep~ (~lgrep~ and
~rgrep~), ~project-find-regexp~, ~find-grep-dired~, ~ibuffer-do-occur~,
... Furthermore, there are lots of high quality packages that have
their own wrappers or extensions for searching file contents, such as
the =ivy= and =helm= completion frameworks, as well as =consult= (the
commands ~consult-grep~ and ~consult-ripgrep~), =consult-notes=, =rg=,
=deadgrep=, =deft=, and probably plenty more that do not come to mind
right now.
I strongly encourage the user to find a universal search solution to the
problem of searching file contents.
* Version 0.4.0 on 2022-07-25
:PROPERTIES:
:CUSTOM_ID: h:1c8098ee-089c-4511-bc6a-4140aab01321
:END:
+ Defined the ~denote-link-dired-marked-notes~ command. It lets the
user produce a typographic list of links to the note files that are
marked in Dired. The list is written at point. If there are multiple
buffers which visit Denote notes, the command first prompts with
minibuffer completion for one among them.
In terms of workflow, ~denote-link-dired-marked-notes~ complements the ~denote-link-add-links~ command for those cases where it is easier to
select files than write an elegant regular expression.
+ Implemented the ~denote-dired-rename-marked-files~ command. This
provides a much-requested facility to perform the familiar renaming
operation on a set of files. In particular:
- the file's existing file name is retained and becomes the =TITLE=
field, per Denote's file-naming scheme;
- the =TITLE= is sluggified and downcased, per our conventions;
- an identifier is prepended to the =TITLE=;
- the file's extension is retained;
- a prompt is asked once for the =KEYWORDS= field and the input is
applied to all file names;
- if the file is recognised as a Denote note, the command rewrites its
front matter to include the new keywords. A confirmation to carry
out this step is performed once at the outset. Note that the
affected buffers are not saved. The user can thus check them to
confirm that the new front matter does not cause any problems
(e.g. with the command ~diff-buffer-with-file~). Multiple buffers
can be saved with ~save-some-buffers~ (read its doc string).
Parts of ~denote-dired-rename-marked-files~ were added or refined over
a series of commits. Consult the Git log for the minutia. Thanks to
Jean-Philippe Gagné Guay for the relevant additions in pull requests
51 and 52 on the GitHub mirror:
- <https://github.com/protesilaos/denote/pull/51>
- <https://github.com/protesilaos/denote/pull/52>
Jean-Philippe has assigned copyright to the Free Software Foundation.
+ Improved how the ~denote-dired-rename-file~ command rewrites front
matter. Before, it would perform a replacement of the whole block,
which had the adverse effect of overwriting custom front matter
entries. Now, it only targets the lines which hold the title and
keywords, leaving everything else intact. Thanks to Peter Prevos for
reporting the problem and testing the solution to it in issue 60 on
the GitHub mirror: <https://github.com/protesilaos/denote/issues/60>.
+ Introduced the ~denote-dired-rename-file-and-add-front-matter~ command
that always prepends front matter to a file whose extension is among
the supported ones (per the user option ~denote-file-type~). This
differs from the standard ~denote-dired-rename-file~ command which
only rewrites the front matter's title and keywords if they exist.
In practice, ~denote-dired-rename-file-and-add-front-matter~ empowers
the user to convert a generic text file to a Denote note.
This command was originally added by Jean-Philippe Gagné Guay in pull
request 49 on the GitHub mirror and refined in subsequent commits:
<https://github.com/protesilaos/denote/pull/49>. Also read issue 48
where this idea was originally discussed:
<https://github.com/protesilaos/denote/issues/48>.
+ Added the ~denote-dired-rename-marked-files-and-add-front-matters~
command, which is like the ~denote-dired-rename-marked-files~ but adds
front matter instead of rewriting existing one, just how the command ~denote-dired-rename-file-and-add-front-matter~ does it (both are
mentioned above). Thanks to Jean-Philippe Gagné Guay for the
refinements to it in pull request 53 on the GitHub mirror:
<https://github.com/protesilaos/denote/pull/53>.
+ Wrote an interactive spec for ~denote-link-buttonize-buffer~. It can
now be invoked with =M-x= or a key binding, should the need arise.
This function is normally called via a hook and takes effect in plain
text as well as Markdown files.
+ Extended the fontification rules so that file names with non-ASCII
characters are styled properly. This issue was brought up on the
mailing list by Frank Ehmsen and was discussed with the participation
of Peter Prevos:
<https://lists.sr.ht/~protesilaos/denote/%3C2273b3b1-344c-6c6e-3ab6-a227b6bc3721%40eh-is.de%3E>.
The same topic was raised at the same time on the GitHub mirror by
user hpgisler in issue 61:
<https://github.com/protesilaos/denote/issues/61>.
After some discussion, we agreed on the right approach, which was
formalised by Peter Prevos as pull request 64 on the GitHub mirror:
<https://github.com/protesilaos/denote/pull/64>. The change is below
the ~15 line threshold and thus does not require copyright assignment
to the Free Software Foundation.
+ Made the registration of the =denote:= custom Org hyperlink type
conditional on the availability of the ~org~ feature. In other words,
those who do not use Org will not be loading this part of the code.
Thanks to Abin Simon for reporting the problem and for showing how
Elfeed handles this case. This was done in issue 47 on the GitHub
mirror: <https://github.com/protesilaos/denote/issues/47>.
+ Ensured that duplicate keywords are not produced by the relevant
prompt. Thanks to user Taoufik for the contribution in pull request
50 on the GitHub mirror: <https://github.com/protesilaos/denote/pull/50>.
The change is below the ~15 line threshold and thus does not require
copyright assignment to the Free Software Foundation.
+ Fixed a typo in the reference to the ~crm-separator~ in the manual.
David Wilson (System Crafters channel) spotted the error in a recent
live stream whose main topic was about Denote (thanks, by the way!):
<https://www.youtube.com/watch?v=QcRY_rsX0yY>.
+ Addressed an inconsistency in the command ~denote-link-find-file~
where it would not recognise links without a title in their format
(those can be inserted by passing a prefix argument (=C-u= by default)
to the commands that insert links, such as ~denote-link~).
+ Attached conditionality to the ~denote~ command's =SUBDIRECTORY=
argument, so that it does not create new file paths. This is only
relevant for those who call ~denote~ from Lisp. Interactive use is
the same as before.
+ Clarified that the user option ~denote-org-capture-specifiers~ can
accept arbitrary text in addition to the formatting specifiers that
Org's capture mechanism introduces.
+ Explained in the manual why ~denote-org-capture-specifiers~ is needed
instead of writing the capture template directly the way one normally
does. The gist is that because our file names are derived dynamically
based on user input, we need to account for the sequence in which the
value of arguments is reified by ~org-capture~.
+ Refactored how notes are prepared internally. Thanks to Jean-Philippe
Gagné Guay for the contribution in pull request 55 on the GitHub
mirror: <https://github.com/protesilaos/denote/pull/55>.
+ Declared the ~denote-punctuation-excluded-extra-regexp~ variable which
is, for the time being, targeted at experienced users. Its purpose is
to extend what we consider "illegal" punctuation for the file name.
Thanks to pRot0ta1p for the feedback in issue 57 over at the GitHub
mirror: <https://github.com/protesilaos/denote/issues/57>. Example
based on the input of pRot0ta1p:
#+begin_src emacs-lisp
(setq denote-punctuation-excluded-extra-regexp
"[『』〖〗{}「」【】〔〕[]()《》〈〉«»!#¥%…&"'*,。;:、?—]*")
#+end_src
The ideal is to make ~denote--punctuation-regexp~ work for all
scripts, but that may be unrealistic.
+ Clarified what the manual means by "attachments" to notes. Those are
for Org, if the user resorts to the relevant Org mechanisms. Denote
does not do any of that.
+ Revised the parsing of a date input as used in the ~denote-date~
command or related. The idea is to turn =2020-01-15= into something
like =2020-01-15 16:19= by using the current time, so that the hour
and minute component is not left to =00:00= when the user does not
specify it explicitly.
This reduces the burden on the user who would otherwise need to input
the time value in order to avoid the error of duplicate identifiers in
the scenario where the same date is used more than once.
The change also addresses a difference between Emacs 28 and Emacs 29
where the former does not read dates without a time component.
Thanks to Peter Prevos for the feedback in issue 58 over at the GitHub
mirror: <https://github.com/protesilaos/denote/issues/58>.
+ Fixed compilation warnings in Emacs 29 about the format of doc strings
that need to output a literal single quote. Thanks to Kyle Meyer for
the patch, which was sent on the mailing list:
<https://lists.sr.ht/~protesilaos/denote/patches/34117>.
+ Fixed typo in the user option ~denote-prompts~ about the ~crm-separator~. Thanks to Kyle Meyer for the patch, which was sent
on the mailing list:
<https://lists.sr.ht/~protesilaos/denote/patches/34116>.
+ Made the built-in =subr-x= library a runtime dependency, due to
complications with the ~when-let*~ form. The problem was made
manifest in a renaming operation, though it was not about renaming per
se. Thanks to hpgisler for reporting the problem in issue 62 and for
testing the proposed solution:
<https://github.com/protesilaos/denote/issues/62>.
+ Streamlined the use of the =seq= library instead of =cl-lib=, as we
were already using the former more heavily and there was no need for
the latter. Thanks to Philip Kaludercic for pointing this out on the
emacs-devel mailing list:
<https://lists.gnu.org/archive/html/emacs-devel/2022-07/msg00838.html>.
+ Added a generic =README.md= file to placate the Git forges. Neither
SourceHut nor GitHub/GitLab are fully compliant with the Org markup we
use in =README.org= (we use Org because it is easy to generate the
Info manual and HTML pages out of it). SourceHut will not render the
file at all, while the others render it but do not parse it properly.
+ Made several other internal tweaks and refinements in the interest of
robustness and/or clarity.
+ Rewrote all relevant documentation.
** Non-changes
:PROPERTIES:
:CUSTOM_ID: h:0ac79968-a575-4380-addc-d58cc2b5f627
:END:
The following are not part of any changes that were made during this
release cycle, though they provide potentially interesting insight into
the workings of the project.
+ Identifiers with milliseconds :: Denote's identifier format extends up
to seconds. This is the product of years of experimentation and is,
in my opinion, the best compromise between usability/readability and
precision. If a user produces two notes within a fraction of a
second, then yes they will have duplicate identifiers. In principle,
there is no reason not to address this potential problem, provided we
do not compromise on Denote's file-naming scheme (making the
identifier less readable is a compromise). We shall see what the best
course of action is. Thanks to Felipe Balbi and Jean-Philippe Gagné
Guay for the discussion thus far in issue 54 on the GitHub mirror:
<https://github.com/protesilaos/denote/issues/54>.
+ Denote and evil-mode :: Users of evil-mode do not have to worry about
Denote, as we do not define any key bindings. The manual includes
sample configuration, which proposes some key bindings, but that is
the user's prerogative. Thanks to Saša Janiška and Alan Schmitt for
their participation on the mailing list:
<https://lists.sr.ht/~protesilaos/denote/%3C87czdxf1dz.fsf%40atmarama.ddns.net%3E>.
+ Denote and Citar :: Peter Prevos started developing a package that
connects Denote with Citar: <https://github.com/pprevos/denote-citar>.
The idea is to use notes as part of one's bibliography. Discussions
which include sample code on how to leverage ~denote~ from Lisp:
- <https://lists.sr.ht/~protesilaos/denote/%3C6add8bc63cab0a557fa4b9919e025afc%40prevos.net%3E>
- <https://lists.sr.ht/~protesilaos/denote/%3C87r12d2w96.fsf%40protesilaos.com%3E>
- <https://lists.sr.ht/~protesilaos/denote/%3C87a69060q6.fsf%40protesilaos.com%3E>
+ Denote and graph of connections :: Saša Janiška asked whether Denote
will provide some way to visualise links between notes. The answer is
negative. Denote's scope is clearly delineated and its feature set is
largely complete (notwithstanding refinements to what we already
provide). Peter Prevos is experimenting with some code that uses the
R language. Any such facility will have to be implemented as a
separate package. I remain at the disposal of anyone who needs help
with Denote's internals. Thanks to the aforementioned fellows for
their participation on the mailing list:
<https://lists.sr.ht/~protesilaos/denote/%3C878roleze1.fsf%40atmarama.ddns.net%3E>.
+ Denote's scalability :: There was a discussion whether Denote will
work well with very large sets of files. The short answer is that it
will work the same way Emacs and/or standard Unix tools do: good
enough! If there are improvements to be made, which do not jeopardise
the principles of the project, we shall implement them without
hesitation. Thanks to Saša Janiška and Peter Prevos for their
participation on the mailing list:
<https://lists.sr.ht/~protesilaos/denote/%3C87sfmtf7im.fsf%40atmarama.ddns.net%3E>.
+ Denote's minimum requirement of Emacs 27.2 :: We cannot depend on
Emacs 27.1 due to this message from the byte compiler:
: You should depend on (emacs "27.2") or the (org "9.3") package if you need `org-link-open-as-file'.
Depending on Org is not an option because Denote optionally works
without Org, so Emacs 27.2 is what we have to opt for. If your
operating system does not provide this version in package format,
please petition its maintainers/providers to do so. Thanks to
Alexander for asking about it on the mailing list:
<https://lists.sr.ht/~protesilaos/denote/%3C9ec818e6a7979efbb2f8b1f5a497665b%40purelymail.com%3E>.
Finally, a mildly interesting piece of trivia: we have exceeded 600
commits since the first day of the project's Git history on 2022-06-04
(the actual history is much longer). That averages to more than 10 per
day! I think things will slow down eventually.
* Version 0.3.0 on 2022-07-11
:PROPERTIES:
:CUSTOM_ID: h:6864cfd4-d0be-4c89-b313-39ba6e892a03
:END:
+ Fixed how references are analysed to produce the backlinks' buffer.
This should resolve the issue that some users faced where the
backlinks would not be produced.
The previous implementation would not yield the appropriate results if
(i) the value of the user option ~denote-directory~ was a "project"
per the built-in project.el and (ii) the link to the given entry was
from a subdirectory. In short, the references were sometimes returned
as relative file paths, whereas they should always be absolute.
Thanks to Jean-Philippe Gagné Guay for the feedback in issue 42 over
at the GitHub mirror: <https://github.com/protesilaos/denote/pull/42>.
[ Jean-Philippe has assigned copyright to the Free Software
Foundation. It is a prerequisite for contributing to core Emacs
and/or any package distributed via the official GNU ELPA. ]
+ Addressed a regression in the function ~denote-directory~ (this is the
function that normalises the variable of the same name) which
prevented it from returning an expanded file path. This too
contributed to problems with the backlinking facility. Thanks to
Jean-Philippe Gagné Guay for the contribution in pull request 44 over
at the GitHub mirror: <https://github.com/protesilaos/denote/pull/44>.
Also thanks to user pRot0ta1p for the relevant feedback in issue 43
(also on the mirror): <https://github.com/protesilaos/denote/issues/43>.
More thanks to Alfredo Borrás, Benjamin Kästner, and Sven Seebeck for
their comments in a related thread on the mailing list:
<https://lists.sr.ht/~protesilaos/denote/%3CCA73E705-1194-4324-9962-70708C4C72E5%40zoho.eu%3E>.
These discussions showed we had a problem, which we managed to
identify.
+ Introduced the user option ~denote-prompts~ (read its doc string or
the relevant entry in the manual). It governs how the standard ~denote~ command for creating new notes will behave in interactive
usage. By default, ~denote~ prompts for a title and keywords. With ~denote-prompts~, the command can also ask for a file type (per ~denote-file-type~), subdirectory of the ~denote-directory~, and a
specific date+time. Prompts occur in the order they are specified.
Furthermore, the ~denote-prompts~ can be set to values which do not
include the title and keywords. This means that the resulting file
names can be any of those permutations:
: DATE.EXT
: DATE--TITLE.EXT
: DATE__KEYWORDS.EXT
Recall that Denote's standard file-naming scheme is defined as follows
(read the manual for the details):
: DATE--TITLE__KEYWORDS.EXT
For our purposes, Denote will work perfectly fine for linking and
backlinking, even if file names do not include the =TITLE= and
=KEYWORDS= fields. However, the user is advised to consider the
implications on usability: notes without a descriptive title and/or
useful keywords may be hard to filter and practically impossible to
manage at scale. File names without such information should at least
be added to subdirectories which themselves have a descriptive name.
At any rate, Denote does not have strong opinions about one's
workflow. The standard file name is the culmination of years of
experience.
Consider the ~denote-prompts~ the affirmative answer to the question
"Can keywords be optional?" as posed by Jack Baty on the mailing list:
<https://lists.sr.ht/~protesilaos/denote/%3C8D392BC3-980A-4E5B-9480-D6A00BE8279F%40baty.net%3E>.
Thanks to Jean-Philippe Gagné Guay for the original contribution in
commit 9b981a2. It was originally part of a pull request, but due to
some internal changes I had to merge it as a patch and technically the
web UI did not count the PR as "merged" (though it was in terms of
substance).
+ Refactored the ~denote~ command to (i) accommodate the new user option ~denote-prompts~ via its interactive specification and (ii) be more
flexible when called from Lisp. The latter scenario is for advanced
users or, generally, those who can maintain some custom code in their
configuration. A case in point is one of the examples we show in the
manual for a programmatic way to create notes that automatically get
the =journal= tag:
#+begin_src emacs-lisp
(defun my-denote-journal ()
"Create an entry tagged 'journal', while prompting for a title."
(interactive)
(denote
(denote--title-prompt)
'("journal")))
#+end_src
Notice that the ='("journal")= is a list of strings even for a single
keyword. Whereas before a single one was a plain string. This is a
breaking change.
Please consult the doc string of the ~denote~ command for the
technicalities.
+ Refashioned the interactive convenience functions of ~denote-type~, ~denote-date~, ~denote-subdirectory~ to leverage the ~denote-prompts~
user option while calling ~denote~ interactively. In practical terms,
they no longer accept any arguments when called from Lisp. Users who
need a programmatic approach are advised to either call ~denote~
directly, or check how these commands ~let~ bind the ~denote-prompts~
to carry out their operations. The doc string of each command
explains how it works. Or evaluate this to check the manual:
#+begin_src emacs-lisp
(info "(denote) Convenience commands for note creation")
#+end_src
Else visit:
<https://protesilaos.com/emacs/denote#h:887bdced-9686-4e80-906f-789e407f2e8f>
+ Documented how the user option ~denote-directory~ can accept a local
value. This is pertinent to scenaria where the user needs to maintain
separate directories of notes. By "separate" we mean sets of notes
that do not communicate with each other, cannot create links between
them, etc. The manual delves into the technicalities. If you have
the Info entry installed, evaluate:
#+begin_src emacs-lisp
(info "(denote) Maintain separate directories for notes")
#+end_src
Else visit:
<https://protesilaos.com/emacs/denote#h:15719799-a5ff-4e9a-9f10-4ca03ef8f6c5>.
Thanks to user "Summer Emacs" for starting the discussion on the
mailing list, and Benjamin Kästner for their participation:
<https://lists.sr.ht/~protesilaos/denote/%3Cm25yk5e856.fsf@gmail.com%3E>.
+ Added an entry to the manual's Frequently Asked Questions about a
failed search for backlinks. It includes sample code that users of
Windows can apply, if necessary. (The error is not Denote's fault.)
Thanks to Benjamin Kästner for the patch, which is below the ~15 line
threshold and thus does not require copyright assignment to the Free
Software Foundation:
<https://lists.sr.ht/~protesilaos/denote/%3Cce117b14-55cf-622e-6cd8-0af698091ae3%40gmail.com%3E>.
+ Removed duplicate entries from the list of file paths that the =xref=
library returns for the purposes of backlinking. Thanks to
Jean-Philippe Gagné Guay for the contribution in pull request 44 on
the GitHub mirror: <https://github.com/protesilaos/denote/issues/44>.
+ Applied an appropriate face to the backlinks' button to mitigate an
error. Thanks to Jean-Philippe Gagné Guay for the contribution in
pull request 45 on the GitHub mirror and for later testing a
subsequent tweak: <https://github.com/protesilaos/denote/issues/45>.
+ Simplfied all the faces we define to make them work with all themes.
The previous colours were consistent with the =modus-themes=:
<https://protesilaos.com/emacs/modus-themes>.
+ Refined how strings are sluggified under all circumstances. Before, a
nil value for the user option ~denote-allow-multi-word-keywords~ would
have the adverse effect of joining all the strings in the title field
of the file name. The intent always was to do that only for
multi-word keywords, not the title. This change was part of a hotfix,
formalised as version =0.2.1= a day after the release of =0.2.0=.
+ Made the fontification rules more robust, while avoiding any false
positives. This was done over a series of commits as it had
implications for the file name permutations that were mentioned
earlier. Thanks to Jean-Philippe Gagné Guay for the patches and/or
discussion about the merits of each change and concomitant
considerations:
- https://github.com/protesilaos/denote/pull/36
- https://github.com/protesilaos/denote/pull/38
- https://github.com/protesilaos/denote/pull/40
- https://github.com/protesilaos/denote/pull/42
+ Rewrote all relevant entries in the manual to reflect all the
user-facing aspects of the aforementioned.
+ Discussed a use-case of rewriting old journal entries as Denote-style
files. As of this writing, we do not support migration of files in
bulk. It might happen at some point, though it is no mean task.
Thanks to Summer Emacs and Alan Schmitt for their participation:
<https://lists.sr.ht/~protesilaos/denote/%3Cm27d4mbktj.fsf%40gmail.com%3E>.
An aside here as this topic was brought up: my packages are open to
users of all skill levels and is why I maintain a mailing list as well
as mirrors of the official git repository on SourceHut. Do not
hesitate to ask a question. If, for whatever reason, those
communication channels are not appropriate, you are welcome to contact
me in private: <https://protesilaos.com/contact>.
Thanks again to Jean-Philippe Gagné Guay for the numerous contributions.
Please read the commit log for the minutia, as this change log entry
omitted some of the finer yet important details.
* Version 0.2.0 on 2022-07-04
:PROPERTIES:
:CUSTOM_ID: h:2002fee6-3f0c-48be-9727-6d4e20f34856
:END:
+ Version =0.1.0= (from 2022-06-27) was never built as a package. The
reason is that the GNU ELPA machinery reads the =Version:= header of
the main file, not the git tag. As the original commit in =denote.el=
included =Version: 0.1.0=, GNU ELPA rightly tries to build the package
using that reference. But because at that time I had not yet updated
the Copyright header to name the Free Software Foundation, the package
could not be prepared. As such, please consider this release to be
the "first formal stable version". My apologies for the delay,
contrary to what was promised in the last change log entry.
- Prospective users are advised to read the manual:
<https://protesilaos.com/emacs/denote>. For a video demonstration:
<https://protesilaos.com/codelog/2022-06-18-denote-demo/>.
- Thanks to Benjamin Kästner for reporting the issue with the GNU ELPA
package on the mailing list:
<https://lists.sr.ht/~protesilaos/denote/%3C9d600ff0-4fed-2ad7-5dbc-5a194639a045@gmail.com%3E>.
+ Originally, Denote was designed to only work with notes in a flat
directory. With code contributions from Jean-Philippe Gagné Guay,
support for subdirectories of the user option ~denote-directory~ is
now available. This covers the case of creating links between notes,
following them, and viewing the backlinks' buffer of the current
entry.
- Thanks to Jean-Philippe for the contributions which took place on
the GitHub mirror: + <https://github.com/protesilaos/denote/pull/24>
+ <https://github.com/protesilaos/denote/pull/25> + <https://github.com/protesilaos/denote/pull/26>
- Jean-Philippe Gagné Guay has assigned copyright to the Free Software
Foundation. This is a prerequisite to contribute code to any
package on the official GNU ELPA archive (and to emacs.git for that
matter).
+ The new ~denote-subdirectory~ command lets the user select a directory
to place the new note in. Available candidates are the value of the ~denote-directory~ as well as all of its subdirectories, minus =.git=.
In future versions, we will consider how to provide a blocklist or a
regexp filter for the user to specify which subdirectories should be
omitted from minibuffer completion. Please consider providing your
feedback on the technicalities.
- Thanks to Jean-Philippe Gagné Guay and Shreyas Ragavan for the
feedback in issue 31 on the GitHub mirror:
<https://github.com/protesilaos/denote/issues/31>.
- Thanks to Jean-Philippe Gagné Guay for fixing a potential problem in
how directories are represented when commands enter the directory
instead of selecting it (again, at the GitHub mirror):
<https://github.com/protesilaos/denote/pull/35>.
+ From 2022-06-24 to 2022-07-03, Denote provided support for links
between Org notes that leveraged the =id:= hyperlink type.
Discussions on the mailing list and the GitHub mirror revealed the
longer-term problems in our implementation. In the Annex below, I
provide my detailed opinion on the matter. The gist is that Denote
does not---and will not---create =id:= links between its notes, but
shall use the =denote:= hyperlink type instead (which works like the
standard =file:= type). As the Annex explains, Denote is not org-roam
lite and we try not to engender such false expectations.
- Despite the fact that the relevant patches are no longer applicable,
I wish to thank Kaushal Modi and Jean-Philippe Gagné Guay for their
contributions over at the GitHub mirror:
+ <https://github.com/protesilaos/denote/pull/20> + <https://github.com/protesilaos/denote/pull/28>
+ The user option ~denote-date-format~ controls how the date and time is
recorded in the file's contents (what we call "front matter"). When
nil (the default value), we use a file-type-specific format (also
check the user option ~denote-file-type~):
- For Org, an inactive timestamp is used, such as =[2022-06-30 Wed 15:31]=.
- For Markdown, the RFC3339 standard is applied: =2022-06-30T15:48:00+03:00=.
- For plain text, the format is that of ISO 8601: =2022-06-30=.
If the value is a string, ignore the above and use it instead. The
string must include format specifiers for the date. These are described
in the doc string of ~format-time-string~.
The ~denote-date-format~ supersedes the now obsolete ~denote-front-matter-date-format~.
Thanks to Peter Prevos and Kaushal Modi for their feedback in issue 27
on the GitHub mirror: <https://github.com/protesilaos/denote/issues/27>.
+ All the faces we define are now declared in the =denote-faces.el=
file. The fontification rules are shared by ~denote-dired-mode~ and
the backlinks' buffer (invoked by ~denote-link-backlinks~ and
controlled by the user option ~denote-link-fontify-backlinks~). The
current list of faces:
- ~denote-faces-date~
- ~denote-faces-delimiter~
- ~denote-faces-extension~
- ~denote-faces-keywords~
- ~denote-faces-subdirectory~
- ~denote-faces-time~
- ~denote-faces-title~
+ Named the mailing list address as the =Maintainer:= of Denote.
Together with the other package headers, they help the user find our
primary sources and/or communication channels. This change conforms
with work being done upstream in package.el by Philip Kaludercic. I
was informed about it here:
<https://lists.sr.ht/~protesilaos/general-issues/%3C875ykl84yi.fsf%40posteo.net%3E>.
+ Fixed how keywords are inferred and combined. The previous code did not
work properly when the user option =denote-infer-keywords= was nil.
It would return a list of symbols, with the parentheses, whereas the
file name needs a string where each keyword is delimited by an
underscore.
+ Simplified how information in the front matter is retrieved. It fixes
cases where, for example, a special character at the end of the title
was ignored. Thanks to Jean-Philippe Gagné Guay for the patch over at
the GitHub mirror: <https://github.com/protesilaos/denote/pull/21>.
+ Rewrote parts of the manual in the interest of clarity.
** Annex about discontinuing support for org-id
:PROPERTIES:
:CUSTOM_ID: h:647d6155-1ac3-4ecb-bd4c-06d09fecd3ba
:END:
My thanks for their participation in the discussions go to Jean-Philippe
Gagné Guay, Kaushal Modi, and Shreyas Ragavan.
#+begin_example
commit f35ef05cb451f265213c3aafc1e62c425b1ff043
Author: Protesilaos <info@protesilaos.com>
Date: Sun Jul 3 17:34:38 2022 +0300
REMOVE support for 'id:' hyperlink types
The original idea was to support the 'org-id' library on the premise
that it makes Denote a good Emacs citizen. However, discussions on the
mailing list[0] and the GitHub mirror[1] have made it clear to me that
'org-id' is not consistent with Denote's emphasis on simplicity.
To support the way 'org-id' works, we will eventually have to develop
some caching mechanism, just how the org-roam package does it. This is
because the variable 'org-id-extra-files' needs to be kept up-to-date
whenever an operation on a file is performed. At scale, this sort of
monitoring requires specialised software. Such a mechanism is outside
the scope of Denote---if you need a db, use org-roam which is already
great.
[0] <https://lists.sr.ht/~protesilaos/denote/%3C8735fk4y1w.fsf%40hallac.net%3E#%3C877d4un73c.fsf@protesilaos.com%3E>
[1] <https://github.com/protesilaos/denote/issues/29>
Quote of what I wrote on the GitHub mirror issue 29:
[ggjp] This is what I was implying. That we are, in fact,
providing an option that is not viable long-term, but keeping
the option for expert users who will be able to handle this.
And we should warn about this clearly in the doc of that option.
[protesilaos] What you write here @ggjp and what @shrysr explained
tells me that those expert users will need to be real experts. To
put it concretely, I am an experienced Emacs user with no
programming background, who has written several Emacs
packages (including the modus-themes which are built into Emacs),
but I have zero knowledge of using a db or of handling things with
python and the like. So if I opt in to 'denote-link-use-org-id' I
will eventually run into problems that my non-existent skills will
prevent me from solving. At that point, I will just use org-roam
which already handles this use-case in a competent way (and has a
massive community to rely on in case I need further support).
If each package needs to write its own optimisations and maintain
its own cache, to me this shows that 'org-id' is not good enough for
the time being: more work needs to be done in org.git to provide a
universal solution.
I wanted to support 'org-id' by default on the premise that Denote
must be a good Emacs citizen which interoperates with the rest of
the wider ecosystem. But if 'org-id' leaves something to be
desired, then that goal is not worth pursuing: we add complexity to
our code, offer an option that we cannot genuinely/adequately
support, and make usage of it contingent on reading the docs and
having a high level of expertise.
I think being a good Emacs citizen is a laudable principle. In this
case, the right thing to do is to recommend the use of org-roam
instead of trying to accommodate 'org-id'. As such, I have now
changed my mind and think we should remove what we previously added.
For some context here: the reason I never used org-roam is
because (i) it is Org-specific whereas I write notes in different
file types and (ii) I did not want to ever rely on a db or
equivalent dependency.
<https://github.com/protesilaos/denote/issues/29#issuecomment-1173036924>
README.org | 226 ++++++++---------------------------------------------
denote-link.el | 99 ++++++-----------------
denote-retrieve.el | 2 +-
denote.el | 14 +---
4 files changed, 63 insertions(+), 278 deletions(-)
#+end_example
Followed up by my explanation:
#+begin_src text
> can we not have denote style links to be default for (de)notes - and
> explicitly supported, while if they need to, users can still link
> denote org files via org-id to any other notes/files (and vice versa)
> -- in which case performance + testing for org-id driven linking is
> not within Denote's purview at all?
The formal support for `id:` links was added shortly before the release
of version `0.1.0`. In the days prior, we supported what you describe
via the manual. The user could change the `denote-org-front-matter`
variable to include a `PROPERTIES` drawer. This possibility still
exists, though yesterday I removed the relevant entry from the manual.
This way only the real do-it-yourself experts will go down that path.
My concern here is with managing expectations. If our Org notes are
superficially the same as org-roam's, an unsuspecting user may think
that Denote is an org-roam lite. We will thus get issues/requests, such
as those already mentioned in this GitHub repo, about migrating from
org-roam to Denote. While there are similarities, Denote is not a
minimalist org-roam and I would not like to encourage the idea of
treating the two as interchangeable.
Doing things half-way-through is a way to create false expectations. A
package on GNU ELPA must be usable by users of all skill levels. If the
functionality we provide is incomplete and needs to be covered by
user-level tweaks, we are excluding a portion of the user base while
still assuming the maintenance burden. If someone trusts Denote to,
say, write a 1000 notes, we do not want to surprise them after the fact.
Imagine if the reported issues that triggered this change happened 6
months into one's daily usage of Denote: it wouldn't be nice.
Setting the right expectations is a matter of responsibility: we let the
user make a more informed choice and show respect for their time. It
also makes it easier for me to keep Denote's scope in check by not
supporting every little extra that Org implements. The premier Org
extension is org-roam: we do not need another one (or, if we do, I am
not the one to implement it).
,* * *
Some comments on the `denote:` hyperlink type for Org as they may be
relevant in this context:
,* It is meant to work like the standard `file:` type. This means that
it links to a file, while it can also have additional search
parameters, as explained in the Org manual. Evaluate:
(info "(org) Search Options")
,* It does not read the front matter, but only the file name. You can
create a note as usual, delete all its contents, save it, and try to
link to it from another note. It works.
,* Exporting now works like the `file:` type for HTML, LaTeX, Texinfo,
and Markdown. Technically, it also supports the ASCII backend but the
format of the output could be tweaked further.
There may be refinements to be made, which is okay as that is part of a
maintainer's duties.
#+end_src
* Version 0.1.0 on 2022-06-27
:PROPERTIES:
:CUSTOM_ID: h:33939747-ad60-4913-a170-4b2f48f139cc
:END:
The present entry is intended for early adopters of Denote who may have
not caught up with the latest developments. Prospective users are
advised to read the manual: <https://protesilaos.com/emacs/denote>. For
a video demonstration: <https://protesilaos.com/codelog/2022-06-18-denote-demo/>.
+ The =denote= package on GNU ELPA will be available a few hours after
this release. GNU ELPA provides the latest stable release. To use a
development snapshot, read:
<https://protesilaos.com/codelog/2022-05-13-emacs-elpa-devel/>.
+ Remember that any significant contribution (above ~15 lines) requires
copyright assignment to the Free Software Foundation. A form with
instructions is included in the manual's "Contributing" section:
<https://protesilaos.com/emacs/denote#h:1ebe4865-c001-4747-a6f2-0fe45aad71cd>.
+ The front matter of notes in Org has changed to be compliant with the
standard =org-id= infrastructure. A =PROPERTIES= drawer is added to
the top of the file, which includes an =ID= property with the value of
the Denote identifier. Sample:
#+begin_src org
:PROPERTIES:
:ID: 20220610T202537
:END:
,#+title: Sample Org front matter
,#+date: 2022-06-10
,#+filetags: denote testing
#+end_src
+ The front matter of Markdown (YAML or TOML) and plain text files
remains constant. For completeness, this is how they look:
#+begin_src md
---
title: "Sample with Markdown and YAML"
date: 2022-06-10
tags: denote testing
identifier: "20220610T202021"
---
#+end_src
#+begin_src md
+++
title = "Sample with Markdown and TOML"
date = 2022-06-10
tags = ["denote", "testing"]
identifier = "20220610T201510"
+++
#+end_src
#+begin_example
title: Sample plain text
date: 2022-06-10
tags: denote testing
identifier: 20220610T202232
---------------------------
#+end_example
+ The integration with =org-id= extends to how linking works. By
default, Denote uses its own custom hyperlink type which starts with
the =denote:= prefix. In Org, it works like the =file:= type. When
the user option ~denote-link-use-org-id~ is non-nil, links from Org
notes to other Org notes will use the standard =id:= type instead. As
this is an Org-specific feature, Denote takes care to use the
major-mode-agnostic =denote:= type when the link targets a non-Org
note.
+ In Org files the links created by Denote are buttonized automatically.
For Markdown and plain text, we use our own methods. When a link is
inserted it is buttonized outright. To buttonize links in existing
notes while visiting them in a buffer, add/evaluate this (it excludes
Org on its own):
#+begin_src emacs-lisp
(add-hook 'find-file-hook #'denote-link-buttonize-buffer)
#+end_src
+ The generation of the backlinks' buffer now uses the built-in =xref=
library instead of relying on a hardcoded call to the =find=
executable. This means that the ~denote-link-backlinks~ command will,
in principle, work properly with all Emacs builds.
+ Users of Emacs 28 or higher can configure ~xref-search-program~ to
change from the default =grep= to =ripgrep=, =ugrep=, or a
user-defined alternative.
+ This is the first stable release of Denote. It covers close to 400
commits starting from 2022-06-04. Denote is the successor to a toy
package of mine, USLS, whose first public version was made available
in early November 2020: <https://gitlab.com/protesilaos/usls>.
+ Thanks to everyone involved in the development of Denote. Code
contributions, bug reports, discussion of ideas, are all valuable.
From A-Z the names mentioned in the manual's "Acknowledgements"
section: Colin McLear, Damien Cassou, Frank Ehmsen, Jack Baty, Kaushal
Modi, Peter Povinec, Sven Seebeck, Ypot.
+ Sources of Denote:
+ Package name (GNU ELPA): =denote=
+ Official manual: <https://protesilaos.com/emacs/denote>
+ Change log: <https://protesilaos.com/emacs/denote-changelog>
+ Git repo on SourceHut: <https://git.sr.ht/~protesilaos/denote>
- Mirrors:
+ GitHub: <https://github.com/protesilaos/denote>
+ GitLab: <https://gitlab.com/protesilaos/denote>
+ Mailing list: <https://lists.sr.ht/~protesilaos/denote>