blob: 3db5b08d15b25184d24aab581365722a1c6801ad (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
;;; generic-search.el -- A search result UI -*- lexical-binding: t -*-
;; Copyright (C) 2023 Free Software Foundation.
;; Author: Yuchen Pei <id@ypei.org>
;; Package-Requires: ((emacs "28.2"))
;; This file is part of dotfiles.
;; dotfiles is free software: you can redistribute it and/or modify it
;; under the terms of the GNU Affero General Public License as
;; published by the Free Software Foundation, either version 3 of the
;; License, or (at your option) any later version.
;; dotfiles is distributed in the hope that it will be useful, but
;; WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;; Affero General Public License for more details.
;; You should have received a copy of the GNU Affero General Public
;; License along with dotfiles. If not, see
;; <https://www.gnu.org/licenses/>.
;;; Commentary:
;; A search result UI. A generic search result mode displaying a list
;; of things, and action on an item
;;; Code:
(defvar-local generic-search-transformer nil)
(defvar-local generic-search-formatter nil)
(defvar-local generic-search-default-action nil)
(defvar-local generic-search-results nil)
(defvar-local generic-search-keymap nil)
(defvar generic-search-default-transformer 'identity)
(defvar generic-search-default-formatter 'pp)
(defvar generic-search-default-default-action 'generic-search-message-pp)
(defvar generic-search-default-keymap button-map)
(defun generic-search-message-pp (data)
(interactive)
(message (pp data)))
(define-derived-mode generic-search-mode special-mode "Generic search"
"Search results.")
(defun generic-search-buffer-name (name)
(format "*generic-search %s*" name))
(defun generic-search-open (results name &optional display-options)
(let ((buffer-name (generic-search-buffer-name name)))
(with-current-buffer (get-buffer-create buffer-name)
(generic-search-mode)
(setq generic-search-results results
generic-search-formatter
(or (alist-get 'formatter display-options)
generic-search-default-formatter)
generic-search-default-action
(or (alist-get 'default-action display-options)
generic-search-default-default-action)
generic-search-keymap
(or (alist-get 'keymap display-options)
generic-search-default-keymap)
generic-search-transformer
(or (alist-get 'transfomer display-options
generic-search-default-transformer)))
(generic-search-update)
(switch-to-buffer-other-window buffer-name))))
(defun generic-search-update ()
(let ((inhibit-read-only t))
(erase-buffer)
(insert (format "%s Results:" (length generic-search-results)))
(seq-do (lambda (result)
(insert "\n----\n")
(let ((start (point)))
(insert
(funcall generic-search-formatter result))
(make-text-button start (point)
'action generic-search-default-action
'button-data
(funcall generic-search-transformer result)
'keymap generic-search-keymap)))
generic-search-results)
(goto-char (point-min))
(forward-button 1)))
(defun generic-search-refresh ()
(interactive)
(generic-search-update))
(define-key generic-search-mode-map "\t" 'forward-button)
(define-key generic-search-mode-map [backtab] 'backward-button)
(define-key generic-search-mode-map "g" 'generic-search-refresh)
(provide 'generic-search)
|