help-gnu-emacs
[Top][All Lists]
Advanced

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

How do I make `man' run some code after the manpage is fully rendered?


From: Eduardo Ochs
Subject: How do I make `man' run some code after the manpage is fully rendered?
Date: Tue, 29 Dec 2020 01:55:11 -0300

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")



reply via email to

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