emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/consult 93bdcd2cda 1/4: docs: add 'Hacking' section


From: ELPA Syncer
Subject: [elpa] externals/consult 93bdcd2cda 1/4: docs: add 'Hacking' section
Date: Fri, 15 Nov 2024 00:57:50 -0500 (EST)

branch: externals/consult
commit 93bdcd2cdadad3422cee59f681c8247a07175f90
Author: Sean Allred <allred.sean@gmail.com>
Commit: Daniel Mendler <mail@daniel-mendler.de>

    docs: add 'Hacking' section
    
    While many examples exist in the current codebase, the basic process
    for using a new asynchronous completion source can get lost in the
    sophistication of examples like `consult-rg` and friends.
    
    Introduce a 'Hacking' section to the README that describes the bare
    minimum required to do this -- including live preview.
---
 README.org | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 88 insertions(+)

diff --git a/README.org b/README.org
index 49ac998ee7..af43229490 100644
--- a/README.org
+++ b/README.org
@@ -1112,6 +1112,90 @@ Please provide the necessary important information with 
your bug report:
 When evaluating Consult-related code snippets you should enable 
[[https://www.gnu.org/software/emacs/manual/html_node/elisp/Lexical-Binding.html][lexical
 binding]].
 Consult often relies on lambdas and lexical closures.
 
+* Hacking
+** Creating a new asynchronous completion source
+
+If you have a completion source that's both dynamic and expensive to generate,
+=completing-read= may not be the best choice. Instead, =consult--read= serves 
as a
+thin wrapper around =completing-read= that provides this functionality.
+
+For example, consider the following script that splits its input on space:
+
+#+begin_src sh
+  #!/usr/bin/env bash
+
+  # simulate work
+  sleep .1
+
+  # generate completion candidates
+  printf "%s\n" "$*" | tr " " "\n" | sort
+#+end_src
+
+Let's assume this script is callable as =testibus hello world=.
+
+To have Consult use it as a completion source, use =consult--async-command=:
+
+#+begin_src emacs-lisp
+  (consult--read
+   (consult--async-command (lambda (input) (list "testibus" (s-trim input))))
+   :prompt "run testibus: ")
+#+end_src
+
+If your completion source is generated by Lisp instead, use
+=consult--dynamic-collection=:
+
+#+begin_src emacs-lisp
+  (consult--read
+   (consult--dynamic-collection
+    (lambda (input)
+      (sit-for 0.1)
+      (thread-first
+        (string-trim input)
+        (split-string nil t)
+        (sort #'string<)))))
+   :prompt "run testibus: ")
+#+end_src
+
+*** ...with live preview
+
+Implementing live preview is a little more involved and requires the definition
+of a =STATE= function as defined by =consult--with-preview=.
+
+The =STATE= function receives the candidate and some action to perform (e.g.,
+='preview=). In its simplest form supporting live preview, it looks something 
like
+this:
+
+#+begin_src emacs-lisp
+  (defun testibus--state ()
+    (lambda (action cand)
+      (pcase action
+        ('preview
+         (with-current-buffer-window " *testibus*" 'action nil
+           (erase-buffer)
+           (insert (format "input: %s\n" cand)))))))
+#+end_src
+
+See =consult--with-preview= for the lifecycle of =ACTION=.
+
+Once defined, we can use this =STATE= function in =consult--read=:
+
+#+begin_src emacs-lisp
+  (consult--read
+   (consult--dynamic-collection
+    (lambda (input)
+      (sit-for 0.1)
+      (thread-first
+        (string-trim input)
+        (split-string nil t)
+        (sort #'string<))))
+   :prompt "run testibus: "
+   :state (testibus--state))
+#+end_src
+
+Note that depending on how expensive the ='preview= logic is, you may wish to 
take
+advantage of the built-in threading support or use an external package such as
+[[https://github.com/jwiegley/emacs-async][emacs-async]].
+
 * Contributions
 :properties:
 :description: Feature requests and pull requests
@@ -1171,3 +1255,7 @@ Smith]], [[https://github.com/manuel-uberti/][Manuel 
Uberti]], [[https://github.
 :end:
 
 #+html: -->
+
+# Local Variables:
+# fill-column: 80
+# End:



reply via email to

[Prev in Thread] Current Thread [Next in Thread]