emacs-devel
[Top][All Lists]
Advanced

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

Info-mode patch


From: Arthur Miller
Subject: Info-mode patch
Date: Mon, 26 Jun 2023 18:09:25 +0200
User-agent: Gnus/5.13 (Gnus v5.13)

After some re-writes and tests with multiple frames and windows; it is possible
to make all commands be callable from other windows, with relatively little
effort, but it is not just to wrap them in with-selected-window.

Care has to be taken to ensure all prompts are presented to the user on the
selected frame, so they don't interfere with the window manager if user has
focus follow mouse enabled.

Some commands call themselves recursively, or they call other info commands
internally. Those commands now take an optional 'window' parameter to avoid
prompting user multiple times in what would be percieved as a single command
from the user perspective.

In general, I have tried to minimze prompting as much as possible; hopefully
user is prompted only when there is ambiguity about which window to act on.

If user is already in an info window, all commands act by default on that
window, so user can use single keys to invoke info commands. This is the same
behavior as pre-patch. If there are multiple info windows, then the user can
press C-u to act on another info window. If there are more then 2 other info
windows, then the user is prompted to choose one, otherwise the "other info
window" is selected automatically (no prompting).

With numeric prefix, C-n, if there is *info*<n>, that window is chosen. If there
are multiple windows with the same number, say two *info*<1> windows, then the
user is prompted which one to choose.

To minimize both prompting, and typing of the prefix; it is also possible to
have multiple info windows, and to create a "connection" to a particular info
window. Consider info buffers *info*<1> and *info*<2>, and say user works with
files "foo" and "bar". It is possible to press C-u C-u before any Info command
and choose *info*<1> in foo, and C-u C-u some-info-command and select *info*<2>
in bar, to create a connection for foo and bar.

After the connection is created the user can just press Info-mode prefix key to
execute info commands in foo or bar and not be prompted which info window to
choose, and not having to type C-1 or C-2 either. To override the default
"link", again user can press C-u to execute in other info window.

Problems:

1. Some commands are already using nummeric prefix, which clashes with using
numeric prefix to choose an info window.

Examples:

info-next-reference
info-prev-reference

When called from other info window, with C-u prefix, the reference jumps four
references instead of one. That because a count is expected in prefix arg, so
when C-u is seen, Emacs jumps 4 refereces forward. I am not sure how, or if it 
is
possible to fix that one, so I have left it as-is (user can still switch to the
buffer and press TAB in which case it works normally).

2. Due the fact that interactive form has to be the very first form in a 
command,
we can't just wrap all commands into with-selected-frame, especially when a
command is called from Lisp. To avoid unnecessary extra prompts, I need a way to
communicate that user has already selected a window. I have tried to declare an
optional variable in function declaration, but interactive form does not seem to
have access to those? For example like this:

#+begin_src emacs-lisp
(defun info-finder (&optional keywords window)
  (interactive
   (let ((w (or window (info-window))))
    ...
#+end_src

but Emacs complains that window is an undefined variable when in interactive
call. Perhaps I am just not familiar enough with interactive forms, but as I
understand I would have to make it a non-optional argument in the function
signature. But that would mess signatures for functions and potentially break
3rd party applications and peoples setups, so I don't think it is an option. But
if I just misunderstand how to write interactive forms, and someone has a better
way, I am happy to learn it.

My option, was to use either a global variable, or closure, or as I did, to 
stash the variable into the symbol plist. I tried with closures, but then I got
some cconv--helper-something as unknown symbol when I was building Emacs. If I
forward declare it in loadup.el, then it works fine. I haven't looked into
cconv.el why is that, but I choose to skipp that, and used the plists instead.

3. Tests

I did attempt to write few; I wanted mostly to test all commands if called from
lisp (non-interactively). However, since most of the functionality require live
buffers and visible windows, I am not really sure how to make a test that work
in batch, without popping and hiding stuff on the screen. Also mouse cursor
position seem to mess up bit with focus when I split windows from lisp and try
to manipulate visible bufers, so I have gave up on automated tests.

I have factored out everything about selecting window to act on, into one a bit
more general function called 'find-window-for-help' and one, more Info specific,
'info-window'. I am not really happy how I have implemented those two, I think
they look too messy, but they seem to work for now, and I am already dizzy from
testing all kind of setups and selections, so I they'll have to do for now.

If someone would prefer different strategy for the interaction, for example
no prompting at all, than info-window is the place to change that, since all
other commands call that one to obtain a window to act on.

I have tested each and every command in all those possible combinations, and
paths I have described above, but I would not be surprised if I have still
missed some (or many? :)).

Anyway, here is a patch; this time only for Info mode, but it is easily to
produce one for help-mode if this one works in regard to the user interaction,
and how it is implemented.

Attachment: 0001-Use-Info-mode-commands-from-any-buffer.patch
Description: Text Data


reply via email to

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