all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Stefan Kangas <stefan@marxist.se>
To: Juri Linkov <juri@jurta.org>
Cc: Reuben Thomas <rrt@sc3d.org>, 12098@debbugs.gnu.org
Subject: bug#12098: How to trap errors in man?
Date: Wed, 19 Aug 2020 12:49:39 +0000	[thread overview]
Message-ID: <CADwFkmnieZFT=pLca1ZyREEVQ5pRQrWXOAib-n6ZH5P2X23WsQ@mail.gmail.com> (raw)
In-Reply-To: <87txwnxbbx.fsf@mail.jurta.org> (Juri Linkov's message of "Wed, 01 Aug 2012 11:23:30 +0300")

severity 12098 wishlist
tags 12098 + patch moreinfo
thanks

Juri Linkov <juri@jurta.org> writes:

>> There are plenty of things that freeze the session for much longer
>> than the fraction of a second it takes to format most man pages! Even
>> bash(1) only takes about a second.
>
> You are right, the largest man page `man bash' takes just 2 sec to format,
> so perhaps it makes no sense to run the man command asynchronously nowadays.
>
> The patch below introduces a new variable `Man-async' whose value
> could be set to nil to run `man' synchronously.
>
>> Are you sure about that bug number? I looked and it seems to be about
>> window layout.
>
> That's right, currently the async mode of man has its peculiarities:
> it arranges window layouts after formatting is done, so formatting
> can't fit into window layout.
>
> So perhaps we should have two asynchronous modes:
> 1. delay changes in window configuration
>    until the process is finished and man page is formatted.
> 2. prepare window layout before formatting;
>
> I'm still not sure whether we need the former for backward compatibility,
> so `Man-async' could have a special value for it.
>
>> I can't see how to use this to communicate back to a particular caller
>> that man failed; help?
>
> I don't know if it's possible with lack of multi-threading
> to yield to the command loop while waiting for the process output.
> But with the following patch you can run `man' synchronously
> by using just `(let ((Man-async nil)) (man "bash"))' when its
> default value is not nil.

This patch adds the possibility to run man asynchronously.  I'm not sure
it's worth the added complexity.  Any other opinions?

> === modified file 'lisp/man.el'
> --- lisp/man.el	2012-07-11 23:13:41 +0000
> +++ lisp/man.el	2012-08-01 08:23:10 +0000
> @@ -144,6 +144,20 @@ (defcustom Man-reverse-face 'highlight
>    :type 'face
>    :group 'man)
>
> +(defcustom Man-async nil
> +  "Synchronicity of the manpage command.
> +If nil, run the manpage command synchronously.
> +If t, run the manpage command asynchronously
> +preparing output windows before the process is started.
> +If the value is `delayed', run the manpage command
> +asynchronously but delay changes in window configuration
> +until the process is finished and man page is formatted."
> +  :type '(choice (const :tag "Synchronous" nil)
> +                 (const :tag "Asynchronous" t)
> +                 (const :tag "Delayed" delayed))
> +  :group 'man
> +  :version "24.2")
> +
>  ;; Use the value of the obsolete user option Man-notify, if set.
>  (defcustom Man-notify-method (if (boundp 'Man-notify) Man-notify 'friendly)
>    "Selects the behavior when manpage is ready.
> @@ -904,16 +920,37 @@ (defun Man-getpage-in-background (topic)
>  Return the buffer in which the manpage will appear."
>    (let* ((man-args topic)
>  	 (bufname (concat "*Man " man-args "*"))
> -	 (buffer  (get-buffer bufname)))
> +	 (buffer  (get-buffer bufname))
> +	 (procbufname (concat " " bufname))
> +	 procbuffer)
>      (if buffer
>  	(Man-notify-when-ready buffer)
>        (require 'env)
> -      (message "Invoking %s %s in the background" manual-program man-args)
> -      (setq buffer (generate-new-buffer bufname))
> -      (with-current-buffer buffer
> -	(setq buffer-undo-list t)
> -	(setq Man-original-frame (selected-frame))
> -	(setq Man-arguments man-args))
> +      (cond
> +       ((eq Man-async 'delayed)
> +	(message "Invoking %s %s in the background" manual-program man-args)
> +	(setq buffer (generate-new-buffer bufname))
> +	(with-current-buffer buffer
> +	  (setq buffer-undo-list t)
> +	  (setq Man-original-frame (selected-frame))
> +	  (setq Man-arguments man-args)))
> +       (t
> +	(setq buffer (generate-new-buffer bufname))
> +	(setq procbuffer (generate-new-buffer procbufname))
> +	;; Display empty output buffer.
> +	(unless (memq Man-notify-method '(polite quiet meek))
> +	  (Man-notify-when-ready buffer))
> +	(with-current-buffer buffer
> +	  (insert (format "Invoking %s %s in the background\n"
> +			  manual-program man-args))
> +	  (setq buffer-undo-list t)
> +	  (setq Man-original-frame (selected-frame))
> +	  (setq Man-arguments man-args))
> +	(with-current-buffer procbuffer
> +	  (setq buffer-undo-list t)
> +	  (setq Man-original-frame (selected-frame))
> +	  (setq Man-arguments man-args))))
> +
>        (let ((process-environment (copy-sequence process-environment))
>  	    ;; The following is so Awk script gets \n intact
>  	    ;; But don't prevent decoding of the outside.
> @@ -952,16 +989,26 @@ (defun Man-getpage-in-background (topic)
>  			     (cond
>  			      ((and (integerp Man-width) (> Man-width 0))
>  			       Man-width)
> -			      (Man-width (frame-width))
> -			      ((window-width))))))
> +			      (Man-width
> +			       (if (eq Man-async 'delayed)
> +				   (frame-width)
> +				 (with-selected-window (get-buffer-window
> +							buffer t)
> +				   (frame-width))))
> +			      (t
> +			       (if (eq Man-async 'delayed)
> +				   (window-width)
> +				 (with-selected-window (get-buffer-window
> +							buffer t)
> +				   (window-width))))))))
>  	(setenv "GROFF_NO_SGR" "1")
>  	;; Since man-db 2.4.3-1, man writes plain text with no escape
>  	;; sequences when stdout is not a tty.	In 2.5.0, the following
>  	;; env-var was added to allow control of this (see Debian Bug#340673).
>  	(setenv "MAN_KEEP_FORMATTING" "1")
> -	(if (fboundp 'start-process)
> +	(if (and Man-async (fboundp 'start-process))
>  	    (set-process-sentinel
> -	     (start-process manual-program buffer
> +	     (start-process manual-program (if (eq Man-async 'delayed) buffer procbuffer)
>  			    (if (memq system-type '(cygwin windows-nt))
>  				shell-file-name
>  			      "sh")
> @@ -969,7 +1016,7 @@ (defun Man-getpage-in-background (topic)
>  			    (format (Man-build-man-command) man-args))
>  	     'Man-bgproc-sentinel)
>  	  (let ((exit-status
> -		 (call-process shell-file-name nil (list buffer nil) nil
> +		 (call-process shell-file-name nil (list procbuffer nil) nil
>  			       shell-command-switch
>  			       (format (Man-build-man-command) man-args)))
>  		(msg ""))
> @@ -980,7 +1027,7 @@ (defun Man-getpage-in-background (topic)
>  			   (format "exited abnormally with code %d"
>  				   exit-status)))
>  		(setq msg exit-status))
> -	    (Man-bgproc-sentinel bufname msg)))))
> +	    (Man-bgproc-sentinel procbufname msg)))))
>      buffer))
>
>  (defun Man-notify-when-ready (man-buffer)
> @@ -1216,16 +1263,18 @@ (defun Man-bgproc-sentinel (process msg)
>  synchronously, PROCESS is the name of the buffer where the manpage
>  command is run.  Second argument MSG is the exit message of the
>  manpage command."
> -  (let ((Man-buffer (if (stringp process) (get-buffer process)
> -		      (process-buffer process)))
> -	(delete-buff nil)
> -	(err-mess nil))
> +  (let* ((Man-procbuffer (if (stringp process) (get-buffer process)
> +			   (process-buffer process)))
> +	 (Man-buffer (get-buffer (replace-regexp-in-string
> +				  "\\` " "" (buffer-name Man-procbuffer))))
> +	 (delete-buff nil)
> +	 (err-mess nil))
>
>      (if (null (buffer-name Man-buffer)) ;; deleted buffer
>  	(or (stringp process)
>  	    (set-process-buffer process nil))
>
> -      (with-current-buffer Man-buffer
> +      (with-current-buffer Man-procbuffer
>  	(let ((case-fold-search nil))
>  	  (goto-char (point-min))
>  	  (cond ((or (looking-at "No \\(manual \\)*entry for")
> @@ -1261,11 +1310,17 @@ (defun Man-bgproc-sentinel (process msg)
>                (Man-fontify-manpage)
>              (Man-cleanup-manpage))
>
> +	  (unless (eq Man-async 'delayed)
> +	    (copy-to-buffer Man-buffer (point-min) (point-max))))))
> +
> +      (unless delete-buff
> +	(with-current-buffer (if (eq Man-async 'delayed) Man-procbuffer Man-buffer)
>            (run-hooks 'Man-cooked-hook)
>  	  (Man-mode)
>
> @@ -1279,11 +1342,13 @@ (defun Man-bgproc-sentinel (process msg)
>  	;; Man-notify-when-ready because it may switch buffers.
>
>  	(if (not delete-buff)
> -	    (Man-notify-when-ready Man-buffer))
> +	    (when (or (eq Man-async 'delayed)
> +		      (memq Man-notify-method '(polite quiet meek)))
> +	      (Man-notify-when-ready Man-buffer)))
>
>  	(if err-mess
>  	    (error "%s" err-mess))
> -	))))
> +	)))
>
>  (defun Man-page-from-arguments (args)
>    ;; Skip arguments and only print the page name.

Best regards,
Stefan Kangas





  parent reply	other threads:[~2020-08-19 12:49 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-07-31 11:53 bug#12098: How to trap errors in man? Reuben Thomas
     [not found] ` <handler.12098.B.13437360754310.ack@debbugs.gnu.org>
2012-07-31 13:36   ` bug#12098: Acknowledgement (How to trap errors in man?) Reuben Thomas
2012-07-31 16:27     ` Eli Zaretskii
2012-08-01  0:15 ` bug#12098: How to trap errors in man? Juri Linkov
2012-08-01  0:38   ` Reuben Thomas
2012-08-01  8:23     ` Juri Linkov
2012-08-01 11:11       ` Reuben Thomas
2020-08-19 12:49       ` Stefan Kangas [this message]
2020-08-19 12:53         ` Reuben Thomas via Bug reports for GNU Emacs, the Swiss army knife of text editors
2020-08-19 13:08           ` Stefan Kangas
2020-08-19 13:08         ` Lars Ingebrigtsen
2020-08-19 13:10           ` Reuben Thomas via Bug reports for GNU Emacs, the Swiss army knife of text editors
2020-08-19 13:24             ` Stefan Kangas
2020-08-19 13:28               ` Reuben Thomas via Bug reports for GNU Emacs, the Swiss army knife of text editors
2020-08-19 13:51                 ` Stefan Kangas
2020-08-19 13:51                   ` Reuben Thomas via Bug reports for GNU Emacs, the Swiss army knife of text editors
2020-08-19 14:12                     ` Stefan Kangas
2020-08-19 14:21                       ` Reuben Thomas via Bug reports for GNU Emacs, the Swiss army knife of text editors
2020-08-19 15:17                         ` Stefan Kangas
2020-08-19 15:22                           ` Reuben Thomas via Bug reports for GNU Emacs, the Swiss army knife of text editors
2020-10-14  6:05               ` Lars Ingebrigtsen
2020-08-19 13:14           ` Stefan Kangas
2020-08-20  0:37             ` Juri Linkov
2020-08-21  7:25               ` Stefan Kangas
2020-08-21  7:41                 ` Eli Zaretskii
2020-08-21  9:41                   ` Reuben Thomas via Bug reports for GNU Emacs, the Swiss army knife of text editors
2012-08-01  9:05     ` Andy Moreton
2012-08-01 23:10       ` Juri Linkov
2012-08-01  8:27   ` Thierry Volpiatto
2012-08-01  8:41     ` Juri Linkov
2012-08-01  8:58       ` Thierry Volpiatto
2012-08-01  9:29         ` Thierry Volpiatto
2012-08-01 23:12           ` Juri Linkov
2012-08-02  5:20             ` Thierry Volpiatto

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CADwFkmnieZFT=pLca1ZyREEVQ5pRQrWXOAib-n6ZH5P2X23WsQ@mail.gmail.com' \
    --to=stefan@marxist.se \
    --cc=12098@debbugs.gnu.org \
    --cc=juri@jurta.org \
    --cc=rrt@sc3d.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.