help-gnu-emacs
[Top][All Lists]
Advanced

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

RE: How to handle default value in read-string?


From: Drew Adams
Subject: RE: How to handle default value in read-string?
Date: Fri, 21 Aug 2015 00:46:20 -0700 (PDT)

> >  (let ((icicle-default-value  nil)) ...)
> >
> > A nil value of `icicle-default-value' tells Icicles not to put the
> > default value in the prompt.  Then you can add it to the prompt
> > explicitly, so it will be there with and without Icicle mode:
> >
> > (defun foo (strg)
> >  (interactive
> >    (let ((icicle-default-value nil))
> >      (list (read-string "String (default my-default): "
> >                         nil nil "my-default")))))
> 
> OK, so I sat to this today, and didn't manage to get it to work.
> Here's my function:
> 
> (defun my-read-string (prompt &optional initial-input history
>                        default-value inherit-input-method)
>   (let ((icicle-default-value nil)
>       (prompt-with-default
>        (progn
>          (string-match "\\(: \\)?$" prompt)
>          (replace-match (format " (%s)\\1" default-value)
>                         t nil prompt))))
>     (read-string prompt-with-default initial-input history
>                  default-value inherit-input-method)))
> 
> If I do M-: (my-read-string "foo: " nil nil "bar") with Icicles
> off, everything is fine.  If Icicles are on, however, this is
> what I get: foo (bar) (bar):
> What am I doing wrong?

1. Let me say first that you need not be hobbled here by
Icicles. ;-)  You can easily take Icicles out of the mix
altogether if you like, by simply customizing option
`icicle-functions-to-redefine', removing `read-string'
from the list of functions to replace in Icicle mode.

2. Just binding `icicle-default-value' to nil should have
done the trick.  You can see that the example I gave works.

But in fact there was a bug: `icicle-read-string' (unlike
`icicle-completing-read', which has similar treatment of the
prompt) hard-coded inserting the default value into the prompt.

I've fixed that now, so all you should need to do, to inhibit
default insertion, is bind `icicle-default-value' to nil -
nothing else.  I thought that was the case already, but it was not.

3. The reason my example worked, even though automatic
inclusion of the default value was hardcoded, is this:

When the default value _is_ to be included, Icicles tries to
DTRT with prompts that might already hard-code the default
value in various ways, as well as with prompts that do not
show the default value.  It recognizes certain patterns of
default-value inclusion, and handles them properly.

4. To understand how it does this, and how you can adapt
it to other prompt patterns you might encounter, see function
`icicle-handle-default-for-prompt', option
`icicle-default-in-prompt-format-function', and variable
`minibuffer-default-in-prompt-regexps' in standard library
`minibuf-eldef.el'.

>From the doc string of `icicle-handle-default-for-prompt':

 In the existing PROMPT before modification, recognizes
 inclusion  of a default value according to these possible
 patterns:

 `minibuffer-default-in-prompt-regexps'
 "(default ___):"
 "(default is ___):"
 " [___] "

That is the default behavior for recognizing defaults in
prompts.  My example fit that (it passed "(default DEF):"),
and yours did not, hence the difference in behavior.

To modify the default recognition of default-in-prompt patterns,
you can customize `minibuffer-default-in-prompt-regexps' if you
use library `minibuf-eldef.el' (good).

A prompt matching one of the recognized patterns gets its
default removed, first.  And then, if argument INCLUDE to
`icicle-handle-default-for-prompt' is non-nil (which it was
in the bugged `icicle-read-string'), the default value is
added back to the prompt using format "(___): ".  So regardless
of the input format of a prompt (provided it is recognized),
the resulting prompt has the same, common format.  Icicles
always adds the default value in the same way (format).

You can control this resulting format by customizing option
`icicle-default-in-prompt-format-function', whose default
value is (lambda (default) (format " (%s)" default)).  The
function, whatever it is, places the formatted default
value just before the `:' in the prompt.

Again, the default value is inserted (using this function)
only if `icicle-default-value' is non-nil.  (That was the
bug - `icicle-default-value' was being ignored for
`icicle-read-string'.)

Note that even with the bug, if you had known about this
option you could have made your example work by customizing
the option to make it a no-op (no insertion):
(lambda (def) "").

Dunno whether all of this explanation makes things clearer,
but in any case the `icicle-read-string' bug that hardcoded
adding the default to the prompt should be fixed now, which
will make your example work.  And all you should need to do,
to inhibit insertion of the default, is to bind (or customize)
`icicle-default-value' to nil.

Sorry for the trouble.



reply via email to

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