emacs-devel
[Top][All Lists]
Advanced

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

Re: Info-mode patch


From: Arthur Miller
Subject: Re: Info-mode patch
Date: Wed, 28 Jun 2023 01:09:57 +0200
User-agent: Gnus/5.13 (Gnus v5.13)

Juri Linkov <juri@linkov.net> writes:

>>> But it seems this is not enough because with-selected-frame
>>> still fails to switch focus to another frame.  You need also
>>> to use select-frame-set-input-focus.
>> Where it fails? For me it prompts me on correct frame. I didn't want to 
>> switch
>> focus on the info frame. I am aware of select-frame-set-input-focus, have 
>> used
>> it in some test actually.
>
> Probably the behaviour depends on the window manager.

Yes, I am quite sure it isn't "probably" but "surely" :), as I wrote earlier by
the way.

> With my window manager with-selected-frame displays
> the prompt in another frame, but input is inserted
> into the original buffer.  Maybe we should have
> a new option whether to use select-frame-set-input-focus?

I am not sure I understand what you mean with input being inserted in the
original buffer.

>> Have you tested *everything*? Interactively and from lisp?
>
> I see no problems with this both interactively and from lisp:

If you don't care to ask the user which window to choose when ambigous, then you
don't have to care about this at all. If you don't want to take care of
multiple windows with possibly ambigous names, user misstyping a name and
possibly irregular name, then you don't need to prompt the user at all, just
take the first info buffer you find or force user to *always* select manually a
window and you are all good. But in my opinion it is not hard to have it 
slightly
more polished and automated as I did. 

> #+begin_src emacs-lisp
> (defmacro with-selected-window-frame (window &rest body)
>   `(let ((old-frame (selected-frame))
>          (frame (window-frame ,window)))
>      (unless (eq frame old-frame)
>        (select-frame frame 'norecord)
>        (select-frame-set-input-focus frame 'norecord))
>      (prog1 (with-selected-window ,window
>               ,@body)
>        (select-frame old-frame 'norecord)
>        (select-frame-set-input-focus old-frame 'norecord))))
>
> (defun Info-index-other-window (topic &optional window)
>   (interactive
>    (with-selected-window-frame (info-window)
>      (append (eval (cadr (interactive-form 'Info-index)))
>              (list (selected-window)))))
>   (with-selected-window (or window (info-window))
>     (Info-index topic)))
> #+end_src
>
> You can't avoid adding the window argument.  Otherwise, you need
> to invent such hacks as sending the window selected by the user
> to the command body via a symbol property.

> But in the wrapper command like above there is no problem
> of adding the window argument to the new command.

I wasn't familiar with interactive form enough and didn't know how to connect
the optional argument from within interactive form. Symbol-plist was just
workaround for lack of a better knowledge :). I stated that explicitly in the
mail with the patch, but you perhaps didn't have time to read the mail?

Anyway, I understand now how is it done:

      (append (eval (cadr (interactive-form 'Info-index)))
              (list (selected-window)))

I have to return a list of all arguments from interactive form; it was that
simple. Thanks for the example.

> Maybe it's possible even to write a macro that will generate
> such wrapper commands automatically from existing commands.
>
> It seems you assume that all commands should take a window.

Why would I assume that? I wrote explicitly which commands were extended with
an optional window argument and why. I don't feel for repeating entire text 
here,
if you have interest, please take a look at the original email, you don't seem
to have read it all. That mail answered your opening question, but I didn't want
to point it out earlier to not sound impolite, instead I tried to clarify the
problems and choices further.

> But there are no such assumption for most commands that work
> only in the selected window.

I am not sure what you are trying to say here. If we have several live buffers
and wish to act on one, then the user has to choose one somehow, no? We can
either try to automate stuff as I have tried in this patch, by prompting the
user in ambigous case when system can't figure it on its own, or we can have a 
dumb system that forces user to *always* select a window prior to acting on a
buffer. If you take a look at the original mail you will understand which 
commands
has got the optional window argument and why, but if you don't prompt the user,
than you don't need that argument at all.

There is also a problem of prompting and input focus. As I wrote in response to
Eli, each command is its own little program, and can prompt user for whatever
reason whenever. Thus each command should be written with the assumption that
input should be presented to user on the frame where user types and with
assumption that user is not executing it from the buffer/window on which it
should act. You can achieve all this with tools already in Emacs, no need to
introduce any new concepts or macros, and it will also work regardless of the
window manager (I think).

It is just that the old commands are not written with those assumptions, so I
rewrote Info commands in this patch. I am not sure you can achive that
with wrapping, but perhaps there is a way, you can try.

In my opinion wrapping is OK if we for some reason can't alter the code, but in
the case of Info and help mode, I don't see such reason, especially since it is
possible to do everything backwards compatible. On the negative side,
wrapping introduces double set of commands, so what are you saving? You are
wrapping code from "outside", while I have done it from "inside", but overall,
the principle is the same. On a plus side for wrappers is that you can actually
write a codegen for wrappers, hopefully in form of a macro and it will work for
other modes. So it is not only negatives, but you could also have both
approaches at the same time too :).










reply via email to

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