ideasman_42 · 2022-12-14 21:05
Recently I've been developing a package for my own use to give suggestions while typing. While there are packages that do this, I couldn't find any that were aimed at my use case exactly.
That is, to suggest something useful while typing based on the current context.
At the moment I have this setup so there are multiple back-ends which can be enabled at once based on the current context, this way I can have different suggestions based on what I'm working on so:
- When typing in code, suggest using code completion or dabbrev.
- When typing in comments, suggest using statistical word prediction, falling back to dabbrev.
I've been interested in how good word prediction can be, at the moment I'm using N-gram's generated by code-comments of the project I'm working on as input as well as every commit message, the user-manual and some NLTK texts as well. So far it's quite nice but doesn't feel like a game-changer and might need some tweaking to improve it's behavior.
While I'm aware other auto-completion frameworks might support this functionality, I find it useful to separate blocking completion from this kind of suggestion generation.
Is anyone doing something similar in Emacs already, any comments?
---
This is the [repository](https://codeberg.org/ideasman42/emacs-mono-complete) if anyone is interested although this isn't yet documented and internals may change.
00-11 · 2022-12-14 21:24
Sounds interesting. FYI, besides `dabbrev.el` (and `hippie-exp.el`) there is also the very old library `completion.el`, which is still part of Emacs. Needs a little love (the "doc" is just the Commentary), but maybe some more food for thought in your experiment.
redguardtoo · 2022-12-16 00:30
`company-mode` is kind of main stream auto-completion framework right now. You could base your backend on it.
`company-mode` is very powerful and can combine multiple backends. Unfortunately its documention is a bit behind its implementation so sometimes reading code is necessary to unleasing its true power.
For example, below setup complete english words (using backend `company-ispell`) in comment and fallback to other backend in code,
```lisp
(defun my-company-ispell-available-hack (orig-func &rest args)
;; in case evil is disabled
(my-ensure 'evil-nerd-commenter)
(cond
((and (derived-mode-p 'prog-mode)
(not (company-in-string-or-comment)) ; respect advice in `company-in-string-or-comment') ; auto-complete in comment only
;; only use company-ispell in comment when coding
nil)
(t
(apply orig-func args))))
(with-eval-after-load 'company-ispell
(advice-add 'company-ispell-available :around #'my-company-ispell-available-hack))
```
See https://github.com/redguardtoo/emacs.d/blob/aa2dd56e2f0912c98e376b65d8f70e3d5e3886e8/lisp/init-company.el#L1 for my company setup
a-concerned-mother · 2022-12-19 10:40
Shouldn't be hard to use cap and a quick context update function to create a completion at point function for this. Then you can use it along side company, Corfu, or even the built in completion system.
ideasman_42 · 2022-12-19 22:33
Right, I've been looking into compleation-at-point, it works OK, although the completion functions tend to expand all possible options.
That's good for the use case they're intended for but means they tend to be slower then custom completion functions that return a single option.
a-concerned-mother · 2022-12-20 00:59
Oh so instead of having a popup with a list this would instead just return a single option? So more like dabbrev-expand (without inserting) rather than dabbrev-complete? I see. You can just wrap that as a completion at point function though. Just using dynamic binding should work. I'll whip up a proof of concept in a bit.
ideasman_42 · 2022-12-23 01:45
I think so, although I'm not all that familier with all the completion options available in emacs, the part I found lacking in existing options which I've solved in my package is:
- Preview a single option on idle.
- Support multiple completion back-ends at once (first hit is shown).
- Completion options should be context sensitive (comments/code should use different options).
- Repeating the complete action (via a macro for e.g.) should enter the same text (verbatim), instead of re-running the complete command which may enter different text.
What I've found with existing options is that I end up having to do so much customization to achieve the exact kind of functionality I'm after that often it ends up working out smoother to write my own package in these cases - although something existing out there might be sufficient.