unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* result of completing-read contradicting require-match
@ 2022-07-02 18:58 carlmarcos--- via Users list for the GNU Emacs text editor
  2022-07-02 19:20 ` Jean Louis
  0 siblings, 1 reply; 10+ messages in thread
From: carlmarcos--- via Users list for the GNU Emacs text editor @ 2022-07-02 18:58 UTC (permalink / raw)
  To: Help Gnu Emacs

I am using completing-read that uses require-match, without initial-input and withoutdef.

If I press return so that the input is neither "name" or "name-mode", it seems that an empty
string is returned.  The result seems to contradict require-match being `t'.

  (let* ( (cseq '("name" "name-mode"))
          (csel (completing-read "Type: " cseq nil t nil)) )




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

* Re: result of completing-read contradicting require-match
  2022-07-02 18:58 result of completing-read contradicting require-match carlmarcos--- via Users list for the GNU Emacs text editor
@ 2022-07-02 19:20 ` Jean Louis
  2022-07-02 19:54   ` Yuri Khan
  2022-07-02 21:13   ` carlmarcos--- via Users list for the GNU Emacs text editor
  0 siblings, 2 replies; 10+ messages in thread
From: Jean Louis @ 2022-07-02 19:20 UTC (permalink / raw)
  To: carlmarcos; +Cc: Help Gnu Emacs

* carlmarcos--- via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> [2022-07-02 21:59]:
> I am using completing-read that uses require-match, without initial-input and withoutdef.
> 
> If I press return so that the input is neither "name" or "name-mode", it seems that an empty
> string is returned.  The result seems to contradict require-match being `t'.
> 

(let* ((cseq '("name" "name-mode"))
       (csel (completing-read "Type: " cseq nil t nil)))
  csel) ⇒ then after pressing ENTER I get: ""


REQUIRE-MATCH can take the following values:
- t means that the user is not allowed to exit unless the input is (or
  completes to) an element of COLLECTION or is null.
- nil means that the user can exit with any input.
- ‘confirm’ means that the user can exit with any input, but she needs
  to confirm her choice if the input is not an element of COLLECTION.
- ‘confirm-after-completion’ means that the user can exit with any
  input, but she needs to confirm her choice if she called
  ‘minibuffer-complete’ right before ‘minibuffer-complete-and-exit’
  and the input is not an element of COLLECTION.
- a function, which will be called with the input as the parameter.
  If it returns a non-nil value, the minibuffer is exited with that value.
- anything else behaves like t except that typing RET does not exit if it
  does non-null completion.

I guess that simple pressing of ENTER means "null" in this case.
But if anything is chosen, then it must be an element of the
collection.

If you then add default, then it would get the first value:
 
(let* ((cseq '("name" "name-mode"))
       (csel (completing-read "Type: " cseq nil t nil nil (car cseq))))
  csel) ⇒ then after pressing ENTER I get: "name"

other way to persist asking until you get the true result is here:
 
(defun rcd-repeat-until-not-empty-string (function &rest args)
  "Repeat FUNCTION with optional ARGS until result is not empty string."
  (let ((result))
    (while (string-empty-p (setq result (apply function args))))
      result))

(defun my-fun ()
  (let* ((cseq '("name" "name-mode"))
	 (csel (completing-read "Type: " cseq nil t nil nil nil)))
    csel))

In this case it will keep asking you until you enter something.

(rcd-repeat-until-not-empty-string 'my-fun) ⇒ "name-mode"


-- 
Jean

Take action in Free Software Foundation campaigns:
https://www.fsf.org/campaigns

In support of Richard M. Stallman
https://stallmansupport.org/



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

* Re: result of completing-read contradicting require-match
  2022-07-02 19:20 ` Jean Louis
@ 2022-07-02 19:54   ` Yuri Khan
  2022-07-02 20:07     ` Jean Louis
  2022-07-09 13:17     ` Jean Louis
  2022-07-02 21:13   ` carlmarcos--- via Users list for the GNU Emacs text editor
  1 sibling, 2 replies; 10+ messages in thread
From: Yuri Khan @ 2022-07-02 19:54 UTC (permalink / raw)
  To: carlmarcos, Help Gnu Emacs

On Sun, 3 Jul 2022 at 02:29, Jean Louis <bugs@gnu.support> wrote:

> REQUIRE-MATCH can take the following values:
> - a function, which will be called with the input as the parameter.
>   If it returns a non-nil value, the minibuffer is exited with that value.

> other way to persist asking until you get the true result is here:
>
> (defun rcd-repeat-until-not-empty-string (function &rest args)
>   "Repeat FUNCTION with optional ARGS until result is not empty string."
>   (let ((result))
>     (while (string-empty-p (setq result (apply function args))))
>       result))

Based on the quoted part of the docstring, you could probably pass a
function that returns t for an allowed value, and nil for disallowed
values, including an empty string or nil.



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

* Re: result of completing-read contradicting require-match
  2022-07-02 19:54   ` Yuri Khan
@ 2022-07-02 20:07     ` Jean Louis
  2022-07-02 20:38       ` Yuri Khan
  2022-07-09 13:17     ` Jean Louis
  1 sibling, 1 reply; 10+ messages in thread
From: Jean Louis @ 2022-07-02 20:07 UTC (permalink / raw)
  To: Yuri Khan; +Cc: carlmarcos, Help Gnu Emacs

* Yuri Khan <yuri.v.khan@gmail.com> [2022-07-02 22:56]:
> On Sun, 3 Jul 2022 at 02:29, Jean Louis <bugs@gnu.support> wrote:
> 
> > REQUIRE-MATCH can take the following values:
> > - a function, which will be called with the input as the parameter.
> >   If it returns a non-nil value, the minibuffer is exited with that value.
> 
> > other way to persist asking until you get the true result is here:
> >
> > (defun rcd-repeat-until-not-empty-string (function &rest args)
> >   "Repeat FUNCTION with optional ARGS until result is not empty string."
> >   (let ((result))
> >     (while (string-empty-p (setq result (apply function args))))
> >       result))
> 
> Based on the quoted part of the docstring, you could probably pass a
> function that returns t for an allowed value, and nil for disallowed
> values, including an empty string or nil.

Do you mean from `completing-read':

"- a function, which will be called with the input as the parameter.
  If it returns a non-nil value, the minibuffer is exited with that value."

Do you mean this:

(let* ((cseq '("name" "name-mode"))
       (csel (completing-read "Type: " cseq nil FUNCTION-HERE? nil )))
  csel)

and what would be value name for function to check it?


-- 
Jean

Take action in Free Software Foundation campaigns:
https://www.fsf.org/campaigns

In support of Richard M. Stallman
https://stallmansupport.org/



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

* Re: result of completing-read contradicting require-match
  2022-07-02 20:07     ` Jean Louis
@ 2022-07-02 20:38       ` Yuri Khan
  2022-07-02 21:58         ` Jean Louis
  0 siblings, 1 reply; 10+ messages in thread
From: Yuri Khan @ 2022-07-02 20:38 UTC (permalink / raw)
  To: Yuri Khan, carlmarcos, Help Gnu Emacs

On Sun, 3 Jul 2022 at 03:07, Jean Louis <bugs@gnu.support> wrote:

> > Based on the quoted part of the docstring, you could probably pass a
> > function that returns t for an allowed value, and nil for disallowed
> > values, including an empty string or nil.
>
> Do you mean from `completing-read':
>
> "- a function, which will be called with the input as the parameter.
>   If it returns a non-nil value, the minibuffer is exited with that value."

I do.

> Do you mean this:
>
> (let* ((cseq '("name" "name-mode"))
>        (csel (completing-read "Type: " cseq nil FUNCTION-HERE? nil )))
>   csel)

I do.

> and what would be value name for function to check it?

I meant a closure over the list of valid strings, something like this:

    (let* ((choices '("name" "name-mode"))
           (is-valid (lambda (s) (member s choices)))
           (choice (completing-read "Type: " choices nil is-valid)))
      choice)

I took the liberty to give variables sane names.
I did not test this as my currently installed Emacs does not accept
functions as the REQUIRE-MATCH argument. (Or, rather, it does but
treats them as the “anything else” case.)



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

* Re: result of completing-read contradicting require-match
  2022-07-02 19:20 ` Jean Louis
  2022-07-02 19:54   ` Yuri Khan
@ 2022-07-02 21:13   ` carlmarcos--- via Users list for the GNU Emacs text editor
  1 sibling, 0 replies; 10+ messages in thread
From: carlmarcos--- via Users list for the GNU Emacs text editor @ 2022-07-02 21:13 UTC (permalink / raw)
  To: Jean Louis; +Cc: Help Gnu Emacs


Jul 2, 2022, 19:20 by bugs@gnu.support:

> * carlmarcos--- via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> [2022-07-02 21:59]:
>
>> I am using completing-read that uses require-match, without initial-input and withoutdef.
>>
>> If I press return so that the input is neither "name" or "name-mode", it seems that an empty
>> string is returned.  The result seems to contradict require-match being `t'.
>>
>
> (let* ((cseq '("name" "name-mode"))
>  (csel (completing-read "Type: " cseq nil t nil)))
>  csel) ⇒ then after pressing ENTER I get: ""
>
>
> REQUIRE-MATCH can take the following values:
> - t means that the user is not allowed to exit unless the input is (or
>  completes to) an element of COLLECTION or is null.
> - nil means that the user can exit with any input.
> - ‘confirm’ means that the user can exit with any input, but she needs
>  to confirm her choice if the input is not an element of COLLECTION.
> - ‘confirm-after-completion’ means that the user can exit with any
>  input, but she needs to confirm her choice if she called
>  ‘minibuffer-complete’ right before ‘minibuffer-complete-and-exit’
>  and the input is not an element of COLLECTION.
> - a function, which will be called with the input as the parameter.
>  If it returns a non-nil value, the minibuffer is exited with that value.
> - anything else behaves like t except that typing RET does not exit if it
>  does non-null completion.
>
Have been playing with REQUIRE-MATCH being 'confirm, but there is not information
what to do if yao want to confirm.



> I guess that simple pressing of ENTER means "null" in this case.
> But if anything is chosen, then it must be an element of the
> collection.
>
> If you then add default, then it would get the first value:
>  
> (let* ((cseq '("name" "name-mode"))
>  (csel (completing-read "Type: " cseq nil t nil nil (car cseq))))
>  csel) ⇒ then after pressing ENTER I get: "name"
>
> other way to persist asking until you get the true result is here:
>  
> (defun rcd-repeat-until-not-empty-string (function &rest args)
>  "Repeat FUNCTION with optional ARGS until result is not empty string."
>  (let ((result))
>  (while (string-empty-p (setq result (apply function args))))
>  result))
>
> (defun my-fun ()
>  (let* ((cseq '("name" "name-mode"))
>  (csel (completing-read "Type: " cseq nil t nil nil nil)))
>  csel))
>
> In this case it will keep asking you until you enter something.
>
> (rcd-repeat-until-not-empty-string 'my-fun) ⇒ "name-mode"
>
>
> -- 
> Jean
>
> Take action in Free Software Foundation campaigns:
> https://www.fsf.org/campaigns
>
> In support of Richard M. Stallman
> https://stallmansupport.org/
>



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

* Re: result of completing-read contradicting require-match
  2022-07-02 20:38       ` Yuri Khan
@ 2022-07-02 21:58         ` Jean Louis
  0 siblings, 0 replies; 10+ messages in thread
From: Jean Louis @ 2022-07-02 21:58 UTC (permalink / raw)
  To: Yuri Khan; +Cc: carlmarcos, Help Gnu Emacs

* Yuri Khan <yuri.v.khan@gmail.com> [2022-07-02 23:39]:
> I meant a closure over the list of valid strings, something like this:

(let* ((choices '("name" "name-mode"))
       (is-valid (lambda (s) (member s choices)))
       (choice (completing-read "Type: " choices nil is-valid)))
  choice) ⇒ results with ""

So it did not work in my development version of Emacs. 

> I took the liberty to give variables sane names.
> I did not test this as my currently installed Emacs does not accept
> functions as the REQUIRE-MATCH argument. (Or, rather, it does but
> treats them as the “anything else” case.)


-- 
Jean

Take action in Free Software Foundation campaigns:
https://www.fsf.org/campaigns

In support of Richard M. Stallman
https://stallmansupport.org/



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

* Re: result of completing-read contradicting require-match
  2022-07-02 19:54   ` Yuri Khan
  2022-07-02 20:07     ` Jean Louis
@ 2022-07-09 13:17     ` Jean Louis
  2022-07-10 14:36       ` [External] : " Drew Adams
  1 sibling, 1 reply; 10+ messages in thread
From: Jean Louis @ 2022-07-09 13:17 UTC (permalink / raw)
  To: Yuri Khan; +Cc: carlmarcos, Help Gnu Emacs

* Yuri Khan <yuri.v.khan@gmail.com> [2022-07-02 22:56]:
> On Sun, 3 Jul 2022 at 02:29, Jean Louis <bugs@gnu.support> wrote:
> 
> > REQUIRE-MATCH can take the following values:
> > - a function, which will be called with the input as the parameter.
> >   If it returns a non-nil value, the minibuffer is exited with that value.
> 
> > other way to persist asking until you get the true result is here:
> >
> > (defun rcd-repeat-until-not-empty-string (function &rest args)
> >   "Repeat FUNCTION with optional ARGS until result is not empty string."
> >   (let ((result))
> >     (while (string-empty-p (setq result (apply function args))))
> >       result))
> 
> Based on the quoted part of the docstring, you could probably pass a
> function that returns t for an allowed value, and nil for disallowed
> values, including an empty string or nil.

I would like to do that Yuri. I was thinking about it, and it bothers
me. I would like to merge these two functions and use each of them
sometimes singly. The third merged one would check for both values.

(defun rcd-repeat-until-not-nil (function &rest args)
  "Repeat FUNCTION with optional ARGS until result is not nil."
  (let ((result))
    (while (not (setq result (apply function args))))
    result))

(defun rcd-repeat-until-not-empty-string (function &rest args)
  "Repeat FUNCTION with optional ARGS until result is not empty string."
  (let ((result))
    (while (string-empty-p (setq result (apply function args))))
      result))

You say to pass the function to check for allowed values. Do you mean
then to have something like 

(defun rcd-repeat- (function check-function &args) ?

Example usage would be like:

(rdc-repeat-until-something 'read-from-minibuffer)

but also

(rdc-repeat-until-something 'read-number)

and here is what I come up with, 

(defun rcd-is-something-p (thing)
  "Return TRUE if THING is something."
  (cond ((and (stringp thing) (seq-empty-p thing)) nil)
	((and (numberp thing) (not thing)) nil)
	(t t)))

(defun rcd-repeat-until-something (function &rest args)
  "Repeat FUNCTION with optional ARGS until result is something.

Result shall be non empty string or number."
  (let ((result))
    (while (rcd-is-nothing-p (setq result (apply function args))))
      result))

Then I can tell for example:

rcd-repeat-until-something 'read-from-minibuffer "Say: ") ⇒ "Something"

without being allowed to exit the loop until the result is there.

But then I am also checking for number to be non-nil as well.

-- 
Jean

Take action in Free Software Foundation campaigns:
https://www.fsf.org/campaigns

In support of Richard M. Stallman
https://stallmansupport.org/



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

* RE: [External] : Re: result of completing-read contradicting require-match
  2022-07-09 13:17     ` Jean Louis
@ 2022-07-10 14:36       ` Drew Adams
  2022-07-10 17:56         ` Jean Louis
  0 siblings, 1 reply; 10+ messages in thread
From: Drew Adams @ 2022-07-10 14:36 UTC (permalink / raw)
  To: Jean Louis, Yuri Khan; +Cc: carlmarcos@tutanota.com, Help Gnu Emacs

> I would like to merge these two functions and use each of them
> sometimes singly. The third merged one would check for both values.

I'm not following this thread.  Just happened to
read your initial statement, which sounds like
you want to repeat invoking a function until it
returns nil or non-nil.

If so, Emacs already gives you that:
`run-hook-with-args-until-failure'
(`*-success' is similar).

https://www.gnu.org/software/emacs/manual/html_node/elisp/Running-Hooks.html


_____ And `C-h v' tells you this ____

run-hook-with-args-until-failure is a built-in function in ‘C source
code’.

(run-hook-with-args-until-failure HOOK &rest ARGS)

Run HOOK with the specified arguments ARGS.
HOOK should be a symbol, a hook variable.  The value of HOOK
may be nil, a function, or a list of functions.  Call each
function in order with arguments ARGS, stopping at the first
one that returns nil, and return nil.  Otherwise (if all functions
return non-nil, or if there are no functions to call), return non-nil
(do not rely on the precise return value in this case).

Do not use `make-local-variable' to make a hook variable buffer-local.
Instead, use `add-hook' and specify t for the LOCAL argument.

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

* Re: [External] : Re: result of completing-read contradicting require-match
  2022-07-10 14:36       ` [External] : " Drew Adams
@ 2022-07-10 17:56         ` Jean Louis
  0 siblings, 0 replies; 10+ messages in thread
From: Jean Louis @ 2022-07-10 17:56 UTC (permalink / raw)
  To: Drew Adams; +Cc: Yuri Khan, carlmarcos@tutanota.com, Help Gnu Emacs

* Drew Adams <drew.adams@oracle.com> [2022-07-10 17:36]:
> > I would like to merge these two functions and use each of them
> > sometimes singly. The third merged one would check for both values.
> 
> I'm not following this thread.  Just happened to
> read your initial statement, which sounds like
> you want to repeat invoking a function until it
> returns nil or non-nil.
> 
> If so, Emacs already gives you that:
> `run-hook-with-args-until-failure'
> (`*-success' is similar).
> 
> https://www.gnu.org/software/emacs/manual/html_node/elisp/Running-Hooks.html

Looks similar, but not that it works straight how I think it
should. It runs the hook until NIL or non-NIL, and there is no
reliability what it will return. It also has purpose to run eventually
many functions, not just one. 

It is not same as what I use. These functions will return the
value from function that is invoked repeatedly until it gives
some value.

I define "nothing" as non-empty string and not null 

(defun rcd-is-nothing-p (thing)
  "Return TRUE if THING is nothing."
  (cond ((and (stringp thing) (seq-empty-p thing)) t)
	((null thing) t)
	(t nil)))

(defun rcd-repeat-until-something (function &rest args)
  "Repeat FUNCTION with optional ARGS until result is something.

Result shall be non empty string or number."
  (let ((result))
    (while (rcd-is-nothing-p (setq result (apply function args))))
      result))


I use it when for example, I do not want an empty string:

(read-from-minibuffer "Tell me: ") ⇒ ""

What I do not want is empty string, I want to make sure there is some
input, so it would keep asking me until I get selection.

(rcd-repeat-until-something 'read-from-minibuffer "Tell me: ") ⇒ "OK"

Then I have for example country selection:

(rcd-repeat-until-something 'cf-country-select) ⇒ 228

- at this moment I can choose among many countries, I could type
  "UNITED STAT-<TAB>" and get value 228

- but I cannot continue with ENTER in no way. And I do not need any
  defaults.

That spares me programming time and evaluating values, it is less
error prone for user.

Instead of:

(let ((country (cf-country-select)))
  (when country
    (do something)))

or instead of:

(let ((country (cf-country-select)))
  (if country
    (do something)
    (error "You did not select country")))

it is more convient to simply demand that selection is made and be sure of it:

(let ((country (rcd-repeat-until-something 'cf-country-select)))
  (do something with country))

thus I am sparing many `when' and `if' clauses, as it ensures
that function returns "something".


-- 
Jean

Take action in Free Software Foundation campaigns:
https://www.fsf.org/campaigns

In support of Richard M. Stallman
https://stallmansupport.org/



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

end of thread, other threads:[~2022-07-10 17:56 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-07-02 18:58 result of completing-read contradicting require-match carlmarcos--- via Users list for the GNU Emacs text editor
2022-07-02 19:20 ` Jean Louis
2022-07-02 19:54   ` Yuri Khan
2022-07-02 20:07     ` Jean Louis
2022-07-02 20:38       ` Yuri Khan
2022-07-02 21:58         ` Jean Louis
2022-07-09 13:17     ` Jean Louis
2022-07-10 14:36       ` [External] : " Drew Adams
2022-07-10 17:56         ` Jean Louis
2022-07-02 21:13   ` carlmarcos--- via Users list for the GNU Emacs text editor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).