From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Thorsten Jolitz Newsgroups: gmane.emacs.help Subject: Re: Suppress user-prompting when calling commands in programs Date: Sat, 14 Jun 2014 10:22:36 +0200 Message-ID: <87ioo3vr1v.fsf@gmail.com> References: <87r42skjd8.fsf@gmail.com> <877g4k7ux4.fsf@geodiff-mac3.ulb.ac.be> <87mwdfvrqd.fsf@gmail.com> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1402734203 27798 80.91.229.3 (14 Jun 2014 08:23:23 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 14 Jun 2014 08:23:23 +0000 (UTC) To: help-gnu-emacs@gnu.org Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Sat Jun 14 10:23:13 2014 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1WvjF2-0006JH-DI for geh-help-gnu-emacs@m.gmane.org; Sat, 14 Jun 2014 10:23:12 +0200 Original-Received: from localhost ([::1]:34587 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WvjF1-0005Ph-Tv for geh-help-gnu-emacs@m.gmane.org; Sat, 14 Jun 2014 04:23:11 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:46806) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WvjEm-0005PI-Bc for help-gnu-emacs@gnu.org; Sat, 14 Jun 2014 04:23:02 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WvjEg-0004P4-CI for help-gnu-emacs@gnu.org; Sat, 14 Jun 2014 04:22:56 -0400 Original-Received: from plane.gmane.org ([80.91.229.3]:41504) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WvjEg-0004O4-5c for help-gnu-emacs@gnu.org; Sat, 14 Jun 2014 04:22:50 -0400 Original-Received: from list by plane.gmane.org with local (Exim 4.69) (envelope-from ) id 1WvjEf-00060b-JE for help-gnu-emacs@gnu.org; Sat, 14 Jun 2014 10:22:49 +0200 Original-Received: from g231110097.adsl.alicedsl.de ([92.231.110.97]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Sat, 14 Jun 2014 10:22:49 +0200 Original-Received: from tjolitz by g231110097.adsl.alicedsl.de with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Sat, 14 Jun 2014 10:22:49 +0200 X-Injected-Via-Gmane: http://gmane.org/ Original-Lines: 108 Original-X-Complaints-To: usenet@ger.gmane.org X-Gmane-NNTP-Posting-Host: g231110097.adsl.alicedsl.de User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) Cancel-Lock: sha1:jQdxDrIvEcoxoawOPqUNdzo4p8w= X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 80.91.229.3 X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.help:98242 Archived-At: Thorsten Jolitz writes: > Stefan Monnier writes: > >>> I tried convincing upstream before and never made it! And I actually >>> understand the authors of code like that and even copied that technique >>> sometimes, because it might be harder to write the interactive spec for >>> both interactive and programmatical use than to write the function >>> itself, and then there is no need for a wrapper command or interactive >>> (lambda ...) expression when it comes to define a key for that command. >> >> I don't know what complications you're referring to. >> >> In 99% of the cases you can just turn >> >> (defun foo (&optional arg) >> (interactive "P") >> (let ((bar (org-icompleting-read ...))))) >> >> into >> >> (defun foo (bar &optional arg) >> (interactive >> (list (org-icompleting-read ...) current-prefix-arg)) >> >> I'm not saying it's always perfect, but there's clearly some difference >> between my experience and yours, so if you give some examples, it would help. [Ups, that one was send to early accidentally ...] Maybe I just find the Emacs Lisp Manual too dense and lacking examples and templates for using lists in the interactive spec? This is more or less or there is: ,------------------------------------------------------------------- | * It may be a Lisp expression that is not a string; then it should | be a form that is evaluated to get a list of arguments to pass | to the command. Usually this form will call various functions to | read input from the user, most often through the minibuffer (see | Minibuffers) or directly from the keyboard (see Reading Input). | | Providing point or the mark as an argument value is also common, | but if you do this and read input (whether using the minibuffer | or not), be sure to get the integer values of point or the mark | after reading. The current buffer may be receiving subprocess | output; if subprocess output arrives while the command is | waiting for input, it could relocate point and the mark. | | Here's an example of what not to do: | | (interactive | (list (region-beginning) (region-end) | (read-string "Foo: " nil 'my-history))) | | Here's how to avoid the problem, by examining point and the mark | after reading the keyboard input: | | (interactive | (let ((string (read-string "Foo: " nil 'my-history))) | (list (region-beginning) (region-end) string))) `------------------------------------------------------------------- But what about a case like this, a command with several optional args, that are not always necessary. How to give the user the option to decide for which args he wants to give input (and use the defaults for the others)? Where to put the (prefix) 'arg argument in this case? How does Emacs know which of the optional arguments should be the prefix-argument? Do I need a "P" or "p" then somewhere in the spec when I add 'arg' to the arguments list? I came up with something like this, but most likely inspired by other elisp libraries, not by the manual. Is it a good solution? Hard to tell, since there are no templates or best practice examples given for more complex interactive specs in the manual. #+begin_src emacs-lisp ;; Start a REPL (defun iorg-scrape-repl (&optional port host how local) "Run inferior Picolisp and setup process for GUI-scripting." (interactive (cond ((equal current-prefix-arg nil) nil) ((equal current-prefix-arg '(4)) (list (read-number "Port: "))) ((equal current-prefix-arg '(16)) (list (read-number "Port: ") (read-string "Host: "))) ((equal current-prefix-arg '(32)) (list (read-number "Port: ") (read-string "Host: ") (read-string "How: "))) (t (list (read-number "Port: ") (read-string "Host: ") (read-string "How: ") (read-string "Local: "))))) (let* ((hst (or host "localhost")) (prt (or port 5000)) [...] #+end_src -- cheers, Thorsten