all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* How do I make `man' run some code after the manpage is fully rendered?
@ 2020-12-29  4:55 Eduardo Ochs
  2020-12-29  6:19 ` Stefan Monnier
  0 siblings, 1 reply; 3+ messages in thread
From: Eduardo Ochs @ 2020-12-29  4:55 UTC (permalink / raw)
  To: help-gnu-emacs

Hi list,

How do I make `man' run some code after the manpage is fully
rendered? In my package "eev" I have several functions that work
as sexp hyperlinks and that accept extra arguments indicating
strings to search for... for example, this sexp

  (find-man "bash(1)" "single-character")

should work as a hyperlink to the first occurrence of the
string "single-character" in the bash manpage... ok, let me be
more precise. The sexp above should do this:

  1) run (man "bash(1)") with settings to make it display the manpage
     in the current window,

  2) wait until the manpage is fully rendered,

  3) go to (point-min),

  4) run (search-forward "single-character").

For doing (2) I had an ugly solution usign a defadvice that stopped
working in some version of Emacs 25 (if I remember correctly)... I
spent some hours today trying to reimplement (2) by redefining `beep'
temporarily, and I got the code below, but when `man' has to render a
big page it calls `beep' before the page is totally ready... see the
comments and the tests below.

Any hints would be greatly appreciated. Btw: is this the right place
for asking this? Or should I try emacs-devel, or what?

  Cheers, thanks in advance,
    Eduardo Ochs
    http://angg.twu.net/#eev
    http://angg.twu.net/emacsconf2019.html
    http://angg.twu.net/emacsconf2020.html



Here is the code:
-- snip, snip --


;; This is a miniature of the real `ee-goto-position'. See:
;; http://angg.twu.net/LATEX/2019emacsconf.pdf#page=5
;; http://angg.twu.net/eev-intros/find-refining-intro.html#1
;; http://angg.twu.net/eev-current/eev-blinks.el.html#ee-goto-position
;;
(defun ee-goto-position-mini (&rest pos-spec-list)
  (when pos-spec-list ; if pos-spec-list is non-nil
    (goto-char (point-min)) ; then go to (point-min)
    (dolist (str pos-spec-list) ; and for each string in pos-spec-list
      (search-forward str)))) ; search forward for that string

(setq ee-man-bufname       nil)
(setq ee-man-pos-spec-list nil)

(defun ee-man-goto-pos-spec-list ()
  (with-current-buffer ee-man-bufname
    (apply 'ee-goto-position-mini ee-man-pos-spec-list)))

(defun ee-man-beep ()
  "A hack: `ee-find-man' makes `man' run this instead of `beep'."
  (ee-man-goto-pos-spec-list)
  (switch-to-buffer ee-man-bufname nil t))

(defun ee-find-man (topic &rest pos-spec-list)
  "Like (man TOPIC), but also searches for the strings in POS-SPEC-LIST.
Ideally this function should run `ee-man-goto-pos-spec-list'
after the manpage is fully rendered, but I haven't been able to
find a way to do that - HELP! It seems that it is calling
`ee-man-beep' after the man buffer is ready and the backgound
processes are all set up, without waiting for the background
processes to finish..."
  (setq topic (Man-translate-references topic))
  (setq ee-man-bufname (concat "*Man " topic "*"))
  (setq ee-man-pos-spec-list pos-spec-list)
  (cl-letf ((Man-notify-method 'polite)
            ((symbol-function 'beep) (symbol-function 'ee-man-beep)))
    (man topic)))


;; Tests:
;; (require 'man)
;; (ee-find-man "bash")
;; (ee-find-man "bash(1)")
;; (ee-find-man "bash(1)" "single-character")



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: How do I make `man' run some code after the manpage is fully rendered?
  2020-12-29  4:55 How do I make `man' run some code after the manpage is fully rendered? Eduardo Ochs
@ 2020-12-29  6:19 ` Stefan Monnier
  2021-01-02  9:04   ` Eduardo Ochs
  0 siblings, 1 reply; 3+ messages in thread
From: Stefan Monnier @ 2020-12-29  6:19 UTC (permalink / raw)
  To: help-gnu-emacs

> How do I make `man' run some code after the manpage is fully
> rendered? In my package "eev" I have several functions that work
> as sexp hyperlinks and that accept extra arguments indicating
> strings to search for... for example, this sexp

If you need to adjust the content of the page, then you can try using
the `Man-cooked-hook`.  But if you need to move to a particular position
that won't help because man moves to page 1 after running this hook.
I think withthe current man.el code you'll need an advice on
`Man-bgproc-sentinel`.


        Stefan




^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: How do I make `man' run some code after the manpage is fully rendered?
  2020-12-29  6:19 ` Stefan Monnier
@ 2021-01-02  9:04   ` Eduardo Ochs
  0 siblings, 0 replies; 3+ messages in thread
From: Eduardo Ochs @ 2021-01-02  9:04 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: help-gnu-emacs

Perfect, thanks!!!

The code below - with (advice-add 'Man-bgproc-sentinel ...) - works in
at least Emacs25.2, Emacs26, and Emacs27 - I got a segfault trying to
compile Emacs25.1 here.

The code is just 32 lines long, so I thought that it would be worth
sharing it with the list.

  Cheers! =)
    Eduardo Ochs
    http://angg.twu.net/#eev

Here it goes:


  (defvar ee-find-man-flag          nil "See `find-man'.")
  (defvar ee-find-man-buffer        nil "See `find-man'.")
  (defvar ee-find-man-pos-spec-list nil "See `find-man'.")

  (defun find-man (manpage &rest pos-spec-list)
    "Hyperlink to a manpage."
    (interactive (list (ee-manpagename-ask)))
    (setq manpage (Man-translate-references manpage))
    ;;
    ;; Set the variables used by `ee-find-man-goto-pos-spec'.
    (setq ee-find-man-flag t)
    (setq ee-find-man-buffer (concat "*Man " manpage "*"))
    (setq ee-find-man-pos-spec-list pos-spec-list)
    ;;
    ;; See: (find-evardescr 'Man-notify-method "pushy" "current window")
    (let ((Man-notify-method 'pushy))
      ;;
      ;; This call to `man' will run `ee-find-man-goto-pos-spec' after
      ;; the manpage is rendered - because of the `advice-add' below.
      ;; This is a dirty trick!... see:
      ;; https://lists.gnu.org/archive/html/help-gnu-emacs/2020-12/msg01100.html
      ;; https://lists.gnu.org/archive/html/help-gnu-emacs/2020-12/msg01102.html
      (man manpage)))

  (defun ee-find-man-goto-pos-spec (&rest rest)
    "An internal function used by `find-man'."
    (when ee-find-man-flag
      (setq ee-find-man-flag nil)
      (with-current-buffer ee-find-man-buffer
        (apply 'ee-goto-position ee-find-man-pos-spec-list))))

  (advice-add 'Man-bgproc-sentinel :after 'ee-find-man-goto-pos-spec)


On Tue, 29 Dec 2020 at 03:19, Stefan Monnier <monnier@iro.umontreal.ca> wrote:
>
> If you need to adjust the content of the page, then you can try using
> the `Man-cooked-hook`.  But if you need to move to a particular position
> that won't help because man moves to page 1 after running this hook.
> I think withthe current man.el code you'll need an advice on
> `Man-bgproc-sentinel`.
>
>         Stefan



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-01-02  9:04 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-12-29  4:55 How do I make `man' run some code after the manpage is fully rendered? Eduardo Ochs
2020-12-29  6:19 ` Stefan Monnier
2021-01-02  9:04   ` Eduardo Ochs

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.