annotate mercurial/utils/stringutil.py @ 40275:f2fbd32c7664

stringutil: make level parameter of pprintgen() 0-origin I think this makes more sense in that the level is incremented where nesting goes one more deep.
author Yuya Nishihara <yuya@tcha.org>
date Sun, 14 Oct 2018 07:18:19 +0200
parents 0f549da54379
children be57c7019c70
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
37083
f99d64e8a4e4 stringutil: move generic string helpers to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37082
diff changeset
1 # stringutil.py - utility for generic string formatting, parsing, etc.
8226
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
2 #
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
3 # Copyright 2005 K. Thananchayan <thananck@yahoo.com>
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
4 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
5 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
6 #
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
7 # This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9996
diff changeset
8 # GNU General Public License version 2 or any later version.
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
9
37083
f99d64e8a4e4 stringutil: move generic string helpers to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37082
diff changeset
10 from __future__ import absolute_import
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
11
37476
e9dea82ea1f3 wireproto: convert python literal to object without using unsafe eval()
Yuya Nishihara <yuya@tcha.org>
parents: 37322
diff changeset
12 import ast
31453
3b7a6941a6ef py3: call codecs.escape_encode() directly
Yuya Nishihara <yuya@tcha.org>
parents: 31451
diff changeset
13 import codecs
21907
7e5dfa00e3c2 util: rename 're' to 'remod'
Siddharth Agarwal <sid0@fb.com>
parents: 21857
diff changeset
14 import re as remod
27358
ac839ee45b6a util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27357
diff changeset
15 import textwrap
39296
ce145f8eface stringutil: teach pprint() to recognize generators
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39063
diff changeset
16 import types
3769
96095d9ff1f8 Add encoding detection
Matt Mackall <mpm@selenic.com>
parents: 3767
diff changeset
17
37083
f99d64e8a4e4 stringutil: move generic string helpers to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37082
diff changeset
18 from ..i18n import _
37210
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
19 from ..thirdparty import attr
37083
f99d64e8a4e4 stringutil: move generic string helpers to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37082
diff changeset
20
f99d64e8a4e4 stringutil: move generic string helpers to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37082
diff changeset
21 from .. import (
27358
ac839ee45b6a util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27357
diff changeset
22 encoding,
ac839ee45b6a util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27357
diff changeset
23 error,
28818
6041fb8f2da8 pycompat: add empty and queue to handle py3 divergence
timeless <timeless@mozdev.org>
parents: 28497
diff changeset
24 pycompat,
27358
ac839ee45b6a util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27357
diff changeset
25 )
37010
8453699a1f21 util: observable proxy objects for sockets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36991
diff changeset
26
38474
96f65bdf0bf4 stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents: 38264
diff changeset
27 # regex special chars pulled from https://bugs.python.org/issue29995
96f65bdf0bf4 stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents: 38264
diff changeset
28 # which was part of Python 3.7.
38477
de275ab362cb stringutil: update list of re-special characters to include &~
Augie Fackler <augie@google.com>
parents: 38474
diff changeset
29 _respecial = pycompat.bytestr(b'()[]{}?*+-|^$\\.&~# \t\n\r\v\f')
38474
96f65bdf0bf4 stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents: 38264
diff changeset
30 _regexescapemap = {ord(i): (b'\\' + i).decode('latin1') for i in _respecial}
96f65bdf0bf4 stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents: 38264
diff changeset
31
96f65bdf0bf4 stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents: 38264
diff changeset
32 def reescape(pat):
96f65bdf0bf4 stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents: 38264
diff changeset
33 """Drop-in replacement for re.escape."""
96f65bdf0bf4 stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents: 38264
diff changeset
34 # NOTE: it is intentional that this works on unicodes and not
96f65bdf0bf4 stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents: 38264
diff changeset
35 # bytes, as it's only possible to do the escaping with
96f65bdf0bf4 stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents: 38264
diff changeset
36 # unicode.translate, not bytes.translate. Sigh.
96f65bdf0bf4 stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents: 38264
diff changeset
37 wantuni = True
96f65bdf0bf4 stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents: 38264
diff changeset
38 if isinstance(pat, bytes):
96f65bdf0bf4 stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents: 38264
diff changeset
39 wantuni = False
96f65bdf0bf4 stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents: 38264
diff changeset
40 pat = pat.decode('latin1')
96f65bdf0bf4 stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents: 38264
diff changeset
41 pat = pat.translate(_regexescapemap)
96f65bdf0bf4 stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents: 38264
diff changeset
42 if wantuni:
96f65bdf0bf4 stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents: 38264
diff changeset
43 return pat
96f65bdf0bf4 stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents: 38264
diff changeset
44 return pat.encode('latin1')
96f65bdf0bf4 stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents: 38264
diff changeset
45
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
46 def pprint(o, bprefix=False, indent=0):
37300
2f859ad7ed8c stringutil: add function to pretty print an object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37290
diff changeset
47 """Pretty print an object."""
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
48 return b''.join(pprintgen(o, bprefix=bprefix, indent=indent))
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
49
40275
f2fbd32c7664 stringutil: make level parameter of pprintgen() 0-origin
Yuya Nishihara <yuya@tcha.org>
parents: 39378
diff changeset
50 def pprintgen(o, bprefix=False, indent=0, _level=0):
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
51 """Pretty print an object to a generator of atoms.
39353
0d21b1f1722c stringutil: refactor core of pprint so it emits chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39296
diff changeset
52
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
53 ``bprefix`` is a flag influencing whether bytestrings are preferred with
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
54 a ``b''`` prefix.
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
55
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
56 ``indent`` controls whether collections and nested data structures
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
57 span multiple lines via the indentation amount in spaces. By default,
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
58 no newlines are emitted.
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
59 """
39353
0d21b1f1722c stringutil: refactor core of pprint so it emits chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39296
diff changeset
60
37619
68132a95df31 stringutil: support more types with pprint()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37476
diff changeset
61 if isinstance(o, bytes):
37750
f7194c925003 stringutil: make b prefixes on string output optional
Augie Fackler <augie@google.com>
parents: 37749
diff changeset
62 if bprefix:
39353
0d21b1f1722c stringutil: refactor core of pprint so it emits chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39296
diff changeset
63 yield "b'%s'" % escapestr(o)
0d21b1f1722c stringutil: refactor core of pprint so it emits chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39296
diff changeset
64 else:
0d21b1f1722c stringutil: refactor core of pprint so it emits chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39296
diff changeset
65 yield "'%s'" % escapestr(o)
37619
68132a95df31 stringutil: support more types with pprint()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37476
diff changeset
66 elif isinstance(o, bytearray):
68132a95df31 stringutil: support more types with pprint()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37476
diff changeset
67 # codecs.escape_encode() can't handle bytearray, so escapestr fails
68132a95df31 stringutil: support more types with pprint()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37476
diff changeset
68 # without coercion.
39353
0d21b1f1722c stringutil: refactor core of pprint so it emits chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39296
diff changeset
69 yield "bytearray['%s']" % escapestr(bytes(o))
37300
2f859ad7ed8c stringutil: add function to pretty print an object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37290
diff changeset
70 elif isinstance(o, list):
39354
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
71 if not o:
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
72 yield '[]'
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
73 return
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
74
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
75 yield '['
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
76
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
77 if indent:
40275
f2fbd32c7664 stringutil: make level parameter of pprintgen() 0-origin
Yuya Nishihara <yuya@tcha.org>
parents: 39378
diff changeset
78 _level += 1
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
79 yield '\n'
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
80 yield ' ' * (_level * indent)
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
81
39354
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
82 for i, a in enumerate(o):
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
83 for chunk in pprintgen(a, bprefix=bprefix, indent=indent,
40275
f2fbd32c7664 stringutil: make level parameter of pprintgen() 0-origin
Yuya Nishihara <yuya@tcha.org>
parents: 39378
diff changeset
84 _level=_level):
39354
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
85 yield chunk
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
86
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
87 if i + 1 < len(o):
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
88 if indent:
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
89 yield ',\n'
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
90 yield ' ' * (_level * indent)
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
91 else:
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
92 yield ', '
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
93
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
94 if indent:
40275
f2fbd32c7664 stringutil: make level parameter of pprintgen() 0-origin
Yuya Nishihara <yuya@tcha.org>
parents: 39378
diff changeset
95 _level -= 1
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
96 yield '\n'
40275
f2fbd32c7664 stringutil: make level parameter of pprintgen() 0-origin
Yuya Nishihara <yuya@tcha.org>
parents: 39378
diff changeset
97 yield ' ' * (_level * indent)
39354
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
98
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
99 yield ']'
37300
2f859ad7ed8c stringutil: add function to pretty print an object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37290
diff changeset
100 elif isinstance(o, dict):
39354
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
101 if not o:
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
102 yield '{}'
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
103 return
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
104
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
105 yield '{'
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
106
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
107 if indent:
40275
f2fbd32c7664 stringutil: make level parameter of pprintgen() 0-origin
Yuya Nishihara <yuya@tcha.org>
parents: 39378
diff changeset
108 _level += 1
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
109 yield '\n'
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
110 yield ' ' * (_level * indent)
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
111
39354
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
112 for i, (k, v) in enumerate(sorted(o.items())):
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
113 for chunk in pprintgen(k, bprefix=bprefix, indent=indent,
40275
f2fbd32c7664 stringutil: make level parameter of pprintgen() 0-origin
Yuya Nishihara <yuya@tcha.org>
parents: 39378
diff changeset
114 _level=_level):
39354
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
115 yield chunk
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
116
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
117 yield ': '
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
118
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
119 for chunk in pprintgen(v, bprefix=bprefix, indent=indent,
40275
f2fbd32c7664 stringutil: make level parameter of pprintgen() 0-origin
Yuya Nishihara <yuya@tcha.org>
parents: 39378
diff changeset
120 _level=_level):
39354
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
121 yield chunk
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
122
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
123 if i + 1 < len(o):
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
124 if indent:
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
125 yield ',\n'
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
126 yield ' ' * (_level * indent)
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
127 else:
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
128 yield ', '
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
129
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
130 if indent:
40275
f2fbd32c7664 stringutil: make level parameter of pprintgen() 0-origin
Yuya Nishihara <yuya@tcha.org>
parents: 39378
diff changeset
131 _level -= 1
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
132 yield '\n'
40275
f2fbd32c7664 stringutil: make level parameter of pprintgen() 0-origin
Yuya Nishihara <yuya@tcha.org>
parents: 39378
diff changeset
133 yield ' ' * (_level * indent)
39354
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
134
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
135 yield '}'
39051
2aebe138ef6e stringutil: teach pprint about sets
Augie Fackler <augie@google.com>
parents: 38783
diff changeset
136 elif isinstance(o, set):
39354
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
137 if not o:
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
138 yield 'set([])'
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
139 return
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
140
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
141 yield 'set(['
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
142
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
143 if indent:
40275
f2fbd32c7664 stringutil: make level parameter of pprintgen() 0-origin
Yuya Nishihara <yuya@tcha.org>
parents: 39378
diff changeset
144 _level += 1
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
145 yield '\n'
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
146 yield ' ' * (_level * indent)
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
147
39354
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
148 for i, k in enumerate(sorted(o)):
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
149 for chunk in pprintgen(k, bprefix=bprefix, indent=indent,
40275
f2fbd32c7664 stringutil: make level parameter of pprintgen() 0-origin
Yuya Nishihara <yuya@tcha.org>
parents: 39378
diff changeset
150 _level=_level):
39354
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
151 yield chunk
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
152
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
153 if i + 1 < len(o):
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
154 if indent:
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
155 yield ',\n'
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
156 yield ' ' * (_level * indent)
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
157 else:
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
158 yield ', '
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
159
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
160 if indent:
40275
f2fbd32c7664 stringutil: make level parameter of pprintgen() 0-origin
Yuya Nishihara <yuya@tcha.org>
parents: 39378
diff changeset
161 _level -= 1
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
162 yield '\n'
40275
f2fbd32c7664 stringutil: make level parameter of pprintgen() 0-origin
Yuya Nishihara <yuya@tcha.org>
parents: 39378
diff changeset
163 yield ' ' * (_level * indent)
39354
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
164
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
165 yield '])'
37932
bf6bb710b40f stringutil: teach pprint about tuples
Augie Fackler <augie@google.com>
parents: 37750
diff changeset
166 elif isinstance(o, tuple):
39354
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
167 if not o:
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
168 yield '()'
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
169 return
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
170
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
171 yield '('
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
172
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
173 if indent:
40275
f2fbd32c7664 stringutil: make level parameter of pprintgen() 0-origin
Yuya Nishihara <yuya@tcha.org>
parents: 39378
diff changeset
174 _level += 1
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
175 yield '\n'
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
176 yield ' ' * (_level * indent)
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
177
39354
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
178 for i, a in enumerate(o):
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
179 for chunk in pprintgen(a, bprefix=bprefix, indent=indent,
40275
f2fbd32c7664 stringutil: make level parameter of pprintgen() 0-origin
Yuya Nishihara <yuya@tcha.org>
parents: 39378
diff changeset
180 _level=_level):
39354
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
181 yield chunk
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
182
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
183 if i + 1 < len(o):
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
184 if indent:
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
185 yield ',\n'
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
186 yield ' ' * (_level * indent)
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
187 else:
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
188 yield ', '
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
189
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
190 if indent:
40275
f2fbd32c7664 stringutil: make level parameter of pprintgen() 0-origin
Yuya Nishihara <yuya@tcha.org>
parents: 39378
diff changeset
191 _level -= 1
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
192 yield '\n'
40275
f2fbd32c7664 stringutil: make level parameter of pprintgen() 0-origin
Yuya Nishihara <yuya@tcha.org>
parents: 39378
diff changeset
193 yield ' ' * (_level * indent)
39354
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
194
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
195 yield ')'
39296
ce145f8eface stringutil: teach pprint() to recognize generators
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39063
diff changeset
196 elif isinstance(o, types.GeneratorType):
39354
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
197 # Special case of empty generator.
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
198 try:
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
199 nextitem = next(o)
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
200 except StopIteration:
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
201 yield 'gen[]'
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
202 return
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
203
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
204 yield 'gen['
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
205
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
206 if indent:
40275
f2fbd32c7664 stringutil: make level parameter of pprintgen() 0-origin
Yuya Nishihara <yuya@tcha.org>
parents: 39378
diff changeset
207 _level += 1
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
208 yield '\n'
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
209 yield ' ' * (_level * indent)
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
210
39354
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
211 last = False
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
212
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
213 while not last:
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
214 current = nextitem
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
215
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
216 try:
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
217 nextitem = next(o)
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
218 except StopIteration:
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
219 last = True
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
220
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
221 for chunk in pprintgen(current, bprefix=bprefix, indent=indent,
40275
f2fbd32c7664 stringutil: make level parameter of pprintgen() 0-origin
Yuya Nishihara <yuya@tcha.org>
parents: 39378
diff changeset
222 _level=_level):
39354
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
223 yield chunk
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
224
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
225 if not last:
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
226 if indent:
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
227 yield ',\n'
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
228 yield ' ' * (_level * indent)
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
229 else:
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
230 yield ', '
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
231
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
232 if indent:
40275
f2fbd32c7664 stringutil: make level parameter of pprintgen() 0-origin
Yuya Nishihara <yuya@tcha.org>
parents: 39378
diff changeset
233 _level -= 1
39378
0f549da54379 stringutil: teach pprint() to indent
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39354
diff changeset
234 yield '\n'
40275
f2fbd32c7664 stringutil: make level parameter of pprintgen() 0-origin
Yuya Nishihara <yuya@tcha.org>
parents: 39378
diff changeset
235 yield ' ' * (_level * indent)
39354
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
236
5ed7c6caf24d stringutil: emit multiple chunks when pretty printing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39353
diff changeset
237 yield ']'
37300
2f859ad7ed8c stringutil: add function to pretty print an object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37290
diff changeset
238 else:
39353
0d21b1f1722c stringutil: refactor core of pprint so it emits chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39296
diff changeset
239 yield pycompat.byterepr(o)
37300
2f859ad7ed8c stringutil: add function to pretty print an object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37290
diff changeset
240
38261
f3033692ccef stringutil: promote smartset.prettyformat() to utility function
Yuya Nishihara <yuya@tcha.org>
parents: 37942
diff changeset
241 def prettyrepr(o):
f3033692ccef stringutil: promote smartset.prettyformat() to utility function
Yuya Nishihara <yuya@tcha.org>
parents: 37942
diff changeset
242 """Pretty print a representation of a possibly-nested object"""
f3033692ccef stringutil: promote smartset.prettyformat() to utility function
Yuya Nishihara <yuya@tcha.org>
parents: 37942
diff changeset
243 lines = []
f3033692ccef stringutil: promote smartset.prettyformat() to utility function
Yuya Nishihara <yuya@tcha.org>
parents: 37942
diff changeset
244 rs = pycompat.byterepr(o)
38264
fbb2eddea4d2 stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents: 38261
diff changeset
245 p0 = p1 = 0
fbb2eddea4d2 stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents: 38261
diff changeset
246 while p0 < len(rs):
fbb2eddea4d2 stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents: 38261
diff changeset
247 # '... field=<type ... field=<type ...'
fbb2eddea4d2 stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents: 38261
diff changeset
248 # ~~~~~~~~~~~~~~~~
fbb2eddea4d2 stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents: 38261
diff changeset
249 # p0 p1 q0 q1
fbb2eddea4d2 stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents: 38261
diff changeset
250 q0 = -1
fbb2eddea4d2 stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents: 38261
diff changeset
251 q1 = rs.find('<', p1 + 1)
fbb2eddea4d2 stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents: 38261
diff changeset
252 if q1 < 0:
fbb2eddea4d2 stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents: 38261
diff changeset
253 q1 = len(rs)
fbb2eddea4d2 stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents: 38261
diff changeset
254 elif q1 > p1 + 1 and rs.startswith('=', q1 - 1):
fbb2eddea4d2 stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents: 38261
diff changeset
255 # backtrack for ' field=<'
fbb2eddea4d2 stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents: 38261
diff changeset
256 q0 = rs.rfind(' ', p1 + 1, q1 - 1)
fbb2eddea4d2 stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents: 38261
diff changeset
257 if q0 < 0:
fbb2eddea4d2 stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents: 38261
diff changeset
258 q0 = q1
fbb2eddea4d2 stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents: 38261
diff changeset
259 else:
fbb2eddea4d2 stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents: 38261
diff changeset
260 q0 += 1 # skip ' '
fbb2eddea4d2 stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents: 38261
diff changeset
261 l = rs.count('<', 0, p0) - rs.count('>', 0, p0)
38261
f3033692ccef stringutil: promote smartset.prettyformat() to utility function
Yuya Nishihara <yuya@tcha.org>
parents: 37942
diff changeset
262 assert l >= 0
38264
fbb2eddea4d2 stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents: 38261
diff changeset
263 lines.append((l, rs[p0:q0].rstrip()))
fbb2eddea4d2 stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents: 38261
diff changeset
264 p0, p1 = q0, q1
38261
f3033692ccef stringutil: promote smartset.prettyformat() to utility function
Yuya Nishihara <yuya@tcha.org>
parents: 37942
diff changeset
265 return '\n'.join(' ' * l + s for l, s in lines)
f3033692ccef stringutil: promote smartset.prettyformat() to utility function
Yuya Nishihara <yuya@tcha.org>
parents: 37942
diff changeset
266
38576
a3130208db1c stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents: 38477
diff changeset
267 def buildrepr(r):
a3130208db1c stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents: 38477
diff changeset
268 """Format an optional printable representation from unexpanded bits
a3130208db1c stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents: 38477
diff changeset
269
a3130208db1c stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents: 38477
diff changeset
270 ======== =================================
a3130208db1c stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents: 38477
diff changeset
271 type(r) example
a3130208db1c stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents: 38477
diff changeset
272 ======== =================================
a3130208db1c stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents: 38477
diff changeset
273 tuple ('<not %r>', other)
a3130208db1c stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents: 38477
diff changeset
274 bytes '<branch closed>'
a3130208db1c stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents: 38477
diff changeset
275 callable lambda: '<branch %r>' % sorted(b)
a3130208db1c stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents: 38477
diff changeset
276 object other
a3130208db1c stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents: 38477
diff changeset
277 ======== =================================
a3130208db1c stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents: 38477
diff changeset
278 """
a3130208db1c stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents: 38477
diff changeset
279 if r is None:
a3130208db1c stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents: 38477
diff changeset
280 return ''
a3130208db1c stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents: 38477
diff changeset
281 elif isinstance(r, tuple):
a3130208db1c stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents: 38477
diff changeset
282 return r[0] % pycompat.rapply(pycompat.maybebytestr, r[1:])
a3130208db1c stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents: 38477
diff changeset
283 elif isinstance(r, bytes):
a3130208db1c stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents: 38477
diff changeset
284 return r
a3130208db1c stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents: 38477
diff changeset
285 elif callable(r):
a3130208db1c stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents: 38477
diff changeset
286 return r()
a3130208db1c stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents: 38477
diff changeset
287 else:
39052
38409be2f521 stringutil: have buildrepr delegate to pprint for unknown types
Augie Fackler <augie@google.com>
parents: 39051
diff changeset
288 return pprint(r)
38576
a3130208db1c stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents: 38477
diff changeset
289
1015
22571b8d35d3 Add automatic binary file detection to diff and export
mpm@selenic.com
parents: 917
diff changeset
290 def binary(s):
6507
9699864de219 Let util.binary check entire data for \0 (issue1066, issue1079)
Christian Ebert <blacktrash@gmx.net>
parents: 6501
diff changeset
291 """return true if a string is binary data"""
8118
35f7fda52c92 util: return boolean result directly in util.binary
Martin Geisler <mg@lazybytes.net>
parents: 8011
diff changeset
292 return bool(s and '\0' in s)
6762
f67d1468ac50 util: add sort helper
Matt Mackall <mpm@selenic.com>
parents: 6746
diff changeset
293
30773
c390b40fe1d7 util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents: 30761
diff changeset
294 def stringmatcher(pattern, casesensitive=True):
26481
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
295 """
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
296 accepts a string, possibly starting with 're:' or 'literal:' prefix.
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
297 returns the matcher name, pattern, and matcher function.
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
298 missing or unknown prefixes are treated as literal matches.
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
299
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
300 helper for tests:
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
301 >>> def test(pattern, *tests):
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
302 ... kind, pattern, matcher = stringmatcher(pattern)
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
303 ... return (kind, pattern, [bool(matcher(t)) for t in tests])
30773
c390b40fe1d7 util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents: 30761
diff changeset
304 >>> def itest(pattern, *tests):
c390b40fe1d7 util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents: 30761
diff changeset
305 ... kind, pattern, matcher = stringmatcher(pattern, casesensitive=False)
c390b40fe1d7 util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents: 30761
diff changeset
306 ... return (kind, pattern, [bool(matcher(t)) for t in tests])
26481
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
307
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
308 exact matching (no prefix):
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34084
diff changeset
309 >>> test(b'abcdefg', b'abc', b'def', b'abcdefg')
26481
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
310 ('literal', 'abcdefg', [False, False, True])
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
311
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
312 regex matching ('re:' prefix)
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34084
diff changeset
313 >>> test(b're:a.+b', b'nomatch', b'fooadef', b'fooadefbar')
26481
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
314 ('re', 'a.+b', [False, False, True])
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
315
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
316 force exact matches ('literal:' prefix)
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34084
diff changeset
317 >>> test(b'literal:re:foobar', b'foobar', b're:foobar')
26481
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
318 ('literal', 're:foobar', [False, True])
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
319
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
320 unknown prefixes are ignored and treated as literals
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34084
diff changeset
321 >>> test(b'foo:bar', b'foo', b'bar', b'foo:bar')
26481
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
322 ('literal', 'foo:bar', [False, False, True])
30773
c390b40fe1d7 util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents: 30761
diff changeset
323
c390b40fe1d7 util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents: 30761
diff changeset
324 case insensitive regex matches
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34084
diff changeset
325 >>> itest(b're:A.+b', b'nomatch', b'fooadef', b'fooadefBar')
30773
c390b40fe1d7 util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents: 30761
diff changeset
326 ('re', 'A.+b', [False, False, True])
c390b40fe1d7 util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents: 30761
diff changeset
327
c390b40fe1d7 util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents: 30761
diff changeset
328 case insensitive literal matches
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34084
diff changeset
329 >>> itest(b'ABCDEFG', b'abc', b'def', b'abcdefg')
30773
c390b40fe1d7 util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents: 30761
diff changeset
330 ('literal', 'ABCDEFG', [False, False, True])
26481
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
331 """
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
332 if pattern.startswith('re:'):
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
333 pattern = pattern[3:]
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
334 try:
30773
c390b40fe1d7 util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents: 30761
diff changeset
335 flags = 0
c390b40fe1d7 util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents: 30761
diff changeset
336 if not casesensitive:
c390b40fe1d7 util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents: 30761
diff changeset
337 flags = remod.I
c390b40fe1d7 util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents: 30761
diff changeset
338 regex = remod.compile(pattern, flags)
26481
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
339 except remod.error as e:
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
340 raise error.ParseError(_('invalid regular expression: %s')
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
341 % e)
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
342 return 're', pattern, regex.search
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
343 elif pattern.startswith('literal:'):
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
344 pattern = pattern[8:]
30773
c390b40fe1d7 util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents: 30761
diff changeset
345
c390b40fe1d7 util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents: 30761
diff changeset
346 match = pattern.__eq__
c390b40fe1d7 util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents: 30761
diff changeset
347
c390b40fe1d7 util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents: 30761
diff changeset
348 if not casesensitive:
c390b40fe1d7 util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents: 30761
diff changeset
349 ipat = encoding.lower(pattern)
c390b40fe1d7 util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents: 30761
diff changeset
350 match = lambda s: ipat == encoding.lower(s)
c390b40fe1d7 util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents: 30761
diff changeset
351 return 'literal', pattern, match
26481
7d132557e44a util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents: 26480
diff changeset
352
1903
e4abeafd6eb1 move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
353 def shortuser(user):
e4abeafd6eb1 move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
354 """Return a short representation of a user name or email address."""
e4abeafd6eb1 move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
355 f = user.find('@')
e4abeafd6eb1 move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
356 if f >= 0:
e4abeafd6eb1 move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
357 user = user[:f]
e4abeafd6eb1 move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
358 f = user.find('<')
e4abeafd6eb1 move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
359 if f >= 0:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
360 user = user[f + 1:]
3176
7492b33bdd9f shortuser should stop before the first space character.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3147
diff changeset
361 f = user.find(' ')
7492b33bdd9f shortuser should stop before the first space character.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3147
diff changeset
362 if f >= 0:
7492b33bdd9f shortuser should stop before the first space character.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3147
diff changeset
363 user = user[:f]
3533
bb44489b901f shortname: truncate at '.' too
Matt Mackall <mpm@selenic.com>
parents: 3466
diff changeset
364 f = user.find('.')
bb44489b901f shortname: truncate at '.' too
Matt Mackall <mpm@selenic.com>
parents: 3466
diff changeset
365 if f >= 0:
bb44489b901f shortname: truncate at '.' too
Matt Mackall <mpm@selenic.com>
parents: 3466
diff changeset
366 user = user[:f]
1903
e4abeafd6eb1 move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1635
diff changeset
367 return user
1920
b7cc0f323a4c merge with crew.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1903 1882
diff changeset
368
16360
e5788269741a templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents: 15720
diff changeset
369 def emailuser(user):
e5788269741a templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents: 15720
diff changeset
370 """Return the user portion of an email address."""
e5788269741a templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents: 15720
diff changeset
371 f = user.find('@')
e5788269741a templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents: 15720
diff changeset
372 if f >= 0:
e5788269741a templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents: 15720
diff changeset
373 user = user[:f]
e5788269741a templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents: 15720
diff changeset
374 f = user.find('<')
e5788269741a templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents: 15720
diff changeset
375 if f >= 0:
e5788269741a templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents: 15720
diff changeset
376 user = user[f + 1:]
e5788269741a templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents: 15720
diff changeset
377 return user
e5788269741a templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents: 15720
diff changeset
378
5975
75d9fe70c654 templater: move email function to util
Matt Mackall <mpm@selenic.com>
parents: 5949
diff changeset
379 def email(author):
75d9fe70c654 templater: move email function to util
Matt Mackall <mpm@selenic.com>
parents: 5949
diff changeset
380 '''get email of author.'''
75d9fe70c654 templater: move email function to util
Matt Mackall <mpm@selenic.com>
parents: 5949
diff changeset
381 r = author.find('>')
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
382 if r == -1:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
383 r = None
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
384 return author[author.find('<') + 1:r]
5975
75d9fe70c654 templater: move email function to util
Matt Mackall <mpm@selenic.com>
parents: 5949
diff changeset
385
37155
fb7140f1d09d stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents: 37154
diff changeset
386 def person(author):
fb7140f1d09d stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents: 37154
diff changeset
387 """Returns the name before an email address,
fb7140f1d09d stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents: 37154
diff changeset
388 interpreting it as per RFC 5322
fb7140f1d09d stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents: 37154
diff changeset
389
fb7140f1d09d stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents: 37154
diff changeset
390 >>> person(b'foo@bar')
fb7140f1d09d stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents: 37154
diff changeset
391 'foo'
fb7140f1d09d stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents: 37154
diff changeset
392 >>> person(b'Foo Bar <foo@bar>')
fb7140f1d09d stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents: 37154
diff changeset
393 'Foo Bar'
fb7140f1d09d stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents: 37154
diff changeset
394 >>> person(b'"Foo Bar" <foo@bar>')
fb7140f1d09d stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents: 37154
diff changeset
395 'Foo Bar'
fb7140f1d09d stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents: 37154
diff changeset
396 >>> person(b'"Foo \"buz\" Bar" <foo@bar>')
fb7140f1d09d stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents: 37154
diff changeset
397 'Foo "buz" Bar'
fb7140f1d09d stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents: 37154
diff changeset
398 >>> # The following are invalid, but do exist in real-life
fb7140f1d09d stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents: 37154
diff changeset
399 ...
fb7140f1d09d stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents: 37154
diff changeset
400 >>> person(b'Foo "buz" Bar <foo@bar>')
fb7140f1d09d stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents: 37154
diff changeset
401 'Foo "buz" Bar'
fb7140f1d09d stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents: 37154
diff changeset
402 >>> person(b'"Foo Bar <foo@bar>')
fb7140f1d09d stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents: 37154
diff changeset
403 'Foo Bar'
fb7140f1d09d stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents: 37154
diff changeset
404 """
fb7140f1d09d stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents: 37154
diff changeset
405 if '@' not in author:
fb7140f1d09d stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents: 37154
diff changeset
406 return author
fb7140f1d09d stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents: 37154
diff changeset
407 f = author.find('<')
fb7140f1d09d stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents: 37154
diff changeset
408 if f != -1:
fb7140f1d09d stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents: 37154
diff changeset
409 return author[:f].strip(' "').replace('\\"', '"')
fb7140f1d09d stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents: 37154
diff changeset
410 f = author.find('@')
fb7140f1d09d stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents: 37154
diff changeset
411 return author[:f].replace('.', ' ')
fb7140f1d09d stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents: 37154
diff changeset
412
37210
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
413 @attr.s(hash=True)
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
414 class mailmapping(object):
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
415 '''Represents a username/email key or value in
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
416 a mailmap file'''
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
417 email = attr.ib()
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
418 name = attr.ib(default=None)
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
419
37246
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
420 def _ismailmaplineinvalid(names, emails):
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
421 '''Returns True if the parsed names and emails
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
422 in a mailmap entry are invalid.
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
423
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
424 >>> # No names or emails fails
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
425 >>> names, emails = [], []
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
426 >>> _ismailmaplineinvalid(names, emails)
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
427 True
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
428 >>> # Only one email fails
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
429 >>> emails = [b'email@email.com']
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
430 >>> _ismailmaplineinvalid(names, emails)
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
431 True
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
432 >>> # One email and one name passes
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
433 >>> names = [b'Test Name']
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
434 >>> _ismailmaplineinvalid(names, emails)
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
435 False
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
436 >>> # No names but two emails passes
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
437 >>> names = []
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
438 >>> emails = [b'proper@email.com', b'commit@email.com']
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
439 >>> _ismailmaplineinvalid(names, emails)
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
440 False
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
441 '''
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
442 return not emails or not names and len(emails) < 2
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
443
37210
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
444 def parsemailmap(mailmapcontent):
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
445 """Parses data in the .mailmap format
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
446
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
447 >>> mmdata = b"\\n".join([
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
448 ... b'# Comment',
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
449 ... b'Name <commit1@email.xx>',
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
450 ... b'<name@email.xx> <commit2@email.xx>',
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
451 ... b'Name <proper@email.xx> <commit3@email.xx>',
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
452 ... b'Name <proper@email.xx> Commit <commit4@email.xx>',
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
453 ... ])
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
454 >>> mm = parsemailmap(mmdata)
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
455 >>> for key in sorted(mm.keys()):
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
456 ... print(key)
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
457 mailmapping(email='commit1@email.xx', name=None)
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
458 mailmapping(email='commit2@email.xx', name=None)
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
459 mailmapping(email='commit3@email.xx', name=None)
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
460 mailmapping(email='commit4@email.xx', name='Commit')
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
461 >>> for val in sorted(mm.values()):
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
462 ... print(val)
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
463 mailmapping(email='commit1@email.xx', name='Name')
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
464 mailmapping(email='name@email.xx', name=None)
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
465 mailmapping(email='proper@email.xx', name='Name')
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
466 mailmapping(email='proper@email.xx', name='Name')
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
467 """
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
468 mailmap = {}
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
469
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
470 if mailmapcontent is None:
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
471 return mailmap
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
472
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
473 for line in mailmapcontent.splitlines():
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
474
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
475 # Don't bother checking the line if it is a comment or
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
476 # is an improperly formed author field
37246
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
477 if line.lstrip().startswith('#'):
37210
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
478 continue
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
479
37245
54b896f195d1 stringutil: rename local email/names variables to their plural forms
Connor Sheehan <sheehan@mozilla.com>
parents: 37210
diff changeset
480 # names, emails hold the parsed emails and names for each line
37210
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
481 # name_builder holds the words in a persons name
37245
54b896f195d1 stringutil: rename local email/names variables to their plural forms
Connor Sheehan <sheehan@mozilla.com>
parents: 37210
diff changeset
482 names, emails = [], []
37210
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
483 namebuilder = []
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
484
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
485 for element in line.split():
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
486 if element.startswith('#'):
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
487 # If we reach a comment in the mailmap file, move on
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
488 break
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
489
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
490 elif element.startswith('<') and element.endswith('>'):
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
491 # We have found an email.
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
492 # Parse it, and finalize any names from earlier
37245
54b896f195d1 stringutil: rename local email/names variables to their plural forms
Connor Sheehan <sheehan@mozilla.com>
parents: 37210
diff changeset
493 emails.append(element[1:-1]) # Slice off the "<>"
37210
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
494
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
495 if namebuilder:
37245
54b896f195d1 stringutil: rename local email/names variables to their plural forms
Connor Sheehan <sheehan@mozilla.com>
parents: 37210
diff changeset
496 names.append(' '.join(namebuilder))
37210
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
497 namebuilder = []
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
498
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
499 # Break if we have found a second email, any other
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
500 # data does not fit the spec for .mailmap
37245
54b896f195d1 stringutil: rename local email/names variables to their plural forms
Connor Sheehan <sheehan@mozilla.com>
parents: 37210
diff changeset
501 if len(emails) > 1:
37210
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
502 break
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
503
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
504 else:
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
505 # We have found another word in the committers name
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
506 namebuilder.append(element)
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
507
37246
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
508 # Check to see if we have parsed the line into a valid form
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
509 # We require at least one email, and either at least one
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
510 # name or a second email
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
511 if _ismailmaplineinvalid(names, emails):
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
512 continue
0e7550b0964c stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents: 37245
diff changeset
513
37210
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
514 mailmapkey = mailmapping(
37245
54b896f195d1 stringutil: rename local email/names variables to their plural forms
Connor Sheehan <sheehan@mozilla.com>
parents: 37210
diff changeset
515 email=emails[-1],
54b896f195d1 stringutil: rename local email/names variables to their plural forms
Connor Sheehan <sheehan@mozilla.com>
parents: 37210
diff changeset
516 name=names[-1] if len(names) == 2 else None,
37210
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
517 )
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
518
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
519 mailmap[mailmapkey] = mailmapping(
37245
54b896f195d1 stringutil: rename local email/names variables to their plural forms
Connor Sheehan <sheehan@mozilla.com>
parents: 37210
diff changeset
520 email=emails[0],
54b896f195d1 stringutil: rename local email/names variables to their plural forms
Connor Sheehan <sheehan@mozilla.com>
parents: 37210
diff changeset
521 name=names[0] if names else None,
37210
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
522 )
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
523
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
524 return mailmap
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
525
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
526 def mapname(mailmap, author):
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
527 """Returns the author field according to the mailmap cache, or
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
528 the original author field.
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
529
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
530 >>> mmdata = b"\\n".join([
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
531 ... b'# Comment',
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
532 ... b'Name <commit1@email.xx>',
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
533 ... b'<name@email.xx> <commit2@email.xx>',
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
534 ... b'Name <proper@email.xx> <commit3@email.xx>',
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
535 ... b'Name <proper@email.xx> Commit <commit4@email.xx>',
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
536 ... ])
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
537 >>> m = parsemailmap(mmdata)
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
538 >>> mapname(m, b'Commit <commit1@email.xx>')
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
539 'Name <commit1@email.xx>'
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
540 >>> mapname(m, b'Name <commit2@email.xx>')
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
541 'Name <name@email.xx>'
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
542 >>> mapname(m, b'Commit <commit3@email.xx>')
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
543 'Name <proper@email.xx>'
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
544 >>> mapname(m, b'Commit <commit4@email.xx>')
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
545 'Name <proper@email.xx>'
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
546 >>> mapname(m, b'Unknown Name <unknown@email.com>')
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
547 'Unknown Name <unknown@email.com>'
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
548 """
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
549 # If the author field coming in isn't in the correct format,
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
550 # or the mailmap is empty just return the original author field
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
551 if not isauthorwellformed(author) or not mailmap:
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
552 return author
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
553
37247
2ed180117f76 stringutil: edit comment to reflect actual data type name
Connor Sheehan <sheehan@mozilla.com>
parents: 37246
diff changeset
554 # Turn the user name into a mailmapping
37210
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
555 commit = mailmapping(name=person(author), email=email(author))
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
556
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
557 try:
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
558 # Try and use both the commit email and name as the key
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
559 proper = mailmap[commit]
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
560
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
561 except KeyError:
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
562 # If the lookup fails, use just the email as the key instead
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
563 # We call this commit2 as not to erase original commit fields
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
564 commit2 = mailmapping(email=commit.email)
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
565 proper = mailmap.get(commit2, mailmapping(None, None))
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
566
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
567 # Return the author field with proper values filled in
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
568 return '%s <%s>' % (
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
569 proper.name if proper.name else commit.name,
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
570 proper.email if proper.email else commit.email,
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
571 )
2a2ce93e12f4 templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents: 37155
diff changeset
572
37154
f8e1f48de118 stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents: 37083
diff changeset
573 _correctauthorformat = remod.compile(br'^[^<]+\s\<[^<>]+@[^<>]+\>$')
f8e1f48de118 stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents: 37083
diff changeset
574
f8e1f48de118 stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents: 37083
diff changeset
575 def isauthorwellformed(author):
f8e1f48de118 stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents: 37083
diff changeset
576 '''Return True if the author field is well formed
f8e1f48de118 stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents: 37083
diff changeset
577 (ie "Contributor Name <contrib@email.dom>")
f8e1f48de118 stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents: 37083
diff changeset
578
f8e1f48de118 stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents: 37083
diff changeset
579 >>> isauthorwellformed(b'Good Author <good@author.com>')
f8e1f48de118 stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents: 37083
diff changeset
580 True
f8e1f48de118 stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents: 37083
diff changeset
581 >>> isauthorwellformed(b'Author <good@author.com>')
f8e1f48de118 stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents: 37083
diff changeset
582 True
f8e1f48de118 stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents: 37083
diff changeset
583 >>> isauthorwellformed(b'Bad Author')
f8e1f48de118 stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents: 37083
diff changeset
584 False
f8e1f48de118 stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents: 37083
diff changeset
585 >>> isauthorwellformed(b'Bad Author <author@author.com')
f8e1f48de118 stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents: 37083
diff changeset
586 False
f8e1f48de118 stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents: 37083
diff changeset
587 >>> isauthorwellformed(b'Bad Author author@author.com')
f8e1f48de118 stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents: 37083
diff changeset
588 False
f8e1f48de118 stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents: 37083
diff changeset
589 >>> isauthorwellformed(b'<author@author.com>')
f8e1f48de118 stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents: 37083
diff changeset
590 False
f8e1f48de118 stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents: 37083
diff changeset
591 >>> isauthorwellformed(b'Bad Author <author>')
f8e1f48de118 stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents: 37083
diff changeset
592 False
f8e1f48de118 stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents: 37083
diff changeset
593 '''
f8e1f48de118 stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents: 37083
diff changeset
594 return _correctauthorformat.match(author) is not None
f8e1f48de118 stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents: 37083
diff changeset
595
3767
1861fa38a6a7 Move ellipsis code to util.ellipsis() and improve maxlength handling.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3721
diff changeset
596 def ellipsis(text, maxlength=400):
21857
86c2d792a4b7 util: replace 'ellipsis' implementation by 'encoding.trim'
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21813
diff changeset
597 """Trim string to at most maxlength (default: 400) columns in display."""
86c2d792a4b7 util: replace 'ellipsis' implementation by 'encoding.trim'
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21813
diff changeset
598 return encoding.trim(text, maxlength, ellipsis='...')
3767
1861fa38a6a7 Move ellipsis code to util.ellipsis() and improve maxlength handling.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3721
diff changeset
599
31451
53865692a354 util: wrap s.encode('string_escape') call for future py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents: 31449
diff changeset
600 def escapestr(s):
39063
1419ba5e3b56 stringutil: if we get a memoryview in escapestr, coerce it to bytes
Augie Fackler <augie@google.com>
parents: 39052
diff changeset
601 if isinstance(s, memoryview):
1419ba5e3b56 stringutil: if we get a memoryview in escapestr, coerce it to bytes
Augie Fackler <augie@google.com>
parents: 39052
diff changeset
602 s = bytes(s)
31453
3b7a6941a6ef py3: call codecs.escape_encode() directly
Yuya Nishihara <yuya@tcha.org>
parents: 31451
diff changeset
603 # call underlying function of s.encode('string_escape') directly for
3b7a6941a6ef py3: call codecs.escape_encode() directly
Yuya Nishihara <yuya@tcha.org>
parents: 31451
diff changeset
604 # Python 3 compatibility
3b7a6941a6ef py3: call codecs.escape_encode() directly
Yuya Nishihara <yuya@tcha.org>
parents: 31451
diff changeset
605 return codecs.escape_encode(s)[0]
31451
53865692a354 util: wrap s.encode('string_escape') call for future py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents: 31449
diff changeset
606
31484
afb335353d28 util: wrap s.decode('string_escape') calls for future py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents: 31465
diff changeset
607 def unescapestr(s):
31485
cad95575dc46 py3: call codecs.escape_decode() directly
Yuya Nishihara <yuya@tcha.org>
parents: 31484
diff changeset
608 return codecs.escape_decode(s)[0]
31484
afb335353d28 util: wrap s.decode('string_escape') calls for future py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents: 31465
diff changeset
609
33682
1d5e497c08b3 py3: convert arbitrary exception object to byte string more reliably
Yuya Nishihara <yuya@tcha.org>
parents: 33619
diff changeset
610 def forcebytestr(obj):
1d5e497c08b3 py3: convert arbitrary exception object to byte string more reliably
Yuya Nishihara <yuya@tcha.org>
parents: 33619
diff changeset
611 """Portably format an arbitrary object (e.g. exception) into a byte
1d5e497c08b3 py3: convert arbitrary exception object to byte string more reliably
Yuya Nishihara <yuya@tcha.org>
parents: 33619
diff changeset
612 string."""
1d5e497c08b3 py3: convert arbitrary exception object to byte string more reliably
Yuya Nishihara <yuya@tcha.org>
parents: 33619
diff changeset
613 try:
1d5e497c08b3 py3: convert arbitrary exception object to byte string more reliably
Yuya Nishihara <yuya@tcha.org>
parents: 33619
diff changeset
614 return pycompat.bytestr(obj)
1d5e497c08b3 py3: convert arbitrary exception object to byte string more reliably
Yuya Nishihara <yuya@tcha.org>
parents: 33619
diff changeset
615 except UnicodeEncodeError:
1d5e497c08b3 py3: convert arbitrary exception object to byte string more reliably
Yuya Nishihara <yuya@tcha.org>
parents: 33619
diff changeset
616 # non-ascii string, may be lossy
1d5e497c08b3 py3: convert arbitrary exception object to byte string more reliably
Yuya Nishihara <yuya@tcha.org>
parents: 33619
diff changeset
617 return pycompat.bytestr(encoding.strtolocal(str(obj)))
1d5e497c08b3 py3: convert arbitrary exception object to byte string more reliably
Yuya Nishihara <yuya@tcha.org>
parents: 33619
diff changeset
618
5291
23651848d638 extdiff: avoid repr() doubling paths backslashes under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 5213
diff changeset
619 def uirepr(s):
23651848d638 extdiff: avoid repr() doubling paths backslashes under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 5213
diff changeset
620 # Avoid double backslash in Windows path repr()
36266
1fa33bd848ee py3: fix bytes-unicode dance while building docstring of extdiff
Yuya Nishihara <yuya@tcha.org>
parents: 36235
diff changeset
621 return pycompat.byterepr(pycompat.bytestr(s)).replace(b'\\\\', b'\\')
7547
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7537
diff changeset
622
13316
d119403fd266 util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents: 13313
diff changeset
623 # delay import of textwrap
37079
736024df4498 util: mark MBTextWrapper as private
Yuya Nishihara <yuya@tcha.org>
parents: 37078
diff changeset
624 def _MBTextWrapper(**kwargs):
13316
d119403fd266 util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents: 13313
diff changeset
625 class tw(textwrap.TextWrapper):
d119403fd266 util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents: 13313
diff changeset
626 """
15066
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
627 Extend TextWrapper for width-awareness.
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
628
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
629 Neither number of 'bytes' in any encoding nor 'characters' is
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
630 appropriate to calculate terminal columns for specified string.
12957
9f2ac318b92e util: clarify purpose of MBTextWrapper class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12938
diff changeset
631
15066
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
632 Original TextWrapper implementation uses built-in 'len()' directly,
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
633 so overriding is needed to use width information of each characters.
12957
9f2ac318b92e util: clarify purpose of MBTextWrapper class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12938
diff changeset
634
15066
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
635 In addition, characters classified into 'ambiguous' width are
17424
e7cfe3587ea4 fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents: 17391
diff changeset
636 treated as wide in East Asian area, but as narrow in other.
15066
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
637
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
638 This requires use decision to determine width of such characters.
13316
d119403fd266 util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents: 13313
diff changeset
639 """
15065
24a6c3f903bb util: wrap lines with multi-byte characters correctly (issue2943)
Mads Kiilerich <mads@kiilerich.com>
parents: 15024
diff changeset
640 def _cutdown(self, ucstr, space_left):
13316
d119403fd266 util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents: 13313
diff changeset
641 l = 0
15066
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
642 colwidth = encoding.ucolwidth
38783
e7aa113b14f7 global: use pycompat.xrange()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38576
diff changeset
643 for i in pycompat.xrange(len(ucstr)):
15066
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
644 l += colwidth(ucstr[i])
13316
d119403fd266 util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents: 13313
diff changeset
645 if space_left < l:
15065
24a6c3f903bb util: wrap lines with multi-byte characters correctly (issue2943)
Mads Kiilerich <mads@kiilerich.com>
parents: 15024
diff changeset
646 return (ucstr[:i], ucstr[i:])
24a6c3f903bb util: wrap lines with multi-byte characters correctly (issue2943)
Mads Kiilerich <mads@kiilerich.com>
parents: 15024
diff changeset
647 return ucstr, ''
11297
d320e70442a5 replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 11256
diff changeset
648
13316
d119403fd266 util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents: 13313
diff changeset
649 # overriding of base class
d119403fd266 util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents: 13313
diff changeset
650 def _handle_long_word(self, reversed_chunks, cur_line, cur_len, width):
d119403fd266 util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents: 13313
diff changeset
651 space_left = max(width - cur_len, 1)
11297
d320e70442a5 replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 11256
diff changeset
652
13316
d119403fd266 util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents: 13313
diff changeset
653 if self.break_long_words:
d119403fd266 util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents: 13313
diff changeset
654 cut, res = self._cutdown(reversed_chunks[-1], space_left)
d119403fd266 util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents: 13313
diff changeset
655 cur_line.append(cut)
d119403fd266 util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents: 13313
diff changeset
656 reversed_chunks[-1] = res
d119403fd266 util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents: 13313
diff changeset
657 elif not cur_line:
d119403fd266 util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents: 13313
diff changeset
658 cur_line.append(reversed_chunks.pop())
11297
d320e70442a5 replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 11256
diff changeset
659
26201
c5b2074ae8c0 util: capitalize Python in MBTextWrapper._wrap_chunks comment
timeless@mozdev.org
parents: 26126
diff changeset
660 # this overriding code is imported from TextWrapper of Python 2.6
15066
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
661 # to calculate columns of string by 'encoding.ucolwidth()'
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
662 def _wrap_chunks(self, chunks):
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
663 colwidth = encoding.ucolwidth
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
664
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
665 lines = []
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
666 if self.width <= 0:
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
667 raise ValueError("invalid width %r (must be > 0)" % self.width)
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
668
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
669 # Arrange in reverse order so items can be efficiently popped
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
670 # from a stack of chucks.
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
671 chunks.reverse()
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
672
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
673 while chunks:
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
674
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
675 # Start the list of chunks that will make up the current line.
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
676 # cur_len is just the length of all the chunks in cur_line.
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
677 cur_line = []
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
678 cur_len = 0
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
679
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
680 # Figure out which static string will prefix this line.
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
681 if lines:
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
682 indent = self.subsequent_indent
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
683 else:
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
684 indent = self.initial_indent
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
685
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
686 # Maximum width for this line.
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
687 width = self.width - len(indent)
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
688
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
689 # First chunk on line is whitespace -- drop it, unless this
17424
e7cfe3587ea4 fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents: 17391
diff changeset
690 # is the very beginning of the text (i.e. no lines started yet).
32527
47ce079b1afa util: look for empty-sysstr instead of empty-bytesstr in textwrap code
Augie Fackler <raf@durin42.com>
parents: 32462
diff changeset
691 if self.drop_whitespace and chunks[-1].strip() == r'' and lines:
15066
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
692 del chunks[-1]
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
693
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
694 while chunks:
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
695 l = colwidth(chunks[-1])
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
696
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
697 # Can at least squeeze this chunk onto the current line.
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
698 if cur_len + l <= width:
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
699 cur_line.append(chunks.pop())
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
700 cur_len += l
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
701
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
702 # Nope, this line is full.
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
703 else:
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
704 break
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
705
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
706 # The current line is full, and the next chunk is too big to
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
707 # fit on *any* line (not just this one).
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
708 if chunks and colwidth(chunks[-1]) > width:
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
709 self._handle_long_word(chunks, cur_line, cur_len, width)
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
710
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
711 # If the last chunk on this line is all whitespace, drop it.
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
712 if (self.drop_whitespace and
32527
47ce079b1afa util: look for empty-sysstr instead of empty-bytesstr in textwrap code
Augie Fackler <raf@durin42.com>
parents: 32462
diff changeset
713 cur_line and cur_line[-1].strip() == r''):
15066
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
714 del cur_line[-1]
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
715
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
716 # Convert current line back to a string and store it in list
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
717 # of all lines (return value).
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
718 if cur_line:
32546
3b8155305fbe util: use sysstr.join instead of bytes.join in textwrap wrapper
Augie Fackler <raf@durin42.com>
parents: 32527
diff changeset
719 lines.append(indent + r''.join(cur_line))
15066
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
720
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
721 return lines
24efa83d81cb i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15065
diff changeset
722
37079
736024df4498 util: mark MBTextWrapper as private
Yuya Nishihara <yuya@tcha.org>
parents: 37078
diff changeset
723 global _MBTextWrapper
736024df4498 util: mark MBTextWrapper as private
Yuya Nishihara <yuya@tcha.org>
parents: 37078
diff changeset
724 _MBTextWrapper = tw
13316
d119403fd266 util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents: 13313
diff changeset
725 return tw(**kwargs)
11297
d320e70442a5 replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 11256
diff changeset
726
12698
7aef77e74cf3 util: make wrap() require a width argument
Matt Mackall <mpm@selenic.com>
parents: 12689
diff changeset
727 def wrap(line, width, initindent='', hangindent=''):
11297
d320e70442a5 replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 11256
diff changeset
728 maxindent = max(len(hangindent), len(initindent))
d320e70442a5 replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 11256
diff changeset
729 if width <= maxindent:
9417
4c3fb45123e5 util, minirst: do not crash with COLUMNS=0
Martin Geisler <mg@lazybytes.net>
parents: 9397
diff changeset
730 # adjust for weird terminal size
11297
d320e70442a5 replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 11256
diff changeset
731 width = max(78, maxindent + 1)
31338
a9a28ca17615 util: pass encoding.[encoding|encodingmode] as unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31315
diff changeset
732 line = line.decode(pycompat.sysstr(encoding.encoding),
37080
bad90b80b315 util: adjust indent level in wrap()
Yuya Nishihara <yuya@tcha.org>
parents: 37079
diff changeset
733 pycompat.sysstr(encoding.encodingmode))
31338
a9a28ca17615 util: pass encoding.[encoding|encodingmode] as unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31315
diff changeset
734 initindent = initindent.decode(pycompat.sysstr(encoding.encoding),
37080
bad90b80b315 util: adjust indent level in wrap()
Yuya Nishihara <yuya@tcha.org>
parents: 37079
diff changeset
735 pycompat.sysstr(encoding.encodingmode))
31338
a9a28ca17615 util: pass encoding.[encoding|encodingmode] as unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31315
diff changeset
736 hangindent = hangindent.decode(pycompat.sysstr(encoding.encoding),
37080
bad90b80b315 util: adjust indent level in wrap()
Yuya Nishihara <yuya@tcha.org>
parents: 37079
diff changeset
737 pycompat.sysstr(encoding.encodingmode))
37079
736024df4498 util: mark MBTextWrapper as private
Yuya Nishihara <yuya@tcha.org>
parents: 37078
diff changeset
738 wrapper = _MBTextWrapper(width=width,
736024df4498 util: mark MBTextWrapper as private
Yuya Nishihara <yuya@tcha.org>
parents: 37078
diff changeset
739 initial_indent=initindent,
736024df4498 util: mark MBTextWrapper as private
Yuya Nishihara <yuya@tcha.org>
parents: 37078
diff changeset
740 subsequent_indent=hangindent)
31338
a9a28ca17615 util: pass encoding.[encoding|encodingmode] as unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31315
diff changeset
741 return wrapper.fill(line).encode(pycompat.sysstr(encoding.encoding))
8938
9b8c9266c59d commands: wrap short descriptions in 'hg help'
Martin Geisler <mg@lazybytes.net>
parents: 8785
diff changeset
742
12088
1f71dffabc53 parsebool: accept always as true and never as false
Augie Fackler <durin42@gmail.com>
parents: 12087
diff changeset
743 _booleans = {'1': True, 'yes': True, 'true': True, 'on': True, 'always': True,
1f71dffabc53 parsebool: accept always as true and never as false
Augie Fackler <durin42@gmail.com>
parents: 12087
diff changeset
744 '0': False, 'no': False, 'false': False, 'off': False,
1f71dffabc53 parsebool: accept always as true and never as false
Augie Fackler <durin42@gmail.com>
parents: 12087
diff changeset
745 'never': False}
12087
a88a4720c2f0 parsebool: create new function and use it for config parsing
Augie Fackler <durin42@gmail.com>
parents: 12086
diff changeset
746
a88a4720c2f0 parsebool: create new function and use it for config parsing
Augie Fackler <durin42@gmail.com>
parents: 12086
diff changeset
747 def parsebool(s):
a88a4720c2f0 parsebool: create new function and use it for config parsing
Augie Fackler <durin42@gmail.com>
parents: 12086
diff changeset
748 """Parse s into a boolean.
a88a4720c2f0 parsebool: create new function and use it for config parsing
Augie Fackler <durin42@gmail.com>
parents: 12086
diff changeset
749
a88a4720c2f0 parsebool: create new function and use it for config parsing
Augie Fackler <durin42@gmail.com>
parents: 12086
diff changeset
750 If s is not a valid boolean, returns None.
a88a4720c2f0 parsebool: create new function and use it for config parsing
Augie Fackler <durin42@gmail.com>
parents: 12086
diff changeset
751 """
a88a4720c2f0 parsebool: create new function and use it for config parsing
Augie Fackler <durin42@gmail.com>
parents: 12086
diff changeset
752 return _booleans.get(s.lower(), None)
37290
cc5a040fe150 wireproto: syntax for encoding CBOR into frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37247
diff changeset
753
37476
e9dea82ea1f3 wireproto: convert python literal to object without using unsafe eval()
Yuya Nishihara <yuya@tcha.org>
parents: 37322
diff changeset
754 def evalpythonliteral(s):
e9dea82ea1f3 wireproto: convert python literal to object without using unsafe eval()
Yuya Nishihara <yuya@tcha.org>
parents: 37322
diff changeset
755 """Evaluate a string containing a Python literal expression"""
e9dea82ea1f3 wireproto: convert python literal to object without using unsafe eval()
Yuya Nishihara <yuya@tcha.org>
parents: 37322
diff changeset
756 # We could backport our tokenizer hack to rewrite '' to u'' if we want
37681
3942bd8db8b2 stringutil: ast.literal_eval needs a unicode on py3
Augie Fackler <augie@google.com>
parents: 37619
diff changeset
757 if pycompat.ispy3:
3942bd8db8b2 stringutil: ast.literal_eval needs a unicode on py3
Augie Fackler <augie@google.com>
parents: 37619
diff changeset
758 return ast.literal_eval(s.decode('latin1'))
37476
e9dea82ea1f3 wireproto: convert python literal to object without using unsafe eval()
Yuya Nishihara <yuya@tcha.org>
parents: 37322
diff changeset
759 return ast.literal_eval(s)