133 raise error.Abort("decoding near '%s': %s!" % (sub, inst)) |
133 raise error.Abort("decoding near '%s': %s!" % (sub, inst)) |
134 except LookupError, k: |
134 except LookupError, k: |
135 raise error.Abort("%s, please check your locale settings" % k) |
135 raise error.Abort("%s, please check your locale settings" % k) |
136 |
136 |
137 # How to treat ambiguous-width characters. Set to 'wide' to treat as wide. |
137 # How to treat ambiguous-width characters. Set to 'wide' to treat as wide. |
138 ambiguous = os.environ.get("HGENCODINGAMBIGUOUS", "narrow") |
138 wide = (os.environ.get("HGENCODINGAMBIGUOUS", "narrow") == "wide" |
|
139 and "WFA" or "WF") |
139 |
140 |
140 def colwidth(s): |
141 def colwidth(s): |
141 "Find the column width of a UTF-8 string for display" |
142 "Find the column width of a UTF-8 string for display" |
142 d = s.decode(encoding, 'replace') |
143 return ucolwidth(s.decode(encoding, 'replace')) |
|
144 |
|
145 def ucolwidth(d): |
|
146 "Find the column width of a Unicode string for display" |
143 eaw = getattr(unicodedata, 'east_asian_width', None) |
147 eaw = getattr(unicodedata, 'east_asian_width', None) |
144 if eaw is not None: |
148 if eaw is not None: |
145 wide = "WF" |
|
146 if ambiguous == "wide": |
|
147 wide = "WFA" |
|
148 return sum([eaw(c) in wide and 2 or 1 for c in d]) |
149 return sum([eaw(c) in wide and 2 or 1 for c in d]) |
149 return len(d) |
150 return len(d) |
150 |
151 |
151 def lower(s): |
152 def lower(s): |
152 "best-effort encoding-aware case-folding of local string s" |
153 "best-effort encoding-aware case-folding of local string s" |