emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Adding built-in fallback mechanism to completing-read?


From: Ryan Thompson
Subject: Adding built-in fallback mechanism to completing-read?
Date: Sat, 03 Jun 2017 17:09:19 +0000

I'm the developer of ido-ubiquitous. In recent discussions on a few issues I reported, it was noted that completing-read encompasses a very wide range of functionality, to the point that any potential alternative value for completing-read-function will probably not be able to handle every case. This puts such functions in the position of needing to implement a mechanism for falling back to completing-read-default. For example, the three that I am aware of, helm-mode, ido-ubiquitous-mode, and ivy-mode, would all break the tmm-menubar command, except that all three of them have code that specifically decativates them when called from tmm (see helm-completing-read-handlers-alist, ido-ubiquitous-command-overrides, and ivy-completing-read-handlers-alist respectively).

To me, this seems like unnecessary duplication. If completing-read wrapped its call to completing-read-function in a condition-case listening for a specific signal, then any completing-read-function could fall back to completing-read-default simply by running something like (signal 'completing-read-fallback "Reason for falling back"). Essentially, the implementation of completing-read would look like (adding a star to the name to avoid accidentally overwriting the actual completing-read if you eval it in Emacs):

(put 'completing-read-fallback 'error-conditions '(completing-read-fallback error))
(put 'completing-read-fallback 'error-message "completing-read-fallback")
(defun completing-read* (prompt collection &optional predicate require-match
                                initial-input hist def inherit-input-method)
  (condition-case sig
      (funcall completing-read-function prompt collection predicate require-match initial-input hist def inherit-input-method)
    (completing-read-fallback
     (funcall 'completing-read-default prompt collection predicate require-match initial-input hist def inherit-input-method))))

And an alternative completer could look like:

(defun my-special-completing-read (prompt collection &optional predicate require-match
                                          initial-input hist def inherit-input-method)
  ;; Check for stuff we can't handle (these are just arbitrary
  ;; examples of what you might check)
  (unless (listp collection)
    (signal 'completing-read-fallback "I can only handle list collections"))
  (when initial-input
    (signal 'completing-read-fallback "I can't handle initial-input"))
  ;; Substitute actual completion code here
  (completing-read-default (concat "(Using my custom completer) " prompt)
                           collection &optional predicate require-match
                           initial-input hist def inherit-input-method))

This is more or less the mechanism I have implemented already for ido-ubiquitous, but since this is a problem that needs to be solved by any completion system aiming to provide a completing-read-function (unless it somehow manages from day 1 to handle every single case that completing-read-default can handle), I figured I would suggest implementing something similar upstream that could be used by any completing-read-function. Obviously the implementation I've suggested above is just one way to implement this. I'm more interested in suggesting the idea than advocating any particular implementation. I'm willing to do the work of reaching out to the ivy and helm developers, as well as any other providers of completing-read-functions that I'm not aware of, to see if they would be interested in seeing this happen.

So, I'm interested to head if anyone thinks this might be a worthwhile addition to completing-read.

(Additional note: The implementation I've suggested above is incomplete, since completing-read would need to do some bookkeeping before falling back to default completion, such as restoring the self-removing hooks added to minibuffer-setup-hook via the minibuffer-with-setup-hook macro.)

reply via email to

[Prev in Thread] Current Thread [Next in Thread]