commit 8f6164aeec88d61918b49ee11ce17ac850a2f29c
parent 9fbbcb78fafa1eb9f78e1ac094e165ee855cf2cc
Author: Vincent Demeester <vincent@sbr.pm>
Date: Fri, 26 Jan 2024 11:37:42 +0100
tools/emacs: dired transient menu and org-search-from-sacha functions :)
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Diffstat:
2 files changed, 197 insertions(+), 0 deletions(-)
diff --git a/tools/emacs/config/config-dired.el b/tools/emacs/config/config-dired.el
@@ -233,5 +233,147 @@ This relies on the external 'fd' executable."
(setq dired-sidebar-theme 'arrow)
(setq dired-sidebar-use-term-integration t))
+(require 'transient)
+(require 'easymenu)
+
+(defcustom cc-dired-listing-switches '("--human-readable"
+ "--group-directories-first"
+ "--time-style=long-iso")
+ "List of GNU ls arguments used by the function `cc/--dired-sort-by'.
+
+This variable requires GNU ls from coreutils installed.\n
+See the man page `ls(1)' for details."
+ :type '(repeat string)
+ :group 'dired)
+
+(transient-define-prefix cc/dired-sort-by ()
+ "Transient menu to sort Dired buffer by different criteria.
+
+This function requires GNU ls from coreutils installed."
+ :value '("--human-readable"
+ "--group-directories-first"
+ "--time-style=long-iso")
+ ; TODO: support cc-dired-listing-switches
+ [["Arguments"
+ ("-a" "all" "--all")
+ ("g" "group directories first" "--group-directories-first")
+ ("-r" "reverse" "--reverse")
+ ("-h" "human readable" "--human-readable")
+ ("t" "time style" "--time-style="
+ :choices ("full-iso" "long-iso" "iso" "locale"))]
+
+ ["Sort By"
+ ("n"
+ "Name"
+ (lambda () (interactive)
+ (cc/--dired-sort-by :name
+ (transient-args transient-current-command)))
+ :transient nil)
+ ("k"
+ "Kind"
+ (lambda () (interactive)
+ (cc/--dired-sort-by :kind
+ (transient-args transient-current-command)))
+ :transient nil)
+ ("l"
+ "Date Last Opened"
+ (lambda () (interactive)
+ (cc/--dired-sort-by :date-last-opened
+ (transient-args transient-current-command)))
+ :transient nil)
+ ("a"
+ "Date Added"
+ (lambda () (interactive)
+ (cc/--dired-sort-by :date-added
+ (transient-args transient-current-command)))
+ :transient nil)
+ ("m"
+ "Date Modified"
+ (lambda () (interactive)
+ (cc/--dired-sort-by :date-modified
+ (transient-args transient-current-command)))
+ :transient nil)
+ ("M"
+ "Date Metadata Changed"
+ (lambda () (interactive)
+ (cc/--dired-sort-by :date-metadata-changed
+ (transient-args transient-current-command)))
+ :transient nil)
+ ("v"
+ "Version"
+ (lambda () (interactive)
+ (cc/--dired-sort-by :version
+ (transient-args transient-current-command)))
+ :transient nil)
+ ("s"
+ "Size"
+ (lambda () (interactive)
+ (cc/--dired-sort-by :size
+ (transient-args transient-current-command)))
+ :transient nil)]])
+
+(defun cc/--dired-sort-by (criteria &optional prefix-args)
+ "Sort current Dired buffer according to CRITERIA and PREFIX-ARGS.
+
+This function will invoke `dired-sort-other' with arguments built from
+CRITERIA and PREFIX-ARGS.
+
+CRITERIA is a keyword of which the following are supported:
+ :name :date-added :version
+ :kind :date-metadata-changed :size
+ :date-last-opened :date-modified
+
+PREFIX-ARGS is a list of GNU ls arguments. If nil, then it will use the value
+of `cc-dired-listing-switches'. Otherwise this is typically populated by the
+Transient menu `cc/dired-sort-by'.
+
+This function requires GNU ls from coreutils installed.
+
+See the man page `ls(1)' for details."
+ (let ((arg-list (list "-l")))
+ (if prefix-args
+ (nconc arg-list prefix-args)
+ (nconc arg-list cc-dired-listing-switches))
+ (cond
+ ((eq criteria :name)
+ (message "Sorted by name"))
+
+ ((eq criteria :kind)
+ (message "Sorted by kind")
+ (push "--sort=extension" arg-list))
+
+ ((eq criteria :date-last-opened)
+ (message "Sorted by date last opened")
+ (push "--sort=time" arg-list)
+ (push "--time=access" arg-list))
+
+ ((eq criteria :date-added)
+ (message "Sorted by date added")
+ (push "--sort=time" arg-list)
+ (push "--time=creation" arg-list))
+
+ ((eq criteria :date-modified)
+ (message "Sorted by date modified")
+ (push "--sort=time" arg-list)
+ (push "--time=modification" arg-list))
+
+ ((eq criteria :date-metadata-changed)
+ (message "Sorted by date metadata changed")
+ (push "--sort=time" arg-list)
+ (push "--time=status" arg-list))
+
+ ((eq criteria :version)
+ (message "Sorted by version")
+ (push "--sort=version" arg-list))
+
+ ((eq criteria :size)
+ (message "Sorted by size")
+ (push "-S" arg-list))
+
+ (t
+ (message "Default sorted by name")))
+
+ (dired-sort-other (mapconcat 'identity arg-list " "))))
+
(provide 'config-dired)
;; config-dired.el ends here
diff --git a/tools/emacs/config/config-org.el b/tools/emacs/config/config-org.el
@@ -834,5 +834,60 @@ file which do not already have one."
;; org-tree-slide-content-margin-top 1
;; org-tree-slide-skip-outline-level 4))
+;; from https://sachachua.com/blog/2024/01/using-consult-and-org-ql-to-search-my-org-mode-agenda-files-and-sort-the-results-to-prioritize-heading-matches/
+(defun my-consult-org-ql-agenda-jump ()
+ "Search agenda files with preview."
+ (interactive)
+ (let* ((marker (consult--read
+ (consult--dynamic-collection
+ #'my-consult-org-ql-agenda-match)
+ :state (consult--jump-state)
+ :category 'consult-org-heading
+ :prompt "Heading: "
+ :sort nil
+ :lookup #'consult--lookup-candidate))
+ (buffer (marker-buffer marker))
+ (pos (marker-position marker)))
+ ;; based on org-agenda-switch-to
+ (unless buffer (user-error "Trying to switch to non-existent buffer"))
+ (pop-to-buffer-same-window buffer)
+ (goto-char pos)
+ (when (derived-mode-p 'org-mode)
+ (org-fold-show-context 'agenda)
+ (run-hooks 'org-agenda-after-show-hook))))
+
+(defun my-consult-org-ql-agenda-format (o)
+ (propertize
+ (org-ql-view--format-element o)
+ 'consult--candidate (org-element-property :org-hd-marker o)))
+
+(defun my-consult-org-ql-agenda-match (string)
+ "Return candidates that match STRING.
+Sort heading matches first, followed by other matches.
+Within those groups, sort by date and priority."
+ (let* ((query (org-ql--query-string-to-sexp string))
+ (sort '(date reverse priority))
+ (heading-query (-tree-map (lambda (x) (if (eq x 'rifle) 'heading x)) query))
+ (matched-heading
+ (mapcar #'my-consult-org-ql-agenda-format
+ (org-ql-select 'org-agenda-files heading-query
+ :action 'element-with-markers
+ :sort sort)))
+ (all-matches
+ (mapcar #'my-consult-org-ql-agenda-format
+ (org-ql-select 'org-agenda-files query
+ :action 'element-with-markers
+ :sort sort))))
+ (append
+ matched-heading
+ (seq-difference all-matches matched-heading))))
+
+(use-package org-ql
+ :after org
+ :bind ("M-s a" . my-consult-org-ql-agenda-jump))
+
+(use-package org-ql-view
+ :after org-ql)
+
(provide 'config-org)
;;; config-org.el ends here