[PATCH] Detect console width on Windows

anatoly techtonik techtonik at gmail.com
Sun Apr 25 01:59:55 CDT 2010


Hello. I've added support for detection of console width on Windows.
It moves one piece of POSIX code, and this move is untested unlike
Windows part.  The patch uses pywin32, and is based on the ctypes code
from http://bitbucket.org/techtonik/python-pager/src/tip/pager.py that
I would like to propose for inclusion in Python stdlib one day as
console module.

In this particular patch the one thing the bugs me is the POSIX part
with detection of width of stderr first, then stdout and stdin
finally. I do not see the reason behind this order and presence of
stdin at all. How does it behave with redirected output? Anyway, I've
just moved that part to posix.py without touching it.

Please, CC.


# HG changeset patch
# Parent 33119d0252c1aa46da82a22aeb067fcd172ce804
# User anatoly techtonik <techtonik at gmail.com>
Detect console width also on Windows

diff -r 33119d0252c1 -r 54266e9958e3 mercurial/posix.py
--- a/mercurial/posix.py	Sun Apr 18 14:20:08 2010 -0700
+++ b/mercurial/posix.py	Sun Apr 25 09:19:40 2010 +0300
@@ -264,3 +264,27 @@

 def gethgcmd():
     return sys.argv[:1]
+
+def get_console_width():
+    try:
+        import termios, array, fcntl
+        for dev in (sys.stderr, sys.stdout, sys.stdin):
+            try:
+                try:
+                    fd = dev.fileno()
+                except AttributeError:
+                    continue
+                if not os.isatty(fd):
+                    continue
+                arri = fcntl.ioctl(fd, termios.TIOCGWINSZ, '\0' * 8)
+                return array.array('h', arri)[1]
+            except ValueError:
+                pass
+            except IOError, e:
+                if e[0] == errno.EINVAL:
+                    pass
+                else:
+                    raise
+    except ImportError:
+        pass
+
\ No newline at end of file
diff -r 33119d0252c1 -r 54266e9958e3 mercurial/util.py
--- a/mercurial/util.py	Sun Apr 18 14:20:08 2010 -0700
+++ b/mercurial/util.py	Sun Apr 25 09:19:40 2010 +0300
@@ -546,6 +546,10 @@
     """
     pass

+def get_console_width():
+    """Detect width of console, return None if failed"""
+    return None
+
 if os.name == 'nt':
     from windows import *
 else:
@@ -1251,27 +1255,9 @@
             return int(os.environ['COLUMNS'])
         except ValueError:
             pass
-    try:
-        import termios, array, fcntl
-        for dev in (sys.stderr, sys.stdout, sys.stdin):
-            try:
-                try:
-                    fd = dev.fileno()
-                except AttributeError:
-                    continue
-                if not os.isatty(fd):
-                    continue
-                arri = fcntl.ioctl(fd, termios.TIOCGWINSZ, '\0' * 8)
-                return array.array('h', arri)[1]
-            except ValueError:
-                pass
-            except IOError, e:
-                if e[0] == errno.EINVAL:
-                    pass
-                else:
-                    raise
-    except ImportError:
-        pass
+    width = get_console_width()
+    if width != None:
+        return width
     return 80

 def wrap(line, hangindent, width=None):
diff -r 33119d0252c1 -r 54266e9958e3 mercurial/win32.py
--- a/mercurial/win32.py	Sun Apr 18 14:20:08 2010 -0700
+++ b/mercurial/win32.py	Sun Apr 25 09:19:40 2010 +0300
@@ -16,7 +16,7 @@
 import win32api

 import errno, os, sys, pywintypes, win32con, win32file, win32process
-import winerror, win32gui
+import winerror, win32gui, win32console
 import osutil, encoding
 from win32com.shell import shell, shellcon

@@ -189,3 +189,14 @@

     pid =  win32process.GetCurrentProcessId()
     win32gui.EnumWindows(callback, pid)
+
+def get_console_width():
+    screenbuf = win32console.GetStdHandle(win32console.STD_OUTPUT_HANDLE)
+    width = None
+    try:
+        width = screenbuf.GetConsoleScreenBufferInfo()['Window'].Right
+        width += 1
+    except pywintypes.error:
+        pass
+    screenbuf.Detach()
+    return width

-- 
anatoly t.


More information about the Mercurial-devel mailing list