[PATCH] pager: disable pager for interactive prompts and subprocesses
Brodie Rao
dackze at gmail.com
Wed Feb 11 22:59:59 UTC 2009
Has anyone had a chance to look at this? I'd like comments if anyone
has any.
Another approach was mentioned on the user mailing list: http://selenic.com/pipermail/mercurial/2009-February/023954.html
- I think it might be useful in conjunction with this.
One limitation of this implementation is that when the pager is
killed, output that was previously paged is lost (unless the user's
pager doesn't use the alternate buffer, e.g. less -X). I think it's
still a huge improvement that the command doesn't get trashed by the
pager.
Another case would be commands that aren't interactive but never
return, like hg serve.
On Dec 11, 2008, at 10:54 AM, Brodie Rao wrote:
> # HG changeset patch
> # User Brodie Rao <me+hg at dackz.net>
> # Date 1228315940 18000
> # Node ID 65aac189ba9643367facf651b95302a06ef7d861
> # Parent d8cd79fbed3c7b358dd820ff5dee44a7cff362bc
> pager: disable pager for interactive prompts and subprocesses
>
> diff --git a/hgext/pager.py b/hgext/pager.py
> --- a/hgext/pager.py
> +++ b/hgext/pager.py
> @@ -23,6 +23,9 @@ If no pager is set, the pager extensions
> variable $PAGER. If neither pager.pager, nor $PAGER is set, no pager
> is used.
>
> +If an interactive prompt or subprocess is opened by Mercurial, the
> prompt
> +will appear when you exit the pager (and subsequent output will not
> be paged).
> +
> If you notice "BROKEN PIPE" error messages, you can disable them
> by setting:
>
> @@ -49,16 +52,41 @@ them in the global .hgrc
> import sys, os, signal
> from mercurial import dispatch, util, extensions
>
> +def pagecmd(orig, ui, options, cmd, cmdfunc):
> + # disable the pager for interactive prompts
> + def wrapper(orig, *args, **kwargs):
> + if sys.stdout != sys.__stdout__:
> + sys.stdout.close()
> + sys.stdout = sys.__stdout__
> + sys.stderr = sys.__stderr__
> + return orig(*args, **kwargs)
> +
> + import __builtin__
> + extensions.wrapfunction(__builtin__, 'input', wrapper)
> + extensions.wrapfunction(__builtin__, 'raw_input', wrapper)
> +
> + import getpass
> + extensions.wrapfunction(getpass, 'getpass', wrapper)
> +
> + from mercurial.ui import ui as uicls
> + extensions.wrapfunction(uicls, 'prompt', wrapper)
> + extensions.wrapfunction(uicls, 'getpass', wrapper)
> +
> + # disable the pager if a subprocess is opened (like ssh)
> + extensions.wrapfunction(util, 'system', wrapper)
> + extensions.wrapfunction(util, 'popen', wrapper)
> + extensions.wrapfunction(util, 'popen2', wrapper)
> + extensions.wrapfunction(util, 'popen3', wrapper)
> +
> + p = ui.config("pager", "pager", os.environ.get("PAGER"))
> + if p and sys.stdout.isatty() and '--debugger' not in sys.argv:
> + attend = ui.configlist('pager', 'attend')
> + if (cmd in attend or
> + (cmd not in ui.configlist('pager', 'ignore') and not
> attend)):
> + sys.stderr = sys.stdout = util.popen(p, "wb")
> + if ui.configbool('pager', 'quiet'):
> + signal.signal(signal.SIGPIPE, signal.SIG_DFL)
> + return orig(ui, options, cmd, cmdfunc)
> +
> def uisetup(ui):
> - def pagecmd(orig, ui, options, cmd, cmdfunc):
> - p = ui.config("pager", "pager", os.environ.get("PAGER"))
> - if p and sys.stdout.isatty() and '--debugger' not in
> sys.argv:
> - attend = ui.configlist('pager', 'attend')
> - if (cmd in attend or
> - (cmd not in ui.configlist('pager', 'ignore') and
> not attend)):
> - sys.stderr = sys.stdout = util.popen(p, "wb")
> - if ui.configbool('pager', 'quiet'):
> - signal.signal(signal.SIGPIPE, signal.SIG_DFL)
> - return orig(ui, options, cmd, cmdfunc)
> -
> extensions.wrapfunction(dispatch, '_runcommand', pagecmd)
More information about the Mercurial-devel
mailing list