diff options
author | Sean Whitton <spwhitton@spwhitton.name> | 2023-03-22 17:30:15 -0700 |
---|---|---|
committer | Sean Whitton <spwhitton@spwhitton.name> | 2023-03-22 17:48:00 -0700 |
commit | fc756057bbc741e64c0984e38cbf18ea338bf354 (patch) | |
tree | f1bd88fbc31c877cc3df3e3c9e014dc7c6fdfef4 | |
parent | baa465208c2589063da0cb64ebd70d9b8cbcb3fa (diff) | |
download | dotfiles-fc756057bbc741e64c0984e38cbf18ea338bf354.tar.gz |
replace fido-mode with plain Icomplete
-rw-r--r-- | .emacs.d/init.el | 96 |
1 files changed, 70 insertions, 26 deletions
diff --git a/.emacs.d/init.el b/.emacs.d/init.el index e8a31326..a8585f94 100644 --- a/.emacs.d/init.el +++ b/.emacs.d/init.el @@ -189,6 +189,7 @@ windows side-by-side in the frame." '(column-number-mode t) '(comint-prompt-read-only t) '(compilation-scroll-output 'first-error) + '(completion-styles '(flex)) '(confirm-kill-emacs 'y-or-n-p) '(copy-region-blink-delay 0) '(copyright-names-regexp "Sean Whitton") @@ -217,7 +218,6 @@ windows side-by-side in the frame." '(eshell-history-size 5000) '(eshell-visual-commands '("vi" "screen" "tmux" "top" "htop" "less" "more" "mutt" "locmaint")) - '(fido-mode t) '(fill-column 78) '(font-lock-maximum-decoration '((lisp-mode . 1) (consfigurator-lisp-mode . 1) (t . t))) '(gc-cons-threshold 16777216) @@ -277,7 +277,11 @@ windows side-by-side in the frame." '(howm-file-name-format "%Y/%Y-%m-%d-%H%M.org") '(howm-keyword-file "~/doc/howm/.howm-keys") '(howm-view-use-grep t) + '(icomplete-hide-common-prefix nil) '(icomplete-in-buffer t) + '(icomplete-mode t) + '(icomplete-show-matches-on-no-input t) + '(icomplete-tidy-shadowed-file-names t t) '(imenu-auto-rescan t) '(initial-major-mode 'spw/scratch-lisp-interaction-mode) '(kill-read-only-ok t) @@ -363,7 +367,7 @@ windows side-by-side in the frame." '(org-log-into-drawer t) '(org-log-repeat nil nil nil "Cluttering, and information probably in git.") '(org-log-states-order-reversed nil) - '(org-outline-path-complete-in-steps nil nil nil "Desirable with `fido-mode'.") + '(org-outline-path-complete-in-steps nil nil nil "Desirable with `icomplete-mode'.") '(org-read-date-prefer-future 'time) '(org-refile-allow-creating-parent-nodes 'confirm) '(org-refile-targets '((org-agenda-files :maxlevel . 5) (nil :maxlevel . 5))) @@ -411,6 +415,8 @@ windows side-by-side in the frame." '(rcirc-track-abbrevate-flag nil) '(rcirc-track-ignore-server-buffer-flag t) '(rcirc-track-minor-mode t) + '(read-buffer-completion-ignore-case t) + '(read-file-name-completion-ignore-case t) '(read-mail-command 'gnus) '(read-minibuffer-restore-windows nil) '(remember-data-file "~/local/tmp/scratch") @@ -1197,35 +1203,75 @@ To be used only when it seems to be necessary." ;; completing the name of a Lisp symbol. (spw/reclaim-keys-from minibuffer minibuffer-local-completion-map " " "?") +(setq completion-ignore-case t) + +(defun spw/minibuffer-completing-file-name-p () + ;; See `icomplete--category'. + (eq (completion-metadata-get + (completion-metadata (minibuffer-contents) + minibuffer-completion-table + minibuffer-completion-predicate) + 'category) + 'file)) + ;; Most common actions are to select the top completion in the way that ;; `icomplete-fido-ret' does, and to exit with the current input. So these -;; two get single keypresses, TAB and RET. We slightly tweak the former such -;; that RET is required to exit with input which has no matches. This helps -;; avoid creating bogus buffers, file-visiting or otherwise, when I mistype. +;; two get single keypresses, TAB and RET. We tweak the former such that RET +;; is required to exit with input which has no matches. This helps avoid +;; creating bogus buffers, file-visiting or otherwise, when I mistype. ;; ;; Choose RET for exiting with current input because then RET behaves the ;; same in `read-string' and `completing-read'. This makes completion less ;; obtrusive given how some commands provide completion even when they are ;; mostly used to enter arbitrary strings (e.g. `notmuch-search'). ;; -;; Don't resettle the previous occupant of <TAB>, `minibuffer-complete' -;; because a `fido-mode' user hardly uses it -(define-key icomplete-fido-mode-map [?\t] - (lambda () - (interactive) - (when completion-all-sorted-completions - (call-interactively #'icomplete-fido-ret)))) -(define-key icomplete-fido-mode-map [?\r] #'icomplete-fido-exit) +;; Don't resettle the previous occupant of <TAB>, `minibuffer-complete', +;; because an `icomplete-mode' user hardly uses it. +;; This is something like a reimplementation of `icomplete-fido-ret'. +(defun spw/icomplete-tab () + (interactive) + (when-let* ((current (car completion-all-sorted-completions))) + ;; For in-buffer completion it should always be fine to just call + ;; `icomplete-force-complete', and not exit, because of how in-buffer + ;; completion uses a transient map. An alternative would be to guess + ;; whether completing a file name, e.g. (string-suffix-p "/" current). + (if (or (not (window-minibuffer-p)) + (and (spw/minibuffer-completing-file-name-p) + (let ((dir (file-name-directory (minibuffer-contents)))) + (file-directory-p + (if dir (expand-file-name (directory-file-name current) + (substitute-env-vars dir)) + current))))) + (icomplete-force-complete) + (icomplete-force-complete-and-exit)))) +(define-key icomplete-minibuffer-map [?\t] #'spw/icomplete-tab) + +(defun spw/icomplete-ret () + (interactive) + (let (completion-auto-help) + (minibuffer-complete-and-exit))) +(define-key icomplete-minibuffer-map [remap minibuffer-complete-and-exit] + #'spw/icomplete-ret) + +;; This is based on `icomplete--fido-ccd'. +(defun spw/update-completion-category-overrides () + (pcase-dolist (`(,cat . ,props) completion-category-defaults) + (setf (alist-get cat completion-category-overrides) + (or (alist-get cat completion-category-overrides) + (cl-loop for entry in props + for (prop . val) = entry + if (eq prop 'styles) collect + `(,prop . (flex . ,(remq 'flex val))) + else collect entry))))) +(add-hook 'icomplete-minibuffer-setup-hook + #'spw/update-completion-category-overrides) +(add-hook 'completion-in-region-mode-hook + #'spw/update-completion-category-overrides) + +;; This is a bit like `icomplete-fido-backward-updir'. (defun spw/icomplete-choose-rubout () - ;; See `icomplete--category'. - (when (eq (completion-metadata-get - (completion-metadata - (buffer-substring-no-properties (minibuffer-prompt-end) (point)) - minibuffer-completion-table - minibuffer-completion-predicate) - 'category) - 'file) + (when (and (window-minibuffer-p) (spw/minibuffer-completing-file-name-p)) (let ((map (make-sparse-keymap))) (define-key map "\C-w" @@ -1235,16 +1281,14 @@ To be used only when it seems to be necessary." (use-local-map (make-composed-keymap map (current-local-map)))))) (add-hook 'icomplete-minibuffer-setup-hook #'spw/icomplete-choose-rubout) -;; Preserve some standard bindings for editing text in the minibuffer. +;; Preserve standard bindings for editing text in the minibuffer. (define-key icomplete-minibuffer-map [?\C-j] nil) -(define-key icomplete-fido-mode-map [?\C-r] nil) -(define-key icomplete-fido-mode-map [?\C-s] nil) ;; Bind M-, and M-. to cycle completions; their normal bindings aren't likely ;; to be needed when completing, and unlike C-, and C-. they work in text ;; terminals. Alternatives might be C-M-r and C-M-s. -(define-key icomplete-fido-mode-map [?\M-.] #'icomplete-forward-completions) -(define-key icomplete-fido-mode-map [?\M-,] #'icomplete-backward-completions) +(define-key icomplete-minibuffer-map [?\M-.] #'icomplete-forward-completions) +(define-key icomplete-minibuffer-map [?\M-,] #'icomplete-backward-completions) (defun spw/empty-minibuffer () (interactive) |