all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* read-from-minibuffer with default value string
@ 2010-12-05 20:33 Tyler Smith
  2010-12-06  3:39 ` Drew Adams
  0 siblings, 1 reply; 4+ messages in thread
From: Tyler Smith @ 2010-12-05 20:33 UTC (permalink / raw
  To: help-gnu-emacs

Hi,

I'm confused by the documentation for read-from-minibuffer. It says that
the INITIAL-CONTENTS argument is obsolete, but I can't duplicate the
functionality using DEFAULT-VALUE.

I'm working on a function that will query the user for input using
completing-read. If the value entered isn't in the collection used for
completing-read, then the user is asked if they want to add the value to
the collection.

The following code works as I want it:

(setq collection-list
      '(("Advances in Ecological Research" "adv_ecol_res") 
	("Acta Oecologica" "acta_oecol") 
	("Acta Botanica Neerlandica" "acta_bot_neerl")))

;; Note that in my full code, collection-list contains three-element
;; lists, which is why I haven't used the normal (key . value) form of
;; normal alists.


(defun double-query ()
  (interactive)
  (let ((key (completing-read "Journal: " collection-list)))
    (if (setq code (cadr (assoc key collection-list)))
	(message "Pass <%s> to another function here" code)
      (if (y-or-n-p "Add to list?")
	  (let* ((key (read-from-minibuffer (format "Journal Title <%s>: " key) key))
		 (code (read-from-minibuffer "Journal Bibtex Code: ")))
	    (push (list key code) collection-list)
	    (message "Pass <%s> to another function here" code))))))

This uses the obsolete INITIAL-CONTENTS argument. If I use the DEFAULT
value list, I either have to set the READ argument to nil, which means
that entering an empty string results in key being set to the empty
string rather than the default value; or I set READ to t, which means
that any text the user enters is treated as an expression, which
produces an error when the string contains a space. The strings will
often contain spaces, so this isn't good.

How can I rewrite this to work without using INITIAL-CONTENTS?

Thanks,

Tyler





^ permalink raw reply	[flat|nested] 4+ messages in thread

* RE: read-from-minibuffer with default value string
  2010-12-05 20:33 read-from-minibuffer with default value string Tyler Smith
@ 2010-12-06  3:39 ` Drew Adams
  2010-12-06 14:08   ` Tyler Smith
  0 siblings, 1 reply; 4+ messages in thread
From: Drew Adams @ 2010-12-06  3:39 UTC (permalink / raw
  To: 'Tyler Smith', help-gnu-emacs

> I'm confused by the documentation for read-from-minibuffer. It says
> that the INITIAL-CONTENTS argument is obsolete, but I can't
> duplicate the functionality using DEFAULT-VALUE.

You are correct that it does not _duplicate_ the functionality.

> I'm working on a function that will query the user for input using
> completing-read. If the value entered isn't in the collection used for
> completing-read, then the user is asked if they want to add 
> the value to the collection.

Note what you just said: "asked _if_" (i.e. whether).  To me, that says
`y-or-n-p'.

What you really do however is ask them again to input the (same) KEY (and then
for a corresponding CODE).  You ask them for the (same) KEY as a proxy for
directly asking _whether_ they want to add an entry for KEY.

> 	  (let* ((key (read-from-minibuffer (format "Journal 
> Title <%s>: " key) key))
> 		 (code (read-from-minibuffer "Journal Bibtex Code: ")))
> 	    (push (list key code) collection-list)
> 	    (message "Pass <%s> to another function here" code))))))
> 
> This uses the obsolete INITIAL-CONTENTS argument. If I use the DEFAULT
> value list, I either have to set the READ argument to nil, which means
> that entering an empty string results in key being set to the empty
> string rather than the default value; or I set READ to t, which means
> that any text the user enters is treated as an expression, which
> produces an error when the string contains a space. The strings will
> often contain spaces, so this isn't good.
> 
> How can I rewrite this to work without using INITIAL-CONTENTS?

A few alternatives I can think of:

1. Use `read-string' with KEY as the DEFAULT-VALUE.  This is likely what you
want to do here.


2. Use `read-from-minibuffer' with INITIAL-CONTENTS, but also use a cons as
HIST.  That usage is not considered obsolete AFAIK.  The doc string does suggest
that _any_ use of this parameter is "obsolete" but it also mentions using it
with a cons HIST value.

And the Elisp manual does not say INITIAL-CONTENTS is "obsolete" at all - it
says that it is "mostly deprecated" (equivocation), and it describes a use case
where it is presumably not deprecated:

     Use of INITIAL-CONTENTS is mostly deprecated; we recommend using a
     non-`nil' value only in conjunction with specifying a cons cell
     for HIST.  *Note Initial Input.

That's not the same thing as being obsolete, and the mention of using a cons
HIST seems to be outside of any deprecation/obsolescence.  But see also node
`Initial Input'.


