diff --git a/ha-config.org b/ha-config.org index 2407b0c..7c6b306 100644 --- a/ha-config.org +++ b/ha-config.org @@ -418,25 +418,30 @@ Scattered throughout my configuration, I use =major-mode-hydra-define= where I The following defines my use of the Emacs completion system. I’ve decided my /rules/ will be: - Nothing should automatically appear; that is annoying and distracting. - Spelling in org files (abbrev or hippie expander) and code completion are separate, but I’m not sure if I can split them - - IDEs overuse the ~TAB~ binding, and I should re-think the bindings. + - IDEs overuse the ~TAB~ binding, and may I should re-think the bindings. -I don’t find the Emacs completion system obvious, with different interfaces, some distinct, some connected. Here’s the summary as I understand: -#+begin_verse - =indent-for-tab-command=, which /we can/ call: - └─ =completion-at-point=, which calls: - └─ =completion-at-point-functions= (capf), which can call: - └─ hippie and dabbrev functions -#+end_verse +I don’t find the Emacs completion system obvious, with different interfaces, some distinct, some connected. As ~TAB~ is often overloaded. Emacs can have a cascade of functions. Here’s the summary as I understand (as well as the overriding keybindings I use): + + #+BEGIN_EXAMPLE + ╭─▷ indent-for-tab-command ╭───────╮ + │ ╷ ╭──┤ M-TAB │ ╭─────╮ + │ ╰─▶ completion-at-point ◁──╯ ╰───────╯ │ M-/ │ + ╭──┴──╮ (completion-at-point-functions) ╰──┬──╯ + │ TAB │ ╷ │ + ╰─────╯ ╰─▶ hippie and dabbrev ◁──────────────╯ + #+END_EXAMPLE + +In =org-mode=, ~TAB~ calls [[help:org-cycle][org-cycle]], which is even more overload and context-specific. In the context of typing text, calls the binding for ~TAB~, which is the [[help:indent-for-tab-command][indent-for-tab-command]]. If the line is /indented/, it then completes the word: -In =org-mode=, ~TAB~ calls [[help:org-cycle][org-cycle]], which, in the context of typing text, calls the binding for ~TAB~, which is the [[help:indent-for-tab-command][indent-for-tab-command]]. If the line is /indented/, I can complete the word: #+begin_src emacs-lisp (setq tab-always-indent 'complete tab-first-completion 'word-or-paren - completion-cycle-threshold nil) + completion-cycle-threshold 2) #+end_src + Note that no matter the setting for =tab-first-completion=, hitting ~TAB~ twice, results in completion. -This calls [[help:completion-at-point][completion-at-point]]. This code (from mini-buffer) doubles with the other [[Vertico][completing processes]] (like [[help:completing-read][completing-read]]) and presents choices based on a series of functions (see [[https://with-emacs.com/posts/tutorials/customize-completion-at-point/][this essay]] for details). This will call into the CAPF function list (see the variable, =completion-at-point-functions= and the [[file:ha-programming.org::*Cape][Cape]] section for details). +This calls [[help:completion-at-point][completion-at-point]]. This code (from mini-buffer) doubles with the other [[Vertico][completing processes]] (like [[help:completing-read][completing-read]]) and presents choices based on a series of functions (see [[https://with-emacs.com/posts/tutorials/customize-completion-at-point/][this essay]] for details). This will call into the CAPF function list (see the variable, =completion-at-point-functions= and the [[*Cape][Cape]] section for details). *** Hippie Expand The venerable [[help:hippie-expand][hippie-expand]] function does a better job than the default, [[help:dabbrev-expand][dabbrev-expand]], so let’s swap it out (see this [[https://www.masteringemacs.org/article/text-expansion-hippie-expand][essay]] by Mickey Petersen) with its default key of ~M-/~ (easy to type on the laptop) as well as ~C-Tab~ (easier on mechanical keyboards): #+begin_src emacs-lisp @@ -445,6 +450,7 @@ The venerable [[help:hippie-expand][hippie-expand]] function does a better job t #+end_src Details on its job? We need to update its [[help:hippie-expand-try-functions-list][list of expanders]]. I don’t care much for [[help:try-expand-line][try-expand-line]], so that is not on the list. + #+begin_src emacs-lisp (setq hippie-expand-try-functions-list '(try-complete-file-name-partially ; complete filenames, start with / @@ -461,13 +467,42 @@ Details on its job? We need to update its [[help:hippie-expand-try-functions-lis #+end_src In the shell, IDEs and other systems, the key binding is typically ~TAB~. In modes other than =org-mode=, ~TAB~ re-indents the line with [[help:indent-for-tab-command][indent-for-tab-command]], but I find that I want that feature when I’m in Evil’s =normal state= and hit the ~=~ key, so changing this sounds good. But why not /have both/? -#+begin_src emacs-lisp :tangle no - (advice-add #'indent-for-tab-command :after #'hippie-expand) + +This screws up the [[file:ha-programming-elisp.org::*Lispyville][lispyville]], so I want automatic expansion limited to text files, like Org and Markdown: + +#+begin_src emacs-lisp + (defun hippie-expand-in-org (&rest ignored) + "Calls `hippie-expand', limited to text buffers." + (when (derived-mode-p 'text-mode) + (call-interactively #'hippie-expand))) + + (advice-add #'indent-for-tab-command :after #'hippie-expand-in-org) #+end_src + +*** Cape +The [[https://github.com/minad/cape][Cape project]] deliver particular [[help:completion-at-point][completion-at-point]] functions that can be /hooked/ in. Since I already have the hippie working as I like, I don’t need =cape-dabbrev= or =cape-dict= hooked in, but for /general modes/ I will choose the emoji capf: + +#+BEGIN_SRC emacs-lisp :tangle no + (use-package cape + :straight (:host github :repo "minad/cape") + :init + (setq completion-at-point-functions (list #'cape-emoji))) +#+END_SRC + +Each programming environment might need some particular love. For instance: +#+BEGIN_SRC emacs-lisp + (add-hook 'emacs-lisp-mode :after + (lambda () + (setq-local completion-at-point-functions + (list #'cape-elisp-symbol)))) +#+END_SRC + + *** Corfu The default completion system either inserts the first option directly in the text (without cycling, so let’s hope it gets it right the first time), or presents choices in another buffer (who wants to hop to it to select an expansion). After using [[http://company-mode.github.io/][company]] for my completion back-end, I switched to [[https://github.com/minad/corfu][corfu]] as it works with the variable-spaced font of my org files (also see [[https://takeonrules.com/2022/01/17/switching-from-company-to-corfu-for-emacs-completion/][this essay]] for my initial motivation). + #+begin_src emacs-lisp (use-package corfu :custom @@ -978,7 +1013,6 @@ Since I already (at this point in my file) have Org installed and running, the f To temporarily read an encrypted part, and call =M-x org-decrypt-entry= when the cursor is inside that section. Saving the file, will re-encrypt it. - #+begin_src emacs-lisp (use-package org :config