I briefly mentioned dabbrev expand in one of my interesting links posts when I noted a post that was covering auto-complete.el. Dabbrev expand is a great little feature of emacs. With one keychord, you can expand text using any match from any buffer that you have opened. Until now, I haven’t particularly wanted more.
However, now it is time to move to auto-complete. It’s nice to get feedback about potential completions. In the linked post, it states that auto-complete is just a framework and it needs quite a bit of tweaking to get the behaviour I want.
The primary thing I want to fix is that by default it only uses completions from the current buffer. I like completion to use all open buffers as dabbrev does by default. I thought that it would be easy to add this by setting ac-sources to ac-source-words-in-all-buffer.
(setq-default ac-sources '(ac-source-words-in-all-buffer))
Unfortunately, that isn’t come close to what I want. There is also an extension called ac-dabbrev.el but that doesn’t work for me either. Fortunately, it is fairly easy to fix myself.
We can use functions from dabbrev to get all of the possible dabbrev expansions.
(require 'cl) (require 'dabbrev) (require 'auto-complete) (defun ac-source-dabbrev (abbrev) (interactive) (dabbrev--reset-global-variables) (let ((dabbrev-check-all-buffers t)) (sort (dabbrev--find-all-expansions abbrev t) #'string<)))
auto-complete allows you to list multiple sources for completions in ac-sources. Here we just want one but I could see that it might be nice to add language keywords or something like that.
(defvar ac-source-dabbrev-words '((candidates . (lambda () (all-completions ac-target (ac-source-dabbrev ac-target))))) "Get all the completions using dabbrev") (setq-default ac-sources '(ac-source-dabbrev-words))
I prefer to manually start completion rather than have it trigger automatically.
(setq ac-auto-start nil)
(global-set-key (kbd "M-/") 'ac-start)
There is a keymap you can add your own keys to. By default, C-g doesn’t cancel the completion window which feels really strange to me. In emacs C-g is pervasive for cancelling options. Fortunately, it is pretty easy to fix that.
(define-key ac-complete-mode-map (kbd "M-x") 'execute-extended-command) (define-key ac-complete-mode-map (kbd "C-n") 'ac-next) (define-key ac-complete-mode-map (kbd "C-p") 'ac-previous) (define-key ac-complete-mode-map (kbd "C-g") 'ac-stop)
I like both RETURN and TAB for completion.
(define-key ac-complete-mode-map "\t" 'ac-complete) (define-key ac-complete-mode-map "\r" 'ac-complete)
I want completions to update as you type. Did you know that by adding a vector to a keymap, you can capture all ascii keypresses?
(defun ac-self-insert () (interactive) (self-insert-command 1) (ac-start)) ;; (define-key ac-complete-mode-map [t] 'ac-self-insert)
However, [t] also absorbs other ASCII keypresses you’ve defined such as TAB and RETURN. Therefore, we have to define them all individually.
(defun ac-fix-keymap () (let ((i 32)) (while (<= i ?z) (define-key ac-complete-mode-map (make-string 1 i) 'ac-self-insert) (incf i)))) (ac-fix-keymap)
I also want DELETE to trigger a new completion update.
(define-key ac-complete-mode-map (kbd "DEL") (lambda () (interactive) (backward-delete-char-untabify 1) (ac-start))) (provide 'auto-complete-config)
Hi.
I’m ac-dabbrev.el author.
If you set (setq ac-dabbrev-all-min-count 1) and (setq ac-dabbrev-sort t), ac-dabbrev.el work you want.
Hi k1LoW,
Thanks for the comment. However, the problem I had with ac-dabbrev.el was not that it didn’t return enough candidates (I didn’t implement that feature due to laziness!) or sort them. The problem was that it often didn’t find candidates that dabbrev-expand would find. It could be that I configured it incorrectly.
Hi!
I understand what you want.
I want to bring your idea into ac-dabbrev.el. (new setting value or …)
Thank you for your idea!
I was going to ask you if auto-complete.el supports the minibuffer, but I see that it is in the TODO list. Darn. I want to see the candidates (using Ido complete buffer, etc) vertically instead of horizontally.
As an aside, remember I reported the erroneous title on your blog posts when viewing from Google Reader? It turns out that there is some problem with Planet Emacsen’s aggregation of your blog. Please take a look at http://planet.emacsen.org/ to see the problem. If I subscribe to your feed directly there is no Blog Title problem.
@k1Low – great, I’ll use the new version when it becomes available
Thanks.
@piyo – yes that would be a great feature. I love ido but maybe I’d love it even more if it was pretty.
And yes, I remember you mentioning the problematic title on my blog. I had a look in my RSS (which looks fine) and Planet Emacsen and it looks like the problem is somewhere between them. Maybe it is down to the theme I’ve chosen.
Have you tried hippie-expand
Hi dericbytes,
I vaguely remember trying it out, but not finding it much superior to dabbrev-expand. Looking at the documentation, it looks like it allows you to add additional functions to try if dabbrev fails which could be useful. E.g. I often want to expand current buffer names.