From: Marcin Borkowski <mbork@wmi.amu.edu.pl>
To: help-gnu-emacs@gnu.org
Subject: Re: How to write the "interactive" form for a command acting on a region
Date: Wed, 14 Jan 2015 00:06:27 +0100 [thread overview]
Message-ID: <874mru5li0.fsf@wmi.amu.edu.pl> (raw)
In-Reply-To: <87twzuwbk7.fsf@kuiper.lan.informatimago.com>
On 2015-01-13, at 23:38, Pascal J. Bourguignon <pjb@informatimago.com> wrote:
> Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:
>
>> Hi all,
>>
>> so I want to have a function which should do something on the region.
>> If no region is active, I want it to act on the whole buffer. If called
>> from Lisp code, I want to be able to supply "begin" and/or "end"
>> parameters, which (if nil) should default to (point-min) and
>> (point-max). Finally, I want my command to behave differently depending
>> on whether it was called interactively or programmatically.
>
> If you want a different behavior, then you should have different
> functions:
Why? In many Emacs functions/commands it works like what I want to
have. What's wrong with this approach? And in fact, I /don't/ want
different behavior: I want both the function and the command to
(essentially) do the same, with the (minor) difference that the function
will return a value and the command will print a message.
> (defun my-FUNCTION (…)
> …)
>
> (defun my-COMMAND (…)
> (interactive …)
> …
> (my-function …)
> …)
>
> (defun my-command (start end)
> (interactive "r")
> (message "start=%s end=%s" start end))
>
> A region is always defined, whether transient-mark-mode is on or off,
> and whether the region is active or not.
Yes, of course. (Incidentally, I didn't notice your snippet above at
first, and just to make sure, I wrote an identical one, differing only
in the names of the parameters and the text of the message;-).)
> Therefore interactive "r" will always give you start and end points.
> You could have a command such as:
>
> (defun my-command (start end)
> (interactive "r")
> (if (use-region-p) ; region is active
> (my-function start end)
> (my-function (point-min) (point-max))))
This does not seem very lispy to me, though most probably have much less
experience than you...
> Otherwise, if the behavior of your command and your function was the
> same, you could write a single command, using (require 'cl) to deal with
> the default values.
I'll have to check cl (I use it anyway for (incf)), but again: what's
wrong with (or start (point-min))?
> But since you want to force the arguments when it's called interactively
> without an active region, you will have to duplicate some code.
This I don't understand. (Though I /do/ have some duplication, see
below.)
> Separating the function and command is probablyh preferable in your
> situation.
>
> (require 'cl)
> (defun* my-command (&optional (start (point-min)) (end (point-max)))
> (interactive "r")
> (when (and (called-interactively-p)
> (not (use-region-p)))
> (setf start (point-min)
> end (point-max)))
> …)
No offence, but this seems plain ugly for me, especially the setf part.
IMHO, using the (interactive) form to define default arguments is more
elegant, though of course I also have some duplicate code (point-min and
point-max appear twice - though for different reasons, so to speak -
which I don't like). I can't see why your proposal is better - I would
prefer to use defun and not defun*, and the Emacs manual says it's
better to use the interactive form and not called-interactively-p (and
I can see the reason).
Regards,
--
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Faculty of Mathematics and Computer Science
Adam Mickiewicz University
next prev parent reply other threads:[~2015-01-13 23:06 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <mailman.17860.1421186716.1147.help-gnu-emacs@gnu.org>
2015-01-13 22:38 ` How to write the "interactive" form for a command acting on a region Pascal J. Bourguignon
2015-01-13 23:06 ` Marcin Borkowski [this message]
[not found] ` <mailman.17861.1421190402.1147.help-gnu-emacs@gnu.org>
2015-01-14 2:04 ` Pascal J. Bourguignon
2015-01-14 3:49 ` Drew Adams
2015-01-13 22:05 Marcin Borkowski
2015-01-13 23:24 ` Nicolas Richard
2015-01-13 23:35 ` Marcin Borkowski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=874mru5li0.fsf@wmi.amu.edu.pl \
--to=mbork@wmi.amu.edu.pl \
--cc=help-gnu-emacs@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).