diff --git a/IPython/genutils.py b/IPython/genutils.py index b4ffd2b..edac109 100644 --- a/IPython/genutils.py +++ b/IPython/genutils.py @@ -5,7 +5,7 @@ General purpose utilities. This is a grab-bag of stuff I find useful in most programs I write. Some of these things are also convenient when working at the command line. -$Id: genutils.py 967 2005-12-29 09:02:13Z fperez $""" +$Id: genutils.py 971 2005-12-29 18:30:45Z fperez $""" #***************************************************************************** # Copyright (C) 2001-2004 Fernando Perez. @@ -37,6 +37,9 @@ import types from IPython.Itpl import Itpl,itpl,printpl from IPython import DPyGetOpt +if os.name == "nt": + from IPython.winconsole import get_console_size + # Build objects which appeared in Python 2.3 for 2.2, to make ipython # 2.2-friendly try: @@ -1179,6 +1182,31 @@ def get_pager_start(pager,start): return start_string #---------------------------------------------------------------------------- +if os.name == "nt": + import msvcrt + def page_more(): + """ Smart pausing between pages + + @return: True if need print more lines, False if quit + """ + Term.cout.write('---Return to continue, q to quit--- ') + ans = msvcrt.getch() + if ans in ("q", "Q"): + result = False + else: + result = True + Term.cout.write("\b"*37 + " "*37 + "\b"*37) + return result +else: + def page_more(): + ans = raw_input('---Return to continue, q to quit--- ') + if ans.lower().startswith('q'): + return False + else: + return True + +esc_re = re.compile(r"(\x1b[^m]+m)") + def page_dumb(strng,start=0,screen_lines=25): """Very dumb 'pager' in Python, for when nothing else works. @@ -1190,12 +1218,16 @@ def page_dumb(strng,start=0,screen_lines=25): if len(screens) == 1: print >>Term.cout, os.linesep.join(screens[0]) else: + last_escape = "" for scr in screens[0:-1]: - print >>Term.cout, os.linesep.join(scr) - ans = raw_input('---Return to continue, q to quit--- ') - if ans.lower().startswith('q'): + hunk = os.linesep.join(scr) + print >>Term.cout, last_escape + hunk + if not page_more(): return - print >>Term.cout, os.linesep.join(screens[-1]) + esc_list = esc_re.findall(hunk) + if len(esc_list) > 0: + last_escape = esc_list[-1] + print >>Term.cout, last_escape + os.linesep.join(screens[-1]) #---------------------------------------------------------------------------- def page(strng,start=0,screen_lines=0,pager_cmd = None): @@ -1235,7 +1267,10 @@ def page(strng,start=0,screen_lines=0,pager_cmd = None): # terminals. If someone later feels like refining it, it's not hard. numlines = max(num_newlines,int(len_str/80)+1) - screen_lines_def = 25 # default value if we can't auto-determine + if os.name == "nt": + screen_lines_def = get_console_size(defaulty=25)[1] + else: + screen_lines_def = 25 # default value if we can't auto-determine # auto-determine screen size if screen_lines <= 0: diff --git a/IPython/winconsole.py b/IPython/winconsole.py new file mode 100644 index 0000000..8c0824f --- /dev/null +++ b/IPython/winconsole.py @@ -0,0 +1,43 @@ +""" +Set of functions to work with console on Windows. + +Author: Alexander Belchenko (e-mail: bialix AT ukr.net) +License: Public domain +""" + +__author__ = 'Alexander Belchenko (e-mail: bialix AT ukr.net)' +__license__ = 'Public domain' + +import struct + +try: + import ctypes +except ImportError: + ctypes = None + +def get_console_size(defaultx=80, defaulty=25): + """ Return size of current console. + + This function try to determine actual size of current working + console window and return tuple (sizex, sizey) if success, + or default size (defaultx, defaulty) otherwise. + + Dependencies: ctypes should be installed. + """ + if ctypes is None: + # no ctypes is found + return (defaultx, defaulty) + + h = ctypes.windll.kernel32.GetStdHandle(-11) + csbi = ctypes.create_string_buffer(22) + res = ctypes.windll.kernel32.GetConsoleScreenBufferInfo(h, csbi) + + if res: + (bufx, bufy, curx, cury, wattr, + left, top, right, bottom, maxx, maxy) = struct.unpack("hhhhHhhhhhh", + csbi.raw) + sizex = right - left + 1 + sizey = bottom - top + 1 + return (sizex, sizey) + else: + return (defaultx, defaulty) diff --git a/doc/ChangeLog b/doc/ChangeLog index 05771fa..2d30d9b 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,5 +1,9 @@ 2005-12-29 Fernando Perez + * IPython/winconsole.py (get_console_size): add new winconsole + module and fixes to page_dumb() to improve its behavior under + win32. Contributed by Alexander Belchenko . + * IPython/Magic.py (Macro): simplified Macro class to just subclass list. We've had only 2.2 compatibility for a very long time, yet I was still avoiding subclassing the builtin types. No @@ -7,7 +11,7 @@ 2.3-specific features quite yet). (magic_store): added Ville's patch for lightweight variable persistence, after a request on the user list by Matt Wilkie - . The new %store magic's docstring has full + . The new %store magic's docstring has full details. * IPython/iplib.py (InteractiveShell.post_config_initialization): diff --git a/doc/manual_base.lyx b/doc/manual_base.lyx index 8b27d71..df491d6 100644 --- a/doc/manual_base.lyx +++ b/doc/manual_base.lyx @@ -9149,4 +9149,13 @@ Tsai \end_inset ). +\layout List +\labelwidthstring 00.00.0000 + +Alexander\SpecialChar ~ +Belchenko +\family typewriter + +\family default + Improvements for win32 paging system. \the_end