]> git.eshelyaron.com Git - esy-publish.git/commitdiff
New post about Completion Preview mode
authorEshel Yaron <me@eshelyaron.com>
Fri, 17 Nov 2023 18:04:23 +0000 (19:04 +0100)
committerEshel Yaron <me@eshelyaron.com>
Fri, 17 Nov 2023 18:04:23 +0000 (19:04 +0100)
esy-publish.el
source/assets/completion-preview-1.png [new file with mode: 0644]
source/assets/completion-preview-2.png [new file with mode: 0644]
source/notes/prolog.org [new file with mode: 0644]
source/notes/python.org [new file with mode: 0644]
source/posts/2023-11-17-completion-preview-in-emacs.org [new file with mode: 0644]

index cb103b78b7dd2f8d0f5260883b61bf651d0650f5..d00212b590d2390abf8466a219ed183f4b675c4d 100644 (file)
   (file-name-as-directory (expand-file-name "posts"
                                             esy-publish-source-directory)))
 
+(defvar esy-publish-assets-source-directory
+  (file-name-as-directory (expand-file-name "assets"
+                                            esy-publish-source-directory)))
+
 (defvar esy-publish-remote-directory
   "root@direct.eshelyaron.com:/var/www/html")
 
   (file-name-as-directory (expand-file-name "local"
                                             esy-publish-root-directory)))
 
