The Emacs built-in completion system.
- ido-mode is like magic pixie dust!
- Sometimes ido can’t find a file, just run M-x ido-reread-directory or C-l in minibuffer to refresh ido candidates.
- Use C-d to enter dired from file switching.
(setq ido-enable-prefix nil
ido-enable-flex-matching t
ido-create-new-buffer 'always
ido-use-virtual-buffers t
ido-auto-merge-work-directories-length -1
ido-save-directory-list-file (concat starter-kit-dir ".ido.last")
ido-max-prospects 10
ido-use-faces nil
flx-ido-threshold 10000
ido-use-filename-at-point 'guess)
(ido-mode 1)
(ido-everywhere 1)
(flx-ido-mode 1)
(ido-ubiquitous-mode 1)
(global-set-key (kbd "C-x C-f") 'ido-find-file)
;; key bindings. For some reason key bindings have to be set in `ido-setup-hook'
(defun ido-setup-key-bindings ()
(define-key ido-completion-map (kbd "C-n") 'ido-next-match)
(define-key ido-completion-map (kbd "C-p") 'ido-prev-match)
(define-key ido-completion-map (kbd "C-c C-c") 'ido-restrict-to-matches))
(add-hook 'ido-setup-hook 'ido-setup-key-bindings)
Tell dired-do-copy and dired-do-rename to use Ido:
(put 'dired-do-copy 'ido 'dir)
(put 'dired-do-rename 'ido 'dir)
Don’t guess file name in Dired buffer:
(defun my/ido-ignore-file-at-point ()
(when (bound-and-true-p ido-use-filename-at-point)
(setq-local ido-use-filename-at-point nil)))
(add-hook 'dired-mode-hook #'my/ido-ignore-file-at-point)
Just use C-o to invoke in other window, no need to remember the key of ido-find-file-other-window or something like that.
(require 'ido-other-window)
A function that insert file name at point using Ido.
(defun my-ido-insert-fname (from b0 b1)
"Use ido to complete read file name.
If file or directory navigated to is within 3 level upward current directory,
relative directory is inserted; otherwise the full path is inserted. You can
always fallback from file completion to directory by C-j."
(let* ((file (ido-read-file-name ": " from))
(relative (file-relative-name file default-directory)))
(delete-region b0 b1)
(if (string= relative (file-name-nondirectory file))
(progn
(when (file-executable-p file)
(insert "./"))
(insert relative))
(insert file))))
(defun my-ido-expand-fname ()
(interactive)
(let (dir-at-point bounds b0 b1)
(cond
((looking-back "\\(^\\|[ \t\"'=]\\)")
(setq dir-at-point "."
b0 (point)
b1 b0)
(my-ido-insert-fname dir-at-point b0 b1))
((and
(setq bounds (bounds-of-thing-at-point 'filename))
(setq b0 (car bounds)
b1 (cdr bounds)
dir-at-point (buffer-substring-no-properties b0 b1))
(file-directory-p dir-at-point))
(my-ido-insert-fname dir-at-point b0 b1)))))
I use English words dict instead.
(setq my-english-words-dict (concat starter-kit-dir "dict/english-words.txt"))
(defun try-expand-by-dict (old)
(unless old
(he-init-string (he-lisp-symbol-beg) (point))
(unless (he-string-member he-search-string he-tried-table)
(setq he-tried-table (cons he-search-string he-tried-table)))
(setq he-expand-list
(and (not (equal he-search-string ""))
(split-string
(shell-command-to-string
(format
"grep \"^%s\" %s"
(buffer-substring-no-properties (he-lisp-symbol-beg) (point))
my-english-words-dict))))))
(if (not he-expand-list)
(progn (when old (he-reset-string) nil))
(he-substitute-string (car he-expand-list))
(setq he-expand-list (cdr he-expand-list))
t))
(defun my-hippie-expand-completions (&optional hippie-expand-function)
"Return the full list of possible completions generated by `hippie-expand'.
The optional argument can be generated with `make-hippie-expand-function'."
(let ((this-command 'my-hippie-expand-completions)
(last-command last-command)
(buffer-modified (buffer-modified-p))
(hippie-expand-function (or hippie-expand-function 'hippie-expand)))
(flet ((ding)) ; avoid the (ding) when hippie-expand exhausts its options.
(while (progn
(funcall hippie-expand-function nil)
(setq last-command 'my-hippie-expand-completions)
(not (equal he-num -1)))))
;; Evaluating the completions modifies the buffer, however we will finish
;; up in the same state that we began.
(set-buffer-modified-p buffer-modified)
;; Provide the options in the order in which they are normally generated.
(delete he-search-string (reverse he-tried-table))))
(defmacro my-ido-hippie-expand-with (hippie-expand-function)
"Generate an interactively-callable function that offers ido-based completion
using the specified hippie-expand function."
`(call-interactively
(lambda (&optional selection)
(interactive
(let ((options (my-hippie-expand-completions ,hippie-expand-function)))
(if options
(list (ido-completing-read "Completions: " options)))))
(if selection
(he-substitute-string selection t)
(message "No expansion found")))))
(defun my-ido-hippie-expand ()
"Offer ido-based completion for the word at point."
(interactive)
(my-ido-hippie-expand-with 'hippie-expand))
(setq hippie-expand-try-functions-list
'(try-expand-dabbrev
try-expand-dabbrev-all-buffers
try-expand-dabbrev-from-kill
try-expand-all-abbrevs))
(defun my-ido-expand-fname-or-hippie-expand ()
(interactive)
(or
(my-ido-expand-fname)
(my-ido-hippie-expand)))
(with-eval-after-load 'evil
(define-key evil-insert-state-map (kbd "C-o")
#'my-ido-expand-fname-or-hippie-expand))
(setq completion-ignore-case t)