3. Use `y-or-n-p' (or `yes-or-no-p') if you are not really letting users add a
different KEY here from what they entered the first time (in `completing-read')
and you just want to let them say _whether or not_ to add an entry with the
_given_ KEY (you would then still read the CODE).  IOW, you show them KEY in the
`y-or-n-p' prompt, which asks for confirmation to add an entry.


(4. You could even use `completing-read' with a singleton COLLECTION.  You
probably do not want to do that, but it is another alternative here.)


FWIW, _personally_ (but who cares?) I do not consider INITIAL-CONTENTS to be
obsolete.  It provides _different_ behavior from a DEFAULT value (as you
noticed).  In particular, the value is inserted in the minibuffer, and that
might be just what is wanted in some contexts.

Emacs Dev opted for declaring INITIAL-CONTENTS obsolete and putting the default
value inside prompts whenever they want to make it clear to users what the
default is.  Those are not quite the same thing.  Since there is a difference in
behaviors there can be uses for both.

The reason given for this obsolescence/deprecation?  From node `Initial Input':

   *We discourage use of a non-`nil' value for INITIAL*, because
   initial input is an intrusive interface.  History lists and default
   values provide a much more convenient method to offer useful default
   inputs to the user.

Intrusive?  Maybe - clearly it offers you an editable value to start with.  But
convenience is in the eye of the user.  If you have a key that empties the
minibuffer (I use `M-k' - none is provided by default in vanilla Emacs), then
it's pretty much a toss-up whether (a) a value is inserted initially and you
sometimes remove it or (b) nothing is inserted and you sometimes use `M-n' to
retrieve a value.

I personally prefer to have even the DEFAULT value inserted in the minibuffer,
because I often do want to edit it.  I use `M-k' to clear it if I don't want it
at all.  I do that less on average than I would have to use `M-n' to retrieve a
value to edit (or copy+paste from the prompt).

That's me - but everyone is different.  I don't think that one usage pattern
should be considered so superior in general that the other should be deprecated.
IMO, Emacs Dev should not have tried to be so controlling here - there was no
need for that.  But what do I know?


[FWIW, in Icicles a user option controls the treatment of the DEFAULT value
(when INTIAL-CONTENTS is nil or "").  Its possible values:

  nil               - Do not insert default value or add it to prompt.
  t                 - Add default value to prompt.  Do not insert it.
  `insert-start'    - Insert default value and leave cursor at start.
  `insert-end'      - Insert default value and leave cursor at end.
  `preselect-start' - Insert and preselect default value;
                      leave cursor at beginning.
  `preselect-end'   - Insert and preselect default value;
                      leave cursor at end.

My personal preference is `insert-end'.  The default value is `t' (similar to
vanilla Emacs behavior).]





^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: read-from-minibuffer with default value string
  2010-12-06  3:39 ` Drew Adams
@ 2010-12-06 14:08   ` Tyler Smith
  2010-12-06 15:49     ` Drew Adams
  0 siblings, 1 reply; 4+ messages in thread
From: Tyler Smith @ 2010-12-06 14:08 UTC (permalink / raw
  To: help-gnu-emacs

"Drew Adams" <drew.adams@oracle.com> writes:

>> I'm confused by the documentation for read-from-minibuffer. It says
>> that the INITIAL-CONTENTS argument is obsolete, but I can't duplicate
>> the functionality using DEFAULT-VALUE.
>
> You are correct that it does not _duplicate_ the functionality.
>
>> I'm working on a function that will query the user for input using
>> completing-read. If the value entered isn't in the collection used
>> for completing-read, then the user is asked if they want to add the
>> value to the collection.
>
> Note what you just said: "asked _if_" (i.e. whether).  To me, that says
> `y-or-n-p'.
>
> What you really do however is ask them again to input the (same) KEY
> (and then for a corresponding CODE). You ask them for the (same) KEY
> as a proxy for directly asking _whether_ they want to add an entry for
> KEY.

Actually, there is a y-or-n-p in there.

The flow I'm aiming for is:

Enter a value from the list (collecting-read ...)

If the value isn't on the list, check to make sure this isn't a mistake
(y-or-n-p ...)

If the value is going to be added permanently, give the user another
chance to make sure there are no typos in it (read-from-minibuffer ...).
Most of the time this will require only one additional keystroke
(<enter>) to confirm the value.

However, your suggestions below about combining the second two queries
looks solid.

>> 
>> How can I rewrite this to work without using INITIAL-CONTENTS?
>
> A few alternatives I can think of:
>
> 1. Use `read-string' with KEY as the DEFAULT-VALUE. This is likely
> what you want to do here.

That's exactly what I want, thanks! And I see that it follows
immediately after read-from-minibuffer in the manual. I was so focused
on trying to get read-from-minibuffer working apparently I didn't scroll
down to the next function. Oops. 

> 2. Use `read-from-minibuffer' with INITIAL-CONTENTS, but also use a
> cons as HIST. That usage is not considered obsolete AFAIK. The doc
> string does suggest that _any_ use of this parameter is "obsolete" but
> it also mentions using it with a cons HIST value.
>
> And the Elisp manual does not say INITIAL-CONTENTS is "obsolete" at
> all - it says that it is "mostly deprecated" (equivocation), and it
> describes a use case where it is presumably not deprecated:
>
>      Use of INITIAL-CONTENTS is mostly deprecated; we recommend using
>      a non-`nil' value only in conjunction with specifying a cons cell
>      for HIST. *Note Initial Input.
>
> That's not the same thing as being obsolete, and the mention of using
> a cons HIST seems to be outside of any deprecation/obsolescence. But
> see also node `Initial Input'.

Yes, I had been trying to puzzle over that page. You quote the passages
that suggest INITIAL-CONTENTS is still ok, but it also includes the
line:

   Use of a cons cell as the value for INITIAL arguments is deprecated
   in user code.

I'm not sure if this might be a documentation bug, but it sure left me
with mixed messages.

> 3. Use `y-or-n-p' (or `yes-or-no-p') if you are not really letting
> users add a different KEY here from what they entered the first time
> (in `completing-read') and you just want to let them say _whether or
> not_ to add an entry with the _given_ KEY (you would then still read
> the CODE). IOW, you show them KEY in the `y-or-n-p' prompt, which asks
> for confirmation to add an entry.

That sounds like a better design than what I had initially set out to
accomplish (described above). I'll play with both to see which gives me
fewer problems as a user.

>
> FWIW, _personally_ (but who cares?) I do not consider INITIAL-CONTENTS
> to be obsolete. It provides _different_ behavior from a DEFAULT value
> (as you noticed). In particular, the value is inserted in the
> minibuffer, and that might be just what is wanted in some contexts.

Sure, my only concerns in sorting this out are 1) to learn to use
correct, idiomatic elisp and 2) to avoid constructs that are likely to
change/disappear in future emacs versions. I think your suggestions will
allow me to avoid the issue entirely, which is good.

