branch: externals/denote-search
commit ac701b674dd0075e5732d31a3e5c3c832f7f7308
Author: Lucas Quintana <[email protected]>
Commit: Lucas Quintana <[email protected]>
Allow searching in files referenced in a region (!!)
This is actually pretty awesome. Just mark a region with links to
other notes and `denote-search-files-referenced-in-region` will be able
to search in them. But this works in every place where a Denote ID is
found, including ls outputs!
---
README.md | 6 ++-
README.org | 112 ++++++++++++++++++++++++++++++++++++++++++++++++-------
denote-search.el | 47 ++++++++++++++++++++++-
3 files changed, 147 insertions(+), 18 deletions(-)
diff --git a/README.md b/README.md
index 05ce416ff0..8fd5ee619c 100644
--- a/README.md
+++ b/README.md
@@ -39,8 +39,10 @@ in the sample configuration:
:vc (:url "https://github.com/lmq-10/denote-search"
:rev :newest)
:bind
- ;; Start search with C-c s
- ("C-c s" . denote-search)
+ ;; Customize keybindings to your liking
+ (("C-c s s" . denote-search)
+ ("C-c s d" . denote-search-marked-dired-files)
+ ("C-c s r" . denote-search-files-referenced-in-region))
:custom
;; Disable help string (set it once you learn the commands)
;; (denote-search-help-string "")
diff --git a/README.org b/README.org
index 03c7bbde68..48deb3624e 100644
--- a/README.org
+++ b/README.org
@@ -4,8 +4,8 @@
#+language: en
#+options: ':t toc:nil author:t email:t num:t
#+startup: content
-#+macro: stable-version 0.2.0
-#+macro: release-date 2024-12-28
+#+macro: stable-version 0.3.0
+#+macro: release-date 2024-12-31
#+export_file_name: denote-search.texi
#+texinfo_filename: denote-search.info
#+texinfo_dir_category: Emacs misc features
@@ -32,7 +32,7 @@ The documentation furnished herein corresponds to stable
version
:COPYING: t
:END:
-Copyright (C) 2024 Lucas Quintana
+Copyright (C) 2024-2025 Lucas Quintana
#+begin_quote
Permission is granted to copy, distribute and/or modify this document
@@ -63,6 +63,13 @@ info:emacs#Xref).
- It allows to search in the files matched by a previous search, which
as far as I know is not possible with other similar packages.
+- It allows to search in the files referenced in a region, with the
+ command ~denote-search-files-referenced-in-region~. That is great
+ for metanotes, shell outputs of =ls=, and more.
+
+- It also allows to search in marked Dired files, with the command
+ ~denote-search-marked-dired-files~.
+
- It doesn't rely on the minibuffer to output results, and it thus
doesn't need a completion stack in order to work (~helm~,
~vertico+consult~, etc.).
@@ -101,15 +108,15 @@ is. Howm has thus powerful search facilities built-in,
some of which
* Points of entry
#+findex: denote-search
-The main (and in practical terms, only) point of entry of this package
-is the ~denote-search~ command. This command will prompt for a
-string. You should input a valid regular expression, as understood by
-the tool which will actually perform the search. Which program that
-is depends on the value of ~xref-search-program~, and its arguments
-are taken from ~xref-search-program-alist~. Note that ~denote-search~
-is really just a wrapper for Xref, albeit an useful one, so anything
-related to the actual search results is the matter (for bad or for
-good) of that library and/or the program it calls.
+The main point of entry of this package is the ~denote-search~
+command. This command will prompt for a string. You should input a
+valid regular expression, as understood by the tool which will
+actually perform the search. Which program that is depends on the
+value of ~xref-search-program~, and its arguments are taken from
+~xref-search-program-alist~. Note that ~denote-search~ is really just
+a wrapper for Xref, albeit an useful one, so anything related to the
+actual search results is the matter (for bad or for good) of that
+library and/or the program it calls.
Once the (synchronous) search is over, a new buffer populated with the
results, if any, will be made current. On that buffer, the user will
@@ -120,6 +127,81 @@ in the matched files (see [[*focused search][focused
search]]).
History is available when searching. Press ~M-p~
(~previous-history-element~) to view past queries.
+There are two additional commands that can start a search:
+~denote-search-marked-dired-files~ and
+~denote-search-files-referenced-in-region~. They allow searching a
+restricted subset of files and are described in the next sections.
+
+** Searching in marked Dired files
+
+#+findex: denote-search-marked-dired-files
+The command ~denote-search-marked-dired-files~ acts just like
+~denote-search~, but it restricts the search to the files marked in
+current Dired buffer (see [[info:emacs#Dired][Marks vs Flags]]). This is
useful if you only
+want to search some files, though depending on the case maybe you'd
+be better served by our built-in filtering capabilities; see
+[[*filtering the search results][filtering the search results]].
+
+This works well in tandem with the Denote command ~denote-sort-dired~,
+which produces a Dired buffer with files matching a regexp. So,
+generating that buffer and then pressing ~t~ (~dired-toggle-marks~)
+will enable you to use ~denote-search-marked-dired-files~ to search on
+those files. Again, using the filtering functionality available for
+the results buffer should suit you better, but you have options.
+
+** Searching in files referenced in a region
+
+#+findex: denote-search-files-referenced-in-region
+The command ~denote-search-files-referenced-in-region~ may seem odd at
+first, but it's probably the most useful one. It allows you to search
+in a set of notes referenced in a buffer. What does that means?
+Well, it means that any buffer can serve as the source for the set of
+files to search for; you just need Denote IDs written somewhere, and
+the command will recognize them as files and search in them.
+
+But let's look at an example. Probably, you already have a note with
+a section that resembles this:
+
+#+begin_src org
+,* See also
+
+- An amazing note
+- Another amazing note
+- Yet another amazing note
+#+end_src
+
+Those notes are links and are highlighted as such, so internally they look
like this:
+
+#+begin_src org
+,* See also
+
+- [[denote:20231205T202124][An amazing note]]
+- [[denote:20230720T154224][Another amazing note]]
+- [[denote:20230719T194132][Yet another amazing note]]
+#+end_src
+
+That ~20231205T202124~ bit is the Denote ID. That's the only thing
+our command needs to recognize a note. So, you just need to select
+the section (with the mouse or ~C-SPC~, whichever you like the most)
+and call ~denote-search-files-referenced-in-region~. It will prompt
+for a regexp just like ~denote-search~, but it will only search the
+files selected.
+
+This is useful for searching in notes linked in Org dynamic blocks
+(first mark the block with ~org-babel-mark-block~), or for searching
+something in linked notes in general (first mark the whole buffer with
+~mark-whole-buffer~, bound to ~C-x h~).
+
+This works everywhere. If you had notes with the exact same IDs as
+the ones depicted previously, you could select them in this very same
+Info buffer (assuming you are reading this in Emacs) and search
+something in them right away.
+
+As the Denote ID is included in file names, you can also use this
+command on Dired, on a shell output of ls from ~async-shell-command~,
+and so on. It's on those cases where you can grasp how powerful the
+Denote file-naming scheme is.
+
* Navigating the search results
To navigate the results buffer, you can use the standard Xref commands
@@ -340,8 +422,10 @@ Everything is in place to set up the package.
:vc (:url "https://github.com/lmq-10/denote-search"
:rev :newest)
:bind
- ;; Start search with C-c s
- ("C-c s" . denote-search)
+ ;; Customize keybindings to your liking
+ (("C-c s s" . denote-search)
+ ("C-c s d" . denote-search-marked-dired-files)
+ ("C-c s r" . denote-search-files-referenced-in-region))
:custom
;; Disable help string (set it once you learn the commands)
;; (denote-search-help-string "")
diff --git a/denote-search.el b/denote-search.el
index eea9a1c549..28334d3644 100644
--- a/denote-search.el
+++ b/denote-search.el
@@ -1,13 +1,13 @@
;;; denote-search.el --- Search the contents of your notes -*-
lexical-binding: t; -*-
-;; Copyright (C) 2024 Lucas Quintana
+;; Copyright (C) 2024-2025 Lucas Quintana
;; Author: Lucas Quintana <[email protected]>
;; Maintainer: Lucas Quintana <[email protected]>
;; URL: https://github.com/lmq-10/denote-search
;; Created: 2024-12-28
;; Keywords: matching
-;; Version: 0.2.0
+;; Version: 0.3.0
;; Package-Requires: ((emacs "29.1") (denote "3.0"))
;; This program is NOT part of GNU Emacs.
@@ -146,6 +146,8 @@ TYPE only affects the prompt, not the returned value."
"Search (only files matched last): ")
((eq type :dired)
"Search (only marked dired files): ")
+ ((eq type :region)
+ "Search (only files referenced in region): ")
(:else
"Search (all Denote files): "))
nil 'denote-search-query-history)))
@@ -194,6 +196,25 @@ line, and any key descriptions within it are replaced using
(seconds-to-string (float-time (time-subtract (current-time) time)))
number-of-files help-string))))
+(defun denote-search--get-files-referenced-in-region (start end)
+ "Return a list with all Denote files referenced between START and END.
+
+START and END should be buffer positions, as integers.
+
+\"Referenced\" here means an ID is present in the text, so it'll work with
+plain links, links written by a dynamic block, or even file lists
+returned by ls (and that naturally includes dired).
+
+Returned value is a list with the absoulte path of referenced files."
+ (let (id-list)
+ (save-excursion
+ (save-restriction
+ (narrow-to-region start end)
+ (goto-char (point-min))
+ (while (re-search-forward denote-id-regexp nil t)
+ (push (match-string 0) id-list))))
+ (and id-list (mapcar #'denote-get-path-by-id id-list))))
+
;;;###autoload
(defun denote-search (query &optional set)
"Search QUERY in the content of Denote files.
@@ -265,6 +286,28 @@ parameter of `denote-search'."
(denote-search query files)
(user-error "No marked files")))
+;;;###autoload
+(defun denote-search-files-referenced-in-region (query start end)
+ "Search QUERY in the content of files referenced between START and END.
+
+START and END should be buffer positions, as integers. Interactively,
+they are the positions of point and mark (i.e. the region).
+
+See `denote-search--get-files-referenced-in-region' for an explanation
+of what referenced means (in short: an ID is present somewhere).
+
+This function is not used for filtering content in the results buffer;
+see e.g. `denote-search-exclude-files' for that."
+ ;; MAYBE: We could respect `use-empty-active-region', but it would
+ ;; complicate things a little
+ (interactive
+ (append
+ (denote-search-query-prompt :region)
+ (list (region-beginning) (region-end))))
+ (if-let* ((files (denote-search--get-files-referenced-in-region start end)))
+ (denote-search query files)
+ (user-error "No files referenced in region")))
+
(defun denote-search-refine (query)
"Search QUERY in the content of files which matched the last `denote-search'.