summaryrefslogtreecommitdiff
path: root/lisp/icomplete.el
diff options
context:
space:
mode:
authorJoão Távora <joaotavora@gmail.com>2019-10-29 00:12:16 +0000
committerJoão Távora <joaotavora@gmail.com>2019-10-29 00:19:33 +0000
commit7373d6eae807af9f0557b28b30e2864f17114c40 (patch)
treeb3791244cb7ecd82b19963f34e0beabbc64cbdb3 /lisp/icomplete.el
parent4e3676726a64018cd4688d2669657878a2975f2c (diff)
downloademacs-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.el85
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