Compare commits

..

212 commits
4.1.3 ... main

Author SHA1 Message Date
Protesilaos 110ced9999
Acknowledge kimsaram32 for commit 840ca21
This was done in pull request 728: <https://github.com/protesilaos/denote/pull/728>.
The change is small, meaning that its author does not need to assign
copyright to the Free Software Foundation.
2026-09-09 14:37:04 +03:00
Protesilaos 32d83aa68b
Merge pull request #728 from kimsaram32/docs-remove-obsolete-functions
Remove obsolete functions in the documentation
2026-09-09 14:35:59 +03:00
kimsaram32 840ca21f92 Remove obsolete functions in the documentation 2026-09-09 19:31:13 +09:00
Protesilaos 0a157981e5
Rename a helper function to be private and have a more accurate name
Also tweak its docstring.
2026-08-28 16:40:30 +03:00
Protesilaos 2c8cf137ac
Fix typo in the manual
Thanks to Ali Bozorgzadeh for reporting it in issue 727:
<https://github.com/protesilaos/denote/issues/727>.
2026-08-27 17:38:03 +03:00
Protesilaos e401e70405
Merge pull request #726 from jeanphilippegg/move-unix-timestamps-code
Move Unix timestamps code in `denote-valid-date-p`
2026-08-24 12:35:53 +03:00
Jean-Philippe Gagné Guay ec73303bff Move Unix timestamps code in denote-valid-date-p 2026-08-23 21:38:04 -04:00
Protesilaos 42085330f3
Update the :package-version of denote-org-store-link-to-heading
This is because it now has a new option, per commit b90b26e (pull
request 723 by Michael Korat: <https://github.com/protesilaos/denote/pull/723>).
2026-08-23 13:33:39 +03:00
Protesilaos 27cdd67b68
Document denote-org-store-link-to-heading "local" value in the manual
This was introduced by Michael Korat in commit 9a354e4 as part of pull
request 723: <https://github.com/protesilaos/denote/pull/723>.
2026-08-23 13:31:39 +03:00
Protesilaos b90b26e938
Acknowledge Michael Korat for commit 9a354e4
This was done in pull request 723: <https://github.com/protesilaos/denote/pull/723>.
The change is small, meaning that Michael does not need to assign
copyright to the Free Software Foundation.
2026-08-23 13:06:01 +03:00
Protesilaos 5effab91ca
Merge pull request #723 from mkorat/main
Add option to use simple heading links to denote-link-ol-store.
2026-08-23 13:05:08 +03:00
Protesilaos 9ae9d0e1ea
Make stylistic change to denote--date-parse-string
The original was contributed by Jeff Valk in commit 9083ad7, pull
request 722: <https://github.com/protesilaos/denote/pull/722>.
2026-08-10 11:38:16 +03:00
Protesilaos 8f7e988a67
Acknowledge Jeff Valk for commit 9083ad7
This was done in pull request 722: <https://github.com/protesilaos/denote/pull/722>.
The change is small, meaning that Jeff does not need to assign
copyright to the Free Software Foundation.
2026-08-10 11:30:39 +03:00
Protesilaos 7d0c06e0a4
Merge pull request #722 from jeffvalk/main
Support Unix timestamps in date input
2026-08-10 11:29:47 +03:00
Michael Korat 9a354e4362 Add option to use simple heading links to denote-link-ol-store. 2026-08-09 20:58:32 +02:00
Jeff Valk 9083ad781e Support Unix timestamps in date input
This allows for other recognized date patterns to be supported as well.
2026-07-31 12:20:10 -04:00
Protesilaos 3718a60305
Make denote-query-focus-last-search reuse the existing query buffer 2026-07-29 13:05:00 +03:00
Protesilaos 5b632ae958
Make denote-query-* commands work as intended in the backlinks buffer
Thanks to 82Kang for reporting the bug in issue 695:
<https://github.com/protesilaos/denote/issues/695>.
2026-07-29 13:04:16 +03:00
Protesilaos b4978d83cb
Make denote-link--collect-identifiers remove duplicates
Thanks to 82Kang for reporting the bug in issue 694:
<https://github.com/protesilaos/denote/issues/694>.
2026-07-29 12:55:45 +03:00
Protesilaos c8aa01c56a
Add denote-slug-remove-accents function
This is based on the code originally written by Jean-Philippe Gagné
Guay in issue 603: <https://github.com/protesilaos/denote/issues/603#issuecomment-2869702877>.
I made stylistic changes to it to make it fit with the rest of denote.el.

I am adding this in response to issue 603 and 718:

- <https://github.com/protesilaos/denote/issues/603> with
  participation from Davi Ramos and Jean-Philippe Gagné Guay;
- <https://github.com/protesilaos/denote/issues/718> with
  participation from o-rxw and Alan Schmitt.

In implementing this, I am changing my mind that this is purely a
documentation issue. I realised it is better for us to have the main
function in denote.el, so that we can test it better.
2026-07-27 19:53:13 +03:00
Protesilaos 1004f735b7
Mention the SIGNATURE in the docstring of all front matter variables
Thanks to Alan Schmitt for telling me this was missing. It was done in
issue 714: <https://github.com/protesilaos/denote/issues/714>.
2026-07-07 22:56:49 +03:00
Protesilaos 65f1bbf1de
Acknowledge Pavlo V. Lysov for commit 72d90f4
This is about mentioning Pavlo's 'denote-solo' package in the Denote
manual.

Done in pull request 713: <https://github.com/protesilaos/denote/pull/713>.
2026-07-06 10:31:07 +03:00
Protesilaos 8c80d91d06
Merge pull request #713 from pavlo/main
Add a section for denote-solo package
2026-07-06 10:28:12 +03:00
Pavlo V. Lysov 72d90f474e Add a section for denote-solo package 2026-07-06 08:49:53 +03:00
Protesilaos cd422b1d22
Acknowledge Matthieu Muller for commit 35d3a2a
This was done in pull request 711: <https://github.com/protesilaos/denote/pull/711>.
The change is small, menaing that Matthieu does not need to assign
copyright to the Free Software Foundation.
2026-06-11 21:41:01 +03:00
Protesilaos 04c39a157f
Merge pull request #711 from matthieumuller/add-denote-paperless-to-docs
Add a section on denote-paperless.el in the documentation
2026-06-11 21:39:34 +03:00
Matthieu MULLER 35d3a2a724 Add a section on denote-paperless.el in the documentation 2026-06-11 14:12:31 -04:00
Protesilaos 9fd6692a32
Bump version number to trigger GNU ELPA package rebuild to include commit 420710f 2026-05-27 20:30:00 +03:00
Protesilaos 420710fb17
Ensure :get-file-type-function is called only when file exists
Otherwise we get an error upon creating the file.

Thanks to potchie-maker for reporting the bug in issue 709:
<https://github.com/protesilaos/denote/issues/709>.
2026-05-27 20:28:38 +03:00
Protesilaos 77813e9956
Bump version number to trigger GNU ELPA rebuild
I am bumping it straight to 4.2.2 because I had a tag earlier for
4.2.1 even though I forgot to update this header...
2026-05-23 23:15:15 +03:00
Protesilaos cf1c81cba9
Make stylistic tweak to denote-file-prompt--format-identifier 2026-05-23 23:12:49 +03:00
Protesilaos 32960f828b
Acknowledge Marco Baringer for commits d47464e, 6ba2097
Those were sent as part of pull request 708: <https://github.com/protesilaos/denote/pull/708>.

The changes are small, meaning that Marco does not need to assign
copyright to the Free Software Foundation.
2026-05-23 23:10:04 +03:00
Protesilaos 197b0acd38
Merge pull request #708 from segv/main
denote-open-or-create errors in directories with oddly-named files (#707)
2026-05-23 23:09:24 +03:00
Marco Baringer d47464e23b
Require non-empty captures in the four field regexps
denote-{identifier,signature,title,keywords}-regexp used a lazy
zero-or-more capture ([^.]*?), so they matched the bare separator
followed by an extension, e.g. __.js, --.org, ==.org, @@.org. Combined
with denote-file-has-denoted-filename-p, this meant such files were
treated as valid denote notes. lodash's node_modules ships __.js files,
which made a denote-directory containing a lodash checkout enumerate
junk candidates in the file prompt (and previously crash, see preceding
commit).

Switch to a non-empty lazy capture ([^.]+?) so the field must contain at
least one character.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 16:20:49 +02:00
Marco Baringer 6ba209704d
Fix file-prompt crash when denote-directory contains files like __.js
Using denote in a directory that includes files matching '*/__.js'
breaks with "Wrong type argument: stringp, nil" on the file prompt.
lodash ships such files in node_modules, so accidentally pointing
denote at a lodash checkout (or having one under denote-directory)
triggers the error.

These files pass denote-file-has-denoted-filename-p because the empty
keywords section matches denote-keywords-regexp, but they have no
identifier, so denote-file-prompt--format-identifier passed nil to
propertize during affixation. Return nil in that case;
denote-file-prompt-affixate already substitutes "" for a nil prefix.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 16:17:47 +02:00
Protesilaos 30c0d6536e
Be precise in the denote-file-prompt-extra-metadata docstring 2026-05-21 20:09:22 +03:00
Protesilaos 13b2164369
Update to Denote version 4.2.0 2026-05-20 15:41:08 +03:00
Protesilaos e40bdc8cdc
Remove spacing in denote--get-front-matter-rewrite-prompt 2026-05-20 15:24:30 +03:00
Protesilaos 3ef7380190
Remove the denote-sort-dired-focus alias
I want to reach a point where only denote-dired and related are used.
Maybe this is more appropriate for the next major version, but I can
do it here since this is a new command.
2026-05-20 12:37:13 +03:00
Protesilaos ea398e9a2a
Throw a user-error if denote-dired-focus is called in a Dired buffer without prior denote-dired 2026-05-20 12:35:57 +03:00
Protesilaos dbfe4b189a
Remove faulty 'or' from denote--dir-in-denote-directory-p
Thanks to Jean-Philippe Gagné Guay for pointing out the problem with
it in a comment to issue 705:
<https://github.com/protesilaos/denote/issues/705#issuecomment-4436808008>.
2026-05-13 11:12:45 +03:00
Protesilaos 3f5ede71d4
Reindent denote-valid-date-p 2026-05-12 13:26:37 +03:00
Protesilaos 1aedcff2d7
Make stylistic tweaks to denote--prepare-note 2026-05-12 13:25:01 +03:00
Protesilaos 59eea50d4b
Reindent denote--valid-file-type 2026-05-12 13:22:35 +03:00
Protesilaos 21b1c81d1a
Make denote--dir-in-denote-directory-p more robust
This is in response to a bug reported by Kevin Izevbigie in issue 705:
<https://github.com/protesilaos/denote/issues/705>.
2026-05-12 13:18:27 +03:00
Protesilaos d7dab477a1
Document the denote-lint package 2026-05-01 18:56:52 +03:00
Protesilaos 0ff9573362
Make stylistic refinements to the helpers introduced in 8e6d83c
I was testing them and was too eager to commit before refining them.
Will need to write tests eventually, but I do not have time right now.
2026-05-01 18:48:34 +03:00
Protesilaos 8e6d83c652
Make rename commands not interfere with existing front matter indentation
This is to address the comment posted by Morten Kjeldgaard in issue
703: <https://github.com/protesilaos/denote/issues/703>.
2026-05-01 18:40:39 +03:00
Protesilaos 06c520de36
Do for the keyword include/exclude commands the same as commit 9b8c96f 2026-04-28 23:31:03 +03:00
Protesilaos 9b8c96f5e8
Redefine denote-query-only-include-files and denote-query-exclude-files to use helper function
The macro we had before was okay, but this feels easier to reason about.
2026-04-28 23:27:03 +03:00
Protesilaos d78ad3f74e
Make denote-link-ol-store work in org-capture as well
This affects the org-capture specifiers that create a link such as %a
and %l.

Thanks to jarofromel for bringing this matter to my attention in
discussion 702: <https://github.com/protesilaos/denote/discussions/702>.
2026-04-28 22:56:36 +03:00
Protesilaos 8112e65bc3
Acknowledge nescias for commit c772378
This was sent to me as a patch via email. The change is small, meaning
that its author does not need to assign copyright the Free Software
Foundation.
2026-04-28 18:47:30 +03:00
nescias c7723784b9
Fix typos in documentation 2026-04-28 17:24:36 +03:00
Protesilaos b5be053380
Document the ~denote-wordcloud package 2026-04-27 23:16:11 +03:00
Protesilaos f113e49988
Document the denote-sections package by Samuel W. Flint
Thanks to Samuel for bringing this matter to my attenion in issue 701:
<https://github.com/protesilaos/denote/issues/701>.
2026-04-27 22:47:57 +03:00
Protesilaos 3cd8d47c00
Document the denote-regexp package by Samuel W. Flint
Thanks to Samuel for bringing this matter to my attenion in issue 701:
<https://github.com/protesilaos/denote/issues/701>.
2026-04-27 22:45:51 +03:00
Protesilaos 348d851eb4
Document the denote-project-notes package by Samuel W. Flint
Thanks to Samuel for bringing this matter to my attenion in issue 701:
<https://github.com/protesilaos/denote/issues/701>.
2026-04-27 22:36:42 +03:00
Protesilaos 7babe195ee
Document the denote-agenda package by Samuel W. Flint
Thanks to Samuel for bringing this matter to my attenion in issue 701:
<https://github.com/protesilaos/denote/issues/701>.
2026-04-27 22:32:25 +03:00
Protesilaos aedbb0cecd
Document the denote-journal-capture package by Samuel W. Flint
Thanks to Samuel for bringing this matter to my attenion in issue 701:
<https://github.com/protesilaos/denote/issues/701>.
2026-04-27 22:25:58 +03:00
Protesilaos 97ffb56320
Use "Protesilaos" instead of "Protesilaos Stavrou"
As I announced here: <https://protesilaos.com/news/2026-04-21-omitting-the-surname/>.
2026-04-24 13:26:01 +03:00
Protesilaos 7574b8cecd
Document in the manual the functions to get the file type for YAML and TOML 2026-04-23 21:25:34 +03:00
Protesilaos 29fd39a4d4
Make sure the denote-file-type function is registered in the function index 2026-04-23 21:25:14 +03:00
Protesilaos 87a4a02afa
Document denote-file-type function in the manual 2026-04-23 21:19:57 +03:00
Protesilaos dd4551ad9c
Rewrite the doc string of denote-file-type 2026-04-23 21:17:20 +03:00
Protesilaos 231d7d64e8
Write a test for denote-file-type 2026-04-23 21:02:08 +03:00
Protesilaos ee1ad314fc
Add :get-file-type-function to the denote-file-type function 2026-04-23 21:01:38 +03:00
Protesilaos 8b9a4e511d
Add a :get-file-type-function to the denote-file-types 2026-04-23 21:00:59 +03:00
Protesilaos 5281b7c3fc
Add a comment related to where denote--title-value-reverse-function is called 2026-04-23 19:55:38 +03:00
Protesilaos 207a365b83
Expand the TODO comment about denote-file-type 2026-04-23 19:30:51 +03:00
Protesilaos 568c807d8d
Add a TODO about denote-file-type 2026-04-23 19:27:16 +03:00
Protesilaos ec4fed24f7
Prevent denote-retrieve-xref-alist-for-backlinks from throwing an error if file type is nil 2026-04-23 19:09:09 +03:00
Protesilaos 383c52be8d
Acknowledge GuutBoy for reporting a bug in denote-markdown
This was done in issue 699: <https://github.com/protesilaos/denote/issues/699>.
2026-04-23 19:07:39 +03:00
Protesilaos Stavrou 5e995cfecc
Acknowledge gnuhack for commit aaa75e7
This was done as part of pull request 697: <https://github.com/protesilaos/denote/pull/697>.
The change is small, repurposing existing code, meaning that the
author does not need to assign copyright to the Free Software Foundation.
2026-04-21 08:38:09 +03:00
Protesilaos Stavrou 59e1304a67
Merge pull request #697 from gnuhack/patch-2
Macro for denote-query-exclude-files and denote-query-only-include-files
2026-04-21 08:37:08 +03:00
gnuhack aaa75e7f13
Macro for denote-query-exclude-files and denote-query-only-include-files
Replaced both functions with a new macro. Created the new functions through the macro.
2026-04-20 12:47:02 +02:00
Protesilaos Stavrou c3b60fcada
Replace "doc string" with "docstring" 2026-04-13 08:41:39 +03:00
Protesilaos Stavrou f6499cbf5c
Merge branch 'main' of github.com:protesilaos/denote 2026-04-09 21:16:03 +03:00
Protesilaos Stavrou 0993df4fbc
Fix typo about "keymap" 2026-04-09 21:11:40 +03:00
Protesilaos Stavrou b77b926505
Merge pull request #696 from gnuhack/patch-1
Fix typo
2026-04-09 08:19:36 +03:00
gnuhack 63c052e1ac
Fix typo 2026-04-09 00:09:56 +02:00
Protesilaos Stavrou 160444b853
Mention denote-dired-focus in the manual and expand its docstring 2026-04-07 12:11:54 +03:00
Protesilaos Stavrou 4483caee95
Update the manual's acknowledgements
This is about the idea behind denote-dired-focus, as discussed in
issue 693: <https://github.com/protesilaos/denote/issues/693>.
2026-04-07 12:03:23 +03:00
Protesilaos Stavrou b4924c853d
Make denote-sort-dired always produce a new buffer
Thanks to 82Kang for telling me about the use-case of maintaining
multiple Denote Dired buffers side-by-side. This is done as part of
issue 693: <https://github.com/protesilaos/denote/issues/693>.
2026-04-07 11:55:38 +03:00
Protesilaos Stavrou e5260315ec
Merge branch 'denote-dired-focus' of github.com:protesilaos/denote into denote-dired-focus 2026-04-07 11:39:37 +03:00
Protesilaos Stavrou 21b8c6d024
Implement prototype of denote-dired-focus
I am doing this in response to a question posted by 82Kang in issue
693: <https://github.com/protesilaos/denote/issues/693>.

We already have similar functionality for the denote-grep (and
related) buffers. This is an opportunity for me to also review all
that.
2026-04-07 11:39:28 +03:00
Protesilaos Stavrou fd4d20b472
Make small stylistic tweaks to denote-grep and a helper function 2026-04-07 11:32:30 +03:00
Protesilaos Stavrou 9dc7420031
Tweak the denote-grep-display-buffer-action documentation 2026-04-07 11:32:13 +03:00
Protesilaos Stavrou beb698f632
Deprecate the denote-grep-history 2026-04-07 11:22:26 +03:00
Protesilaos Stavrou 1058caea0c
Tweak the make-obsolete warnings for the grep prompt and its history 2026-04-07 11:19:46 +03:00
Protesilaos Stavrou dcb3daf81a
Add TODO for denote-grep and friends 2026-04-06 22:59:03 +03:00
Protesilaos Stavrou 3e8c2c835d
Make stylistic changes and minor refinements to the query include/exclude commands 2026-04-06 22:57:54 +03:00
Protesilaos Stavrou 37beb39c3b
Consolidate the query/grep prompts for a REGEXP 2026-04-06 22:57:20 +03:00
Protesilaos Stavrou 5e4b95a1b7
Make stylistic refinements to denote-query-focus-last-search 2026-04-06 22:30:03 +03:00
Protesilaos Stavrou d0252aff0c
Make stylistic refinements to denote-query-prompt 2026-04-06 22:29:51 +03:00
Protesilaos Stavrou 15415e7956
Refine how the prompt for query buffer narrowing is implemented 2026-04-06 22:23:39 +03:00
Protesilaos Stavrou 2dae5773f2
Rewrite the tests in the interest of clarity and expand them where necessary 2026-04-06 21:58:02 +03:00
Protesilaos Stavrou 7b9be290e5
Inhibit denote--regexp-in-file-p error in denote-file-type
In the case where the check returns nil, we want to move to the next
condition, so no need for an error here.
2026-04-06 21:57:15 +03:00
Protesilaos Stavrou acadd80426
Move denote--regexp-in-file-p further up 2026-04-06 21:56:59 +03:00
Protesilaos Stavrou 53bb758384
Rewrite denote-file-has-denoted-filename-p docstring for clarity 2026-04-06 21:56:43 +03:00
Protesilaos Stavrou ded4c50b8c
Make denote-directories--get-paths take an argument and do error checking 2026-04-06 21:56:24 +03:00
Protesilaos Stavrou 9d5711ea50
Update copyright years in denote-test.el 2026-04-06 20:01:49 +03:00
Protesilaos Stavrou 90d84d6501
Implement prototype of denote-dired-focus
I am doing this in response to a question posted by 82Kang in issue
693: <https://github.com/protesilaos/denote/issues/693>.

We already have similar functionality for the denote-grep (and
related) buffers. This is an opportunity for me to also review all
that.
2026-04-06 12:20:58 +03:00
Protesilaos Stavrou 627ed49989
Move denote--user-error-if-not-major-mode further up 2026-04-06 11:48:25 +03:00
Protesilaos Stavrou 75ef0f827a
Make small refinement to denote-sort-dired 2026-04-06 11:17:17 +03:00
Protesilaos Stavrou 8dfadbc085
Split up denote-sort-dired for legibility and fix a bug with revert-buffer 2026-04-06 10:43:04 +03:00
Protesilaos Stavrou 7852585578
Set denote-file-type explicitly to Org
Otherwise, the user will not necessarily get what they want if they
add to the denote-file-types.
2026-04-02 09:56:45 +03:00
Protesilaos Stavrou e6f6111d3d
Ensure denote--act-on-query-link get the buffer of denote-sort-dired 2026-03-24 14:51:55 +02:00
Protesilaos Stavrou 7f92fd4af3
Acknowledge bplubell for commit d8c2488
This was done in pull request 685: <https://github.com/protesilaos/denote/pull/685>
The change is small, meaning that the author does not need to assign
copyright to the Free Software Foundation.
2026-03-19 07:13:07 +02:00
Protesilaos Stavrou d93056137f
In denote-link--prepare-links pass the file-type to denote-get-link-description 2026-03-19 07:12:31 +02:00
Protesilaos Stavrou 6c0fb263c8
Merge pull request #685 from bplubell/fix-follow-markdown-link
Fix error when following non-Denote Markdown links
2026-03-19 07:09:52 +02:00
bplubell d8c2488622 Fix error when following non-Denote Markdown links
When following links in markdown-mode that are to non-Denote resources
like URLs, you would see the error:

    Cannot open ‘nil’ of unknown link type

That is because Denote adds denote-link-markdown-follow to
markdown-follow-link-functions, which eventually calls
denote--act-on-query-link with a nil value.

To solve this, we return nil from denote-link-markdown-follow when we do
not know how to handle the link. That lets markdown-mode try its link
handling. Per the markdown-follow-link-functions documentation, we
should "return non-nil if [we] followed the link, or nil if not."
2026-03-18 15:46:12 -07:00
Protesilaos Stavrou 76c2e27e80
Document how users can have a custom identifier without "T" in it 2026-03-06 19:23:10 +02:00
Protesilaos Stavrou e1d16ba77b
Make stylistic refinements to denote-link-preview-file
We use a similar approach in related functions for the Org link
mechanism.

This builds on top of the contribution of Samuel W. Flint in pull
request 683: <https://github.com/protesilaos/denote/pull/683>.
2026-02-28 22:22:37 +02:00
Protesilaos Stavrou 2ca985d57b
Acknowledge Samuel W. Flint for commit 3d24ea5
The change is small, meaning that Samuel does not need to assign
copyright to the Free Software Foundation.

This change was done in pull request 683: <https://github.com/protesilaos/denote/pull/683>.
2026-02-28 21:31:01 +02:00
Protesilaos Stavrou 6f3649eff4
Merge pull request #683 from swflint/enable-preview
Enable preview of denote links
2026-02-28 21:29:01 +02:00
Protesilaos Stavrou e7478b1627
Simplify how denote-get-link-description checks for function arity
I found func-arity by chance and immediately thought of this. What I
had before was ugly by comparison, even though its idea made sense.
2026-02-28 21:16:40 +02:00
Samuel W. Flint 3d24ea54eb Enable preview of denote links
Preview will only happen if there is one file with the denote ID/path,
and will work with any format supported by `org-link-preview-file`.
2026-02-24 10:13:06 -06:00
Protesilaos Stavrou 9f5a16f625
Tweak how denote--get-common-root-directory checks absolute paths to also work on Windows
I do not have a Windows machine to test this, though it seems
reasonable. I am doing this in response to issue 682 by Pratik-Mishra-497:
<https://github.com/protesilaos/denote/issues/682>.
2026-02-23 17:50:39 +02:00
Protesilaos Stavrou da0685d48d
Expand the manual with how to auto-encrypt new notes with a custom file type
I did this in response to issue 681 by Michael Jones:
<https://github.com/protesilaos/denote/issues/681>.
2026-02-13 13:52:34 +02:00
Protesilaos Stavrou e5d5a4f2d9
Clarify that denote-sequence is its own package
It used to be part of denote.git, but I moved it to its own repository.
2026-02-07 16:09:15 +02:00
Protesilaos Stavrou 2a542e20ff
Link to a more specific section in the manual about "-with-command" commands 2026-01-23 09:30:43 +02:00
Protesilaos Stavrou 3af6cbeb39
Mention denote-link-or-create-with-command in the manual
Thanks to Matthew Batson for the contribution in pull request 674:
<https://github.com/protesilaos/denote/pull/674>.

Matthew has assigned copyright to the Free Software Foundation.
2026-01-23 09:29:27 +02:00
Protesilaos Stavrou 0db5c56a8d
Adjust the spaces in denote-link-or-create-with-command
Thanks to Matthew Batson for the contribution in pull request 674:
<https://github.com/protesilaos/denote/pull/674>.

Matthew has assigned copyright to the Free Software Foundation.
2026-01-23 09:25:06 +02:00
Protesilaos Stavrou 8a573f8247
Merge pull request #674 from mbatson/add-denote-link-or-create-with-command
[Feature Proposal] Add denote-link-or-create-with-command
2026-01-23 09:20:43 +02:00
Protesilaos Stavrou 7b5fb18fab
Acknowledge gvalson for commit 9a9f71d
This was done in pull request 676: <https://github.com/protesilaos/denote/pull/676>.

The change is small, meaning that gvalson does not need to assign
copyright to the Free Software Foundation.
2026-01-23 08:52:03 +02:00
Protesilaos Stavrou 9f70a619db
Merge pull request #676 from gvalson/main
Add reference to the mir package in the manual
2026-01-23 08:50:19 +02:00
gvalson 9a9f71d109 Add reference to the mir package in the manual 2026-01-22 20:22:51 -05:00
Matthew Batson 51cbb47311 Add denote-link-or-create-with-command to the menu bar
The code in this commit was originally written by Protesilaos Stavrou
in commit 69391aa.
2026-01-21 18:38:59 +11:00
Matthew Batson 6ffa6881ce Add denote-link-or-create-with-command 2026-01-21 17:13:11 +11:00
Protesilaos Stavrou e9c44eec58
Use insert-buffer-substring instead of insert-buffer in denote--file-with-temp-buffer
The function insert-buffer is meant to be for interactive use only.

This follows the change made by duli in commit 0f71f12 via pull
request 672: <https://github.com/protesilaos/denote/pull/672>. The
author of the original change has assigned copyright to the Free
Software Foundation.

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>.
2026-01-18 09:08:27 +02:00
Protesilaos Stavrou 927c862685
Reword the doc string of denote--file-with-temp-buffer
This follows the change made by duli in commit 0f71f12 via pull
request 672: <https://github.com/protesilaos/denote/pull/672>. The
author of the original change has assigned copyright to the Free
Software Foundation.

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>.
2026-01-18 09:03:39 +02:00
Protesilaos Stavrou 159134fee1
Merge pull request #672 from kilesduli/fix-file-not-saved-but-need-rename
Fix front-matter retrieving when buffer is unsaved or file missing
2026-01-18 09:01:53 +02:00
duli 0f71f126cc
Fix front-matter retrieving when buffer is unsaved or file missing
This addresses a regression where
'denote-rename-file-using-front-matter' would fail to recognize changes
in an unsaved buffer, or fail entirely if the file had not yet been
created on disk (as described in
https://github.com/protesilaos/denote/pull/670).

The logic now consistently prioritizes the content of an open buffer
over the file on disk. Previously, the code would revert to reading the
file if the buffer was marked as modified; however, since we cannot
reliably detect if a modification affects the front-matter, it is safe
to always use the live buffer state.

* (denote--file-with-temp-buffer-subr): Remove.
(denote--file-with-temp-buffer): Refactor to prioritize buffer content
and remove the dependency on the internal subr.

Fixes: https://github.com/protesilaos/denote/pull/670
2026-01-17 23:17:14 +08:00
Protesilaos Stavrou 3563d2b3fe
Acknowledge Matthew Batson for commit a31969f
The change is small, meaning that Matthew does not need to assign
copyright to the Free Software Foundation.
2026-01-17 07:18:53 +02:00
Protesilaos Stavrou 7649f42c88
Merge pull request #671 from mbatson/fix-denote-query-extract-title-docstring
Fix docstring of denote-query-extract-title
2026-01-17 07:15:31 +02:00
Matthew Batson a31969fea2 Fix docstring of denote-query-extract-title
Docstring says function returns denote-grep-untitled-string, but it
actually returns denote-query-untitled-string. This commit corrects
the name of the variable in the docstring.
2026-01-17 14:56:52 +11:00
Protesilaos Stavrou 07dcaeebb9
Merge pull request #666 from kilesduli/refactor-denote-sort-dired
Refactor denote-sort-dired and remove the helper function
2026-01-15 08:56:50 +02:00
Protesilaos Stavrou bcbc805f4f
Fix typo in latest commit 1d1732f 2026-01-14 20:57:23 +02:00
Protesilaos Stavrou 1d1732fb57
Acknowledge duilkiles for commits 8a88fcd, e9e8f6f
The author has assigned copyright to the Free Software Foundation.
2026-01-14 20:54:06 +02:00
Protesilaos Stavrou eaedec7463
Merge pull request #669 from kilesduli/fix-input-gpg-password-too-many-times
Fix denote--define-retrieve-front-matter not reusing opened buffer
2026-01-14 20:52:01 +02:00
Protesilaos Stavrou 7ab5f4e9b5
Merge pull request #668 from kilesduli/make-rename-buffer-check-early
Make rename buffer check early
2026-01-14 20:31:38 +02:00
duli 8a88fcde81
Fix denote--define-retrieve-front-matter not reusing opened buffer
In earlier commits, `denote-rename-buffer' could open the same file
multiple times when retrieving front matter, as described in
https://github.com/protesilaos/denote/issues/652 .

This occurred because the subroutine `denote--file-with-temp-buffer-subr',
used in the definition of `denote--define-retrieve-front-matter',
contained incorrect conditional logic. As a result, files were reopened
instead of reusing already opened buffers.

Fixes: https://github.com/protesilaos/denote/issues/652

* (denote--file-with-temp-buffer-subr):
2026-01-15 00:23:23 +08:00
duli e9e8f6f91e
Make rename buffer check early
When users customize `denote-rename-buffer-function' without checking
whether the current buffer is a Denote buffer, `find-file-hook' may
trigger unintended renames.

Because `denote-rename-buffer' accepts an optional buffer argument, the
Denote buffer check must be performed twice.

* (denote-rename-buffer-rename-function-or-fallback):
2026-01-14 21:52:03 +08:00
duli b92f185818
Refactor denote-sort-dired and remove the helper function
This function is extremely slow because calling (dired (cons directory
files)) triggers ls for every file. When there are a large number of
files, The `call-process' becomes expensive. There is no other way to
change this behavior in dired. We should use Emacs’s built-in ls
implementation (ls-lisp). On my machine, with around 200 files, this
reduces execution time by about 6x.

Additionally, prepare-buffer seems unnecessary. It is a private
function (indicated by the double dash) and is not intended for user
access or other use cases. It calls files-fn twice, which is redundant.
We should instead set the revert-function directly in a single function
to make its purpose explicit.

* (denote-sort-dired): refactor
* (denote-sort-dired--prepare-buffer): remove
2026-01-14 20:30:09 +08:00
Protesilaos Stavrou 47207e9cb2
Add missing part from commit c94a848 2026-01-14 09:44:22 +02:00
Protesilaos Stavrou c94a8484ca
Use let* instead of needless when-let* in one instance 2026-01-14 09:43:22 +02:00
Protesilaos Stavrou 23e1e8642b
Tweak the denote--get-common-root-directory error check 2026-01-14 09:37:18 +02:00
Protesilaos Stavrou 1786ebcd0f
Make two stylistic changes to denote--get-common-root-directory 2026-01-14 09:36:08 +02:00
Protesilaos Stavrou d90f3633de
Rewrite denote--get-common-root-directory and include a test for it 2026-01-14 09:19:34 +02:00
Protesilaos Stavrou 0afdc6af14
Acknowledge Matto Fransen for commit b9ff7e6
The change is small which means that Matto does not need to assign
copyright to the Free Software Foundation.
2026-01-12 22:49:32 +02:00
Matto Fransen b9ff7e6617
Add reference to denote-review package in the manual 2026-01-12 22:48:49 +02:00
Protesilaos Stavrou 301575c318
Add another condition to denote-file-type to fall back to user's preferred file type 2026-01-11 19:06:39 +02:00
Protesilaos Stavrou a0b834f53b
Update copyright years 2026-01-11 11:30:27 +02:00
Protesilaos Stavrou 0a076981a9
Acknowledge Alvin Hsu for commit 46c49e5
This was done in pull request 664: <https://github.com/protesilaos/denote/pull/664>.
The change is small, meaning that Alvin does not need to assign
copyright to the Free Software Foundation,
2026-01-09 10:03:47 +02:00
Protesilaos Stavrou 89875abad6
Merge pull request #664 from aurtzy/fix-denote-sort-dired
Fix error in denote-sort-dired when regexp is a subdirectory
2026-01-09 10:01:36 +02:00
Alvin Hsu 46c49e51ee Fix error in denote-sort-dired when regexp is a subdirectory
In the DIRNAME list argument to `dired', the first element is treated as a
directory name, with the rest being file paths relative to that directory.
`dired' appears to fall back to the parent directory when DIRED-NAME does not
match any subdirectory, resulting in expected correct behavior; however, when
there is a matched directory, it will attempt to search for files relative to
that directory instead, which may result in file-not-found errors.

Thus, we remove and replace DIRED-NAME such that we always use the directory
that the files are supposed to be relative to.

Fixes: #662
2026-01-08 20:59:31 +08:00
Protesilaos Stavrou 9e02bf4bd0
Merge pull request #661 from jeanphilippegg/directories-parameter
Fix #654
2026-01-08 07:43:28 +02:00
Jean-Philippe Gagné Guay 786c86f567 Add denote--get-file-name-relative-to-directories 2026-01-04 19:42:08 -05:00
Jean-Philippe Gagné Guay 65255f46df Make denote-directory-get-files private 2026-01-04 19:18:04 -05:00
Jean-Philippe Gagné Guay b8be7d7bf0 Remove directories parameter from some functions 2026-01-04 19:17:55 -05:00
Protesilaos Stavrou cf2a6b082b
BREAKING: make denote-fontify-links-mode only work in plain text
Check what I am doing in denote-fontify-links-mode to make it work
only in some places and to work around the default behaviour of
toggling a minor mode interactively.
2026-01-03 08:33:48 +02:00
Protesilaos Stavrou 40192c9fcc
Rename the keymap used by denote-fontify-links-mode 2026-01-03 08:33:48 +02:00
Protesilaos Stavrou dc50c92ac8
Expand the doc string of denote-fontify-links-mode 2026-01-03 08:33:48 +02:00
Protesilaos Stavrou 2d83bf12a3
Make denote-fontify-links-mode-maybe also cover markdown-mode
This is because of commit 72e3c01, which makes Markdown mode buffers
work with all Denote links (direct links and query links).
2026-01-03 08:33:48 +02:00
Protesilaos Stavrou 3a66793dd0
Add alias for denote-add-links 2026-01-03 08:33:48 +02:00
Protesilaos Stavrou d8cd571f91
Clarify the doc string of denote-add-links 2026-01-03 08:33:48 +02:00
Protesilaos Stavrou d16465816e
Mention the link to contents in denote-add-links 2026-01-03 08:33:48 +02:00
Protesilaos Stavrou f55b84317a
Mention the link to contents command in the "Getting started with Denote" 2026-01-03 08:33:48 +02:00
Protesilaos Stavrou 730d3d9734
Reword doc string of denote--command-with-features
Just so that it is imperative.
2026-01-03 08:33:48 +02:00
Protesilaos Stavrou b42fc5fea4
Fix error with nil values for the affix function
When the helpers there return nil I am getting an error because the
completion expects a string.
2026-01-02 11:18:31 +02:00
Protesilaos Stavrou 9b907d5457
Acknowledge alvmts for commit 7f91907
This was done in pull request 658: <https://github.com/protesilaos/denote/pull/658>.
The change is small, meaning that alvmts does not need to assign
copyright to the Free Software Foundation.
2026-01-02 08:25:04 +02:00
Protesilaos Stavrou 2aacd8f90d
Merge pull request #658 from alvmts/alvmts-patch-1
Fix trimming of Org links in `denote-link-ol-follow'
2026-01-02 08:23:54 +02:00
alvmts 7f91907a79
Simplify regexp in `denote-link-ol-follow' 2026-01-01 02:10:43 -05:00
alvmts 54494edf5a
Fix trimming of Org links in `denote-link-ol-follow'
This patch makes it so only search options in Org links get trimmed when checking whether the linked file exists.

The old regex erroneously truncates filenames containing a single colon, so "/tmp/foo:bar/file.ext" becomes "/tmp/foo".
2026-01-01 01:39:22 -05:00
Protesilaos Stavrou a576d8917c
Clarify that denote-org-capture-with-prompts SIGNATURE is part of the current development target 2025-12-29 07:39:49 +02:00
Protesilaos Stavrou 06cc35ab80
Fix wrapping in commit 1c3f404 and acknowledge Tobias Lidman-Strauss for it
The commit was done in merge request 2 on the GitLab mirror:
<https://gitlab.com/protesilaos/denote/-/merge_requests/2>.
2025-12-28 08:43:46 +02:00
Protesilaos Stavrou e3a363f367 Merge branch 'drostan-main-patch-47068' into 'main'
Function denote-org-capture-with-prompts updated to accept signature prompt (new try)

See merge request protesilaos/denote!2
2025-12-28 08:39:22 +02:00
Tobias Lidman-Strauss 1c3f4042f9 Function denote-org-capture-with-prompts updated to accept signature prompt (new try) 2025-12-28 08:39:22 +02:00
Protesilaos Stavrou 1d0b6fb5d4
Reimplement commit be6e713 without removing HAS-IDENTIFIER from denote-directory-files
Thanks to Jean-Philippe Gagné Guay for reminding me that
HAS-IDENTIFIER is for use-cases we support. This was done in issue
655: <https://github.com/protesilaos/denote/issues/655>
2025-12-28 08:10:09 +02:00
Protesilaos Stavrou bea7718049
Revert "REMOVE the has-identifier from denote-directory-files and make obsolete denote-directory-get-files-function"
This reverts commit be6e713d88.

Thanks to Jean-Philippe Gagné Guay for reminding me that this change
breaks some of the use-cases we support. This was done in issue 655:
<https://github.com/protesilaos/denote/issues/655>
2025-12-28 07:49:09 +02:00
Protesilaos Stavrou be6e713d88
REMOVE the has-identifier from denote-directory-files and make obsolete denote-directory-get-files-function
This was making things too complex for our purposes. Users who need to
do something else should write an advice for this function.

I am also adding an optional DIRECTORIES parameter in the spirit of
commit 5203bc0.
2025-12-22 06:59:43 +02:00
Protesilaos Stavrou 5203bc00cf
Ensure that denote-directories is not computed multiple times 2025-12-22 06:41:04 +02:00
Protesilaos Stavrou 916dde6ba7
Throw error if denote-get-file-name-relative-to-denote-directory FILE is not absolute 2025-12-22 05:47:53 +02:00
Protesilaos Stavrou 6751c1b999
Use file prompt metadata for denote-select-from-files-prompt as well 2025-12-22 05:24:59 +02:00
Protesilaos Stavrou 0dfaf46a68
Make affixation for file prompt also cover custom identifiers and signatures 2025-12-22 05:18:55 +02:00
Protesilaos Stavrou 09a382fc46
Add FIXME about the group-function breaking the completion highlight of match visible words
I cannot tell why this is happening. Will need to investigate further.
I thought it might have to do with 'denote-retrieve-filename-title'
changing the match data. But the problem persists even if I put a
regular string in its case which is also found in the completion
candidates I am testing it against.
2025-12-16 17:55:51 +02:00
Protesilaos Stavrou badafe9782
Simplify the denote-file-prompt group-function 2025-12-16 17:54:24 +02:00
Protesilaos Stavrou f6243f1ecb
Make stylistic change to an if-let in denote-file-prompt-group 2025-12-16 09:25:32 +02:00
Protesilaos Stavrou fde5e924fc
Tone down the directory component (see commit cdfffba) 2025-12-16 08:47:06 +02:00
Protesilaos Stavrou cdfffbaeaa
Account for subdirs in denote-file-prompt-group function 2025-12-16 08:45:10 +02:00
Protesilaos Stavrou 5f082c5a07
Use as Commentary what I have in the README.md and on my website 2025-12-16 07:37:35 +02:00
Protesilaos Stavrou 75c75a90e3
Use 'denote-file' completion category and make icons' packages know about it 2025-12-16 06:30:22 +02:00
Protesilaos Stavrou ce86684870
Avoid calling the denote-directories twice when single-dir-p is relevant 2025-12-15 18:23:49 +02:00
Protesilaos Stavrou 1064cc2f38
Make stylistic change to denote-sort-component-prompt 2025-12-15 09:52:11 +02:00
Protesilaos Stavrou bc5f10d963
Use completion table for denote-command-prompt 2025-12-15 09:51:59 +02:00
Protesilaos Stavrou 8ea5ac5cd9
Expand the completion metadata of the denote-file-prompt 2025-12-15 09:51:17 +02:00
Protesilaos Stavrou cc83feb3ba
Include denote-rename-file-identifier in the manual
Thanks to jarofromel for telling me about its absence in issue 646:
<https://github.com/protesilaos/denote/issues/646>.
2025-12-14 09:29:22 +02:00
Protesilaos Stavrou f7e6f4d442
Define group function and display-sort-function for denote-file-prompt 2025-12-14 09:12:29 +02:00
Protesilaos Stavrou ee0685ccc7
Rewrite the denote-subdirectory-prompt and add relevant comments 2025-12-14 08:07:56 +02:00
Protesilaos Stavrou d9537e2c9d
Add FIXME about denote-get-file-name-relative-to-denote-directory 2025-12-14 08:07:44 +02:00
Protesilaos Stavrou d9ecf5a988
Add optional DIRECTORIES to denote-directory-subdirectories and relevant FIXME 2025-12-14 08:04:45 +02:00
Protesilaos Stavrou a2476e9ac7
Add FIXME comment about denote-directory-get-files 2025-12-14 08:02:57 +02:00
Protesilaos Stavrou 7cc62eb5fb
Make denote--directory-all-files-recursively accept DIRECTORIES and add FIXME about it 2025-12-14 08:01:43 +02:00
Protesilaos Stavrou 68a5c712d5
Add optional DIRECTORIES to denote-directories-get-common-root 2025-12-14 07:59:50 +02:00
Protesilaos Stavrou 4fe3cf165e
Define denote-get-completion-table and use it 2025-12-14 07:18:09 +02:00
Protesilaos Stavrou 220644d97c
Add missing reference to denote-query-format-heading-function in the manual 2025-12-13 05:26:17 +02:00
Protesilaos Stavrou 72e3c01a7b
Change how we integrate with markdown-follow-link-functions and explain why
I hope this does not comes back to bite me but we will find out in
time. It looks safe.
2025-12-13 05:19:29 +02:00
Protesilaos Stavrou 04f604877e
Make small refinements to denote-fontify-links 2025-12-13 05:19:00 +02:00
Protesilaos Stavrou 4497f11b35
Remove wrong key binding from denote-link-mouse-map 2025-12-13 05:18:26 +02:00
Protesilaos Stavrou 74c7aeeb1b
Explain why denote-grep display-buffer action is different 2025-12-13 05:18:03 +02:00
Protesilaos Stavrou 42a3f393e2
Use consistent display-buffer actions for backlinks and query links 2025-12-13 05:17:36 +02:00
Protesilaos Stavrou e45fde09c1
Use diffent fn for denote-query-format-heading-function value and update docstring 2025-12-13 05:16:30 +02:00
5 changed files with 2209 additions and 1202 deletions

View file

@ -1,5 +1,5 @@
#+title: Change log of Denote
#+author: Protesilaos Stavrou
#+author: Protesilaos
#+email: info@protesilaos.com
#+language: en
#+options: ':t toc:nil author:t email:t num:t
@ -13,6 +13,497 @@ 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
@ -252,7 +743,7 @@ copyright to the Free Software Foundation.
#+begin_src sh
~/Git/Projects/denote $ git shortlog 4.0.0..4.1.0 --summary --numbered
156 Protesilaos Stavrou
156 Protesilaos
29 Jean-Philippe Gagné Guay
4 Lucas Quintana
2 James Kalyan
@ -372,7 +863,7 @@ core Denote as well as ~consult-denote~.
#+begin_src sh
~/Git/Projects/denote-journal $ git shortlog 0.1.0..0.2.0 --summary --numbered
35 Protesilaos Stavrou
35 Protesilaos
3 Alan Schmitt
2 Ettore Berardi
1 Abdelhak Bougouffa
@ -422,7 +913,7 @@ core Denote as well as ~consult-denote~.
#+begin_src sh
~/Git/Projects/denote-org $ git shortlog 0.1.0..0.2.0 --summary --numbered
42 Protesilaos Stavrou
42 Protesilaos
8 Peter Prevos
#+end_src
@ -466,7 +957,7 @@ core Denote as well as ~consult-denote~.
#+begin_src sh
~/Git/Projects/denote-sequence $ git shortlog 0.1.0..0.2.0 --summary --numbered
61 Protesilaos Stavrou
61 Protesilaos
1 Ashton Wiersdorf
1 Peter Prevos
1 Rory Molinari
@ -1034,7 +1525,7 @@ tiny.
#+begin_src
~/Git/Projects/denote $ git shortlog 3.1.0..4.0.0 --summary --numbered
470 Protesilaos Stavrou
470 Protesilaos
90 Jean-Philippe Gagné Guay
6 Kierin Bell
4 Alan Schmitt
@ -1054,29 +1545,29 @@ after the reorganisation I made. But we have to start from somewhere.
#+begin_src
~/Git/Projects/denote-journal $ git shortlog --summary --numbered
54 Protesilaos Stavrou
54 Protesilaos
2 Honza Pokorny
1 Vineet C. Kulkarni
#+end_src
#+begin_src
~/Git/Projects/denote-sequence $ git shortlog --summary --numbered
22 Protesilaos Stavrou
22 Protesilaos
#+end_src
#+begin_src
~/Git/Projects/denote-silo $ git shortlog --summary --numbered
17 Protesilaos Stavrou
17 Protesilaos
#+end_src
#+begin_src
~/Git/Projects/denote-org $ git shortlog --summary --numbered
15 Protesilaos Stavrou
15 Protesilaos
#+end_src
#+begin_src
~/Git/Projects/denote-markdown $ git shortlog --summary --numbered
11 Protesilaos Stavrou
11 Protesilaos
#+end_src
* Version 3.1.0 on 2024-09-04
@ -1587,7 +2078,7 @@ involved!
#+begin_src
~/Git/Projects/denote $ git shortlog 3.0.0..3.1.0 --summary --numbered
104 Protesilaos Stavrou
104 Protesilaos
7 Jean-Philippe Gagné Guay
3 Ashton Wiersdorf
1 Ad
@ -2018,7 +2509,7 @@ 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 Stavrou
169 Protesilaos
52 Jean-Philippe Gagné Guay
3 Al Haji-Ali
2 Alan Schmitt
@ -2733,7 +3224,7 @@ 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 Stavrou
246 Protesilaos
46 Jean-Philippe Gagné Guay
6 Vedang Manerikar
3 Joseph Turner
@ -3111,7 +3602,7 @@ 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 Stavrou
125 Protesilaos
17 Jean-Philippe Gagné Guay
2 Vedang Manerikar
1 Henrik Hörmann
@ -3740,7 +4231,7 @@ 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 Stavrou
153 Protesilaos
15 Jean-Philippe Gagné Guay
5 Vedang Manerikar
1 Alan Schmitt
@ -5096,7 +5587,7 @@ such a section):
#+begin_quote
Denote is meant to be a collective effort. Every bit of help matters.
+ Author/maintainer :: Protesilaos Stavrou.
+ Author/maintainer :: Protesilaos.
+ Contributions to code or the manual :: Abin Simon, Alan Schmitt,
Benjamin Kästner, Clemens Radermacher, Colin McLear, Damien Cassou,
@ -6322,7 +6813,7 @@ Gagné Guay, Kaushal Modi, and Shreyas Ragavan.
#+begin_example
commit f35ef05cb451f265213c3aafc1e62c425b1ff043
Author: Protesilaos Stavrou <info@protesilaos.com>
Author: Protesilaos <info@protesilaos.com>
Date: Sun Jul 3 17:34:38 2022 +0300
REMOVE support for 'id:' hyperlink types

View file

@ -632,7 +632,7 @@ state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 2021 Protesilaos Stavrou
Copyright (C) 2021 Protesilaos
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -652,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) 2021 Protesilaos Stavrou
<program> Copyright (C) 2021 Protesilaos
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.

File diff suppressed because it is too large Load diff

1497
denote.el

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,9 @@
;;; denote-test.el --- Unit tests for Denote -*- lexical-binding: t -*-
;; Copyright (C) 2023-2025 Free Software Foundation, Inc.
;; Copyright (C) 2023-2026 Free Software Foundation, Inc.
;; Author: Protesilaos Stavrou <info@protesilaos.com>
;; Maintainer: Protesilaos Stavrou <info@protesilaos.com>
;; Author: Protesilaos <info@protesilaos.com>
;; Maintainer: Protesilaos <info@protesilaos.com>
;; URL: https://github.com/protesilaos/denote
;; This file is NOT part of GNU Emacs.
@ -37,21 +37,68 @@
(require 'denote)
(ert-deftest dt-denote-directories--get-paths ()
"Test that `denote-directories--get-paths' returns a list of paths."
(let ((path "~/Documents/notes"))
(should (equal
(denote-directories--get-paths path)
(list (file-name-as-directory (expand-file-name path))))))
(let ((paths (list "~/Documents/notes" "~/Documents/books")))
(should (equal
(denote-directories--get-paths paths)
(mapcar
(lambda (path)
(file-name-as-directory (expand-file-name path)))
paths)))
(should (seq-every-p
(lambda (path)
(string-suffix-p "/" path))
(denote-directories--get-paths paths)))
(should-not (null (denote-directories--get-paths paths))))
(should-error (denote-directories--get-paths 'hello))
(should-error (denote-directories--get-paths '(hello)))
(should-error (denote-directories--get-paths '(1 2 3))))
(ert-deftest dt-denote--make-denote-directory ()
"Test that `denote--make-denote-directory' creates the directory."
(should (null (denote--make-denote-directory))))
(let* ((names (list "denote-test-made-directory-1" "denote-test-made-directory-2"))
(directories (mapcar
(lambda (directory)
(file-name-as-directory (expand-file-name directory temporary-file-directory)))
names)))
(should-not (denote-directories--make-paths directories))
(should (seq-every-p #'file-name-directory directories))
(dolist (directory directories)
(delete-directory directory))))
(ert-deftest dt-denote-directory ()
"Test that variable `denote-directory' returns an absolute directory name."
(let ((path (denote-directory)))
(should (and (file-directory-p path)
(file-name-absolute-p path)))))
(ert-deftest dt-denote-directories ()
"Test that `denote-directories' returns list of directories.
It does so by expanding the value of the user option `denote-directory'.
Also see `denote-test--denote--make-denote-directory',
`denote-test---denote-directories--get-paths'."
(let ((denote-directory "/tmp/denote-test-notes"))
(should
(equal
(denote-directories)
(list (file-name-as-directory (expand-file-name denote-directory)))))
(should (and (file-directory-p denote-directory)
(file-name-absolute-p denote-directory))))
(let ((denote-directory (list "/tmp/denote-test-notes-1" "/tmp/denote-test-notes-2")))
(should
(equal
(denote-directories)
(mapcar
(lambda (directory)
(file-name-as-directory (expand-file-name directory)))
denote-directory)))
(should (and (seq-every-p #'file-directory-p denote-directory)
(seq-every-p #'file-name-absolute-p denote-directory)))))
(ert-deftest dt-denote-sluggify-title ()
"Test that `denote-sluggify-title' removes punctuation from the string.
Concretely, remove anything specified in `denote-sluggify-title'."
(should (equal (denote-sluggify-title "this-is-!@#test")
"this-is-test")))
(should (equal (denote-sluggify-title "this-is-!@#test") "this-is-test")))
(ert-deftest dt-denote-slug-keep-only-ascii ()
"Test that `denote-slug-keep-only-ascii' removes non-ASCII characters."
@ -63,101 +110,89 @@ Concretely, remove anything specified in `denote-sluggify-title'."
"Test that `denote-slug-hyphenate' hyphenates the string.
Also replace multiple hyphens with a single one and remove any
leading and trailing hyphen."
(should (equal (denote-slug-hyphenate "__ This is a test __ ")
"This-is-a-test")))
(should (equal (denote-slug-hyphenate "__ This is a test __ ") "This-is-a-test")))
(ert-deftest dt-denote-sluggify ()
"Test that `denote-sluggify' sluggifies the string.
To sluggify is to (i) downcase, (ii) hyphenate, (iii) de-punctuate, and (iv) remove spaces from the string."
(should (equal (denote-sluggify 'title " ___ !~!!$%^ This iS a tEsT ++ ?? ")
"this-is-a-test")))
(should (equal (denote-sluggify 'title " ___ !~!!$%^ This iS a tEsT ++ ?? ") "this-is-a-test")))
(ert-deftest Ddenote--slug-put-equals ()
"Test that `denote-slug-put-equals' replaces spaces/underscores with =.
Otherwise do the same as what is described in
`dt-denote-slug-hyphenate'.
`denote-test--denote-slug-hyphenate'.
The use of the equals sign is for the SIGNATURE field of the
Denote file name."
(should (equal (denote-slug-put-equals "__ This is a test __ ")
"This=is=a=test")))
(should (equal (denote-slug-put-equals "__ This is a test __ ") "This=is=a=test")))
(ert-deftest dt-denote-sluggify-signature ()
"Test that `denote-sluggify-signature' sluggifies the string for file signatures.
This is like `dt-denote-sluggify', except that it also
accounts for what we describe in `dt-denote-slug-put-equals'."
(should (equal (denote-sluggify-signature "--- ___ !~!!$%^ This -iS- a tEsT ++ ?? ")
"this=is=a=test")))
This is like `denote-test--denote-sluggify', except that it also
accounts for what we describe in `denote-test--denote-slug-put-equals'."
(should (equal (denote-sluggify-signature "--- ___ !~!!$%^ This -iS- a tEsT ++ ?? ") "this=is=a=test")))
(ert-deftest dt-denote-sluggify-keyword ()
"Test that `denote-sluggify-keyword' sluggifies the string while joining words.
In this context, to join words is to elimitate any space or
delimiter between them.
Otherwise, this is like `dt-denote-sluggify'."
(should (equal (denote-sluggify-keyword "--- ___ !~!!$%^ This iS a - tEsT ++ ?? ")
"thisisatest")))
Otherwise, this is like `denote-test--denote-sluggify'."
(should (equal (denote-sluggify-keyword "--- ___ !~!!$%^ This iS a - tEsT ++ ?? ") "thisisatest")))
(ert-deftest dt-denote-sluggify-keywords ()
"Test that `denote-sluggify-keywords' sluggifies a list of strings.
The function also account for the value of the user option
`denote-allow-multi-word-keywords'."
(should
(equal (denote-sluggify-keywords '("one !@# --- one" " two" "__ three __"))
'("oneone" "two" "three"))))
(should (equal (denote-sluggify-keywords '("one !@# --- one" " two" "__ three __")) '("oneone" "two" "three"))))
(ert-deftest dt-denote-slug-remove-accents ()
"Test that `denote-slug-remove-accents' removed diacretics."
(should (string= (denote-slug-remove-accents "ê") "e"))
(should (string= (denote-slug-remove-accents "ñ") "n")))
(ert-deftest dt-denote--file-empty-p ()
"Test that `denote--file-empty-p' returns non-nil on empty file."
;; (should (null (denote--file-empty-p user-init-file))
(should (let ((file (make-temp-file "denote-test")))
(prog1
(denote--file-empty-p file)
(delete-file file)))))
(let ((file (make-temp-file "denote-test")))
(should (denote--file-empty-p file))
(with-current-buffer (find-file-noselect file)
(insert "Hello world, this is not empty anymore!")
(save-buffer))
(should-not (denote--file-empty-p file))
(delete-file file)))
(ert-deftest dt-denote-file-is-note-p ()
"Test that `denote-file-is-note-p' checks that files is a Denote note.
For our purposes, a note must note be a directory, must satisfy
`file-regular-p', its path must be part of the variable
`denote-directory', it must have a Denote identifier in its name,
and use one of the extensions implied by the variable `denote-file-type'."
(should (let* ((tmp (temporary-file-directory))
(denote-directory tmp)
(file (concat tmp "20230522T154900--test__keyword.txt")))
(with-current-buffer (find-file-noselect file)
(write-file file))
(prog1
(denote-file-is-note-p file)
(delete-file file)))))
(ert-deftest dt-denote-file-has-denoted-filename-p ()
"Test that `denote-file-has-denoted-filename-p' validates a Denote file name."
(should (denote-file-has-denoted-filename-p "20230522T154900--test__keyword.txt"))
(should-not (denote-file-has-denoted-filename-p "hello")))
(ert-deftest dt-denote-file-has-identifier-p ()
"Test that `denote-file-has-identifier-p' checks for a Denote identifier."
(should (denote-file-has-identifier-p "20230522T154900--test__keyword.txt"))
(should (null (denote-file-has-identifier-p "T154900--test__keyword.txt"))))
(should-not (denote-file-has-identifier-p "T154900--test__keyword.txt")))
(ert-deftest dt-denote-file-has-signature-p ()
"Test that `denote-file-has-signature-p' checks for a Denote signature."
(should (denote-file-has-signature-p "20230522T154900==sig--test__keyword.txt"))
(should (null (denote-file-has-signature-p "20230522T154900--test__keyword.txt"))))
(should-not (denote-file-has-signature-p "20230522T154900--test__keyword.txt")))
(ert-deftest dt-denote-file-has-supported-extension-p ()
"Test that `denote-file-has-supported-extension-p' matches a supported extension."
(should
(member
(file-name-extension "20230522T154900==sig--test__keyword.txt" :period)
(denote-file-type-extensions-with-encryption)))
(should
(null
(member
(file-name-extension "20230522T154900==sig--test__keyword" :period)
(denote-file-type-extensions-with-encryption)))))
(let ((extensions (denote-file-type-extensions-with-encryption)))
(should
(member
(file-name-extension "20230522T154900==sig--test__keyword.txt" :period)
extensions))
(should-not
(member
(file-name-extension "20230522T154900==sig--test__keyword" :period)
extensions))))
(ert-deftest dt-denote-file-type-extensions ()
"Test that `denote-file-type-extensions' returns file extensions.
We check for the common file type extensions, though the user can
theoretically set `denote-file-types' to nil and handle things on
their own. We do not have to test for that scenario, because
such a user will be redefining large parts of Denote's behaviour
with regard to file types."
We check for the common file type extensions, though the user can set
`denote-file-types' to nil and handle things on their own or, anyhow,
modify that variable."
(let ((extensions (denote-file-type-extensions)))
(should (or (member ".md" extensions)
(member ".org" extensions)
@ -165,7 +200,7 @@ with regard to file types."
(ert-deftest dt-denote-file-type-extensions-with-encryption ()
"Test that `denote-file-type-extensions-with-encryption' covers encryption.
Extend what we do in `dt-denote-file-type-extensions'."
Extend what we do in `denote-test--denote-file-type-extensions'."
(let ((extensions (denote-file-type-extensions-with-encryption)))
(should (or (member ".md" extensions)
(member ".org" extensions)
@ -183,331 +218,186 @@ To make the test reproducible, set `denote-date-format' to a value that
does not involve the time zone."
(let ((denote-date-format "%Y-%m-%d")
(denote-front-matter-components-present-even-if-empty-value '(title keywords signature date identifier)))
(should (and (equal (denote--format-front-matter "" (date-to-time "20240101T120000") '("") "" "" 'text)
(mapconcat #'identity
'("title: "
"date: 2024-01-01"
"tags: "
"identifier: "
"signature: "
"---------------------------\n\n")
"\n"))
(equal
(denote--format-front-matter
"Some test" (date-to-time "2023-06-05") '("one" "two")
"20230605T102234" "sig" 'text)
(mapconcat #'identity
'("title: Some test"
"date: 2023-06-05"
"tags: one two"
"identifier: 20230605T102234"
"signature: sig"
"---------------------------\n\n")
"\n"))))
(should (and (equal (denote--format-front-matter "" (date-to-time "20240101T120000") nil "" "" 'org)
(mapconcat #'identity
'("#+title: "
"#+date: 2024-01-01"
"#+filetags: "
"#+identifier: "
"#+signature: "
"\n")
"\n"))
(equal
(denote--format-front-matter
"Some test" (date-to-time "2023-06-05") '("one" "two")
"20230605T102234" "sig" 'org)
(mapconcat #'identity
'("#+title: Some test"
"#+date: 2023-06-05"
"#+filetags: :one:two:"
"#+identifier: 20230605T102234"
"#+signature: sig"
"\n")
"\n"))))
(should (and (equal (denote--format-front-matter "" (date-to-time "20240101T120000") nil "" "" 'markdown-yaml)
(mapconcat #'identity
'("---"
"title: \"\""
"date: 2024-01-01"
"tags: []"
"identifier: \"\""
"signature: \"\""
"---"
"\n")
"\n"))
(equal
(denote--format-front-matter
"Some test" (date-to-time "2023-06-05") '("one" "two")
"20230605T102234" "sig" 'markdown-yaml)
(mapconcat #'identity
'("---"
"title: \"Some test\""
"date: 2023-06-05"
"tags: [\"one\", \"two\"]"
"identifier: \"20230605T102234\""
"signature: \"sig\""
"---"
"\n")
"\n"))))
(should (and (equal (denote--format-front-matter "" (date-to-time "20240101T120000") nil "" "" 'markdown-toml)
(mapconcat #'identity
'("+++"
"title = \"\""
"date = 2024-01-01"
"tags = []"
"identifier = \"\""
"signature = \"\""
"+++"
"\n")
"\n"))
(equal
(denote--format-front-matter
"Some test" (date-to-time "2023-06-05") '("one" "two")
"20230605T102234" "sig" 'markdown-toml)
(mapconcat #'identity
'("+++"
"title = \"Some test\""
"date = 2023-06-05"
"tags = [\"one\", \"two\"]"
"identifier = \"20230605T102234\""
"signature = \"sig\""
"+++"
"\n")
"\n"))))))
(should (equal (denote--format-front-matter "" (date-to-time "20240101T120000") '("") "" "" 'text)
(string-join
'("title: "
"date: 2024-01-01"
"tags: "
"identifier: "
"signature: "
"---------------------------\n\n")
"\n")))
(should (equal (denote--format-front-matter "Some test" (date-to-time "2023-06-05") '("one" "two") "20230605T102234" "sig" 'text)
(string-join
'("title: Some test"
"date: 2023-06-05"
"tags: one two"
"identifier: 20230605T102234"
"signature: sig"
"---------------------------\n\n")
"\n")))
(should (equal (denote--format-front-matter "" (date-to-time "20240101T120000") nil "" "" 'org)
(string-join
'("#+title: "
"#+date: 2024-01-01"
"#+filetags: "
"#+identifier: "
"#+signature: "
"\n")
"\n")))
(should (equal
(denote--format-front-matter
"Some test" (date-to-time "2023-06-05") '("one" "two")
"20230605T102234" "sig" 'org)
(string-join
'("#+title: Some test"
"#+date: 2023-06-05"
"#+filetags: :one:two:"
"#+identifier: 20230605T102234"
"#+signature: sig"
"\n")
"\n")))
(should (equal (denote--format-front-matter "" (date-to-time "20240101T120000") nil "" "" 'markdown-yaml)
(string-join
'("---"
"title: \"\""
"date: 2024-01-01"
"tags: []"
"identifier: \"\""
"signature: \"\""
"---"
"\n")
"\n")))
(should (equal (denote--format-front-matter "Some test" (date-to-time "2023-06-05") '("one" "two") "20230605T102234" "sig" 'markdown-yaml)
(string-join
'("---"
"title: \"Some test\""
"date: 2023-06-05"
"tags: [\"one\", \"two\"]"
"identifier: \"20230605T102234\""
"signature: \"sig\""
"---"
"\n")
"\n")))
(should (equal (denote--format-front-matter "" (date-to-time "20240101T120000") nil "" "" 'markdown-toml)
(string-join
'("+++"
"title = \"\""
"date = 2024-01-01"
"tags = []"
"identifier = \"\""
"signature = \"\""
"+++"
"\n")
"\n")))
(should (equal (denote--format-front-matter "Some test" (date-to-time "2023-06-05") '("one" "two") "20230605T102234" "sig" 'markdown-toml)
(string-join
'("+++"
"title = \"Some test\""
"date = 2023-06-05"
"tags = [\"one\", \"two\"]"
"identifier = \"20230605T102234\""
"signature = \"sig\""
"+++"
"\n")
"\n")))))
(ert-deftest dt-denote-format-file-name ()
"Test that `denote-format-file-name' returns all expected paths."
(let* ((title "Some test")
(id (format-time-string denote-date-identifier-format (denote-valid-date-p "2023-11-28 05:53:11")))
(denote-directory "/tmp/test-denote")
(dir (car (denote-directories)))
(ext (denote--file-extension 'org))
(kws '("one" "two")))
(should-error (denote-format-file-name
nil
id
kws
title
(denote--file-extension 'org)
""))
(should-error (denote-format-file-name
""
id
kws
title
(denote--file-extension 'org)
""))
(should-error (denote-format-file-name
denote-directory ; notice this is the `let' bound value without the suffix
id
kws
title
(denote--file-extension 'org)
""))
(should-error (denote-format-file-name
(denote-directory)
""
nil
""
(denote--file-extension 'org)
""))
(should (equal (denote-format-file-name
(denote-directory)
nil
kws
title
(denote--file-extension 'org)
"")
"/tmp/test-denote/--some-test__one_two.org"))
(should (equal (denote-format-file-name
(denote-directory)
""
kws
title
(denote--file-extension 'org)
"")
"/tmp/test-denote/--some-test__one_two.org"))
(should (equal (denote-format-file-name
(denote-directory)
"0123456"
kws
title
(denote--file-extension 'org)
"")
"/tmp/test-denote/@@0123456--some-test__one_two.org"))
(should (equal (denote-format-file-name
(denote-directory)
id
kws
title
(denote--file-extension 'org)
"")
"/tmp/test-denote/20231128T055311--some-test__one_two.org"))
(should (equal (denote-format-file-name
(denote-directory)
id
nil
""
(denote--file-extension 'org)
"")
"/tmp/test-denote/20231128T055311.org"))
(should (equal (denote-format-file-name
(denote-directory)
id
nil
nil
(denote--file-extension 'org)
nil)
"/tmp/test-denote/20231128T055311.org"))
(should (equal (denote-format-file-name
(denote-directory)
id
kws
title
(denote--file-extension 'org)
"sig")
"/tmp/test-denote/20231128T055311==sig--some-test__one_two.org"))))
(should-error (denote-format-file-name nil id kws title ext ""))
(should-error (denote-format-file-name "" id kws title ext ""))
;; NOTE that `denote-directory' is the `let' bound value without the suffix
(should-error (denote-format-file-name denote-directory id kws title ext ""))
(should-error (denote-format-file-name dir "" nil "" ext ""))
(should (equal (denote-format-file-name dir nil kws title ext "") "/tmp/test-denote/--some-test__one_two.org"))
(should (equal (denote-format-file-name dir "" kws title ext "") "/tmp/test-denote/--some-test__one_two.org"))
(should (equal (denote-format-file-name dir "0123456" kws title ext "") "/tmp/test-denote/@@0123456--some-test__one_two.org"))
(should (equal (denote-format-file-name dir id kws title ext "") "/tmp/test-denote/20231128T055311--some-test__one_two.org"))
(should (equal (denote-format-file-name dir id nil "" ext "") "/tmp/test-denote/20231128T055311.org"))
(should (equal (denote-format-file-name dir id nil nil ext nil) "/tmp/test-denote/20231128T055311.org"))
(should (equal (denote-format-file-name dir id kws title ext "sig") "/tmp/test-denote/20231128T055311==sig--some-test__one_two.org"))))
(ert-deftest dt-denote-get-file-extension ()
"Test that `denote-get-file-extension' gets the correct file extension."
(should (and (equal (denote-get-file-extension "20231010T105034--some-test-file__denote_testing") "")
(equal (denote-get-file-extension "20231010T105034--some-test-file__denote_testing.org") ".org")
(equal (denote-get-file-extension "20231010T105034--some-test-file__denote_testing.org.gpg") ".org.gpg")
(equal (denote-get-file-extension "20231010T105034--some-test-file__denote_testing.org.age") ".org.age"))))
(should (equal (denote-get-file-extension "20231010T105034--some-test-file__denote_testing") ""))
(should (equal (denote-get-file-extension "20231010T105034--some-test-file__denote_testing.org") ".org"))
(should (equal (denote-get-file-extension "20231010T105034--some-test-file__denote_testing.org.gpg") ".org.gpg"))
(should (equal (denote-get-file-extension "20231010T105034--some-test-file__denote_testing.org.age") ".org.age")))
(ert-deftest dt-denote-get-file-extension-sans-encryption ()
"Test that `denote-get-file-extension-sans-encryption' gets the file extension without encryption."
(should (and (equal (denote-get-file-extension-sans-encryption "20231010T105034--some-test-file__denote_testing") "")
(equal (denote-get-file-extension-sans-encryption "20231010T105034--some-test-file__denote_testing.org") ".org")
(equal (denote-get-file-extension-sans-encryption "20231010T105034--some-test-file__denote_testing.org.gpg") ".org")
(equal (denote-get-file-extension-sans-encryption "20231010T105034--some-test-file__denote_testing.org.age") ".org"))))
(should (equal (denote-get-file-extension-sans-encryption "20231010T105034--some-test-file__denote_testing") ""))
(should (equal (denote-get-file-extension-sans-encryption "20231010T105034--some-test-file__denote_testing.org") ".org"))
(should (equal (denote-get-file-extension-sans-encryption "20231010T105034--some-test-file__denote_testing.org.gpg") ".org"))
(should (equal (denote-get-file-extension-sans-encryption "20231010T105034--some-test-file__denote_testing.org.age") ".org")))
;; TODO 2026-04-06: For the `denote-file-type'.
(ert-deftest dt-denote-filetype-heuristics ()
"Test that `denote-filetype-heuristics' gets the correct file type."
(should (and (eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing") nil)
(eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing.org") 'org)
(eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing.org.gpg") 'org)
(eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing.org.age") 'org)
(eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing.txt") 'text)
(eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing.txt.gpg") 'text)
(eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing.txt.age") 'text)
;; NOTE 2023-10-11: It returns `markdown-yaml' as a fallback. In
;; an actual file, it reads the file contents to determine what
;; it is and can return `markdown-toml'. In principle, we should
;; be testing this here, though I prefer to keep things simple.
(eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing.md") 'markdown-yaml)
(eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing.md.gpg") 'markdown-yaml)
(eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing.md.age") 'markdown-yaml))))
(should-not (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing"))
(should (eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing.org") 'org))
(should (eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing.org.gpg") 'org))
(should (eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing.org.age") 'org))
(should (eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing.txt") 'text))
(should (eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing.txt.gpg") 'text))
(should (eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing.txt.age") 'text))
(should (eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing.md")
(caar (denote--file-types-with-extension ".md"))))
(should (eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing.md.gpg")
(caar (denote--file-types-with-extension ".md"))))
(should (eq (denote-filetype-heuristics "20231010T105034--some-test-file__denote_testing.md.age")
(caar (denote--file-types-with-extension ".md")))))
(ert-deftest dt-denote-retrieve-filename-identifier ()
"Test that `denote-retrieve-filename-identifier' returns only the identifier."
(should (and (null
(denote-retrieve-filename-identifier "/path/to/testing/--this-is-a-test-reordered__denote_testing.org"))
(equal
(denote-retrieve-filename-identifier "/path/to/testing/20240610T194654--this-is-a-test-reordered__denote_testing.org")
"20240610T194654")
(equal
(denote-retrieve-filename-identifier "/path/to/testing/20240610T194654==signature--this-is-a-test-reordered__denote_testing.org")
"20240610T194654")
(equal
(denote-retrieve-filename-identifier "/path/to/testing/--this-is-a-test-reordered__denote_testing@@20240610T194654.org")
"20240610T194654")
(equal
(denote-retrieve-filename-identifier "/path/to/testing/__denote_testing--this-is-a-test-reordered@@20240610T194654.org")
"20240610T194654")
(equal
(denote-retrieve-filename-identifier "/path/to/testing/__denote_testing@@20240610T194654--this-is-a-test-reordered.org")
"20240610T194654")
(equal
(denote-retrieve-filename-identifier "/path/to/testing/==signature__denote_testing@@20240610T194654--this-is-a-test-reordered.org")
"20240610T194654"))))
(should (null (denote-retrieve-filename-identifier "/path/to/testing/--this-is-a-test-reordered__denote_testing.org")))
(should (equal (denote-retrieve-filename-identifier "/path/to/testing/20240610T194654--this-is-a-test-reordered__denote_testing.org") "20240610T194654"))
(should (equal (denote-retrieve-filename-identifier "/path/to/testing/20240610T194654==signature--this-is-a-test-reordered__denote_testing.org") "20240610T194654"))
(should (equal (denote-retrieve-filename-identifier "/path/to/testing/--this-is-a-test-reordered__denote_testing@@20240610T194654.org") "20240610T194654"))
(should (equal (denote-retrieve-filename-identifier "/path/to/testing/__denote_testing--this-is-a-test-reordered@@20240610T194654.org") "20240610T194654"))
(should (equal (denote-retrieve-filename-identifier "/path/to/testing/__denote_testing@@20240610T194654--this-is-a-test-reordered.org") "20240610T194654"))
(should (equal (denote-retrieve-filename-identifier "/path/to/testing/==signature__denote_testing@@20240610T194654--this-is-a-test-reordered.org") "20240610T194654")))
(ert-deftest dt-denote-retrieve-filename-title ()
"Test that `denote-retrieve-filename-title' returns only the title."
(should (and (null
(denote-retrieve-filename-title "/path/to/testing/20240610T194654__denote_testing.org"))
(equal
(denote-retrieve-filename-title "/path/to/testing/20240610T194654--this-is-a-test-reordered__denote_testing.org")
"this-is-a-test-reordered")
(equal
(denote-retrieve-filename-title "/path/to/testing/20240610T194654==signature--this-is-a-test-reordered__denote_testing.org")
"this-is-a-test-reordered")
(equal
(denote-retrieve-filename-title "/path/to/testing/--this-is-a-test-reordered__denote_testing@@20240610T194654.org")
"this-is-a-test-reordered")
(equal
(denote-retrieve-filename-title "/path/to/testing/__denote_testing--this-is-a-test-reordered@@20240610T194654.org")
"this-is-a-test-reordered")
(equal
(denote-retrieve-filename-title "/path/to/testing/__denote_testing@@20240610T194654--this-is-a-test-reordered.org")
"this-is-a-test-reordered")
(equal
(denote-retrieve-filename-title "/path/to/testing/==signature__denote_testing@@20240610T194654--this-is-a-test-reordered.org")
"this-is-a-test-reordered"))))
(should (null (denote-retrieve-filename-title "/path/to/testing/20240610T194654__denote_testing.org")))
(should (equal (denote-retrieve-filename-title "/path/to/testing/20240610T194654--this-is-a-test-reordered__denote_testing.org") "this-is-a-test-reordered"))
(should (equal (denote-retrieve-filename-title "/path/to/testing/20240610T194654==signature--this-is-a-test-reordered__denote_testing.org") "this-is-a-test-reordered"))
(should (equal (denote-retrieve-filename-title "/path/to/testing/--this-is-a-test-reordered__denote_testing@@20240610T194654.org") "this-is-a-test-reordered"))
(should (equal (denote-retrieve-filename-title "/path/to/testing/__denote_testing--this-is-a-test-reordered@@20240610T194654.org") "this-is-a-test-reordered"))
(should (equal (denote-retrieve-filename-title "/path/to/testing/__denote_testing@@20240610T194654--this-is-a-test-reordered.org") "this-is-a-test-reordered"))
(should (equal (denote-retrieve-filename-title "/path/to/testing/==signature__denote_testing@@20240610T194654--this-is-a-test-reordered.org") "this-is-a-test-reordered")))
(ert-deftest dt-denote-retrieve-filename-keywords ()
"Test that `denote-retrieve-filename-keywords' returns only the keywords."
(should (and (null
(denote-retrieve-filename-keywords "/path/to/testing/20240610T194654--this-is-a-test-reordered.org"))
(equal
(denote-retrieve-filename-keywords "/path/to/testing/20240610T194654--this-is-a-test-reordered__denote_testing.org")
"denote_testing")
(equal
(denote-retrieve-filename-keywords "/path/to/testing/20240610T194654==signature--this-is-a-test-reordered__denote_testing.org")
"denote_testing")
(equal
(denote-retrieve-filename-keywords "/path/to/testing/--this-is-a-test-reordered__denote_testing@@20240610T194654.org")
"denote_testing")
(equal
(denote-retrieve-filename-keywords "/path/to/testing/__denote_testing--this-is-a-test-reordered@@20240610T194654.org")
"denote_testing")
(equal
(denote-retrieve-filename-keywords "/path/to/testing/__denote_testing@@20240610T194654--this-is-a-test-reordered.org")
"denote_testing")
(equal
(denote-retrieve-filename-keywords "/path/to/testing/==signature__denote_testing@@20240610T194654--this-is-a-test-reordered.org")
"denote_testing"))))
(should (null (denote-retrieve-filename-keywords "/path/to/testing/20240610T194654--this-is-a-test-reordered.org")))
(should (equal (denote-retrieve-filename-keywords "/path/to/testing/20240610T194654--this-is-a-test-reordered__denote_testing.org") "denote_testing"))
(should (equal (denote-retrieve-filename-keywords "/path/to/testing/20240610T194654==signature--this-is-a-test-reordered__denote_testing.org") "denote_testing"))
(should (equal (denote-retrieve-filename-keywords "/path/to/testing/--this-is-a-test-reordered__denote_testing@@20240610T194654.org") "denote_testing"))
(should (equal (denote-retrieve-filename-keywords "/path/to/testing/__denote_testing--this-is-a-test-reordered@@20240610T194654.org") "denote_testing"))
(should (equal (denote-retrieve-filename-keywords "/path/to/testing/__denote_testing@@20240610T194654--this-is-a-test-reordered.org") "denote_testing"))
(should (equal (denote-retrieve-filename-keywords "/path/to/testing/==signature__denote_testing@@20240610T194654--this-is-a-test-reordered.org") "denote_testing")))
(ert-deftest dt-denote-retrieve-filename-signature ()
"Test that `denote-retrieve-filename-signature' returns only the signature."
(should (and (null
(denote-retrieve-filename-signature "/path/to/testing/20240610T194654--this-is-a-test-reordered__denote_testing.org"))
(equal
(denote-retrieve-filename-signature "/path/to/testing/20240610T194654==signature--this-is-a-test-reordered__denote_testing.org")
"signature")
(equal
(denote-retrieve-filename-signature "/path/to/testing/--this-is-a-test-reordered==signature__denote_testing@@20240610T194654.org")
"signature")
(equal
(denote-retrieve-filename-signature "/path/to/testing/__denote_testing--this-is-a-test-reordered==signature@@20240610T194654.org")
"signature")
(equal
(denote-retrieve-filename-signature "/path/to/testing/__denote_testing@@20240610T194654--this-is-a-test-reordered==signature.org")
"signature")
(equal
(denote-retrieve-filename-signature "/path/to/testing/==signature__denote_testing@@20240610T194654--this-is-a-test-reordered.org")
"signature"))))
(should (null (denote-retrieve-filename-signature "/path/to/testing/20240610T194654--this-is-a-test-reordered__denote_testing.org")))
(should (equal (denote-retrieve-filename-signature "/path/to/testing/20240610T194654==signature--this-is-a-test-reordered__denote_testing.org") "signature"))
(should (equal (denote-retrieve-filename-signature "/path/to/testing/--this-is-a-test-reordered==signature__denote_testing@@20240610T194654.org") "signature"))
(should (equal (denote-retrieve-filename-signature "/path/to/testing/__denote_testing--this-is-a-test-reordered==signature@@20240610T194654.org") "signature"))
(should (equal (denote-retrieve-filename-signature "/path/to/testing/__denote_testing@@20240610T194654--this-is-a-test-reordered==signature.org") "signature"))
(should (equal (denote-retrieve-filename-signature "/path/to/testing/==signature__denote_testing@@20240610T194654--this-is-a-test-reordered.org") "signature")))
(ert-deftest dt-denote-identifier-p ()
"Test that `denote-identifier-p' works for Denote identifiers."
(should (and (denote-identifier-p "20240901T090910")
(null (denote-identifier-p "20240901T090910-not-identifier-format")))))
(ert-deftest dt-denote-date-identifier-p ()
"Test that `denote-date-identifier-p' works for Denote identifiers."
(should (denote-date-identifier-p "20240901T090910"))
(should-not (denote-date-identifier-p "20240901T090910-not-identifier-format")))
(ert-deftest dt-denote-id-to-date ()
"Test that `denote-id-to-date' returns the date from an identifier."
@ -516,21 +406,75 @@ does not involve the time zone."
(ert-deftest dt-denote--date-convert ()
"Test that `denote--date-convert' works with dates."
(should (and
(equal (denote--date-convert '(26454 45206 461174 657000) :list)
'(26454 45206 461174 657000))
(equal (denote--date-convert '(26454 45206 461174 657000) :string)
"2024-12-09 10:55:50")
(equal (denote--date-convert nil :string)
"")
(equal (denote--date-convert nil :list)
nil)))
(should (equal (denote--date-convert '(26454 45206 461174 657000) :list) '(26454 45206 461174 657000)))
(should (equal (denote--date-convert '(26454 45206 461174 657000) :string) "2024-12-09 10:55:50"))
(should (equal (denote--date-convert nil :string) ""))
(should (equal (denote--date-convert nil :list) nil))
(should-error (denote--date-convert '(26454 45206 461174 657000) :not-valid-type))
(should-error (denote--date-convert nil :not-valid-type)))
;; TODO 2026-02-23: Add support for Windows paths. But I need somebody who has a Windows machine...
(ert-deftest dt-denote--get-common-root-directory ()
"Test that `denote--get-common-root-directory' returns the right path."
(should (string=
(denote--get-common-root-directory
'("/home/prot/Documents/notes/"
"/home/prot/Documents/notes/attachments"))
"/home/prot/Documents/notes/"))
(should (string=
(denote--get-common-root-directory
'("/home/prot/Documents/"
"/home/prot/Documents/notes/attachments"))
"/home/prot/Documents/"))
(should (string=
(denote--get-common-root-directory
'("/home/prot/Books/"
"/home/prot/Documents/notes/"))
"/home/prot/"))
(should (string=
(denote--get-common-root-directory
'("/tmp/notes/"
"/home/prot/Documents/notes/"))
"/"))
(should (string=
(denote--get-common-root-directory
'("/home/prot/Documents/notes/"))
"/home/prot/Documents/notes/"))
(should-error (denote--get-common-root-directory '("~/Documents/notes/"))))
(ert-deftest dt-denote-query--keywords-as-regexp ()
"Test that `denote-query--keywords-as-regexp' works as intended."
(should (string= (denote-query--keywords-as-regexp '("one" "two")) "_\\(?:one\\|two\\)"))
(should-error (denote-query--keywords-as-regexp "one"))
(should-error (denote-query--keywords-as-regexp '("one" 1))))
(ert-deftest dt-denote-file-type ()
"Test that function `denote-file-type' does what it is meant to."
(let* ((create-file-fn (lambda (name extension)
(expand-file-name
(format "denote-test-file-type-%s.%s" name extension)
(temporary-file-directory))))
(modify-file-fn (lambda (file contents)
(with-current-buffer (find-file-noselect file)
(erase-buffer)
(insert contents)
(save-buffer))))
(yaml-file (funcall create-file-fn "yaml" "md"))
(toml-file (funcall create-file-fn "toml" "md"))
(org-file (funcall create-file-fn "org" "org")))
(progn
(funcall modify-file-fn yaml-file denote-yaml-front-matter)
(should (eq (denote-file-type yaml-file) 'markdown-yaml)))
(progn
(funcall modify-file-fn toml-file denote-toml-front-matter)
(should (eq (denote-file-type toml-file) 'markdown-toml)))
(progn
(funcall modify-file-fn org-file denote-org-front-matter)
(should (eq (denote-file-type org-file) 'org)))
(should-not (denote-file-type "test"))
(let ((denote-file-types nil))
(should-not (denote-file-type "test.md")))))
(provide 'denote-test)
;;; denote-test.el ends here