Add: Search buffer refreshing, header line, etc.
This commit is contained in:
parent
a74520c223
commit
0aec8ec603
3 changed files with 109 additions and 33 deletions
18
README.org
18
README.org
|
|
@ -69,7 +69,23 @@ Feedback on these APIs is welcome. Eventually, after being tested and polished,
|
||||||
|
|
||||||
*** org-ql-search
|
*** org-ql-search
|
||||||
|
|
||||||
The command =org-ql-search= prompts for a query, a list of buffers or files, and how to group and sort results. Without prefix, it searches the current buffer instead of prompting. Then it presents the results in an agenda-like view.
|
Read ~QUERY~ and search with ~org-ql~. Interactively, prompt for these variables:
|
||||||
|
|
||||||
|
~BUFFERS-FILES~: ~A~ list of buffers and/or files to search. Interactively, may also be:
|
||||||
|
|
||||||
|
+ ~buffer~: search the current buffer
|
||||||
|
+ ~all~: search all Org buffers
|
||||||
|
+ ~agenda~: search buffers returned by the function ~org-agenda-files~
|
||||||
|
+ An expression which evaluates to a list of files/buffers
|
||||||
|
+ A space-separated list of file or buffer names
|
||||||
|
|
||||||
|
~GROUPS~: An ~org-super-agenda~ group set. See variable ~org-super-agenda-groups~.
|
||||||
|
|
||||||
|
~NARROW~: When non-nil, don't widen buffers before searching. Interactively, with prefix, leave narrowed.
|
||||||
|
|
||||||
|
~SORT~: One or a list of ~org-ql~ sorting functions, like ~date~ or ~priority~.
|
||||||
|
|
||||||
|
Press =g= to refresh the results buffer.
|
||||||
|
|
||||||
[[images/org-ql-search.gif]]
|
[[images/org-ql-search.gif]]
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 414 KiB After Width: | Height: | Size: 202 KiB |
|
|
@ -47,6 +47,13 @@
|
||||||
(defvar org-ql-agenda-buffer-name "*Org Agenda NG*"
|
(defvar org-ql-agenda-buffer-name "*Org Agenda NG*"
|
||||||
"Name of default `org-ql-agenda' buffer.")
|
"Name of default `org-ql-agenda' buffer.")
|
||||||
|
|
||||||
|
;; For refreshing results buffers.
|
||||||
|
(defvar org-ql-buffers-files)
|
||||||
|
(defvar org-ql-query)
|
||||||
|
(defvar org-ql-sort)
|
||||||
|
(defvar org-ql-narrow)
|
||||||
|
(defvar org-ql-super-groups)
|
||||||
|
|
||||||
;;;; Macros
|
;;;; Macros
|
||||||
|
|
||||||
;; FIXME: DRY these two macros.
|
;; FIXME: DRY these two macros.
|
||||||
|
|
@ -124,8 +131,13 @@ is used, rather than binding it locally."
|
||||||
Interactively, prompt for these variables:
|
Interactively, prompt for these variables:
|
||||||
|
|
||||||
BUFFERS-FILES: A list of buffers and/or files to search.
|
BUFFERS-FILES: A list of buffers and/or files to search.
|
||||||
Interactively, may also be an expression which evaluates to such
|
Interactively, may also be:
|
||||||
a list.
|
|
||||||
|
- `buffer': search the current buffer
|
||||||
|
- `all': search all Org buffers
|
||||||
|
- `agenda': search buffers returned by the function `org-agenda-files'
|
||||||
|
- An expression which evaluates to a list of files/buffers
|
||||||
|
- A space-separated list of file or buffer names
|
||||||
|
|
||||||
GROUPS: An `org-super-agenda' group set. See variable
|
GROUPS: An `org-super-agenda' group set. See variable
|
||||||
`org-super-agenda-groups'.
|
`org-super-agenda-groups'.
|
||||||
|
|
@ -136,17 +148,14 @@ searching. Interactively, with prefix, leave narrowed.
|
||||||
SORT: One or a list of `org-ql' sorting functions, like `date' or
|
SORT: One or a list of `org-ql' sorting functions, like `date' or
|
||||||
`priority'."
|
`priority'."
|
||||||
(declare (indent defun))
|
(declare (indent defun))
|
||||||
(interactive (progn
|
(interactive (list (pcase-exhaustive (completing-read "Buffers/Files:"
|
||||||
(when (and current-prefix-arg
|
(list 'buffer 'agenda 'all))
|
||||||
(not (derived-mode-p 'org-mode)))
|
("agenda" (org-agenda-files))
|
||||||
(user-error "Not an Org buffer: %s" (buffer-name)))
|
("all" (--select (equal (buffer-local-value 'major-mode it) 'org-mode)
|
||||||
(list (--if-let (read-from-minibuffer "Buffers/Files (blank for current buffer): ")
|
(buffer-list)))
|
||||||
;; TODO: Add glob matching? Buffer mode matching?
|
("buffer" (current-buffer))
|
||||||
(pcase it
|
((and form (guard (rx bos "("))) (-flatten (eval (read form))))
|
||||||
("" (current-buffer))
|
(else (s-split (rx (1+ space)) else)))
|
||||||
((rx bos "(") (-flatten (eval (read it))))
|
|
||||||
(_ (s-split (rx (1+ space)) it)))
|
|
||||||
(current-buffer))
|
|
||||||
(read-minibuffer "Query: ")
|
(read-minibuffer "Query: ")
|
||||||
:narrow (eq current-prefix-arg '(4))
|
:narrow (eq current-prefix-arg '(4))
|
||||||
:groups (pcase (completing-read "Group by: "
|
:groups (pcase (completing-read "Group by: "
|
||||||
|
|
@ -163,12 +172,23 @@ SORT: One or a list of `org-ql' sorting functions, like `date' or
|
||||||
"scheduled"
|
"scheduled"
|
||||||
"todo"))
|
"todo"))
|
||||||
("Don't sort" nil)
|
("Don't sort" nil)
|
||||||
(sort (intern sort))))))
|
(sort (intern sort)))))
|
||||||
(org-ql-agenda--agenda buffers-files
|
(org-ql-agenda--agenda buffers-files
|
||||||
query
|
query
|
||||||
:narrow narrow
|
:narrow narrow
|
||||||
:sort sort
|
:sort sort
|
||||||
:super-groups groups))
|
:super-groups groups
|
||||||
|
:buffer "*Org QL Search*"))
|
||||||
|
|
||||||
|
(defun org-ql-search-refresh ()
|
||||||
|
"Refresh current `org-ql-search' buffer."
|
||||||
|
(interactive)
|
||||||
|
(org-ql-agenda--agenda org-ql-buffers-files
|
||||||
|
org-ql-query
|
||||||
|
:sort org-ql-sort
|
||||||
|
:narrow org-ql-narrow
|
||||||
|
:super-groups org-ql-super-groups
|
||||||
|
:buffer (current-buffer)))
|
||||||
|
|
||||||
;;;; Functions
|
;;;; Functions
|
||||||
|
|
||||||
|
|
@ -191,14 +211,54 @@ SORT: One or a list of `org-ql' sorting functions, like `date' or
|
||||||
(cond ((bound-and-true-p org-super-agenda-mode) (org-super-agenda--group-items it))
|
(cond ((bound-and-true-p org-super-agenda-mode) (org-super-agenda--group-items it))
|
||||||
(t it))
|
(t it))
|
||||||
(s-join "\n" it)))
|
(s-join "\n" it)))
|
||||||
|
(buffer (cl-etypecase buffer
|
||||||
|
(string (org-ql-agenda--buffer buffer))
|
||||||
|
(null (org-ql-agenda--buffer buffer))
|
||||||
|
(buffer buffer)))
|
||||||
(inhibit-read-only t))
|
(inhibit-read-only t))
|
||||||
(with-current-buffer (org-ql-agenda--buffer buffer)
|
(with-current-buffer buffer
|
||||||
|
;; Prepare buffer, saving data for refreshing.
|
||||||
|
(setq-local org-ql-buffers-files buffers-files)
|
||||||
|
(setq-local org-ql-query query)
|
||||||
|
(setq-local org-ql-sort sort)
|
||||||
|
(setq-local org-ql-narrow narrow)
|
||||||
|
(setq-local org-ql-super-groups super-groups)
|
||||||
|
;; TODO: Derive a minor mode and set keymap there.
|
||||||
|
(local-set-key "g" #'org-ql-search-refresh)
|
||||||
|
(let* ((query-formatted (format "%S" query))
|
||||||
|
(query-formatted (propertize (org-ql-agenda--font-lock-string 'emacs-lisp-mode query-formatted)
|
||||||
|
'help-echo query-formatted))
|
||||||
|
(query-width (length query-formatted))
|
||||||
|
(available-width (- (window-width)
|
||||||
|
(length "In: ")
|
||||||
|
(length "Query: ")
|
||||||
|
query-width 4))
|
||||||
|
(buffers-files-formatted (format "%S" buffers-files))
|
||||||
|
(buffers-files-formatted (propertize (->> buffers-files-formatted
|
||||||
|
(org-ql-agenda--font-lock-string 'emacs-lisp-mode)
|
||||||
|
(s-truncate available-width))
|
||||||
|
'help-echo buffers-files-formatted)))
|
||||||
|
(setq-local header-line-format (concat (propertize "Query: " 'face 'org-agenda-structure)
|
||||||
|
query-formatted " "
|
||||||
|
(propertize "In: " 'face 'org-agenda-structure)
|
||||||
|
buffers-files-formatted)))
|
||||||
|
;; Clear buffer, insert entries, etc.
|
||||||
(erase-buffer)
|
(erase-buffer)
|
||||||
(insert entries)
|
(insert entries)
|
||||||
(pop-to-buffer (current-buffer))
|
(pop-to-buffer (current-buffer))
|
||||||
(org-agenda-finalize)
|
(org-agenda-finalize)
|
||||||
(goto-char (point-min)))))
|
(goto-char (point-min)))))
|
||||||
|
|
||||||
|
(defun org-ql-agenda--font-lock-string (mode s)
|
||||||
|
"Return string S font-locked according to MODE."
|
||||||
|
;; FIXME: Is this the proper way to do this? It works, but I feel like there must be a built-in way...
|
||||||
|
(with-temp-buffer
|
||||||
|
(delay-mode-hooks
|
||||||
|
(insert s)
|
||||||
|
(funcall mode)
|
||||||
|
(font-lock-ensure)
|
||||||
|
(buffer-string))))
|
||||||
|
|
||||||
(defun org-ql-agenda--buffer (&optional name)
|
(defun org-ql-agenda--buffer (&optional name)
|
||||||
"Return Agenda NG buffer, creating it if necessary.
|
"Return Agenda NG buffer, creating it if necessary.
|
||||||
If NAME is non-nil, return buffer by that name instead of using
|
If NAME is non-nil, return buffer by that name instead of using
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue