Do Not Prompt User to Set Search Type before Querying Khoj via Emacs

### Why
- Reduce time from intent to results by using reasonable defaults
- Make interactions smoother, more intuitive
- Users expect to start querying immediately. The prompt to enter search type creates unnecessary friction

### How
- By default, search using last searched content type
- Allow user to change search type, while querying, by using keyboard shortcuts
- For reference, display keyboard shortcuts to set search-type when user initiates (incremental) search
This commit is contained in:
Debanjum 2022-08-05 20:51:00 +03:00 committed by GitHub
commit 3a4e5de7fa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -65,9 +65,44 @@
(defconst khoj--query-prompt "🦅Khoj: " (defconst khoj--query-prompt "🦅Khoj: "
"Query prompt shown to user in the minibuffer.") "Query prompt shown to user in the minibuffer.")
(defconst khoj--buffer-name "*🦅Khoj*"
"Name of buffer to show results from Khoj.")
(defvar khoj--search-type "org" (defvar khoj--search-type "org"
"The type of content to perform search on.") "The type of content to perform search on.")
(defvar khoj--keybindings-info-message
"
Set Search Type
-------------------------
C-x m | markdown
C-x o | org-mode
C-x l | ledger/beancount
C-x i | images
")
(defun khoj--search-markdown (interactive) (setq khoj--search-type "markdown"))
(defun khoj--search-org (interactive) (setq khoj--search-type "org"))
(defun khoj--search-ledger (interactive) (setq khoj--search-type "ledger"))
(defun khoj--search-images (interactive) (setq khoj--search-type "image"))
(defun khoj--make-search-keymap (&optional existing-keymap)
"Setup keymap to configure Khoj search"
(let ((kmap (or existing-keymap (make-sparse-keymap))))
(define-key kmap (kbd "C-x m") #'khoj--search-markdown)
(define-key kmap (kbd "C-x o") #'khoj--search-org)
(define-key kmap (kbd "C-x l") #'khoj--search-ledger)
(define-key kmap (kbd "C-x i") #'khoj--search-images)
kmap))
(defun khoj--display-keybinding-info ()
"Display information on keybindings to customize khoj search.
Use `which-key` if available, else display simple message in echo area"
(if (fboundp 'which-key--create-buffer-and-show)
(which-key--create-buffer-and-show
(kbd "C-x")
(symbolp (khoj--make-search-keymap))
'(lambda (binding) (string-prefix-p "khoj--" (cdr binding)))
"Khoj Bindings")
(message "%s" khoj--keybindings-info-message)))
(defun khoj--extract-entries-as-markdown (json-response query) (defun khoj--extract-entries-as-markdown (json-response query)
"Convert json response from API to markdown entries" "Convert json response from API to markdown entries"
;; remove leading (, ) or SPC from extracted entries string ;; remove leading (, ) or SPC from extracted entries string
@ -141,7 +176,7 @@
(let ((file-extension (file-name-extension buffer-name))) (let ((file-extension (file-name-extension buffer-name)))
(cond (cond
((equal buffer-name "Music.org") "music") ((equal buffer-name "Music.org") "music")
((equal file-extension "bean") "ledger") ((or (equal file-extension "bean") (equal file-extension "beancount")) "ledger")
((equal file-extension "org") "org") ((equal file-extension "org") "org")
((or (equal file-extension "markdown") (equal file-extension "md")) "markdown") ((or (equal file-extension "markdown") (equal file-extension "md")) "markdown")
(t "org")))) (t "org"))))
@ -183,21 +218,23 @@
;; Incremental Search on Khoj ;; Incremental Search on Khoj
(defun khoj--incremental-search (&optional rerank) (defun khoj--incremental-search (&optional rerank)
(let* ((rerank-str (cond (rerank "true") (t "false"))) (let* ((rerank-str (cond (rerank "true") (t "false")))
(search-type khoj--search-type) (khoj-buffer-name (get-buffer-create khoj--buffer-name))
(buffer-name (get-buffer-create (format "*Khoj (t:%s)*" search-type)))
(query (minibuffer-contents-no-properties)) (query (minibuffer-contents-no-properties))
(query-url (khoj--construct-api-query query search-type rerank-str))) (query-url (khoj--construct-api-query query khoj--search-type rerank-str)))
;; Query khoj API only when user in khoj minibuffer. ;; Query khoj API only when user in khoj minibuffer and non-empty query
;; Prevents querying during recursive edits or with contents of other buffers user may jump to ;; Prevents querying if
(when (and (active-minibuffer-window) (equal (current-buffer) khoj--minibuffer-window)) ;; 1. user hasn't started typing query
;; 2. during recursive edits
;; 3. with contents of other buffers user may jump to
(when (and (not (equal query "")) (active-minibuffer-window) (equal (current-buffer) khoj--minibuffer-window))
(progn (progn
(when rerank (when rerank
(message "[Khoj]: Rerank Results")) (message "Khoj: Rerank Results"))
(khoj--query-api-and-render-results (khoj--query-api-and-render-results
query query
search-type khoj--search-type
query-url query-url
buffer-name))))) khoj-buffer-name)))))
(defun delete-open-network-connections-to-khoj () (defun delete-open-network-connections-to-khoj ()
"Delete all network connections to khoj server" "Delete all network connections to khoj server"
@ -229,17 +266,20 @@
(defun khoj () (defun khoj ()
"Natural, Incremental Search for your personal notes, transactions and music using Khoj" "Natural, Incremental Search for your personal notes, transactions and music using Khoj"
(interactive) (interactive)
(let* ((default-type (khoj--buffer-name-to-search-type (buffer-name))) (let* ((khoj-buffer-name (get-buffer-create khoj--buffer-name)))
(search-type (completing-read "Type: " '("org" "markdown" "ledger" "music") nil t default-type)) ;; set khoj search type to last used or based on current buffer
(buffer-name (get-buffer-create (format "*Khoj (t:%s)*" search-type)))) (setq khoj--search-type (or khoj--search-type (khoj--buffer-name-to-search-type (buffer-name))))
(setq khoj--search-type search-type)
;; setup rerank to improve results once user idle for KHOJ--RERANK-AFTER-IDLE-TIME seconds ;; setup rerank to improve results once user idle for KHOJ--RERANK-AFTER-IDLE-TIME seconds
(setq khoj--rerank-timer (run-with-idle-timer khoj--rerank-after-idle-time t 'khoj--incremental-search t)) (setq khoj--rerank-timer (run-with-idle-timer khoj--rerank-after-idle-time t 'khoj--incremental-search t))
;; switch to khoj results buffer ;; switch to khoj results buffer
(switch-to-buffer buffer-name) (switch-to-buffer khoj-buffer-name)
;; open and setup minibuffer for incremental search ;; open and setup minibuffer for incremental search
(minibuffer-with-setup-hook (minibuffer-with-setup-hook
(lambda () (lambda ()
;; Add khoj keybindings for configuring search to minibuffer keybindings
(khoj--make-search-keymap minibuffer-local-map)
;; Display information on keybindings to customize khoj search
(khoj--display-keybinding-info)
;; set current (mini-)buffer entered as khoj minibuffer ;; set current (mini-)buffer entered as khoj minibuffer
;; used to query khoj API only when user in khoj minibuffer ;; used to query khoj API only when user in khoj minibuffer
(setq khoj--minibuffer-window (current-buffer)) (setq khoj--minibuffer-window (current-buffer))
@ -257,7 +297,7 @@
(default-type (khoj--buffer-name-to-search-type (buffer-name))) (default-type (khoj--buffer-name-to-search-type (buffer-name)))
(search-type (completing-read "Type: " '("org" "markdown" "ledger" "music" "image") nil t default-type)) (search-type (completing-read "Type: " '("org" "markdown" "ledger" "music" "image") nil t default-type))
(query-url (khoj--construct-api-query query search-type rerank)) (query-url (khoj--construct-api-query query search-type rerank))
(buffer-name (get-buffer-create (format "*Khoj (q:%s t:%s)*" query search-type)))) (buffer-name (get-buffer-create (format "*%s (q:%s t:%s)*" khoj--buffer-name query search-type))))
(khoj--query-api-and-render-results (khoj--query-api-and-render-results
query query
search-type search-type