@@ -1637,11 +1637,11 @@ def bold(self, text):
1637
1637
1638
1638
# --------------------------------------------------------- user interfaces
1639
1639
1640
- def pager (text ):
1640
+ def pager (text , title = '' ):
1641
1641
"""The first time this is called, determine what kind of pager to use."""
1642
1642
global pager
1643
1643
pager = getpager ()
1644
- pager (text )
1644
+ pager (text , title )
1645
1645
1646
1646
def getpager ():
1647
1647
"""Decide what method to use for paging through text."""
@@ -1656,24 +1656,24 @@ def getpager():
1656
1656
use_pager = os .environ .get ('MANPAGER' ) or os .environ .get ('PAGER' )
1657
1657
if use_pager :
1658
1658
if sys .platform == 'win32' : # pipes completely broken in Windows
1659
- return lambda text : tempfilepager (plain (text ), use_pager )
1659
+ return lambda text , title = '' : tempfilepager (plain (text ), use_pager )
1660
1660
elif os .environ .get ('TERM' ) in ('dumb' , 'emacs' ):
1661
- return lambda text : pipepager (plain (text ), use_pager )
1661
+ return lambda text , title = '' : pipepager (plain (text ), use_pager , title )
1662
1662
else :
1663
- return lambda text : pipepager (text , use_pager )
1663
+ return lambda text , title = '' : pipepager (text , use_pager , title )
1664
1664
if os .environ .get ('TERM' ) in ('dumb' , 'emacs' ):
1665
1665
return plainpager
1666
1666
if sys .platform == 'win32' :
1667
- return lambda text : tempfilepager (plain (text ), 'more <' )
1667
+ return lambda text , title = '' : tempfilepager (plain (text ), 'more <' )
1668
1668
if hasattr (os , 'system' ) and os .system ('(less) 2>/dev/null' ) == 0 :
1669
- return lambda text : pipepager (text , 'less' )
1669
+ return lambda text , title = '' : pipepager (text , 'less' , title )
1670
1670
1671
1671
import tempfile
1672
1672
(fd , filename ) = tempfile .mkstemp ()
1673
1673
os .close (fd )
1674
1674
try :
1675
1675
if hasattr (os , 'system' ) and os .system ('more "%s"' % filename ) == 0 :
1676
- return lambda text : pipepager (text , 'more' )
1676
+ return lambda text , title = '' : pipepager (text , 'more' , title )
1677
1677
else :
1678
1678
return ttypager
1679
1679
finally :
@@ -1683,12 +1683,18 @@ def plain(text):
1683
1683
"""Remove boldface formatting from text."""
1684
1684
return re .sub ('.\b ' , '' , text )
1685
1685
1686
- def pipepager (text , cmd ):
1686
+ def escape_less (s ):
1687
+ return re .sub (r'([?:.%\\])' , r'\\\1' , s )
1688
+
1689
+ def pipepager (text , cmd , title = '' ):
1687
1690
"""Page through text by feeding it to another program."""
1688
1691
import subprocess
1689
1692
env = os .environ .copy ()
1693
+ if title :
1694
+ title += ' '
1695
+ esc_title = escape_less (title )
1690
1696
prompt_string = (
1691
- ' '
1697
+ f' { esc_title } ' +
1692
1698
'?ltline %lt?L/%L.'
1693
1699
':byte %bB?s/%s.'
1694
1700
'.'
@@ -1716,7 +1722,7 @@ def pipepager(text, cmd):
1716
1722
# left running and the terminal is in raw mode and unusable.
1717
1723
pass
1718
1724
1719
- def tempfilepager (text , cmd ):
1725
+ def tempfilepager (text , cmd , title = '' ):
1720
1726
"""Page through text by invoking a program on a temporary file."""
1721
1727
import tempfile
1722
1728
with tempfile .TemporaryDirectory () as tempdir :
@@ -1733,7 +1739,7 @@ def _escape_stdout(text):
1733
1739
encoding = getattr (sys .stdout , 'encoding' , None ) or 'utf-8'
1734
1740
return text .encode (encoding , 'backslashreplace' ).decode (encoding )
1735
1741
1736
- def ttypager (text ):
1742
+ def ttypager (text , title = '' ):
1737
1743
"""Page through text on a text terminal."""
1738
1744
lines = plain (_escape_stdout (text )).split ('\n ' )
1739
1745
try :
@@ -1777,7 +1783,7 @@ def ttypager(text):
1777
1783
if tty :
1778
1784
tty .tcsetattr (fd , tty .TCSAFLUSH , old )
1779
1785
1780
- def plainpager (text ):
1786
+ def plainpager (text , title = '' ):
1781
1787
"""Simply print unformatted text. This is the ultimate fallback."""
1782
1788
sys .stdout .write (plain (_escape_stdout (text )))
1783
1789
@@ -1879,7 +1885,8 @@ def doc(thing, title='Python Library Documentation: %s', forceload=0,
1879
1885
"""Display text documentation, given an object or a path to an object."""
1880
1886
if output is None :
1881
1887
try :
1882
- pager (render_doc (thing , title , forceload ))
1888
+ what = thing if isinstance (thing , str ) else type (thing ).__name__
1889
+ pager (render_doc (thing , title , forceload ), f'Help on { what !s} ' )
1883
1890
except ImportError as exc :
1884
1891
if is_cli :
1885
1892
raise
@@ -2253,7 +2260,7 @@ def showtopic(self, topic, more_xrefs=''):
2253
2260
text = 'Related help topics: ' + ', ' .join (xrefs .split ()) + '\n '
2254
2261
wrapped_text = textwrap .wrap (text , 72 )
2255
2262
doc += '\n %s\n ' % '\n ' .join (wrapped_text )
2256
- pager (doc )
2263
+ pager (doc , f'Help on { topic !s } ' )
2257
2264
2258
2265
def _gettopic (self , topic , more_xrefs = '' ):
2259
2266
"""Return unbuffered tuple of (topic, xrefs).
0 commit comments