From: Eshel Yaron Date: Fri, 17 Nov 2023 18:04:23 +0000 (+0100) Subject: New post about Completion Preview mode X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=a2a2fa32710b5dbf388299d04c31ac08274124c7;p=esy-publish.git New post about Completion Preview mode --- diff --git a/esy-publish.el b/esy-publish.el index cb103b7..d00212b 100644 --- a/esy-publish.el +++ b/esy-publish.el @@ -59,6 +59,10 @@ (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") @@ -66,6 +70,10 @@ (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))) @@ -565,12 +573,17 @@ (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 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 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 index 0000000..256889a --- /dev/null +++ b/source/notes/prolog.org @@ -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 index 0000000..0f8104d --- /dev/null +++ b/source/notes/python.org @@ -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 index 0000000..e32ffad --- /dev/null +++ b/source/posts/2023-11-17-completion-preview-in-emacs.org @@ -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:
@@Created on [{{{date}}}], last updated [{{{modification-time(%Y-%m-%d, t)}}}]@@html:
@@ + +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~.)