[PATCH] hgext/win32chcp: switches the console into an encoding actually used (issue2926)
Adrian Buehlmann
adrian at cadifra.com
Fri Jul 29 11:51:16 CDT 2011
On 2011-07-29 01:47, Andrei Polushin wrote:
> # HG changeset patch
> # User Andrei Polushin <polushin at gmail.com>
> # Date 1311886282 -25200
> # Branch stable
> # Node ID 79b6058b58e93cd5b3edbd3340b1348e46e043a7
> # Parent 56848e2bb0c5a43b580dd2ca7ce1e781d4e75b2b
> hgext/win32chcp: switches the console into an encoding actually used (issue2926)
>
> The encoding of the Windows console is switched temporarily, for the time the
> Mercurial is running, and restored to the previous value on exit.
>
> This solution is backward compatible, it changes almost nothing, i.e. neither
> stdout/pipe encoding, nor internal string handling are affected anyway.
> For maximum compatibility, it is implemented as an optional extension.
>
> One problem still remains: `hg log | more' doesn't produce readable output on
> OEM console, I've found no way to change the console encoding when redirected.
>
> One problem possibly introduced: killing hg process may not restore previous
> console encoding. I'm unable to reproduce the problem, however.
>
> diff -r 56848e2bb0c5 -r 79b6058b58e9 hgext/win32chcp.py
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++ b/hgext/win32chcp.py Fri Jul 29 03:51:22 2011 +0700
> @@ -0,0 +1,30 @@
> +# Copyright 2011 Andrei Polushin <polushin at gmail.com>
> +#
> +# This software may be used and distributed according to the terms of the
> +# GNU General Public License version 2 or any later version.
> +
> +'''switch the Windows console into an encoding actually used on output'''
> +
> +import os, codecs
> +from mercurial.i18n import _
> +from mercurial import osutil, encoding
> +
> +_cpaliases = {
> + 'utf-8': 'cp65001',
> +}
> +
> +def uisetup(ui):
> + if os.name != 'nt':
> + ui.warn(_("[win32chcp] is not supported on this platform.\n"))
> + return
> +
> + cp = encoding.encoding
> + try:
> + cp = codecs.lookup(cp).name
> + cp = _cpaliases.get(cp, cp)
> + if cp.startswith('cp'):
> + cp = cp[2:]
> + osutil.forceconsoleencoding(int(cp))
> + except (LookupError, ValueError):
> + ui.warn(_("[win32chcp] unrecognized encoding: %s.\n") % cp)
> + pass
Can you try this? (requires no change in core):
import os, codecs, ctypes, atexit
from mercurial.i18n import _
from mercurial import encoding
_cpaliases = {
'utf-8': 'cp65001',
}
_inputcp = 0
_outputcp = 0
def restoreconsoleencoding():
_kernel32 = ctypes.windll.kernel32
_kernel32.SetConsoleCP(_inputcp)
_kernel32.SetConsoleOutputCP(_outputcp)
def forceconsoleencoding(cp):
global _inputcp
global _outputcp
_kernel32 = ctypes.windll.kernel32
_inputcp = _kernel32.GetConsoleCP()
_outputcp = _kernel32.GetConsoleOutputCP()
_kernel32.SetConsoleCP(cp)
_kernel32.SetConsoleOutputCP(cp)
atexit.register(restoreconsoleencoding)
def uisetup(ui):
if os.name != 'nt':
ui.warn(_("[win32chcp] is not supported on this platform.\n"))
return
cp = encoding.encoding
try:
cp = codecs.lookup(cp).name
cp = _cpaliases.get(cp, cp)
if cp.startswith('cp'):
cp = cp[2:]
forceconsoleencoding(int(cp))
except (LookupError, ValueError):
ui.warn(_("[win32chcp] unrecognized encoding: %s.\n") % cp)
pass
More information about the Mercurial-devel
mailing list