DarwinAwardWinner/ido-completing-read-plus

Option to disable empty entry

ivan-m opened this issue · 17 comments

You've documented that an empty entry is inserted when no default has been specified.

However, with various packages that I use that didn't supply a default (possibly because the list is dynamically generated via an external tool), my muscle memory is such that I know that the first is the one I want, or I hit right arrow then enter, etc.

Now with this new behaviour, I keep accidentally selecting an invalid "blank" value or the wrong one if I'm used to choosing the one I want by its old position.

Would it be possible to disable this new behaviour?

There's currently a hidden variable called ido-cr+-no-default-action that controls this behavior. You can set it to either nil or append-empty-string to get what you're looking for, at the cost of breaking any commands that rely on the nil default behavior. You can get more granular control by advising the commands you care about using around-advice that let-bind this variable.

I'm open to the possibility of implementing a whitelist and/or blacklist to control which commands get an empty entry, but the better solution would be to contact the maintainers of those packages and urge them to provide a default if the empty string is not a valid completion. Can you give some examples of commands/packages where this causes a problem?

This is the query that drove me to look for what was causing it this morning (I have (setq ebal-completing-read-function 'ebal-ido-completing-read) in my configuration).

There was another one the other day but I don't recall which off the top of my head.

That function definitely has a bug in it from assuming that require-match actually means what it says. It can easily be rewritten to provide a default argument here: https://github.com/mrkkrp/ebal/blob/master/ebal.el#L903-L907

Probably all uses of ebal-completing-read-function should be likewise modified. In the meantime, you could advise that function not to allow the empty string default:

(define-advice ebal--init-query (:around (orig-fun &rest args) no-ido-empty-string)
  (let ((ido-cr+-no-default-action nil))
    (apply orig-fun args)))

@DarwinAwardWinner I've been having this exact same issue for a while now, but doing (setq ido-cr+-no-default-action 'append-empty-string) does not seem to be solving the problem. The empty string is still at the beginning of the completion list even after I evaluate that form, although setting it to nil makes the empty string disappear entirely from the completion list. I have been living with it set to nil for a while now, but that does not always work for commands that require you to insert an empty string to terminate the list, e.g., describe-face or customize-face. I would very much appreciate it if running (setq ido-cr+-no-default-action 'append-empty-string) at least did what I expected it to do.

Side note, I'm not a fan of the new behavior even though it may be more correct or proper and it has definitely screwed with my muscle memory when ido-cr+-no-default-action is not set to nil.

Hmm. The append-empty-string option is the least tested, since I wasn't sure there was really a use case for it. I need to check whether ido is internally re-sorting the entries after ido-cr+ sorts the empty string at the end.

As for things like describe-face, are you by any chance using my other package crm-custom to get ido completion in completing-read-multiple? If so, then I think I need to have that package force ido-cr+-no-default-action to prepend-empty-string when it runs.

Anyway, it looks like I should probably implement a blacklist system for the nil default compatibility feature. I can also possibly mitigate the problem in some cases by parsing the default out of the prompt string using minibuffer-default-in-prompt-regexps.

@DarwinAwardWinner Yes, I am using the crm-custom package. Those other changes sound good as well; I appreciate your efforts.

Thanks for the feedback. I realize the change in behavior is potentially disruptive, which is part of the reason I still have MELPA Stable on the 3.x branch.

Ah, I see. Sadly, I can't use MELPA stable since many other packages that I use are not available on it.

Ok, I figured out the problem. With append-empty-string, the empty string is put at the end, but then because it exactly matches the current input (i.e. also the empty string), ido immediately promotes it to the front of the list. This means I'll have to implement this some other way, probably by just allowing C-j to exit with the empty string rather than adding the empty string to the collection.

On the other hand, is this mode of operation even required? Or are you just using it as a workaround? If the latter, I think I can fix the real problem and remove the append-empty-string behavior entirely.

@DarwinAwardWinner I'm just using the append-empty-string behavior as a workaround, if that's what you mean. I personally would be fine with having C-j exit with the empty string since that's the behavior I was used to before this change.

I'm tempted to name the new variable ido-cr+-require-match-wall-of-shame.

Docstring: "List of functions whose authors didn't read the docstring for completing-read"

Oh boy, that sounds like fun... ;)

@DarwinAwardWinner Hey, I just installed the new update here and added the functions that I wanted to have the old behavior to ido-cr+-nil-def-alternate-behavior-list and it seems to work great. Thanks!

If you had to add any functions that weren't already there by default, can you please also tell me which ones? They should probably be added to the defaults.

@DarwinAwardWinner So far just bookmark-completing-read. I think there's another command that I used with the old behavior, but I haven't used it since updating and I can't remember it right now.