mirror of
https://github.com/khoaliber/khoj.git
synced 2026-03-09 05:39:12 +00:00
Find items of specified type similar to current text item at point
- Support querying with text surrounding point in any text buffer
Previously could only find items similar to org entry at point
- Find similar items of specified content type indexed on khoj
Previously only looked for similar org entries indexed on khoj
Now uses the content-type configured in khoj transient menu to find
items of the specified content type
- Details
- Generalize the get-current-org-entry-text func to get text for any
outline section
- Replace leading whitespaces from query text as well
- Create method to get current paragraph text from non-outline mode
buffers
- Update transient, find-similar funcs to pass, use content-type
configured in khoj transient menu
- Generalize query title creation logic to remove markdown headings
prefix (#) apart from org heading prefix (*) as well
- Update last used khoj content-type and results from the
find-similar and update funcs for later reuse
- Jump to top of results buffer after results rendered
This commit is contained in:
@@ -49,6 +49,7 @@
|
|||||||
(require 'url)
|
(require 'url)
|
||||||
(require 'json)
|
(require 'json)
|
||||||
(require 'transient)
|
(require 'transient)
|
||||||
|
(require 'outline)
|
||||||
|
|
||||||
|
|
||||||
;; -------------------------
|
;; -------------------------
|
||||||
@@ -383,38 +384,66 @@ Render results in BUFFER-NAME."
|
|||||||
;; Similar Search
|
;; Similar Search
|
||||||
;; --------------
|
;; --------------
|
||||||
|
|
||||||
(defun khoj--get-current-org-entry-text ()
|
(defun khoj--get-current-outline-entry-text ()
|
||||||
"Get text in org entry at point."
|
"Get text under current outline section."
|
||||||
(with-current-buffer (current-buffer)
|
(with-current-buffer (current-buffer)
|
||||||
(org-with-wide-buffer
|
;; jump to cursor in current buffer
|
||||||
;; jump to cursor in current buffer
|
(goto-char (point))
|
||||||
(goto-char (point))
|
;; trim leading whitespaces from text
|
||||||
|
(replace-regexp-in-string
|
||||||
|
"^[ \t\n]*" ""
|
||||||
;; trim trailing whitespaces from text
|
;; trim trailing whitespaces from text
|
||||||
(replace-regexp-in-string
|
(replace-regexp-in-string
|
||||||
"[ \t\n]*$" ""
|
"[ \t\n]*$" ""
|
||||||
;; get text of current entry
|
;; get text of current outline entry
|
||||||
(save-excursion
|
(buffer-substring-no-properties
|
||||||
;; jump to heading of current entry
|
(save-excursion (outline-previous-heading) (point))
|
||||||
(org-back-to-heading t)
|
(save-excursion (outline-next-heading) (point)))))))
|
||||||
;; get text of current entry using org-element-at-point
|
|
||||||
(buffer-substring-no-properties
|
|
||||||
(org-element-property :begin (org-element-at-point))
|
|
||||||
(org-element-property :end (org-element-at-point))))))))
|
|
||||||
|
|
||||||
(defun khoj--find-similar-notes ()
|
(defun khoj--get-current-paragraph-text ()
|
||||||
"Search for org entries similar to entry at point."
|
"Get text in current paragraph at point."
|
||||||
|
(with-current-buffer (current-buffer)
|
||||||
|
;; jump to cursor in current buffer
|
||||||
|
(goto-char (point))
|
||||||
|
;; trim leading whitespaces from text
|
||||||
|
(replace-regexp-in-string
|
||||||
|
"^[ \t\n]*" ""
|
||||||
|
;; trim trailing whitespaces from text
|
||||||
|
(replace-regexp-in-string
|
||||||
|
"[ \t\n]*$" ""
|
||||||
|
;; get text of current entry
|
||||||
|
(buffer-substring-no-properties
|
||||||
|
(save-excursion (backward-paragraph) (point))
|
||||||
|
(save-excursion (forward-paragraph) (point)))))))
|
||||||
|
|
||||||
|
(defun khoj--find-similar (&optional content-type)
|
||||||
|
"Find items of CONTENT-TYPE in khoj index similar to text surrounding point."
|
||||||
|
(interactive)
|
||||||
(let* ((rerank "true")
|
(let* ((rerank "true")
|
||||||
(content-type (khoj--buffer-name-to-content-type (buffer-name)))
|
;; set content type to: specified > based on current buffer > default type
|
||||||
(query (khoj--get-current-org-entry-text))
|
(content-type (or content-type (khoj--buffer-name-to-content-type (buffer-name))))
|
||||||
|
;; get text surrounding current point based on the major mode context
|
||||||
|
(query (cond
|
||||||
|
;; get section outline derived mode like org or markdown
|
||||||
|
((or (derived-mode-p 'outline-mode) (equal major-mode 'markdown-mode))
|
||||||
|
(khoj--get-current-outline-entry-text))
|
||||||
|
;; get paragraph, if in text mode
|
||||||
|
(t
|
||||||
|
(khoj--get-current-paragraph-text))))
|
||||||
(query-url (khoj--construct-api-query query content-type rerank))
|
(query-url (khoj--construct-api-query query content-type rerank))
|
||||||
|
;; extract heading to show in result buffer from query
|
||||||
|
(query-title
|
||||||
|
(format "Similar to: %s"
|
||||||
|
(replace-regexp-in-string "^[#\\*]* " "" (car (split-string query "\n")))))
|
||||||
(buffer-name (get-buffer-create khoj--buffer-name)))
|
(buffer-name (get-buffer-create khoj--buffer-name)))
|
||||||
(khoj--query-api-and-render-results
|
(progn
|
||||||
;; extract headline from query string containing org-entry
|
(khoj--query-api-and-render-results
|
||||||
(replace-regexp-in-string "^\\** " "" (car (split-string query "\n")))
|
query-title
|
||||||
content-type
|
content-type
|
||||||
query-url
|
query-url
|
||||||
buffer-name)
|
buffer-name)
|
||||||
(switch-to-buffer buffer-name)))
|
(switch-to-buffer buffer-name)
|
||||||
|
(goto-char (point-min)))))
|
||||||
|
|
||||||
|
|
||||||
;; ---------
|
;; ---------
|
||||||
@@ -425,7 +454,7 @@ Render results in BUFFER-NAME."
|
|||||||
:class 'transient-switches
|
:class 'transient-switches
|
||||||
:argument-format "--content-type=%s"
|
:argument-format "--content-type=%s"
|
||||||
:argument-regexp ".+"
|
:argument-regexp ".+"
|
||||||
;; set content type to last used or based on current buffer or to default
|
;; set content type to: last used > based on current buffer > default type
|
||||||
:init-value (lambda (obj) (oset obj value (format "--content-type=%s" (or khoj--content-type (khoj--buffer-name-to-content-type (buffer-name))))))
|
:init-value (lambda (obj) (oset obj value (format "--content-type=%s" (or khoj--content-type (khoj--buffer-name-to-content-type (buffer-name))))))
|
||||||
;; dynamically set choices to content types enabled on khoj backend
|
;; dynamically set choices to content types enabled on khoj backend
|
||||||
:choices (or (ignore-errors (mapcar #'symbol-name (khoj--get-enabled-content-types))) '("org" "markdown" "ledger" "music" "image")))
|
:choices (or (ignore-errors (mapcar #'symbol-name (khoj--get-enabled-content-types))) '("org" "markdown" "ledger" "music" "image")))
|
||||||
@@ -433,26 +462,34 @@ Render results in BUFFER-NAME."
|
|||||||
(transient-define-suffix khoj--search-command (&optional args)
|
(transient-define-suffix khoj--search-command (&optional args)
|
||||||
(interactive (list (transient-args transient-current-command)))
|
(interactive (list (transient-args transient-current-command)))
|
||||||
(progn
|
(progn
|
||||||
;; set content type to last used or based on current buffer or to default
|
;; set content type to: specified > last used > based on current buffer > default type
|
||||||
(setq khoj--content-type (or (transient-arg-value "--content-type=" args) (khoj--buffer-name-to-content-type (buffer-name))))
|
(setq khoj--content-type (or (transient-arg-value "--content-type=" args) (khoj--buffer-name-to-content-type (buffer-name))))
|
||||||
;; set results count to last used or to default
|
;; set results count to: specified > last used > to default
|
||||||
(setq khoj-results-count (or (transient-arg-value "--results-count=" args) khoj-results-count))
|
(setq khoj-results-count (or (transient-arg-value "--results-count=" args) khoj-results-count))
|
||||||
;; trigger incremental search
|
;; trigger incremental search
|
||||||
(call-interactively #'khoj-incremental)))
|
(call-interactively #'khoj-incremental)))
|
||||||
|
|
||||||
(transient-define-suffix khoj--find-similar-command (&optional _)
|
(transient-define-suffix khoj--find-similar-command (&optional args)
|
||||||
"Find other notes similar to current note at point."
|
"Find items similar to current item at point."
|
||||||
(interactive)
|
(interactive (list (transient-args transient-current-command)))
|
||||||
(khoj--find-similar-notes))
|
(progn
|
||||||
|
;; set content type to: specified > last used > based on current buffer > default type
|
||||||
|
(setq khoj--content-type (or (transient-arg-value "--content-type=" args) (khoj--buffer-name-to-content-type (buffer-name))))
|
||||||
|
;; set results count to: specified > last used > to default
|
||||||
|
(setq khoj-results-count (or (transient-arg-value "--results-count=" args) khoj-results-count))
|
||||||
|
(khoj--find-similar khoj--content-type)))
|
||||||
|
|
||||||
(transient-define-suffix khoj--update-command (&optional args)
|
(transient-define-suffix khoj--update-command (&optional args)
|
||||||
"Call khoj API to update index of specified content type."
|
"Call khoj API to update index of specified content type."
|
||||||
(interactive (list (transient-args transient-current-command)))
|
(interactive (list (transient-args transient-current-command)))
|
||||||
(let* ((force-update (if (member "--force-update" args) "true" "false"))
|
(let* ((force-update (if (member "--force-update" args) "true" "false"))
|
||||||
|
;; set content type to: specified > last used > based on current buffer > default type
|
||||||
(content-type (or (transient-arg-value "--content-type=" args) (khoj--buffer-name-to-content-type (buffer-name))))
|
(content-type (or (transient-arg-value "--content-type=" args) (khoj--buffer-name-to-content-type (buffer-name))))
|
||||||
(update-url (format "%s/api/update?t=%s&force=%s" khoj-server-url content-type force-update))
|
(update-url (format "%s/api/update?t=%s&force=%s" khoj-server-url content-type force-update))
|
||||||
(url-request-method "GET"))
|
(url-request-method "GET"))
|
||||||
(url-retrieve update-url (lambda (_) (message "Khoj %s index %supdated!" content-type (if (member "--force-update" args) "force " ""))))))
|
(progn
|
||||||
|
(setq khoj--content-type content-type)
|
||||||
|
(url-retrieve update-url (lambda (_) (message "Khoj %s index %supdated!" content-type (if (member "--force-update" args) "force " "")))))))
|
||||||
|
|
||||||
(transient-define-prefix khoj-menu ()
|
(transient-define-prefix khoj-menu ()
|
||||||
"Create Khoj Menu to Configure and Execute Commands."
|
"Create Khoj Menu to Configure and Execute Commands."
|
||||||
@@ -464,7 +501,7 @@ Render results in BUFFER-NAME."
|
|||||||
("-f" "Force Update" "--force-update")]]
|
("-f" "Force Update" "--force-update")]]
|
||||||
[["Act"
|
[["Act"
|
||||||
("s" "Search" khoj--search-command)
|
("s" "Search" khoj--search-command)
|
||||||
("f" "Find Similar Notes" khoj--find-similar-command)
|
("f" "Find Similar" khoj--find-similar-command)
|
||||||
("u" "Update" khoj--update-command)
|
("u" "Update" khoj--update-command)
|
||||||
("q" "Quit" transient-quit-one)]])
|
("q" "Quit" transient-quit-one)]])
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user