emacs-devel
[Top][All Lists]
Advanced

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

Re: Control help- and Info-mode buffers from other buffers


From: Arthur Miller
Subject: Re: Control help- and Info-mode buffers from other buffers
Date: Wed, 31 May 2023 07:55:31 +0200
User-agent: Gnus/5.13 (Gnus v5.13)

Juri Linkov <juri@linkov.net> writes:

>> I have actually tried to find some general way to do this
>> programmatically with any buffer, but thus far, I don't see any
>> general way that is both efficient and 100% failsafe.
>
> Please share your experience what have you tried

Hi Juri;

I have tried several quite different things, so that would be quite a long mail
:-).

In that particular place, I am actually referring to something different
then what you think of, I believe. As I wrote to Manuel, I was basically doing
programmatic what I have done manually with the patch. Problem with the 
programmatic way
was too much processing, and some functions didn't work. The former could be
perhaps helped by using a macro to do it at compile time, and the latter is
perhaps lack of lisp-fu on my side. I don't know, but the idea was to advise the
already prefixed commands in a mode-map, and to generate new commands for those
that are not prefixed. The advice switches to the buffer, executes the original
commands, and switches back. Something like this (just the advising and 
generation part):

#+begin_src emacs-lisp
(defun remote--make-advice-body (buffer-name)
  "Create lambda function for buffer with name BUFFER-NAME."
  #'(lambda (fn &rest args)
      (let ((previous (selected-window))
            (buffer (get-buffer buffer-name))
            (window (get-buffer-window buffer-name)))
        (unwind-protect
            (when (get-buffer buffer)
              (unless (window-live-p window)
                (display-buffer buffer))
              (select-window window)
              (apply #'call-interactively fn args))
          (select-window previous)))))

(defun remote--make-advice-function (buffer-name)
  "Create advice function for buffer with name BUFFER-NAME."
  (let ((advice-name
         (intern (format "help-remote--%s-advice-fn" buffer-name))))
    (unless (fboundp advice-name)
      (defalias advice-name (remote--make-advice-body buffer-name)))
    advice-name))

(defun remote--advise (fn buffer-name advised)
  "Advice function FN to run in buffer with name BUFFER-NAME."
  (let ((advice (remote--make-advice-function buffer-name)))
    (add-to-list advised (cons fn advice))
    (advice-add fn :around advice)))

(defun remote--gen-cons (binding prefix buffer-name advised)
  "Ensure BINDING in buffer named BUFFER-NAME uses symbol prefixed with PREFIX."
  (let ((name (symbol-name (cdr binding)))
        (symb (cdr binding)))
    (unless (string-match-p prefix name)
      (setq symb (intern (concat prefix name)))
      (defalias symb (symbol-function (cdr binding))))
    (remote--advise symb buffer-name advised)
    (cons (car binding) symb)))
#+end_src

However I was not able to trick Emacs to trust me
its executing in the "correct" environment. Also, there was too much
processing in info mode. Some methods worked well; for example everything in
help-mode, but some functions that asks for user input in info-mode, for example
info-menu, didn't work at all.

> since it would be nice to have a general function
> that will delegate key presses to any window,

I think it is similar, but still a different problem then remotely executing 
commands available in other buffer. To start with there is a nice trick
via pre/post command hooks, someone posted to me on Reddit:

https://www.reddit.com/r/emacs/comments/x0r0pe/share_your_otherwindow_commands/

It works quite well in some cases, but not in all. For example it does not work
with Info-menu when invoked from other buffer either.

> not just the hard-coded *Help* and *Info*.

I understand  your sentiment, and I agree that it might be useful to have
a way to delegate input to other window, but I also think we would still like
to wrap such generic command into some hard-coded cases to save typing. For
example in case of generic command and multiple windows, you will have to ask
user which window to execute in. In order to save that prompting and additional
typing on user part, it is handy to hard code such generic function to certain
cases like help and info here.

To shorten, I haven't found a good way to delegate input to other windows and I
am not sure if it will even work as a general idea at all. Perhaps for some
cases, it would work, but not for all. I am inclined to believe that this is the
wrong side to attack the problem. Perhaps it is better to write commands that
are aware that they could be executed from other buffers than the one they act 
on?
In that case command could prompt the user for a window or buffer to act on and
auto switch to that window and back. Since the command usually knows which mode
it belongs, it could even filter out windows/buffer that does not have that
mode activated, or some other feature it requires. It would be relatively simple
to implement with prefix-argument?

But perhaps I am wrong too. Perhaps  you have something different? :)




reply via email to

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