From 541e03da3db618b8e9322a84f30140726a56638c Mon Sep 17 00:00:00 2001 From: Debanjum Singh Solanky Date: Sat, 13 Aug 2022 20:29:06 +0300 Subject: [PATCH] Make khoj.el pass checkdoc, package-lint, flycheck checks - Add docstrings, mention args in them. Make docstring crisper - prefix funcs, variables with khoj-- - Require emacs >27.1 for json-parse-buffer - Use lexical binding - Add quickstart docs to elisp file itself - Bump version of khoj.el --- src/interface/emacs/khoj.el | 74 ++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 26 deletions(-) diff --git a/src/interface/emacs/khoj.el b/src/interface/emacs/khoj.el index fe0d7248..04a1f611 100644 --- a/src/interface/emacs/khoj.el +++ b/src/interface/emacs/khoj.el @@ -1,10 +1,12 @@ -;;; khoj.el --- Natural, Incremental Search via Emacs +;;; khoj.el --- Natural, Incremental Search for your Second Brain -*- lexical-binding: t -*- ;; Copyright (C) 2021-2022 Debanjum Singh Solanky ;; Author: Debanjum Singh Solanky -;; Version: 2.0 -;; Keywords: search, org-mode, outlines, markdown, image +;; Description: Natural, Incremental Search for your Second Brain +;; Keywords: search, org-mode, outlines, markdown, beancount, ledger, image +;; Version: 2.1 +;; Package-Requires: ((emacs "27.1")) ;; URL: http://github.com/debanjum/khoj/interface/emacs ;; This file is NOT part of GNU Emacs. @@ -27,9 +29,20 @@ ;;; Commentary: ;; This package provides a natural, incremental search interface to your -;; org-mode notes, markdown files, beancount transactions and images. -;; It is a wrapper that interfaces with transformer based ML models. -;; The models search capabilities are exposed via the Khoj HTTP API. +;; `org-mode' notes, `markdown' files, `beancount' transactions and images. +;; It is a wrapper that interfaces with the Khoj server. +;; The server exposes an API for advanced search using transformer ML models. +;; The Khoj server needs to be running to use this package. +;; See the repository docs for detailed setup of the Khoj server. +;; +;; Quickstart +;; ------------- +;; 1. Install Khoj Server +;; pip install khoj-assistant +;; 2. Start, Configure Khoj Server +;; khoj +;; 3. Install khoj.el +;; (use-package khoj :bind ("C-c s" . 'khoj)) ;;; Code: @@ -52,7 +65,7 @@ :type 'integer) (defcustom khoj-rerank-after-idle-time 2.0 - "Idle time (in seconds) to trigger cross-encoder to rerank incremental search results." + "Idle time (in seconds) to rerank incremental search results." :group 'khoj :type 'float) @@ -70,7 +83,7 @@ (const "music"))) (defvar khoj--rerank-timer nil - "Idle timer to make cross-encoder re-rank incremental search results if user idle.") + "Idle timer to re-rank incremental search results if user idle.") (defvar khoj--minibuffer-window nil "Minibuffer window being used by user to enter query.") @@ -85,6 +98,7 @@ "The type of content to perform search on.") (defun khoj--keybindings-info-message () + "Show available khoj keybindings in-context, when user invokes Khoj." (let ((enabled-content-types (khoj--get-enabled-content-types))) (concat " @@ -101,13 +115,13 @@ (when (member 'music enabled-content-types) "C-x M | music\n")))) -(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--search-music () (interactive) (setq khoj--search-type "music")) +(defun khoj--search-markdown () "Set search-type to 'markdown'." (interactive) (setq khoj--search-type "markdown")) +(defun khoj--search-org () "Set search-type to 'org-mode'." (interactive) (setq khoj--search-type "org")) +(defun khoj--search-ledger () "Set search-type to 'ledger'." (interactive) (setq khoj--search-type "ledger")) +(defun khoj--search-images () "Set search-type to image." (interactive) (setq khoj--search-type "image")) +(defun khoj--search-music () "Set search-type to music." (interactive) (setq khoj--search-type "music")) (defun khoj--make-search-keymap (&optional existing-keymap) - "Setup keymap to configure Khoj search" + "Setup keymap to configure Khoj search. Build of EXISTING-KEYMAP when passed." (let ((enabled-content-types (khoj--get-enabled-content-types)) (kmap (or existing-keymap (make-sparse-keymap)))) (when (member 'markdown enabled-content-types) @@ -121,6 +135,8 @@ (when (member 'music enabled-content-types) (define-key kmap (kbd "C-x M") #'khoj--search-music)) kmap)) + +(defvar khoj--keymap nil "Track Khoj keymap in this variable.") (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" @@ -132,7 +148,7 @@ Use `which-key` if available, else display simple message in echo area" (message "%s" (khoj--keybindings-info-message)))) (defun khoj--extract-entries-as-markdown (json-response query) - "Convert json response from API to markdown entries" + "Convert JSON-RESPONSE, QUERY from API to markdown entries." ;; remove leading (, ) or SPC from extracted entries string (replace-regexp-in-string "^[\(\) ]" "" @@ -147,7 +163,7 @@ Use `which-key` if available, else display simple message in echo area" json-response)))) (defun khoj--extract-entries-as-org (json-response query) - "Convert json response from API to org-mode entries" + "Convert JSON-RESPONSE, QUERY from API to 'org-mode' entries." ;; remove leading (, ) or SPC from extracted entries string (replace-regexp-in-string "^[\(\) ]" "" @@ -162,7 +178,7 @@ Use `which-key` if available, else display simple message in echo area" json-response)))) (defun khoj--extract-entries-as-images (json-response query) - "Convert json response from API to html with images" + "Convert JSON-RESPONSE, QUERY from API to html with images." ;; remove leading (, ) or SPC from extracted entries string (replace-regexp-in-string "[\(\) ]$" "" @@ -188,7 +204,7 @@ Use `which-key` if available, else display simple message in echo area" json-response))))) (defun khoj--extract-entries-as-ledger (json-response query) - "Convert json response from API to ledger entries" + "Convert JSON-RESPONSE, QUERY from API to ledger entries." ;; remove leading (, ) or SPC from extracted entries string (replace-regexp-in-string "[\(\) ]$" "" @@ -203,6 +219,7 @@ Use `which-key` if available, else display simple message in echo area" json-response))))) (defun khoj--buffer-name-to-search-type (buffer-name) + "Infer search type based on BUFFER-NAME." (let ((enabled-content-types (khoj--get-enabled-content-types)) (file-extension (file-name-extension buffer-name))) (cond @@ -213,7 +230,7 @@ Use `which-key` if available, else display simple message in echo area" (t khoj-default-search-type)))) (defun khoj--get-enabled-content-types () - "Get content types enabled for search from API" + "Get content types enabled for search from API." (let ((config-url (format "%s/config/data" khoj-server-url))) (with-temp-buffer (erase-buffer) @@ -228,11 +245,14 @@ Use `which-key` if available, else display simple message in echo area" content-type)))))) (defun khoj--construct-api-query (query search-type &optional rerank) + "Construct API Query from QUERY, SEARCH-TYPE and (optional) RERANK params." (let ((rerank (or rerank "false")) (encoded-query (url-hexify-string query))) (format "%s/search?q=%s&t=%s&r=%s&n=%s" khoj-server-url encoded-query search-type rerank khoj-results-count))) (defun khoj--query-api-and-render-results (query search-type query-url buffer-name) + "Query Khoj API using QUERY, SEARCH-TYPE, QUERY-URL. +Render results in BUFFER-NAME." ;; get json response from api (with-current-buffer buffer-name (let ((inhibit-read-only t)) @@ -260,8 +280,8 @@ Use `which-key` if available, else display simple message in echo area" (read-only-mode t))) -;; Incremental Search on Khoj (defun khoj--incremental-search (&optional rerank) + "Perform Incremental Search on Khoj. Allow optional RERANK of results." (let* ((rerank-str (cond (rerank "true") (t "false"))) (khoj-buffer-name (get-buffer-create khoj--buffer-name)) (query (minibuffer-contents-no-properties)) @@ -281,8 +301,8 @@ Use `which-key` if available, else display simple message in echo area" query-url khoj-buffer-name))))) -(defun delete-open-network-connections-to-khoj () - "Delete all network connections to khoj server" +(defun khoj--delete-open-network-connections-to-server () + "Delete all network connections to khoj server." (dolist (proc (process-list)) (let ((proc-buf (buffer-name (process-buffer proc))) (khoj-network-proc-buf (string-join (split-string khoj-server-url "://") " "))) @@ -290,6 +310,7 @@ Use `which-key` if available, else display simple message in echo area" (delete-process proc))))) (defun khoj--teardown-incremental-search () + "Teardown timers and hooks used for incremental search." (message "Khoj: Teardown Incremental Search") ;; remove advice to rerank results on normal exit from minibuffer (advice-remove 'exit-minibuffer #'khoj--minibuffer-exit-advice) @@ -298,19 +319,20 @@ Use `which-key` if available, else display simple message in echo area" ;; cancel rerank timer (when (timerp khoj--rerank-timer) (cancel-timer khoj--rerank-timer)) - ;; delete open connections to khoj - (delete-open-network-connections-to-khoj) + ;; delete open connections to khoj server + (khoj--delete-open-network-connections-to-server) ;; remove hooks for khoj incremental query and self (remove-hook 'post-command-hook #'khoj--incremental-search) (remove-hook 'minibuffer-exit-hook #'khoj--teardown-incremental-search)) (defun khoj--minibuffer-exit-advice (&rest _args) + "Rerank results of incremental search on exiting minibuffer." (khoj--incremental-search t)) ;;;###autoload (defun khoj () - "Natural, Incremental Search for your personal notes, transactions and music using Khoj" + "Natural, Incremental Search for your personal notes, transactions and music." (interactive) (let* ((khoj-buffer-name (get-buffer-create khoj--buffer-name))) ;; set khoj search type to last used or based on current buffer @@ -337,7 +359,7 @@ Use `which-key` if available, else display simple message in echo area" ;;;###autoload (defun khoj-simple (query) - "Natural Search for QUERY in your personal notes, transactions, music and images using Khoj" + "Natural Search for QUERY on your personal notes, transactions, music and images." (interactive "s🦅Khoj: ") (let* ((rerank "true") (default-type (khoj--buffer-name-to-search-type (buffer-name)))