IDO - Emacs
Table of Contents
- Minibuffer Completion
- Use SPACES in the minibuffer
- Vertical candidates
- Move to most used folders
- Ignore some buffers
- Open dired immediately in current directory at find-file
Minibuffer Completion
Emacs-land is gifted with many options for Minibuffer completion
e.g. ivy,
helm, icomplete, selectrum, and
ido. But when I started , (ido-mode t)
was the first line of Elisp
code that I wrote, therefore I have a special care about it.
I tried almost all third-party packages for minibuffer completions, but I always go back to IDO after a while. Probably I am not a power user for the kind of functionality these frameworks provide.
This is my current setup for ido:
(defun ido-choose-from-recentf ()
"Use ido to select recently visited files."
(interactive)
(find-file (ido-completing-read "Open file: " recentf-list nil t)))
(defun bk/go-straight-home ()
(interactive)
(cond
((looking-back "~/") (insert "projects/"))
((looking-back "/") (insert "~/"))
(:else (call-interactively 'self-insert-command))))
(defun ido-disable-line-truncation ()
(set (make-local-variable 'truncate-lines) nil))
(defun ido-define-keys ()
(define-key ido-completion-map (kbd "C-n") 'ido-next-match)
(define-key ido-completion-map (kbd "C-p") 'ido-prev-match))
(use-package ido
:ensure nil
:init
(setq ido-enable-flex-matching t
ido-use-filename-at-point nil
ido-create-new-buffer 'always
confirm-nonexistent-file-or-buffer nil
completion-ignored-extensions (cons "*.aux" completion-ignored-extensions)
max-mini-window-height 0.5
ido-enable-tramp-completion t
ido-auto-merge-work-directories-length -1
ido-confirm-unique-completion t
ido-default-file-method 'selected-window
ido-case-fold t
ido-show-dot-for-dired t
ido-everywhere t
ido-ignore-buffers (list (rx (or (and bos " ")
(and bos
(or "*Completions*"
"*Compile-Log*"
"*Ido Completions*"
"*Shell Command Output*"
"*vc-diff*")
eos))))
ido-decorations (quote ("\n-> " "" "\n " "\n ..." "[" "]" "
[No match]" " [Matched]" " [Not readable]" " [Too big]" "
[Confirm]")))
:config
(define-key ido-common-completion-map (kbd "M-SPC") 'just-one-space)
(define-key ido-common-completion-map (kbd "SPC") 'self-insert-command)
(define-key ido-file-completion-map (kbd "~") 'bk/go-straight-home)
(add-hook 'ido-setup-hook 'ido-define-keys)
(add-hook 'ido-minibuffer-setup-hook 'ido-disable-line-truncation)
(set-default 'imenu-auto-rescan t)
(add-to-list 'ido-ignore-directories "target")
(add-to-list 'ido-ignore-directories "node_modules")
(add-hook 'after-init-hook 'ido-mode))
This might be a bit lengthy, but I want to explain some of the highlights.
Use SPACES in the minibuffer
Yes, I really like how Ivy let us use the spaces to add more tokens to our searches. That is nice. I didn’t go that deep to reproduce such functionality in IDO, but I use org-roam a lot and several of my notes have spaces in their names.
Thus, the idea was to be able to add SPACES in the minibuffer to filter candidates from Org-Roam.
Turns out you can type M-q SPC
to add a space symbol in the
minibuffer. But we can do better, right?
(define-key minibuffer-local-completion-map (kbd "SPC") 'self-insert-command)
The code above let us type SPC in the minibuffer, however, IDO also
uses the SPC keyword for ido-complete-space
function, therefore we
need to remap it too:
(define-key ido-common-completion-map (kbd "SPC") 'self-insert-command)
Vertical candidates
I tried to get used to the horizontal display, but even not being so bad, I find the benefits for vertical mode very appealing and the necessary tweaks are simple to do:
(setq ido-decorations (quote "\n-> " "" "\n " "\n ..." "[" "]" "
[No match]" " [Matched]" " [Not readable]" " [Too big]" "
[Confirm]"))
I also like to adjust the height of the candidate list to be a little bit taller than usual to fit more candidates before typing anything.
(setq max-mini-window-height 0.5)
Also need to adjust the navigation keys to use standard C-n and C-p to move up and down the list.
(defun ido-define-keys ()
(define-key ido-completion-map (kbd "C-n") 'ido-next-match)
(define-key ido-completion-map (kbd "C-p") 'ido-prev-match))
(add-hook 'ido-setup-hook 'ido-define-keys)
Move to most used folders
I like to type ~
twice and be taken to my “projects” folder. This is a
nice recipe for you to change as you like.
(defun bk/go-straight-home ()
(interactive)
(cond
((looking-back "~/") (insert "projects/"))
((looking-back "/") (insert "~/"))
(:else (call-interactively 'self-insert-command))))
(define-key ido-file-completion-map (kbd "~") 'bk/go-straight-home)
Ignore some buffers
I really don’t like to see some buffers like *Completions*
,
*Compile-Log*
, etc. If I want to look at them, I will go to M-x ibuffer
or M-x buffer-list
explicitly.
(setq ido-ignore-buffers (list (rx (or (and bos " ")
(and bos
(or "*Completions*"
"*Compile-Log*"
"*Ido Completions*"
"*Shell Command Output*"
"*vc-diff*")
eos)))))
As soon as I find a new buffer bothering me, I add the name to my blocklist.
Similar situation for some file extensions like the auxiliary files created by LaTeX compilation process.
(setq completion-ignored-extensions (cons "*.aux" completion-ignored-extensions))
Open dired immediately in current directory at find-file
This simple setup is very handy. it will add a dot as the first item
of your candidates when you fire find-file
. You can open dired
immediately using RET on the dot.
(setq ido-show-dot-for-dired t)
Conclusion
I keep learning something new in IDO everytime. Up to now I manage to
survive without flx-ido
or even ido-completing-read+
. I might give
then another chance in the near future.
If you have more tweaks to IDO, I would love to know about.
Happy New Year, keep hacking!