Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Overhaul compatibility mode

Now compatibilty is only activated if the current call to
"ido-completing-read" was done through the ido-ubiquitous wrapper
"completing-read-ido". The new implementation now also works with
recursive minibuffers.

This *should* fix both #16 and #17, which I previously thought might
be mutually exclusive.
  • Loading branch information...
commit 49de8ee59f618e5bf538f0329b2305c91fd5c599 1 parent 6a86f22
@DarwinAwardWinner authored
Showing with 59 additions and 47 deletions.
  1. +59 −47 ido-ubiquitous.el
View
106 ido-ubiquitous.el
@@ -121,6 +121,9 @@ ido-ubiquitous in non-interactive functions, customize
(define-obsolete-variable-alias 'ido-ubiquitous-exceptions
'ido-ubiquitous-command-exceptions "0.4")
+(defvar ido-next-call-replaces-completing-read nil)
+(defvar ido-this-call-replaces-completing-read nil)
+
(defun completing-read-ido (prompt collection &optional predicate
require-match initial-input
hist def inherit-input-method)
@@ -141,13 +144,22 @@ be used as the value of `completing-read-function'."
;; Only use ido completion if there are actually any completions
;; to offer.
(if allcomp
- (ido-completing-read prompt allcomp
- nil require-match initial-input hist def)
+ (let ((ido-next-call-replaces-completing-read t))
+ (ido-completing-read prompt allcomp
+ nil require-match initial-input hist def))
(funcall ido-ubiquitous-orig-completing-read-function
prompt collection predicate
require-match initial-input
hist def inherit-input-method)))))
+(defadvice ido-completing-read (around detect-replacing-cr activate)
+ (if ido-next-call-replaces-completing-read
+ (let ((ido-next-call-replaces-completing-read nil)
+ (ido-this-call-replaces-completing-read t))
+ ad-do-it)
+ (let ((ido-this-call-replaces-completing-read nil))
+ ad-do-it)))
+
(defmacro ido-ubiquitous-disable-in (func)
"Disable ido-ubiquitous in FUNC."
(let ((docstring
@@ -232,35 +244,34 @@ already.)"
:set 'ido-ubiquitous-set-function-exceptions)
(defcustom ido-ubiquitous-enable-compatibility t
- "Emulate a quirk of `completing-read'.
-
-In the past, the `completing-read' function had no way of
-specifying a default item, so instead the convention was to
-request the default by returning an empty string. This occurrs in
-standard emacs completion system when you press \"RET\" without
-typing anything first. This is a problem for ido completion
-because when ido is used this way, it does not know which item is
-the default, so it cannot put the default at the head of the
-list. Hence, simply pressing \"RET\" will not properly select the
-advertised default. Setting this variable to non-nil will force
-ido to emulate this quirk of the standard emacs completion system
-in order to maintain compatibility with old functions that still
-use the empty-string-as-default convention.
-
-Specifically, when this variable is non-nil, ido will return an
-empty string (thereby requesting the default) if you press \"RET\"
-without entering any text or cycling through the offered choices.
-This replaces the standard ido behavior of returning the first
-item on the list. Enabling this option improves compatibility
-with many older functions that use `completing-read' in this way,
-but may also break compatibility with others, since it changes
-what ido returns.
-
-If you want this enabled most of the time but once in a while you
-really want to select the first item on the list, you can do so
-by prefixing \"RET\" with \"C-u\".
-
-This has no effect when ido is completing buffers or files."
+ "Allow ido to emulate a quirk of `completing-read'.
+
+From the `completing-read' docstring:
+
+> If the input is null, `completing-read' returns DEF, or the
+> first element of the list of default values, or an empty string
+> if DEF is nil, regardless of the value of REQUIRE-MATCH.
+
+If this variable is non-nil, then ido-ubiquitous will attempt to
+emulate this behavior. Specifically, if RET is pressed
+immediately upon entering completion, an empty string will be
+returned instead of the first element in the list. This behavior
+is only enabled when ido is being used as a substitute for
+`completing-read', and not when it is used directly.
+
+This odd behavior is required for compatibility with an old-style
+usage pattern whereby the default was requested by returning an
+empty string. In this mode, the caller receives the empty string
+and handles the default case manually, while `completing-read'
+never has any knowledge of the default. This is a problem for
+ido, which always returns the first element in the list when the
+input is empty. Without knowledge of the default, it cannot
+ensure that the default is first on the list, so returning the
+first item is not the correct behavior. Instead, it must return
+an empty string like `completing-read'.
+
+When this mode is enabled, you can still select the first item on
+the list by prefixing \"RET\" with \"C-u\"."
:type 'boolean
:group 'ido-ubiquitous)
@@ -280,29 +291,30 @@ This has no effect when ido is completing buffers or files."
(defadvice ido-prev-match (after clear-initial-item activate)
(setq ido-ubiquitous-initial-item nil))
-(defadvice ido-exit-minibuffer (around required-allow-empty-string activate)
+(defadvice ido-exit-minibuffer (around compatibility activate)
"Emulate a quirk of `completing-read'.
-Apparently, in the past `completing-read' used to request the
-default item by returning an empty string when RET was pressed
-with an empty input. This forces `ido-completing-read' to do the
-same (instead of returning the first choice in the list),
-allowing the default to be properly selected.
-
-This has no effect when ido is completing buffers or files.
-
-This behavior is disabled by setting
-`ido-ubiquitous-enable-compatibility' to nil."
- (if (and ido-ubiquitous-enable-compatibility
- (eq ido-cur-item 'list)
- ido-require-match
+> If the input is null, `completing-read' returns DEF, or the
+> first element of the list of default values, or an empty string
+> if DEF is nil, regardless of the value of REQUIRE-MATCH.
+
+See `ido-ubiquitous-enable-compatibility', which controls whether
+this advice has any effect."
+ (if (and (eq ido-cur-item 'list)
+ ido-ubiquitous-enable-compatibility
+ ;; Only enable if we are replacing `completing-read'
+ ido-this-call-replaces-completing-read
+ ;; Input is empty
+ (string= ido-text "")
+ ;; Default is nil
(null ido-default-item)
+ ;; Prefix disables compatibility
(not current-prefix-arg)
- (string= ido-text "")
(string= (car ido-cur-list)
ido-ubiquitous-initial-item))
(ido-select-text)
- ad-do-it))
+ ad-do-it)
+ (setq ido-ubiquitous-initial-item nil))
(defadvice bookmark-completing-read (around disable-ido-compatibility activate)
"`bookmark-completing-read' uses `completing-read' in an odd
Please sign in to comment.
Something went wrong with that request. Please try again.