>
> That's me - but everyone is different. I don't think that one usage
> pattern should be considered so superior in general that the other
> should be deprecated. IMO, Emacs Dev should not have tried to be so
> controlling here - there was no need for that.

Agreed.

>
>
> [FWIW, in Icicles a user option controls the treatment of the DEFAULT
> value (when INTIAL-CONTENTS is nil or ""). Its possible values:
>
>   nil               - Do not insert default value or add it to prompt.
>   t                 - Add default value to prompt.  Do not insert it.
>   `insert-start'    - Insert default value and leave cursor at start.
>   `insert-end'      - Insert default value and leave cursor at end.
>   `preselect-start' - Insert and preselect default value;
>                       leave cursor at beginning.
>   `preselect-end'   - Insert and preselect default value;
>                       leave cursor at end.
>
> My personal preference is `insert-end'. The default value is `t'
> (similar to vanilla Emacs behavior).]

One more reason that I ought to dig into Icicles. I've been meaning to
look at it, but there are still a few issues with higher priority. Not
least is getting to work this morning.

Thanks for your help!

Tyler





^ permalink raw reply	[flat|nested] 4+ messages in thread

* RE: read-from-minibuffer with default value string
  2010-12-06 14:08   ` Tyler Smith
@ 2010-12-06 15:49     ` Drew Adams
  0 siblings, 0 replies; 4+ messages in thread
From: Drew Adams @ 2010-12-06 15:49 UTC (permalink / raw
  To: 'Tyler Smith', help-gnu-emacs

> Yes, I had been trying to puzzle over that page. You quote 
> the passages that suggest INITIAL-CONTENTS is still ok, but
> it also includes the line:
> 
>    Use of a cons cell as the value for INITIAL arguments is deprecated
>    in user code.
> 
> I'm not sure if this might be a documentation bug, but it sure left me
> with mixed messages.

No, it's not a typo.  That's something else again.  It pertains to this earlier
paragraph:

   INITIAL can also be a cons cell of the form `(STRING . POSITION)'.
   This means to insert STRING in the minibuffer but put point at POSITION
   within the string's text.

(So both HIST and INITIAL can be cons cells.)  Admittedly the statement you
quote can be confusing, especially because:

1. It is separated by a large paragraph from the statement that INITIAL can be a
cons.

2. It speaks about "user code".  That's easy to miss - and easy to wonder about.
What it is presumably saying is that Emacs Dev does not consider this deprecated
for its own (Emacs-developer) use in (officially distributed) Emacs code, but it
considers it deprecated for coding by users.  Silly?

You might want to file a doc bug to try to get this part clarified: `M-x
report-emacs-bug'.

> Sure, my only concerns in sorting this out are 1) to learn to use
> correct, idiomatic elisp and 2) to avoid constructs that are likely to
> change/disappear in future emacs versions. I think your 
> suggestions will allow me to avoid the issue entirely, which is good.

Yes, that's the right approach, IMO.  I do the same thing, for the same reason,
in spite of my view that this should _not_ be considered deprecated/obsolete.




^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2010-12-06 15:49 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-12-05 20:33 read-from-minibuffer with default value string Tyler Smith
2010-12-06  3:39 ` Drew Adams
2010-12-06 14:08   ` Tyler Smith
2010-12-06 15:49     ` Drew Adams

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.