[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")
- How do I make `man' run some code after the manpage is fully rendered?,
Eduardo Ochs <=