+(defvar esy-publish-local-assets-directory
+  (file-name-as-directory (expand-file-name "assets"
+                                            esy-publish-local-directory)))
+
 (defvar esy-publish-local-posts-directory
   (file-name-as-directory (expand-file-name "posts"
                                             esy-publish-local-directory)))
          (esy-publish--publishing t)
          (initial-buffers (buffer-list))
          (org-publish-project-alist
-          (list '("all" :components ("assets" "org"))
+          (list '("all" :components ("assets" "sassets" "org"))
                 (list "assets"
                       :base-directory esy-publish-source-directory
                       :publishing-directory esy-publish-local-directory
                       :base-extension "svg\\|ico\\|css\\|png"
                       :publishing-function #'org-publish-attachment)
+                (list "sassets"
+                      :base-directory esy-publish-assets-source-directory
+                      :publishing-directory esy-publish-local-assets-directory
+                      :base-extension "svg\\|ico\\|css\\|png"
+                      :publishing-function #'org-publish-attachment)
                 (list "org"
                       :completion-function #'esy-publish--finalize
                       :base-directory esy-publish-source-directory
diff --git a/source/assets/completion-preview-1.png b/source/assets/completion-preview-1.png
new file mode 100644 (file)
index 0000000..4c0ba6b
Binary files /dev/null and b/source/assets/completion-preview-1.png differ
diff --git a/source/assets/completion-preview-2.png b/source/assets/completion-preview-2.png
new file mode 100644 (file)
index 0000000..fd111d3
Binary files /dev/null and b/source/assets/completion-preview-2.png differ
diff --git a/source/notes/prolog.org b/source/notes/prolog.org
new file mode 100644 (file)
index 0000000..256889a
--- /dev/null
@@ -0,0 +1,13 @@
+#+TITLE:       Prolog
+#+SUBTITLE:    My favorite programming language
+#+DESCRIPTION: Eshel Yaron's notes about Prolog
+#+KEYWORDS:    logic
+#+DATE:        2023-11-17
+
+
+* References in published posts
+#+BEGIN: links-to-note :dir "/Users/eshelyaron/checkouts/esy-publish/source/posts/"
+#+END:
+* References in other notes
+#+BEGIN: links-to-note :dir "/Users/eshelyaron/checkouts/esy-publish/source/notes/"
+#+END:
diff --git a/source/notes/python.org b/source/notes/python.org
new file mode 100644 (file)
index 0000000..0f8104d
--- /dev/null
@@ -0,0 +1,13 @@
+#+TITLE:       Python
+#+SUBTITLE:    Something to avoid
+#+DESCRIPTION: Eshel Yaron's notes about Python
+#+KEYWORDS:    computers
+#+DATE:        2023-11-17
+
+
+* References in published posts
+#+BEGIN: links-to-note :dir "/Users/eshelyaron/checkouts/esy-publish/source/posts/"
+#+END:
+* References in other notes
+#+BEGIN: links-to-note :dir "/Users/eshelyaron/checkouts/esy-publish/source/notes/"
+#+END:
diff --git a/source/posts/2023-11-17-completion-preview-in-emacs.org b/source/posts/2023-11-17-completion-preview-in-emacs.org
new file mode 100644 (file)
index 0000000..e32ffad
--- /dev/null
@@ -0,0 +1,161 @@
+#+TITLE:       Completion Preview in Emacs
+#+SUBTITLE:    Some details about a new Emacs text completion feature
+#+DESCRIPTION: Post by Eshel Yaron with details about a new Emacs text completion feature
+#+KEYWORDS:    emacs,lisp
+#+DATE:        2023-11-17
+
+@@html:<div class="metadata">@@Created on [{{{date}}}], last updated [{{{modification-time(%Y-%m-%d, t)}}}]@@html:</div>@@
+
+Earlier this week, a new Elisp library of mine,
+=completion-preview.el=, made its way to upstream [[note:emacs][Emacs]] master.
+
+This library provides a minor mode called Completion Preview mode.
+Can you guess what it does?  Well, let me spell it out anyway.
+Completion Preview mode automatically displays a preview of a
+completion suggestion as you type.  Here's how this preview looks like
+when you start typing something (a [[note:prolog][Prolog]] predicate, in this case):
+
+#+attr_html: :width 300px
+[[file:../assets/completion-preview-1.png]]
+
+The preview appears right after the cursor, showing you how the text
+will look if you follow this completion suggestion.  When there's only
+one matching completion candidate, Completion Preview mode indicates
+that with an underline:
+
+#+attr_html: :width 300px
+[[file:../assets/completion-preview-2.png]]
+
+The idea is to suggest something that you might want to insert, and
+give you a shortcut for inserting it quickly, while staying minimally
+intrusive.
+
+The Emacs manual and the commentary section of =completion-preview.el=
+contain helpful documentation for using this library, nevertheless I
+want to go into more detail and share a bit about my own set up here.
+
+* Usage
+
+To enable Completion Preview mode, say ~M-x completion-preview-mode~.
+Whenever Completion Preview mode shows the preview, it temporarily
+enables a helper minor mode called ~completion-preview-active-mode~.
+The most important job of this "active" minor mode is to enable its
+associated keymap, ~completion-preview-active-mode-map~.  Other than
+that, it doesn't do much by default, but this gives us a convenient
+way to bind some keys only when showing the completion preview.
+Crucially, whenever the preview is shown, ~TAB~ inserts its contents.
+Otherwise, Completion Preview mode doesn't bind any keys.  Again, the
+aim is to be maximally helpful while remaining minimally intrusive.
+
+So far I've mostly described what the completion preview looks like
+and how you use it, but there are two important questions that you
+probably want me to explain to really understand how this mode works.
+
+The first question is "where do the completion suggestions come from"?
+The answer is that Completion Preview mode uses
+~completion-at-point-functions~ as its "backend", and only that.  This
+means that you control which completion suggestions you get with the
+same extensible mechanism that you use for customizing your regular
+in-buffer completions, no extra configuration needed.  You can think
+of Completion Preview as another, second, "frontend" for
+~completion-at-point-functions~.  I explicitly say it's a second
+frontend, because Completion Preview does not replace your regular
+completion selection UI, be it [[https://github.com/minad/corfu][~corfu~]] and its kind or the good old
+=*Completions*= buffer.  The preview and the selection UI are two
+complementary features, so you can use Completion Preview with any
+completion UI.
+
+The second important question is "when exactly is the preview shown?"
+The answer is that it /may/ be shown after each command.  My initial
+implementation included a user-extensible hook that Completion Preview
+mode consulted with after each command to determine whether or not to
+show the preview, but that was [[https://debbugs.gnu.org/cgi/bugreport.cgi?bug=66948#68][dimmed]] "over-engineered" during the
+patch review, so currently we have two simple conditions that must
+hold for Completion Preview to show the preview:
+
+1. the last command is one of ~completion-preview-commands~, and
+2. the symbol at point is at least
+   ~completion-preview-minimum-symbol-length~ characters long.
+
+By default, this concretely means that the preview is shown whenever
+you're typing or deleting characters and there's a partial symbol/word
+of at least three characters at point.  Of course, you can customize
+~completion-preview-commands~ and
+~completion-preview-minimum-symbol-length~ to modify these conditions.
+If you need more flexibility in specifying restrictions for when to
+show the preview, please speak up, and I'll try to reintroduce that
+hook I mentioned earlier.
+
+Here's my current personal configuration for Completion Preview mode:
+
+#+begin_src emacs-lisp
+  ;; Enable Completion Preview mode in code buffers
+  (add-hook 'prog-mode-hook #'completion-preview-mode)
+  ;; also in text buffers
+  (add-hook 'text-mode-hook #'completion-preview-mode)
+  ;; and in \\[shell] and friends
+  (with-eval-after-load 'comint
+    (add-hook 'comint-mode-hook #'completion-preview-mode))
+
+  (with-eval-after-load 'completion-preview
+    ;; Show the preview already after two symbol characters
+    (setq completion-preview-minimum-symbol-length 2)
+
+    ;; Non-standard commands to that should show the preview:
+
+    ;; Org mode has a custom `self-insert-command'
+    (push 'org-self-insert-command completion-preview-commands)
+    ;; Paredit has a custom `delete-backward-char' command
+    (push 'paredit-backward-delete completion-preview-commands)
+
+    ;; Bindings that take effect when the preview is shown:
+
+    ;; Cycle the completion candidate that the preview shows
+    (keymap-set completion-preview-active-mode-map "M-n" #'completion-preview-next-candidate)
+    (keymap-set completion-preview-active-mode-map "M-p" #'completion-preview-prev-candidate)
+    ;; Convenient alternative to C-i after typing one of the above
+    (keymap-set completion-preview-active-mode-map "M-i" #'completion-preview-insert))
+#+end_src
+
+Recall that Completion Preview mode relies on
+~completion-at-point-functions~ to produce the actual candidates, so
+make sure you set that up properly as well!
+
+* Alternatives
+
+Now that we know what this new Completion Preview mode is all about,
+you might be wondering how it compares to other habitants of
+Emacs-land.  There are several third party packages whose
+functionality is similar to, or overlaps with, that of Completion
+Preview mode.  Sometimes, the same concept goes by different names,
+such as "suggestion preview" or "ghost text".
+
+Other than shipping with core Emacs, here are some key differences of
+Completion Preview compared to other embodiments of similar concepts:
+
+- [[https://code.bsdgeek.org/adam/corfu-candidate-overlay][~corfu-candidate-overlay~]] :: builds on top of ~corfu~ while
+  Completion Preview is completely agnostic to which completion UI
+  you're using
+- [[https://codeberg.org/ideasman42/emacs-mono-complete][~mono-complete~]] :: departs from the strong coupling with
+  ~completion-at-point-functions~ that Completion Preview enjoys by
+  supporting multiple backends, and even including a bespoke word
+  prediction [[note:python][Python]] program
+- [[https://github.com/jrosdahl/fancy-dabbrev][~fancy-dabbrev~]] :: targets only ~dabbrev~ as its backend
+- [[https://repo.or.cz/emacs-capf-autosuggest.git][~capf-autosuggest~]] :: only works in ~comint-mode~ buffers
+- [[http://company-mode.github.io/][~company~]] :: brings along its own completion framework with multiple
+  backends and frontends, including a preview completion frontend.
+  Unlike other packages on this list, it makes sense to use Company
+  and Completion Preview together, when you're using Company for its
+  other frontends.
+
+* Conclusion
+
+I've been using this mode myself since I started working on it several
+weeks ago, and so far I find it quite nice.  I usually steer clear of
+various autopopups that distract me from what I'm actually trying to
+write down, but I find that this preview interface strikes a great
+balance between being suggestive and being pushy.  So I'm pretty happy
+with this addition to Emacs.  There's still some time before Emacs 30
+will be cut, so if you're reading this and you find something that
+warrants some improvement, let me know!  (Or just do ~M-x
+report-emacs-bug~.)