diff options
author | João Távora <joaotavora@gmail.com> | 2019-10-29 00:12:16 +0000 |
---|---|---|
committer | João Távora <joaotavora@gmail.com> | 2019-10-29 00:19:33 +0000 |
commit | 7373d6eae807af9f0557b28b30e2864f17114c40 (patch) | |
tree | b3791244cb7ecd82b19963f34e0beabbc64cbdb3 /lisp/icomplete.el | |
parent | 4e3676726a64018cd4688d2669657878a2975f2c (diff) | |
download | emacs-7373d6eae807af9f0557b28b30e2864f17114c40.tar.gz |
New commands for making icomplete behave more like ido
This tries (not particularly hard) to emulate Ido's magic C-k, C-d,
RET and DEL. For now, the new commands have to be explicitly added to
an active map by the user, using something like this:
(let ((imap icomplete-minibuffer-map))
(define-key imap (kbd "C-k") 'icomplete-magic-ido-kill)
(define-key imap (kbd "C-d") 'icomplete-magic-ido-delete-char)
(define-key imap (kbd "RET") 'icomplete-magic-ido-ret)
(define-key imap (kbd "DEL") 'icomplete-magic-ido-backward-updir))
* lisp/icomplete.el (icomplete-magic-ido-kill)
(icomplete-magic-ido-delete-char, icomplete-magic-ido-ret)
(icomplete-magic-ido-backward-updir): New commands.
Diffstat (limited to 'lisp/icomplete.el')
-rw-r--r-- | lisp/icomplete.el | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/lisp/icomplete.el b/lisp/icomplete.el index 5cd11b125d2..f2745fb30aa 100644 --- a/lisp/icomplete.el +++ b/lisp/icomplete.el @@ -195,6 +195,91 @@ Last entry becomes the first and can be selected with (push (car last) comps) (completion--cache-all-sorted-completions beg end comps)))) +;;; `ido-mode' emulation +;;; +;;; The following "magic-ido" commands can be bound in +;;; `icomplete-mode-map' to make `icomplete-mode' behave more like +;;; `ido-mode'. Evaluate this to try it out. +;;; +;;; (let ((imap icomplete-minibuffer-map)) +;;; (define-key imap (kbd "C-k") 'icomplete-magic-ido-kill) +;;; (define-key imap (kbd "C-d") 'icomplete-magic-ido-delete-char) +;;; (define-key imap (kbd "RET") 'icomplete-magic-ido-ret) +;;; (define-key imap (kbd "DEL") 'icomplete-magic-ido-backward-updir)) + +(defun icomplete-magic-ido-kill () + "Kill line or current completion, like `ido-mode'. +If killing to the end of line make sense, call `kill-line', +otherwise kill the currently selected completion candidate. +Exactly what killing entails is dependent on the things being +completed. If completing files, it means delete the file. If +completing buffers it means kill the buffer. Both actions +require user confirmation." + (interactive) + (let ((beg (icomplete--field-beg)) (end (icomplete--field-end))) + (if (< (point) end) + (call-interactively 'kill-line) + (let* ((md (completion--field-metadata beg)) + (category (alist-get 'category (cdr md))) + (all (completion-all-sorted-completions)) + (thing (car all)) + (action + (pcase category + (`buffer + (lambda () + (when (yes-or-no-p (concat "Kill buffer " thing "? ")) + (kill-buffer thing)))) + (`file + (lambda () + (let* ((dir (file-name-directory (icomplete--field-string))) + (path (expand-file-name thing dir))) + (when (yes-or-no-p (concat "Delete file " path "? ")) + (delete-file path) t))))))) + (when (funcall action) + (completion--cache-all-sorted-completions + (icomplete--field-beg) + (icomplete--field-end) + (cdr all))) + (message nil))))) + +(defun icomplete-magic-ido-delete-char () + "Delete char or maybe call `dired', like `ido-mode'." + (interactive) + (let* ((beg (icomplete--field-beg)) + (end (icomplete--field-end)) + (md (completion--field-metadata beg)) + (category (alist-get 'category (cdr md)))) + (if (or (< (point) end) (not (eq category 'file))) + (call-interactively 'delete-char) + (dired (file-name-directory (icomplete--field-string))) + (exit-minibuffer)))) + +(defun icomplete-magic-ido-ret () + "Exit forcing completion or enter directory, like `ido-mode'." + (interactive) + (let* ((beg (icomplete--field-beg)) + (md (completion--field-metadata beg)) + (category (alist-get 'category (cdr md))) + (dir (and (eq category 'file) + (file-name-directory (icomplete--field-string)))) + (current (and dir + (car (completion-all-sorted-completions)))) + (probe (and current + (expand-file-name (directory-file-name current) dir)))) + (if (and probe (file-directory-p probe) (not (string= current "./"))) + (icomplete-force-complete) + (icomplete-force-complete-and-exit)))) + +(defun icomplete-magic-ido-backward-updir () + "Delete char before or go up directory, like `ido-mode'." + (interactive) + (let* ((beg (icomplete--field-beg)) + (md (completion--field-metadata beg)) + (category (alist-get 'category (cdr md)))) + (if (and (eq (char-before) ?/) (eq category 'file)) + (backward-kill-sexp 1) + (call-interactively 'backward-delete-char)))) + ;;;_ > icomplete-mode (&optional prefix) ;;;###autoload (define-minor-mode icomplete-mode |