##// END OF EJS Templates
color: change the debug output format...
Matt Mackall -
r22464:964dd1c4 default
parent child Browse files
Show More
@@ -1,621 +1,619 b''
1 # color.py color output for the status and qseries commands
1 # color.py color output for the status and qseries commands
2 #
2 #
3 # Copyright (C) 2007 Kevin Christen <kevin.christen@gmail.com>
3 # Copyright (C) 2007 Kevin Christen <kevin.christen@gmail.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 '''colorize output from some commands
8 '''colorize output from some commands
9
9
10 This extension modifies the status and resolve commands to add color
10 This extension modifies the status and resolve commands to add color
11 to their output to reflect file status, the qseries command to add
11 to their output to reflect file status, the qseries command to add
12 color to reflect patch status (applied, unapplied, missing), and to
12 color to reflect patch status (applied, unapplied, missing), and to
13 diff-related commands to highlight additions, removals, diff headers,
13 diff-related commands to highlight additions, removals, diff headers,
14 and trailing whitespace.
14 and trailing whitespace.
15
15
16 Other effects in addition to color, like bold and underlined text, are
16 Other effects in addition to color, like bold and underlined text, are
17 also available. By default, the terminfo database is used to find the
17 also available. By default, the terminfo database is used to find the
18 terminal codes used to change color and effect. If terminfo is not
18 terminal codes used to change color and effect. If terminfo is not
19 available, then effects are rendered with the ECMA-48 SGR control
19 available, then effects are rendered with the ECMA-48 SGR control
20 function (aka ANSI escape codes).
20 function (aka ANSI escape codes).
21
21
22 Text receives color effects depending on the labels that it has. Many
22 Text receives color effects depending on the labels that it has. Many
23 default Mercurial commands emit labelled text. You can also define
23 default Mercurial commands emit labelled text. You can also define
24 your own labels in templates using the label function, see :hg:`help
24 your own labels in templates using the label function, see :hg:`help
25 templates`. A single portion of text may have more than one label. In
25 templates`. A single portion of text may have more than one label. In
26 that case, effects given to the last label will override any other
26 that case, effects given to the last label will override any other
27 effects. This includes the special "none" effect, which nullifies
27 effects. This includes the special "none" effect, which nullifies
28 other effects.
28 other effects.
29
29
30 Labels are normally invisible. In order to see these labels and their
30 Labels are normally invisible. In order to see these labels and their
31 position in the text, use the global --color=debug option. In case of
31 position in the text, use the global --color=debug option. In case of
32 multiple labels for the same text, the labels will be enclosed by
32 multiple labels for the same text, the labels will be enclosed by
33 square brackets, e.g.
33 square brackets, e.g.
34
34
35 [log.changeset changeset.secret](changeset: 22611:6f0a53c8f587)
35 [log.changeset changeset.secret](changeset: 22611:6f0a53c8f587)
36
36
37 The following are the default effects for some default labels. Default
37 The following are the default effects for some default labels. Default
38 effects may be overridden from your configuration file::
38 effects may be overridden from your configuration file::
39
39
40 [color]
40 [color]
41 status.modified = blue bold underline red_background
41 status.modified = blue bold underline red_background
42 status.added = green bold
42 status.added = green bold
43 status.removed = red bold blue_background
43 status.removed = red bold blue_background
44 status.deleted = cyan bold underline
44 status.deleted = cyan bold underline
45 status.unknown = magenta bold underline
45 status.unknown = magenta bold underline
46 status.ignored = black bold
46 status.ignored = black bold
47
47
48 # 'none' turns off all effects
48 # 'none' turns off all effects
49 status.clean = none
49 status.clean = none
50 status.copied = none
50 status.copied = none
51
51
52 qseries.applied = blue bold underline
52 qseries.applied = blue bold underline
53 qseries.unapplied = black bold
53 qseries.unapplied = black bold
54 qseries.missing = red bold
54 qseries.missing = red bold
55
55
56 diff.diffline = bold
56 diff.diffline = bold
57 diff.extended = cyan bold
57 diff.extended = cyan bold
58 diff.file_a = red bold
58 diff.file_a = red bold
59 diff.file_b = green bold
59 diff.file_b = green bold
60 diff.hunk = magenta
60 diff.hunk = magenta
61 diff.deleted = red
61 diff.deleted = red
62 diff.inserted = green
62 diff.inserted = green
63 diff.changed = white
63 diff.changed = white
64 diff.trailingwhitespace = bold red_background
64 diff.trailingwhitespace = bold red_background
65
65
66 resolve.unresolved = red bold
66 resolve.unresolved = red bold
67 resolve.resolved = green bold
67 resolve.resolved = green bold
68
68
69 bookmarks.current = green
69 bookmarks.current = green
70
70
71 branches.active = none
71 branches.active = none
72 branches.closed = black bold
72 branches.closed = black bold
73 branches.current = green
73 branches.current = green
74 branches.inactive = none
74 branches.inactive = none
75
75
76 tags.normal = green
76 tags.normal = green
77 tags.local = black bold
77 tags.local = black bold
78
78
79 rebase.rebased = blue
79 rebase.rebased = blue
80 rebase.remaining = red bold
80 rebase.remaining = red bold
81
81
82 shelve.age = cyan
82 shelve.age = cyan
83 shelve.newest = green bold
83 shelve.newest = green bold
84 shelve.name = blue bold
84 shelve.name = blue bold
85
85
86 histedit.remaining = red bold
86 histedit.remaining = red bold
87
87
88 The available effects in terminfo mode are 'blink', 'bold', 'dim',
88 The available effects in terminfo mode are 'blink', 'bold', 'dim',
89 'inverse', 'invisible', 'italic', 'standout', and 'underline'; in
89 'inverse', 'invisible', 'italic', 'standout', and 'underline'; in
90 ECMA-48 mode, the options are 'bold', 'inverse', 'italic', and
90 ECMA-48 mode, the options are 'bold', 'inverse', 'italic', and
91 'underline'. How each is rendered depends on the terminal emulator.
91 'underline'. How each is rendered depends on the terminal emulator.
92 Some may not be available for a given terminal type, and will be
92 Some may not be available for a given terminal type, and will be
93 silently ignored.
93 silently ignored.
94
94
95 Note that on some systems, terminfo mode may cause problems when using
95 Note that on some systems, terminfo mode may cause problems when using
96 color with the pager extension and less -R. less with the -R option
96 color with the pager extension and less -R. less with the -R option
97 will only display ECMA-48 color codes, and terminfo mode may sometimes
97 will only display ECMA-48 color codes, and terminfo mode may sometimes
98 emit codes that less doesn't understand. You can work around this by
98 emit codes that less doesn't understand. You can work around this by
99 either using ansi mode (or auto mode), or by using less -r (which will
99 either using ansi mode (or auto mode), or by using less -r (which will
100 pass through all terminal control codes, not just color control
100 pass through all terminal control codes, not just color control
101 codes).
101 codes).
102
102
103 Because there are only eight standard colors, this module allows you
103 Because there are only eight standard colors, this module allows you
104 to define color names for other color slots which might be available
104 to define color names for other color slots which might be available
105 for your terminal type, assuming terminfo mode. For instance::
105 for your terminal type, assuming terminfo mode. For instance::
106
106
107 color.brightblue = 12
107 color.brightblue = 12
108 color.pink = 207
108 color.pink = 207
109 color.orange = 202
109 color.orange = 202
110
110
111 to set 'brightblue' to color slot 12 (useful for 16 color terminals
111 to set 'brightblue' to color slot 12 (useful for 16 color terminals
112 that have brighter colors defined in the upper eight) and, 'pink' and
112 that have brighter colors defined in the upper eight) and, 'pink' and
113 'orange' to colors in 256-color xterm's default color cube. These
113 'orange' to colors in 256-color xterm's default color cube. These
114 defined colors may then be used as any of the pre-defined eight,
114 defined colors may then be used as any of the pre-defined eight,
115 including appending '_background' to set the background to that color.
115 including appending '_background' to set the background to that color.
116
116
117 By default, the color extension will use ANSI mode (or win32 mode on
117 By default, the color extension will use ANSI mode (or win32 mode on
118 Windows) if it detects a terminal. To override auto mode (to enable
118 Windows) if it detects a terminal. To override auto mode (to enable
119 terminfo mode, for example), set the following configuration option::
119 terminfo mode, for example), set the following configuration option::
120
120
121 [color]
121 [color]
122 mode = terminfo
122 mode = terminfo
123
123
124 Any value other than 'ansi', 'win32', 'terminfo', or 'auto' will
124 Any value other than 'ansi', 'win32', 'terminfo', or 'auto' will
125 disable color.
125 disable color.
126 '''
126 '''
127
127
128 import os
128 import os
129
129
130 from mercurial import cmdutil, commands, dispatch, extensions, ui as uimod, util
130 from mercurial import cmdutil, commands, dispatch, extensions, ui as uimod, util
131 from mercurial import templater, error
131 from mercurial import templater, error
132 from mercurial.i18n import _
132 from mercurial.i18n import _
133
133
134 cmdtable = {}
134 cmdtable = {}
135 command = cmdutil.command(cmdtable)
135 command = cmdutil.command(cmdtable)
136 testedwith = 'internal'
136 testedwith = 'internal'
137
137
138 # start and stop parameters for effects
138 # start and stop parameters for effects
139 _effects = {'none': 0, 'black': 30, 'red': 31, 'green': 32, 'yellow': 33,
139 _effects = {'none': 0, 'black': 30, 'red': 31, 'green': 32, 'yellow': 33,
140 'blue': 34, 'magenta': 35, 'cyan': 36, 'white': 37, 'bold': 1,
140 'blue': 34, 'magenta': 35, 'cyan': 36, 'white': 37, 'bold': 1,
141 'italic': 3, 'underline': 4, 'inverse': 7,
141 'italic': 3, 'underline': 4, 'inverse': 7,
142 'black_background': 40, 'red_background': 41,
142 'black_background': 40, 'red_background': 41,
143 'green_background': 42, 'yellow_background': 43,
143 'green_background': 42, 'yellow_background': 43,
144 'blue_background': 44, 'purple_background': 45,
144 'blue_background': 44, 'purple_background': 45,
145 'cyan_background': 46, 'white_background': 47}
145 'cyan_background': 46, 'white_background': 47}
146
146
147 def _terminfosetup(ui, mode):
147 def _terminfosetup(ui, mode):
148 '''Initialize terminfo data and the terminal if we're in terminfo mode.'''
148 '''Initialize terminfo data and the terminal if we're in terminfo mode.'''
149
149
150 global _terminfo_params
150 global _terminfo_params
151 # If we failed to load curses, we go ahead and return.
151 # If we failed to load curses, we go ahead and return.
152 if not _terminfo_params:
152 if not _terminfo_params:
153 return
153 return
154 # Otherwise, see what the config file says.
154 # Otherwise, see what the config file says.
155 if mode not in ('auto', 'terminfo'):
155 if mode not in ('auto', 'terminfo'):
156 return
156 return
157
157
158 _terminfo_params.update((key[6:], (False, int(val)))
158 _terminfo_params.update((key[6:], (False, int(val)))
159 for key, val in ui.configitems('color')
159 for key, val in ui.configitems('color')
160 if key.startswith('color.'))
160 if key.startswith('color.'))
161
161
162 try:
162 try:
163 curses.setupterm()
163 curses.setupterm()
164 except curses.error, e:
164 except curses.error, e:
165 _terminfo_params = {}
165 _terminfo_params = {}
166 return
166 return
167
167
168 for key, (b, e) in _terminfo_params.items():
168 for key, (b, e) in _terminfo_params.items():
169 if not b:
169 if not b:
170 continue
170 continue
171 if not curses.tigetstr(e):
171 if not curses.tigetstr(e):
172 # Most terminals don't support dim, invis, etc, so don't be
172 # Most terminals don't support dim, invis, etc, so don't be
173 # noisy and use ui.debug().
173 # noisy and use ui.debug().
174 ui.debug("no terminfo entry for %s\n" % e)
174 ui.debug("no terminfo entry for %s\n" % e)
175 del _terminfo_params[key]
175 del _terminfo_params[key]
176 if not curses.tigetstr('setaf') or not curses.tigetstr('setab'):
176 if not curses.tigetstr('setaf') or not curses.tigetstr('setab'):
177 # Only warn about missing terminfo entries if we explicitly asked for
177 # Only warn about missing terminfo entries if we explicitly asked for
178 # terminfo mode.
178 # terminfo mode.
179 if mode == "terminfo":
179 if mode == "terminfo":
180 ui.warn(_("no terminfo entry for setab/setaf: reverting to "
180 ui.warn(_("no terminfo entry for setab/setaf: reverting to "
181 "ECMA-48 color\n"))
181 "ECMA-48 color\n"))
182 _terminfo_params = {}
182 _terminfo_params = {}
183
183
184 def _modesetup(ui, coloropt):
184 def _modesetup(ui, coloropt):
185 global _terminfo_params
185 global _terminfo_params
186
186
187 if coloropt == 'debug':
187 if coloropt == 'debug':
188 return 'debug'
188 return 'debug'
189
189
190 auto = (coloropt == 'auto')
190 auto = (coloropt == 'auto')
191 always = not auto and util.parsebool(coloropt)
191 always = not auto and util.parsebool(coloropt)
192 if not always and not auto:
192 if not always and not auto:
193 return None
193 return None
194
194
195 formatted = always or (os.environ.get('TERM') != 'dumb' and ui.formatted())
195 formatted = always or (os.environ.get('TERM') != 'dumb' and ui.formatted())
196
196
197 mode = ui.config('color', 'mode', 'auto')
197 mode = ui.config('color', 'mode', 'auto')
198 realmode = mode
198 realmode = mode
199 if mode == 'auto':
199 if mode == 'auto':
200 if os.name == 'nt' and 'TERM' not in os.environ:
200 if os.name == 'nt' and 'TERM' not in os.environ:
201 # looks line a cmd.exe console, use win32 API or nothing
201 # looks line a cmd.exe console, use win32 API or nothing
202 realmode = 'win32'
202 realmode = 'win32'
203 else:
203 else:
204 realmode = 'ansi'
204 realmode = 'ansi'
205
205
206 if realmode == 'win32':
206 if realmode == 'win32':
207 _terminfo_params = {}
207 _terminfo_params = {}
208 if not w32effects:
208 if not w32effects:
209 if mode == 'win32':
209 if mode == 'win32':
210 # only warn if color.mode is explicitly set to win32
210 # only warn if color.mode is explicitly set to win32
211 ui.warn(_('warning: failed to set color mode to %s\n') % mode)
211 ui.warn(_('warning: failed to set color mode to %s\n') % mode)
212 return None
212 return None
213 _effects.update(w32effects)
213 _effects.update(w32effects)
214 elif realmode == 'ansi':
214 elif realmode == 'ansi':
215 _terminfo_params = {}
215 _terminfo_params = {}
216 elif realmode == 'terminfo':
216 elif realmode == 'terminfo':
217 _terminfosetup(ui, mode)
217 _terminfosetup(ui, mode)
218 if not _terminfo_params:
218 if not _terminfo_params:
219 if mode == 'terminfo':
219 if mode == 'terminfo':
220 ## FIXME Shouldn't we return None in this case too?
220 ## FIXME Shouldn't we return None in this case too?
221 # only warn if color.mode is explicitly set to win32
221 # only warn if color.mode is explicitly set to win32
222 ui.warn(_('warning: failed to set color mode to %s\n') % mode)
222 ui.warn(_('warning: failed to set color mode to %s\n') % mode)
223 realmode = 'ansi'
223 realmode = 'ansi'
224 else:
224 else:
225 return None
225 return None
226
226
227 if always or (auto and formatted):
227 if always or (auto and formatted):
228 return realmode
228 return realmode
229 return None
229 return None
230
230
231 try:
231 try:
232 import curses
232 import curses
233 # Mapping from effect name to terminfo attribute name or color number.
233 # Mapping from effect name to terminfo attribute name or color number.
234 # This will also force-load the curses module.
234 # This will also force-load the curses module.
235 _terminfo_params = {'none': (True, 'sgr0'),
235 _terminfo_params = {'none': (True, 'sgr0'),
236 'standout': (True, 'smso'),
236 'standout': (True, 'smso'),
237 'underline': (True, 'smul'),
237 'underline': (True, 'smul'),
238 'reverse': (True, 'rev'),
238 'reverse': (True, 'rev'),
239 'inverse': (True, 'rev'),
239 'inverse': (True, 'rev'),
240 'blink': (True, 'blink'),
240 'blink': (True, 'blink'),
241 'dim': (True, 'dim'),
241 'dim': (True, 'dim'),
242 'bold': (True, 'bold'),
242 'bold': (True, 'bold'),
243 'invisible': (True, 'invis'),
243 'invisible': (True, 'invis'),
244 'italic': (True, 'sitm'),
244 'italic': (True, 'sitm'),
245 'black': (False, curses.COLOR_BLACK),
245 'black': (False, curses.COLOR_BLACK),
246 'red': (False, curses.COLOR_RED),
246 'red': (False, curses.COLOR_RED),
247 'green': (False, curses.COLOR_GREEN),
247 'green': (False, curses.COLOR_GREEN),
248 'yellow': (False, curses.COLOR_YELLOW),
248 'yellow': (False, curses.COLOR_YELLOW),
249 'blue': (False, curses.COLOR_BLUE),
249 'blue': (False, curses.COLOR_BLUE),
250 'magenta': (False, curses.COLOR_MAGENTA),
250 'magenta': (False, curses.COLOR_MAGENTA),
251 'cyan': (False, curses.COLOR_CYAN),
251 'cyan': (False, curses.COLOR_CYAN),
252 'white': (False, curses.COLOR_WHITE)}
252 'white': (False, curses.COLOR_WHITE)}
253 except ImportError:
253 except ImportError:
254 _terminfo_params = {}
254 _terminfo_params = {}
255
255
256 _styles = {'grep.match': 'red bold',
256 _styles = {'grep.match': 'red bold',
257 'grep.linenumber': 'green',
257 'grep.linenumber': 'green',
258 'grep.rev': 'green',
258 'grep.rev': 'green',
259 'grep.change': 'green',
259 'grep.change': 'green',
260 'grep.sep': 'cyan',
260 'grep.sep': 'cyan',
261 'grep.filename': 'magenta',
261 'grep.filename': 'magenta',
262 'grep.user': 'magenta',
262 'grep.user': 'magenta',
263 'grep.date': 'magenta',
263 'grep.date': 'magenta',
264 'bookmarks.current': 'green',
264 'bookmarks.current': 'green',
265 'branches.active': 'none',
265 'branches.active': 'none',
266 'branches.closed': 'black bold',
266 'branches.closed': 'black bold',
267 'branches.current': 'green',
267 'branches.current': 'green',
268 'branches.inactive': 'none',
268 'branches.inactive': 'none',
269 'diff.changed': 'white',
269 'diff.changed': 'white',
270 'diff.deleted': 'red',
270 'diff.deleted': 'red',
271 'diff.diffline': 'bold',
271 'diff.diffline': 'bold',
272 'diff.extended': 'cyan bold',
272 'diff.extended': 'cyan bold',
273 'diff.file_a': 'red bold',
273 'diff.file_a': 'red bold',
274 'diff.file_b': 'green bold',
274 'diff.file_b': 'green bold',
275 'diff.hunk': 'magenta',
275 'diff.hunk': 'magenta',
276 'diff.inserted': 'green',
276 'diff.inserted': 'green',
277 'diff.trailingwhitespace': 'bold red_background',
277 'diff.trailingwhitespace': 'bold red_background',
278 'diffstat.deleted': 'red',
278 'diffstat.deleted': 'red',
279 'diffstat.inserted': 'green',
279 'diffstat.inserted': 'green',
280 'histedit.remaining': 'red bold',
280 'histedit.remaining': 'red bold',
281 'ui.prompt': 'yellow',
281 'ui.prompt': 'yellow',
282 'log.changeset': 'yellow',
282 'log.changeset': 'yellow',
283 'rebase.rebased': 'blue',
283 'rebase.rebased': 'blue',
284 'rebase.remaining': 'red bold',
284 'rebase.remaining': 'red bold',
285 'resolve.resolved': 'green bold',
285 'resolve.resolved': 'green bold',
286 'resolve.unresolved': 'red bold',
286 'resolve.unresolved': 'red bold',
287 'shelve.age': 'cyan',
287 'shelve.age': 'cyan',
288 'shelve.newest': 'green bold',
288 'shelve.newest': 'green bold',
289 'shelve.name': 'blue bold',
289 'shelve.name': 'blue bold',
290 'status.added': 'green bold',
290 'status.added': 'green bold',
291 'status.clean': 'none',
291 'status.clean': 'none',
292 'status.copied': 'none',
292 'status.copied': 'none',
293 'status.deleted': 'cyan bold underline',
293 'status.deleted': 'cyan bold underline',
294 'status.ignored': 'black bold',
294 'status.ignored': 'black bold',
295 'status.modified': 'blue bold',
295 'status.modified': 'blue bold',
296 'status.removed': 'red bold',
296 'status.removed': 'red bold',
297 'status.unknown': 'magenta bold underline',
297 'status.unknown': 'magenta bold underline',
298 'tags.normal': 'green',
298 'tags.normal': 'green',
299 'tags.local': 'black bold'}
299 'tags.local': 'black bold'}
300
300
301
301
302 def _effect_str(effect):
302 def _effect_str(effect):
303 '''Helper function for render_effects().'''
303 '''Helper function for render_effects().'''
304
304
305 bg = False
305 bg = False
306 if effect.endswith('_background'):
306 if effect.endswith('_background'):
307 bg = True
307 bg = True
308 effect = effect[:-11]
308 effect = effect[:-11]
309 attr, val = _terminfo_params[effect]
309 attr, val = _terminfo_params[effect]
310 if attr:
310 if attr:
311 return curses.tigetstr(val)
311 return curses.tigetstr(val)
312 elif bg:
312 elif bg:
313 return curses.tparm(curses.tigetstr('setab'), val)
313 return curses.tparm(curses.tigetstr('setab'), val)
314 else:
314 else:
315 return curses.tparm(curses.tigetstr('setaf'), val)
315 return curses.tparm(curses.tigetstr('setaf'), val)
316
316
317 def render_effects(text, effects):
317 def render_effects(text, effects):
318 'Wrap text in commands to turn on each effect.'
318 'Wrap text in commands to turn on each effect.'
319 if not text:
319 if not text:
320 return text
320 return text
321 if not _terminfo_params:
321 if not _terminfo_params:
322 start = [str(_effects[e]) for e in ['none'] + effects.split()]
322 start = [str(_effects[e]) for e in ['none'] + effects.split()]
323 start = '\033[' + ';'.join(start) + 'm'
323 start = '\033[' + ';'.join(start) + 'm'
324 stop = '\033[' + str(_effects['none']) + 'm'
324 stop = '\033[' + str(_effects['none']) + 'm'
325 else:
325 else:
326 start = ''.join(_effect_str(effect)
326 start = ''.join(_effect_str(effect)
327 for effect in ['none'] + effects.split())
327 for effect in ['none'] + effects.split())
328 stop = _effect_str('none')
328 stop = _effect_str('none')
329 return ''.join([start, text, stop])
329 return ''.join([start, text, stop])
330
330
331 def extstyles():
331 def extstyles():
332 for name, ext in extensions.extensions():
332 for name, ext in extensions.extensions():
333 _styles.update(getattr(ext, 'colortable', {}))
333 _styles.update(getattr(ext, 'colortable', {}))
334
334
335 def valideffect(effect):
335 def valideffect(effect):
336 'Determine if the effect is valid or not.'
336 'Determine if the effect is valid or not.'
337 good = False
337 good = False
338 if not _terminfo_params and effect in _effects:
338 if not _terminfo_params and effect in _effects:
339 good = True
339 good = True
340 elif effect in _terminfo_params or effect[:-11] in _terminfo_params:
340 elif effect in _terminfo_params or effect[:-11] in _terminfo_params:
341 good = True
341 good = True
342 return good
342 return good
343
343
344 def configstyles(ui):
344 def configstyles(ui):
345 for status, cfgeffects in ui.configitems('color'):
345 for status, cfgeffects in ui.configitems('color'):
346 if '.' not in status or status.startswith('color.'):
346 if '.' not in status or status.startswith('color.'):
347 continue
347 continue
348 cfgeffects = ui.configlist('color', status)
348 cfgeffects = ui.configlist('color', status)
349 if cfgeffects:
349 if cfgeffects:
350 good = []
350 good = []
351 for e in cfgeffects:
351 for e in cfgeffects:
352 if valideffect(e):
352 if valideffect(e):
353 good.append(e)
353 good.append(e)
354 else:
354 else:
355 ui.warn(_("ignoring unknown color/effect %r "
355 ui.warn(_("ignoring unknown color/effect %r "
356 "(configured in color.%s)\n")
356 "(configured in color.%s)\n")
357 % (e, status))
357 % (e, status))
358 _styles[status] = ' '.join(good)
358 _styles[status] = ' '.join(good)
359
359
360 class colorui(uimod.ui):
360 class colorui(uimod.ui):
361 def popbuffer(self, labeled=False):
361 def popbuffer(self, labeled=False):
362 if self._colormode is None:
362 if self._colormode is None:
363 return super(colorui, self).popbuffer(labeled)
363 return super(colorui, self).popbuffer(labeled)
364
364
365 self._bufferstates.pop()
365 self._bufferstates.pop()
366 if labeled:
366 if labeled:
367 return ''.join(self.label(a, label) for a, label
367 return ''.join(self.label(a, label) for a, label
368 in self._buffers.pop())
368 in self._buffers.pop())
369 return ''.join(a for a, label in self._buffers.pop())
369 return ''.join(a for a, label in self._buffers.pop())
370
370
371 _colormode = 'ansi'
371 _colormode = 'ansi'
372 def write(self, *args, **opts):
372 def write(self, *args, **opts):
373 if self._colormode is None:
373 if self._colormode is None:
374 return super(colorui, self).write(*args, **opts)
374 return super(colorui, self).write(*args, **opts)
375
375
376 label = opts.get('label', '')
376 label = opts.get('label', '')
377 if self._buffers:
377 if self._buffers:
378 self._buffers[-1].extend([(str(a), label) for a in args])
378 self._buffers[-1].extend([(str(a), label) for a in args])
379 elif self._colormode == 'win32':
379 elif self._colormode == 'win32':
380 for a in args:
380 for a in args:
381 win32print(a, super(colorui, self).write, **opts)
381 win32print(a, super(colorui, self).write, **opts)
382 else:
382 else:
383 return super(colorui, self).write(
383 return super(colorui, self).write(
384 *[self.label(str(a), label) for a in args], **opts)
384 *[self.label(str(a), label) for a in args], **opts)
385
385
386 def write_err(self, *args, **opts):
386 def write_err(self, *args, **opts):
387 if self._colormode is None:
387 if self._colormode is None:
388 return super(colorui, self).write_err(*args, **opts)
388 return super(colorui, self).write_err(*args, **opts)
389
389
390 label = opts.get('label', '')
390 label = opts.get('label', '')
391 if self._bufferstates and self._bufferstates[-1]:
391 if self._bufferstates and self._bufferstates[-1]:
392 return self.write(*args, **opts)
392 return self.write(*args, **opts)
393 if self._colormode == 'win32':
393 if self._colormode == 'win32':
394 for a in args:
394 for a in args:
395 win32print(a, super(colorui, self).write_err, **opts)
395 win32print(a, super(colorui, self).write_err, **opts)
396 else:
396 else:
397 return super(colorui, self).write_err(
397 return super(colorui, self).write_err(
398 *[self.label(str(a), label) for a in args], **opts)
398 *[self.label(str(a), label) for a in args], **opts)
399
399
400 def showlabel(self, msg, label):
400 def showlabel(self, msg, label):
401 if ' ' in label:
402 label = '[' + label + ']'
403 if label:
401 if label:
404 if msg and msg[-1] == '\n':
402 if msg and msg[-1] == '\n':
405 return "%s(%s)\n" % (label, msg[:-1])
403 return "[%s|%s]\n" % (label, msg[:-1])
406 else:
404 else:
407 return "%s(%s)" % (label, msg)
405 return "[%s|%s]" % (label, msg)
408 else:
406 else:
409 return msg
407 return msg
410
408
411 def label(self, msg, label):
409 def label(self, msg, label):
412 if self._colormode is None:
410 if self._colormode is None:
413 return super(colorui, self).label(msg, label)
411 return super(colorui, self).label(msg, label)
414
412
415 if self._colormode == 'debug':
413 if self._colormode == 'debug':
416 return self.showlabel(msg, label)
414 return self.showlabel(msg, label)
417
415
418 effects = []
416 effects = []
419 for l in label.split():
417 for l in label.split():
420 s = _styles.get(l, '')
418 s = _styles.get(l, '')
421 if s:
419 if s:
422 effects.append(s)
420 effects.append(s)
423 elif valideffect(l):
421 elif valideffect(l):
424 effects.append(l)
422 effects.append(l)
425 effects = ' '.join(effects)
423 effects = ' '.join(effects)
426 if effects:
424 if effects:
427 return '\n'.join([render_effects(s, effects)
425 return '\n'.join([render_effects(s, effects)
428 for s in msg.split('\n')])
426 for s in msg.split('\n')])
429 return msg
427 return msg
430
428
431 def templatelabel(context, mapping, args):
429 def templatelabel(context, mapping, args):
432 if len(args) != 2:
430 if len(args) != 2:
433 # i18n: "label" is a keyword
431 # i18n: "label" is a keyword
434 raise error.ParseError(_("label expects two arguments"))
432 raise error.ParseError(_("label expects two arguments"))
435
433
436 # add known effects to the mapping so symbols like 'red', 'bold',
434 # add known effects to the mapping so symbols like 'red', 'bold',
437 # etc. don't need to be quoted
435 # etc. don't need to be quoted
438 mapping.update(dict([(k, k) for k in _effects]))
436 mapping.update(dict([(k, k) for k in _effects]))
439
437
440 thing = templater._evalifliteral(args[1], context, mapping)
438 thing = templater._evalifliteral(args[1], context, mapping)
441
439
442 # apparently, repo could be a string that is the favicon?
440 # apparently, repo could be a string that is the favicon?
443 repo = mapping.get('repo', '')
441 repo = mapping.get('repo', '')
444 if isinstance(repo, str):
442 if isinstance(repo, str):
445 return thing
443 return thing
446
444
447 label = templater._evalifliteral(args[0], context, mapping)
445 label = templater._evalifliteral(args[0], context, mapping)
448
446
449 thing = templater.stringify(thing)
447 thing = templater.stringify(thing)
450 label = templater.stringify(label)
448 label = templater.stringify(label)
451
449
452 return repo.ui.label(thing, label)
450 return repo.ui.label(thing, label)
453
451
454 def uisetup(ui):
452 def uisetup(ui):
455 if ui.plain():
453 if ui.plain():
456 return
454 return
457 if not isinstance(ui, colorui):
455 if not isinstance(ui, colorui):
458 colorui.__bases__ = (ui.__class__,)
456 colorui.__bases__ = (ui.__class__,)
459 ui.__class__ = colorui
457 ui.__class__ = colorui
460 def colorcmd(orig, ui_, opts, cmd, cmdfunc):
458 def colorcmd(orig, ui_, opts, cmd, cmdfunc):
461 mode = _modesetup(ui_, opts['color'])
459 mode = _modesetup(ui_, opts['color'])
462 colorui._colormode = mode
460 colorui._colormode = mode
463 if mode and mode != 'debug':
461 if mode and mode != 'debug':
464 extstyles()
462 extstyles()
465 configstyles(ui_)
463 configstyles(ui_)
466 return orig(ui_, opts, cmd, cmdfunc)
464 return orig(ui_, opts, cmd, cmdfunc)
467 extensions.wrapfunction(dispatch, '_runcommand', colorcmd)
465 extensions.wrapfunction(dispatch, '_runcommand', colorcmd)
468 templater.funcs['label'] = templatelabel
466 templater.funcs['label'] = templatelabel
469
467
470 def extsetup(ui):
468 def extsetup(ui):
471 commands.globalopts.append(
469 commands.globalopts.append(
472 ('', 'color', 'auto',
470 ('', 'color', 'auto',
473 # i18n: 'always', 'auto', 'never', and 'debug' are keywords
471 # i18n: 'always', 'auto', 'never', and 'debug' are keywords
474 # and should not be translated
472 # and should not be translated
475 _("when to colorize (boolean, always, auto, never, or debug)"),
473 _("when to colorize (boolean, always, auto, never, or debug)"),
476 _('TYPE')))
474 _('TYPE')))
477
475
478 @command('debugcolor', [], 'hg debugcolor')
476 @command('debugcolor', [], 'hg debugcolor')
479 def debugcolor(ui, repo, **opts):
477 def debugcolor(ui, repo, **opts):
480 global _styles
478 global _styles
481 _styles = {}
479 _styles = {}
482 for effect in _effects.keys():
480 for effect in _effects.keys():
483 _styles[effect] = effect
481 _styles[effect] = effect
484 ui.write(('color mode: %s\n') % ui._colormode)
482 ui.write(('color mode: %s\n') % ui._colormode)
485 ui.write(_('available colors:\n'))
483 ui.write(_('available colors:\n'))
486 for label, colors in _styles.items():
484 for label, colors in _styles.items():
487 ui.write(('%s\n') % colors, label=label)
485 ui.write(('%s\n') % colors, label=label)
488
486
489 if os.name != 'nt':
487 if os.name != 'nt':
490 w32effects = None
488 w32effects = None
491 else:
489 else:
492 import re, ctypes
490 import re, ctypes
493
491
494 _kernel32 = ctypes.windll.kernel32
492 _kernel32 = ctypes.windll.kernel32
495
493
496 _WORD = ctypes.c_ushort
494 _WORD = ctypes.c_ushort
497
495
498 _INVALID_HANDLE_VALUE = -1
496 _INVALID_HANDLE_VALUE = -1
499
497
500 class _COORD(ctypes.Structure):
498 class _COORD(ctypes.Structure):
501 _fields_ = [('X', ctypes.c_short),
499 _fields_ = [('X', ctypes.c_short),
502 ('Y', ctypes.c_short)]
500 ('Y', ctypes.c_short)]
503
501
504 class _SMALL_RECT(ctypes.Structure):
502 class _SMALL_RECT(ctypes.Structure):
505 _fields_ = [('Left', ctypes.c_short),
503 _fields_ = [('Left', ctypes.c_short),
506 ('Top', ctypes.c_short),
504 ('Top', ctypes.c_short),
507 ('Right', ctypes.c_short),
505 ('Right', ctypes.c_short),
508 ('Bottom', ctypes.c_short)]
506 ('Bottom', ctypes.c_short)]
509
507
510 class _CONSOLE_SCREEN_BUFFER_INFO(ctypes.Structure):
508 class _CONSOLE_SCREEN_BUFFER_INFO(ctypes.Structure):
511 _fields_ = [('dwSize', _COORD),
509 _fields_ = [('dwSize', _COORD),
512 ('dwCursorPosition', _COORD),
510 ('dwCursorPosition', _COORD),
513 ('wAttributes', _WORD),
511 ('wAttributes', _WORD),
514 ('srWindow', _SMALL_RECT),
512 ('srWindow', _SMALL_RECT),
515 ('dwMaximumWindowSize', _COORD)]
513 ('dwMaximumWindowSize', _COORD)]
516
514
517 _STD_OUTPUT_HANDLE = 0xfffffff5L # (DWORD)-11
515 _STD_OUTPUT_HANDLE = 0xfffffff5L # (DWORD)-11
518 _STD_ERROR_HANDLE = 0xfffffff4L # (DWORD)-12
516 _STD_ERROR_HANDLE = 0xfffffff4L # (DWORD)-12
519
517
520 _FOREGROUND_BLUE = 0x0001
518 _FOREGROUND_BLUE = 0x0001
521 _FOREGROUND_GREEN = 0x0002
519 _FOREGROUND_GREEN = 0x0002
522 _FOREGROUND_RED = 0x0004
520 _FOREGROUND_RED = 0x0004
523 _FOREGROUND_INTENSITY = 0x0008
521 _FOREGROUND_INTENSITY = 0x0008
524
522
525 _BACKGROUND_BLUE = 0x0010
523 _BACKGROUND_BLUE = 0x0010
526 _BACKGROUND_GREEN = 0x0020
524 _BACKGROUND_GREEN = 0x0020
527 _BACKGROUND_RED = 0x0040
525 _BACKGROUND_RED = 0x0040
528 _BACKGROUND_INTENSITY = 0x0080
526 _BACKGROUND_INTENSITY = 0x0080
529
527
530 _COMMON_LVB_REVERSE_VIDEO = 0x4000
528 _COMMON_LVB_REVERSE_VIDEO = 0x4000
531 _COMMON_LVB_UNDERSCORE = 0x8000
529 _COMMON_LVB_UNDERSCORE = 0x8000
532
530
533 # http://msdn.microsoft.com/en-us/library/ms682088%28VS.85%29.aspx
531 # http://msdn.microsoft.com/en-us/library/ms682088%28VS.85%29.aspx
534 w32effects = {
532 w32effects = {
535 'none': -1,
533 'none': -1,
536 'black': 0,
534 'black': 0,
537 'red': _FOREGROUND_RED,
535 'red': _FOREGROUND_RED,
538 'green': _FOREGROUND_GREEN,
536 'green': _FOREGROUND_GREEN,
539 'yellow': _FOREGROUND_RED | _FOREGROUND_GREEN,
537 'yellow': _FOREGROUND_RED | _FOREGROUND_GREEN,
540 'blue': _FOREGROUND_BLUE,
538 'blue': _FOREGROUND_BLUE,
541 'magenta': _FOREGROUND_BLUE | _FOREGROUND_RED,
539 'magenta': _FOREGROUND_BLUE | _FOREGROUND_RED,
542 'cyan': _FOREGROUND_BLUE | _FOREGROUND_GREEN,
540 'cyan': _FOREGROUND_BLUE | _FOREGROUND_GREEN,
543 'white': _FOREGROUND_RED | _FOREGROUND_GREEN | _FOREGROUND_BLUE,
541 'white': _FOREGROUND_RED | _FOREGROUND_GREEN | _FOREGROUND_BLUE,
544 'bold': _FOREGROUND_INTENSITY,
542 'bold': _FOREGROUND_INTENSITY,
545 'black_background': 0x100, # unused value > 0x0f
543 'black_background': 0x100, # unused value > 0x0f
546 'red_background': _BACKGROUND_RED,
544 'red_background': _BACKGROUND_RED,
547 'green_background': _BACKGROUND_GREEN,
545 'green_background': _BACKGROUND_GREEN,
548 'yellow_background': _BACKGROUND_RED | _BACKGROUND_GREEN,
546 'yellow_background': _BACKGROUND_RED | _BACKGROUND_GREEN,
549 'blue_background': _BACKGROUND_BLUE,
547 'blue_background': _BACKGROUND_BLUE,
550 'purple_background': _BACKGROUND_BLUE | _BACKGROUND_RED,
548 'purple_background': _BACKGROUND_BLUE | _BACKGROUND_RED,
551 'cyan_background': _BACKGROUND_BLUE | _BACKGROUND_GREEN,
549 'cyan_background': _BACKGROUND_BLUE | _BACKGROUND_GREEN,
552 'white_background': (_BACKGROUND_RED | _BACKGROUND_GREEN |
550 'white_background': (_BACKGROUND_RED | _BACKGROUND_GREEN |
553 _BACKGROUND_BLUE),
551 _BACKGROUND_BLUE),
554 'bold_background': _BACKGROUND_INTENSITY,
552 'bold_background': _BACKGROUND_INTENSITY,
555 'underline': _COMMON_LVB_UNDERSCORE, # double-byte charsets only
553 'underline': _COMMON_LVB_UNDERSCORE, # double-byte charsets only
556 'inverse': _COMMON_LVB_REVERSE_VIDEO, # double-byte charsets only
554 'inverse': _COMMON_LVB_REVERSE_VIDEO, # double-byte charsets only
557 }
555 }
558
556
559 passthrough = set([_FOREGROUND_INTENSITY,
557 passthrough = set([_FOREGROUND_INTENSITY,
560 _BACKGROUND_INTENSITY,
558 _BACKGROUND_INTENSITY,
561 _COMMON_LVB_UNDERSCORE,
559 _COMMON_LVB_UNDERSCORE,
562 _COMMON_LVB_REVERSE_VIDEO])
560 _COMMON_LVB_REVERSE_VIDEO])
563
561
564 stdout = _kernel32.GetStdHandle(
562 stdout = _kernel32.GetStdHandle(
565 _STD_OUTPUT_HANDLE) # don't close the handle returned
563 _STD_OUTPUT_HANDLE) # don't close the handle returned
566 if stdout is None or stdout == _INVALID_HANDLE_VALUE:
564 if stdout is None or stdout == _INVALID_HANDLE_VALUE:
567 w32effects = None
565 w32effects = None
568 else:
566 else:
569 csbi = _CONSOLE_SCREEN_BUFFER_INFO()
567 csbi = _CONSOLE_SCREEN_BUFFER_INFO()
570 if not _kernel32.GetConsoleScreenBufferInfo(
568 if not _kernel32.GetConsoleScreenBufferInfo(
571 stdout, ctypes.byref(csbi)):
569 stdout, ctypes.byref(csbi)):
572 # stdout may not support GetConsoleScreenBufferInfo()
570 # stdout may not support GetConsoleScreenBufferInfo()
573 # when called from subprocess or redirected
571 # when called from subprocess or redirected
574 w32effects = None
572 w32effects = None
575 else:
573 else:
576 origattr = csbi.wAttributes
574 origattr = csbi.wAttributes
577 ansire = re.compile('\033\[([^m]*)m([^\033]*)(.*)',
575 ansire = re.compile('\033\[([^m]*)m([^\033]*)(.*)',
578 re.MULTILINE | re.DOTALL)
576 re.MULTILINE | re.DOTALL)
579
577
580 def win32print(text, orig, **opts):
578 def win32print(text, orig, **opts):
581 label = opts.get('label', '')
579 label = opts.get('label', '')
582 attr = origattr
580 attr = origattr
583
581
584 def mapcolor(val, attr):
582 def mapcolor(val, attr):
585 if val == -1:
583 if val == -1:
586 return origattr
584 return origattr
587 elif val in passthrough:
585 elif val in passthrough:
588 return attr | val
586 return attr | val
589 elif val > 0x0f:
587 elif val > 0x0f:
590 return (val & 0x70) | (attr & 0x8f)
588 return (val & 0x70) | (attr & 0x8f)
591 else:
589 else:
592 return (val & 0x07) | (attr & 0xf8)
590 return (val & 0x07) | (attr & 0xf8)
593
591
594 # determine console attributes based on labels
592 # determine console attributes based on labels
595 for l in label.split():
593 for l in label.split():
596 style = _styles.get(l, '')
594 style = _styles.get(l, '')
597 for effect in style.split():
595 for effect in style.split():
598 try:
596 try:
599 attr = mapcolor(w32effects[effect], attr)
597 attr = mapcolor(w32effects[effect], attr)
600 except KeyError:
598 except KeyError:
601 # w32effects could not have certain attributes so we skip
599 # w32effects could not have certain attributes so we skip
602 # them if not found
600 # them if not found
603 pass
601 pass
604 # hack to ensure regexp finds data
602 # hack to ensure regexp finds data
605 if not text.startswith('\033['):
603 if not text.startswith('\033['):
606 text = '\033[m' + text
604 text = '\033[m' + text
607
605
608 # Look for ANSI-like codes embedded in text
606 # Look for ANSI-like codes embedded in text
609 m = re.match(ansire, text)
607 m = re.match(ansire, text)
610
608
611 try:
609 try:
612 while m:
610 while m:
613 for sattr in m.group(1).split(';'):
611 for sattr in m.group(1).split(';'):
614 if sattr:
612 if sattr:
615 attr = mapcolor(int(sattr), attr)
613 attr = mapcolor(int(sattr), attr)
616 _kernel32.SetConsoleTextAttribute(stdout, attr)
614 _kernel32.SetConsoleTextAttribute(stdout, attr)
617 orig(m.group(2), **opts)
615 orig(m.group(2), **opts)
618 m = re.match(ansire, m.group(3))
616 m = re.match(ansire, m.group(3))
619 finally:
617 finally:
620 # Explicitly reset original attributes
618 # Explicitly reset original attributes
621 _kernel32.SetConsoleTextAttribute(stdout, origattr)
619 _kernel32.SetConsoleTextAttribute(stdout, origattr)
@@ -1,350 +1,350 b''
1 $ echo "[extensions]" >> $HGRCPATH
1 $ echo "[extensions]" >> $HGRCPATH
2 $ echo "color=" >> $HGRCPATH
2 $ echo "color=" >> $HGRCPATH
3 $ echo "[color]" >> $HGRCPATH
3 $ echo "[color]" >> $HGRCPATH
4 $ echo "mode=ansi" >> $HGRCPATH
4 $ echo "mode=ansi" >> $HGRCPATH
5 Terminfo codes compatibility fix
5 Terminfo codes compatibility fix
6 $ echo "color.none=0" >> $HGRCPATH
6 $ echo "color.none=0" >> $HGRCPATH
7
7
8 $ hg init repo1
8 $ hg init repo1
9 $ cd repo1
9 $ cd repo1
10 $ mkdir a b a/1 b/1 b/2
10 $ mkdir a b a/1 b/1 b/2
11 $ touch in_root a/in_a b/in_b a/1/in_a_1 b/1/in_b_1 b/2/in_b_2
11 $ touch in_root a/in_a b/in_b a/1/in_a_1 b/1/in_b_1 b/2/in_b_2
12
12
13 hg status in repo root:
13 hg status in repo root:
14
14
15 $ hg status --color=always
15 $ hg status --color=always
16 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/1/in_a_1\x1b[0m (esc)
16 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/1/in_a_1\x1b[0m (esc)
17 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/in_a\x1b[0m (esc)
17 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/in_a\x1b[0m (esc)
18 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/1/in_b_1\x1b[0m (esc)
18 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/1/in_b_1\x1b[0m (esc)
19 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/2/in_b_2\x1b[0m (esc)
19 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/2/in_b_2\x1b[0m (esc)
20 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/in_b\x1b[0m (esc)
20 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/in_b\x1b[0m (esc)
21 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_root\x1b[0m (esc)
21 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_root\x1b[0m (esc)
22
22
23 $ hg status --color=debug
23 $ hg status --color=debug
24 status.unknown(? )status.unknown(a/1/in_a_1)
24 [status.unknown|? ][status.unknown|a/1/in_a_1]
25 status.unknown(? )status.unknown(a/in_a)
25 [status.unknown|? ][status.unknown|a/in_a]
26 status.unknown(? )status.unknown(b/1/in_b_1)
26 [status.unknown|? ][status.unknown|b/1/in_b_1]
27 status.unknown(? )status.unknown(b/2/in_b_2)
27 [status.unknown|? ][status.unknown|b/2/in_b_2]
28 status.unknown(? )status.unknown(b/in_b)
28 [status.unknown|? ][status.unknown|b/in_b]
29 status.unknown(? )status.unknown(in_root)
29 [status.unknown|? ][status.unknown|in_root]
30
30
31 hg status . in repo root:
31 hg status . in repo root:
32
32
33 $ hg status --color=always .
33 $ hg status --color=always .
34 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/1/in_a_1\x1b[0m (esc)
34 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/1/in_a_1\x1b[0m (esc)
35 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/in_a\x1b[0m (esc)
35 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/in_a\x1b[0m (esc)
36 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/1/in_b_1\x1b[0m (esc)
36 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/1/in_b_1\x1b[0m (esc)
37 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/2/in_b_2\x1b[0m (esc)
37 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/2/in_b_2\x1b[0m (esc)
38 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/in_b\x1b[0m (esc)
38 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/in_b\x1b[0m (esc)
39 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_root\x1b[0m (esc)
39 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_root\x1b[0m (esc)
40
40
41 $ hg status --color=always --cwd a
41 $ hg status --color=always --cwd a
42 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/1/in_a_1\x1b[0m (esc)
42 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/1/in_a_1\x1b[0m (esc)
43 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/in_a\x1b[0m (esc)
43 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/in_a\x1b[0m (esc)
44 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/1/in_b_1\x1b[0m (esc)
44 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/1/in_b_1\x1b[0m (esc)
45 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/2/in_b_2\x1b[0m (esc)
45 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/2/in_b_2\x1b[0m (esc)
46 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/in_b\x1b[0m (esc)
46 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/in_b\x1b[0m (esc)
47 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_root\x1b[0m (esc)
47 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_root\x1b[0m (esc)
48 $ hg status --color=always --cwd a .
48 $ hg status --color=always --cwd a .
49 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m1/in_a_1\x1b[0m (esc)
49 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m1/in_a_1\x1b[0m (esc)
50 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_a\x1b[0m (esc)
50 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_a\x1b[0m (esc)
51 $ hg status --color=always --cwd a ..
51 $ hg status --color=always --cwd a ..
52 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m1/in_a_1\x1b[0m (esc)
52 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m1/in_a_1\x1b[0m (esc)
53 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_a\x1b[0m (esc)
53 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_a\x1b[0m (esc)
54 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../b/1/in_b_1\x1b[0m (esc)
54 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../b/1/in_b_1\x1b[0m (esc)
55 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../b/2/in_b_2\x1b[0m (esc)
55 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../b/2/in_b_2\x1b[0m (esc)
56 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../b/in_b\x1b[0m (esc)
56 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../b/in_b\x1b[0m (esc)
57 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../in_root\x1b[0m (esc)
57 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../in_root\x1b[0m (esc)
58
58
59 $ hg status --color=always --cwd b
59 $ hg status --color=always --cwd b
60 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/1/in_a_1\x1b[0m (esc)
60 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/1/in_a_1\x1b[0m (esc)
61 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/in_a\x1b[0m (esc)
61 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/in_a\x1b[0m (esc)
62 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/1/in_b_1\x1b[0m (esc)
62 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/1/in_b_1\x1b[0m (esc)
63 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/2/in_b_2\x1b[0m (esc)
63 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/2/in_b_2\x1b[0m (esc)
64 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/in_b\x1b[0m (esc)
64 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/in_b\x1b[0m (esc)
65 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_root\x1b[0m (esc)
65 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_root\x1b[0m (esc)
66 $ hg status --color=always --cwd b .
66 $ hg status --color=always --cwd b .
67 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m1/in_b_1\x1b[0m (esc)
67 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m1/in_b_1\x1b[0m (esc)
68 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m2/in_b_2\x1b[0m (esc)
68 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m2/in_b_2\x1b[0m (esc)
69 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_b\x1b[0m (esc)
69 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_b\x1b[0m (esc)
70 $ hg status --color=always --cwd b ..
70 $ hg status --color=always --cwd b ..
71 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../a/1/in_a_1\x1b[0m (esc)
71 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../a/1/in_a_1\x1b[0m (esc)
72 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../a/in_a\x1b[0m (esc)
72 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../a/in_a\x1b[0m (esc)
73 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m1/in_b_1\x1b[0m (esc)
73 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m1/in_b_1\x1b[0m (esc)
74 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m2/in_b_2\x1b[0m (esc)
74 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m2/in_b_2\x1b[0m (esc)
75 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_b\x1b[0m (esc)
75 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_b\x1b[0m (esc)
76 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../in_root\x1b[0m (esc)
76 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../in_root\x1b[0m (esc)
77
77
78 $ hg status --color=always --cwd a/1
78 $ hg status --color=always --cwd a/1
79 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/1/in_a_1\x1b[0m (esc)
79 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/1/in_a_1\x1b[0m (esc)
80 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/in_a\x1b[0m (esc)
80 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/in_a\x1b[0m (esc)
81 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/1/in_b_1\x1b[0m (esc)
81 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/1/in_b_1\x1b[0m (esc)
82 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/2/in_b_2\x1b[0m (esc)
82 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/2/in_b_2\x1b[0m (esc)
83 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/in_b\x1b[0m (esc)
83 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/in_b\x1b[0m (esc)
84 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_root\x1b[0m (esc)
84 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_root\x1b[0m (esc)
85 $ hg status --color=always --cwd a/1 .
85 $ hg status --color=always --cwd a/1 .
86 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_a_1\x1b[0m (esc)
86 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_a_1\x1b[0m (esc)
87 $ hg status --color=always --cwd a/1 ..
87 $ hg status --color=always --cwd a/1 ..
88 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_a_1\x1b[0m (esc)
88 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_a_1\x1b[0m (esc)
89 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../in_a\x1b[0m (esc)
89 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../in_a\x1b[0m (esc)
90
90
91 $ hg status --color=always --cwd b/1
91 $ hg status --color=always --cwd b/1
92 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/1/in_a_1\x1b[0m (esc)
92 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/1/in_a_1\x1b[0m (esc)
93 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/in_a\x1b[0m (esc)
93 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/in_a\x1b[0m (esc)
94 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/1/in_b_1\x1b[0m (esc)
94 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/1/in_b_1\x1b[0m (esc)
95 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/2/in_b_2\x1b[0m (esc)
95 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/2/in_b_2\x1b[0m (esc)
96 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/in_b\x1b[0m (esc)
96 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/in_b\x1b[0m (esc)
97 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_root\x1b[0m (esc)
97 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_root\x1b[0m (esc)
98 $ hg status --color=always --cwd b/1 .
98 $ hg status --color=always --cwd b/1 .
99 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_b_1\x1b[0m (esc)
99 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_b_1\x1b[0m (esc)
100 $ hg status --color=always --cwd b/1 ..
100 $ hg status --color=always --cwd b/1 ..
101 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_b_1\x1b[0m (esc)
101 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_b_1\x1b[0m (esc)
102 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../2/in_b_2\x1b[0m (esc)
102 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../2/in_b_2\x1b[0m (esc)
103 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../in_b\x1b[0m (esc)
103 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../in_b\x1b[0m (esc)
104
104
105 $ hg status --color=always --cwd b/2
105 $ hg status --color=always --cwd b/2
106 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/1/in_a_1\x1b[0m (esc)
106 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/1/in_a_1\x1b[0m (esc)
107 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/in_a\x1b[0m (esc)
107 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/in_a\x1b[0m (esc)
108 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/1/in_b_1\x1b[0m (esc)
108 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/1/in_b_1\x1b[0m (esc)
109 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/2/in_b_2\x1b[0m (esc)
109 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/2/in_b_2\x1b[0m (esc)
110 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/in_b\x1b[0m (esc)
110 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/in_b\x1b[0m (esc)
111 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_root\x1b[0m (esc)
111 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_root\x1b[0m (esc)
112 $ hg status --color=always --cwd b/2 .
112 $ hg status --color=always --cwd b/2 .
113 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_b_2\x1b[0m (esc)
113 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_b_2\x1b[0m (esc)
114 $ hg status --color=always --cwd b/2 ..
114 $ hg status --color=always --cwd b/2 ..
115 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../1/in_b_1\x1b[0m (esc)
115 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../1/in_b_1\x1b[0m (esc)
116 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_b_2\x1b[0m (esc)
116 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_b_2\x1b[0m (esc)
117 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../in_b\x1b[0m (esc)
117 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../in_b\x1b[0m (esc)
118
118
119 Make sure --color=never works
119 Make sure --color=never works
120 $ hg status --color=never
120 $ hg status --color=never
121 ? a/1/in_a_1
121 ? a/1/in_a_1
122 ? a/in_a
122 ? a/in_a
123 ? b/1/in_b_1
123 ? b/1/in_b_1
124 ? b/2/in_b_2
124 ? b/2/in_b_2
125 ? b/in_b
125 ? b/in_b
126 ? in_root
126 ? in_root
127
127
128 Make sure ui.formatted=False works
128 Make sure ui.formatted=False works
129 $ hg status --config ui.formatted=False
129 $ hg status --config ui.formatted=False
130 ? a/1/in_a_1
130 ? a/1/in_a_1
131 ? a/in_a
131 ? a/in_a
132 ? b/1/in_b_1
132 ? b/1/in_b_1
133 ? b/2/in_b_2
133 ? b/2/in_b_2
134 ? b/in_b
134 ? b/in_b
135 ? in_root
135 ? in_root
136
136
137 $ cd ..
137 $ cd ..
138
138
139 $ hg init repo2
139 $ hg init repo2
140 $ cd repo2
140 $ cd repo2
141 $ touch modified removed deleted ignored
141 $ touch modified removed deleted ignored
142 $ echo "^ignored$" > .hgignore
142 $ echo "^ignored$" > .hgignore
143 $ hg ci -A -m 'initial checkin'
143 $ hg ci -A -m 'initial checkin'
144 adding .hgignore
144 adding .hgignore
145 adding deleted
145 adding deleted
146 adding modified
146 adding modified
147 adding removed
147 adding removed
148 $ hg log --color=debug
148 $ hg log --color=debug
149 [log.changeset changeset.draft](changeset: 0:389aef86a55e)
149 [log.changeset changeset.draft|changeset: 0:389aef86a55e]
150 log.tag(tag: tip)
150 [log.tag|tag: tip]
151 log.user(user: test)
151 [log.user|user: test]
152 log.date(date: Thu Jan 01 00:00:00 1970 +0000)
152 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
153 log.summary(summary: initial checkin)
153 [log.summary|summary: initial checkin]
154
154
155 $ touch modified added unknown ignored
155 $ touch modified added unknown ignored
156 $ hg add added
156 $ hg add added
157 $ hg remove removed
157 $ hg remove removed
158 $ rm deleted
158 $ rm deleted
159
159
160 hg status:
160 hg status:
161
161
162 $ hg status --color=always
162 $ hg status --color=always
163 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1madded\x1b[0m (esc)
163 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1madded\x1b[0m (esc)
164 \x1b[0;31;1mR \x1b[0m\x1b[0;31;1mremoved\x1b[0m (esc)
164 \x1b[0;31;1mR \x1b[0m\x1b[0;31;1mremoved\x1b[0m (esc)
165 \x1b[0;36;1;4m! \x1b[0m\x1b[0;36;1;4mdeleted\x1b[0m (esc)
165 \x1b[0;36;1;4m! \x1b[0m\x1b[0;36;1;4mdeleted\x1b[0m (esc)
166 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4munknown\x1b[0m (esc)
166 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4munknown\x1b[0m (esc)
167
167
168 hg status modified added removed deleted unknown never-existed ignored:
168 hg status modified added removed deleted unknown never-existed ignored:
169
169
170 $ hg status --color=always modified added removed deleted unknown never-existed ignored
170 $ hg status --color=always modified added removed deleted unknown never-existed ignored
171 never-existed: * (glob)
171 never-existed: * (glob)
172 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1madded\x1b[0m (esc)
172 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1madded\x1b[0m (esc)
173 \x1b[0;31;1mR \x1b[0m\x1b[0;31;1mremoved\x1b[0m (esc)
173 \x1b[0;31;1mR \x1b[0m\x1b[0;31;1mremoved\x1b[0m (esc)
174 \x1b[0;36;1;4m! \x1b[0m\x1b[0;36;1;4mdeleted\x1b[0m (esc)
174 \x1b[0;36;1;4m! \x1b[0m\x1b[0;36;1;4mdeleted\x1b[0m (esc)
175 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4munknown\x1b[0m (esc)
175 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4munknown\x1b[0m (esc)
176
176
177 $ hg copy modified copied
177 $ hg copy modified copied
178
178
179 hg status -C:
179 hg status -C:
180
180
181 $ hg status --color=always -C
181 $ hg status --color=always -C
182 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1madded\x1b[0m (esc)
182 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1madded\x1b[0m (esc)
183 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1mcopied\x1b[0m (esc)
183 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1mcopied\x1b[0m (esc)
184 \x1b[0;0m modified\x1b[0m (esc)
184 \x1b[0;0m modified\x1b[0m (esc)
185 \x1b[0;31;1mR \x1b[0m\x1b[0;31;1mremoved\x1b[0m (esc)
185 \x1b[0;31;1mR \x1b[0m\x1b[0;31;1mremoved\x1b[0m (esc)
186 \x1b[0;36;1;4m! \x1b[0m\x1b[0;36;1;4mdeleted\x1b[0m (esc)
186 \x1b[0;36;1;4m! \x1b[0m\x1b[0;36;1;4mdeleted\x1b[0m (esc)
187 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4munknown\x1b[0m (esc)
187 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4munknown\x1b[0m (esc)
188
188
189 hg status -A:
189 hg status -A:
190
190
191 $ hg status --color=always -A
191 $ hg status --color=always -A
192 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1madded\x1b[0m (esc)
192 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1madded\x1b[0m (esc)
193 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1mcopied\x1b[0m (esc)
193 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1mcopied\x1b[0m (esc)
194 \x1b[0;0m modified\x1b[0m (esc)
194 \x1b[0;0m modified\x1b[0m (esc)
195 \x1b[0;31;1mR \x1b[0m\x1b[0;31;1mremoved\x1b[0m (esc)
195 \x1b[0;31;1mR \x1b[0m\x1b[0;31;1mremoved\x1b[0m (esc)
196 \x1b[0;36;1;4m! \x1b[0m\x1b[0;36;1;4mdeleted\x1b[0m (esc)
196 \x1b[0;36;1;4m! \x1b[0m\x1b[0;36;1;4mdeleted\x1b[0m (esc)
197 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4munknown\x1b[0m (esc)
197 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4munknown\x1b[0m (esc)
198 \x1b[0;30;1mI \x1b[0m\x1b[0;30;1mignored\x1b[0m (esc)
198 \x1b[0;30;1mI \x1b[0m\x1b[0;30;1mignored\x1b[0m (esc)
199 \x1b[0;0mC \x1b[0m\x1b[0;0m.hgignore\x1b[0m (esc)
199 \x1b[0;0mC \x1b[0m\x1b[0;0m.hgignore\x1b[0m (esc)
200 \x1b[0;0mC \x1b[0m\x1b[0;0mmodified\x1b[0m (esc)
200 \x1b[0;0mC \x1b[0m\x1b[0;0mmodified\x1b[0m (esc)
201
201
202
202
203 hg status -A (with terminfo color):
203 hg status -A (with terminfo color):
204
204
205 #if tic
205 #if tic
206
206
207 $ mkdir "$TESTTMP/terminfo"
207 $ mkdir "$TESTTMP/terminfo"
208 $ TERMINFO="$TESTTMP/terminfo" tic "$TESTDIR/hgterm.ti"
208 $ TERMINFO="$TESTTMP/terminfo" tic "$TESTDIR/hgterm.ti"
209 $ TERM=hgterm TERMINFO="$TESTTMP/terminfo" hg status --config color.mode=terminfo --color=always -A
209 $ TERM=hgterm TERMINFO="$TESTTMP/terminfo" hg status --config color.mode=terminfo --color=always -A
210 \x1b[30m\x1b[32m\x1b[1mA \x1b[30m\x1b[30m\x1b[32m\x1b[1madded\x1b[30m (esc)
210 \x1b[30m\x1b[32m\x1b[1mA \x1b[30m\x1b[30m\x1b[32m\x1b[1madded\x1b[30m (esc)
211 \x1b[30m\x1b[32m\x1b[1mA \x1b[30m\x1b[30m\x1b[32m\x1b[1mcopied\x1b[30m (esc)
211 \x1b[30m\x1b[32m\x1b[1mA \x1b[30m\x1b[30m\x1b[32m\x1b[1mcopied\x1b[30m (esc)
212 \x1b[30m\x1b[30m modified\x1b[30m (esc)
212 \x1b[30m\x1b[30m modified\x1b[30m (esc)
213 \x1b[30m\x1b[31m\x1b[1mR \x1b[30m\x1b[30m\x1b[31m\x1b[1mremoved\x1b[30m (esc)
213 \x1b[30m\x1b[31m\x1b[1mR \x1b[30m\x1b[30m\x1b[31m\x1b[1mremoved\x1b[30m (esc)
214 \x1b[30m\x1b[36m\x1b[1m\x1b[4m! \x1b[30m\x1b[30m\x1b[36m\x1b[1m\x1b[4mdeleted\x1b[30m (esc)
214 \x1b[30m\x1b[36m\x1b[1m\x1b[4m! \x1b[30m\x1b[30m\x1b[36m\x1b[1m\x1b[4mdeleted\x1b[30m (esc)
215 \x1b[30m\x1b[35m\x1b[1m\x1b[4m? \x1b[30m\x1b[30m\x1b[35m\x1b[1m\x1b[4munknown\x1b[30m (esc)
215 \x1b[30m\x1b[35m\x1b[1m\x1b[4m? \x1b[30m\x1b[30m\x1b[35m\x1b[1m\x1b[4munknown\x1b[30m (esc)
216 \x1b[30m\x1b[30m\x1b[1mI \x1b[30m\x1b[30m\x1b[30m\x1b[1mignored\x1b[30m (esc)
216 \x1b[30m\x1b[30m\x1b[1mI \x1b[30m\x1b[30m\x1b[30m\x1b[1mignored\x1b[30m (esc)
217 \x1b[30m\x1b[30mC \x1b[30m\x1b[30m\x1b[30m.hgignore\x1b[30m (esc)
217 \x1b[30m\x1b[30mC \x1b[30m\x1b[30m\x1b[30m.hgignore\x1b[30m (esc)
218 \x1b[30m\x1b[30mC \x1b[30m\x1b[30m\x1b[30mmodified\x1b[30m (esc)
218 \x1b[30m\x1b[30mC \x1b[30m\x1b[30m\x1b[30mmodified\x1b[30m (esc)
219
219
220 #endif
220 #endif
221
221
222
222
223 $ echo "^ignoreddir$" > .hgignore
223 $ echo "^ignoreddir$" > .hgignore
224 $ mkdir ignoreddir
224 $ mkdir ignoreddir
225 $ touch ignoreddir/file
225 $ touch ignoreddir/file
226
226
227 hg status ignoreddir/file:
227 hg status ignoreddir/file:
228
228
229 $ hg status --color=always ignoreddir/file
229 $ hg status --color=always ignoreddir/file
230
230
231 hg status -i ignoreddir/file:
231 hg status -i ignoreddir/file:
232
232
233 $ hg status --color=always -i ignoreddir/file
233 $ hg status --color=always -i ignoreddir/file
234 \x1b[0;30;1mI \x1b[0m\x1b[0;30;1mignoreddir/file\x1b[0m (esc)
234 \x1b[0;30;1mI \x1b[0m\x1b[0;30;1mignoreddir/file\x1b[0m (esc)
235 $ cd ..
235 $ cd ..
236
236
237 check 'status -q' and some combinations
237 check 'status -q' and some combinations
238
238
239 $ hg init repo3
239 $ hg init repo3
240 $ cd repo3
240 $ cd repo3
241 $ touch modified removed deleted ignored
241 $ touch modified removed deleted ignored
242 $ echo "^ignored$" > .hgignore
242 $ echo "^ignored$" > .hgignore
243 $ hg commit -A -m 'initial checkin'
243 $ hg commit -A -m 'initial checkin'
244 adding .hgignore
244 adding .hgignore
245 adding deleted
245 adding deleted
246 adding modified
246 adding modified
247 adding removed
247 adding removed
248 $ touch added unknown ignored
248 $ touch added unknown ignored
249 $ hg add added
249 $ hg add added
250 $ echo "test" >> modified
250 $ echo "test" >> modified
251 $ hg remove removed
251 $ hg remove removed
252 $ rm deleted
252 $ rm deleted
253 $ hg copy modified copied
253 $ hg copy modified copied
254
254
255 test unknown color
255 test unknown color
256
256
257 $ hg --config color.status.modified=periwinkle status --color=always
257 $ hg --config color.status.modified=periwinkle status --color=always
258 ignoring unknown color/effect 'periwinkle' (configured in color.status.modified)
258 ignoring unknown color/effect 'periwinkle' (configured in color.status.modified)
259 M modified
259 M modified
260 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1madded\x1b[0m (esc)
260 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1madded\x1b[0m (esc)
261 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1mcopied\x1b[0m (esc)
261 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1mcopied\x1b[0m (esc)
262 \x1b[0;31;1mR \x1b[0m\x1b[0;31;1mremoved\x1b[0m (esc)
262 \x1b[0;31;1mR \x1b[0m\x1b[0;31;1mremoved\x1b[0m (esc)
263 \x1b[0;36;1;4m! \x1b[0m\x1b[0;36;1;4mdeleted\x1b[0m (esc)
263 \x1b[0;36;1;4m! \x1b[0m\x1b[0;36;1;4mdeleted\x1b[0m (esc)
264 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4munknown\x1b[0m (esc)
264 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4munknown\x1b[0m (esc)
265
265
266 Run status with 2 different flags.
266 Run status with 2 different flags.
267 Check if result is the same or different.
267 Check if result is the same or different.
268 If result is not as expected, raise error
268 If result is not as expected, raise error
269
269
270 $ assert() {
270 $ assert() {
271 > hg status --color=always $1 > ../a
271 > hg status --color=always $1 > ../a
272 > hg status --color=always $2 > ../b
272 > hg status --color=always $2 > ../b
273 > if diff ../a ../b > /dev/null; then
273 > if diff ../a ../b > /dev/null; then
274 > out=0
274 > out=0
275 > else
275 > else
276 > out=1
276 > out=1
277 > fi
277 > fi
278 > if [ $3 -eq 0 ]; then
278 > if [ $3 -eq 0 ]; then
279 > df="same"
279 > df="same"
280 > else
280 > else
281 > df="different"
281 > df="different"
282 > fi
282 > fi
283 > if [ $out -ne $3 ]; then
283 > if [ $out -ne $3 ]; then
284 > echo "Error on $1 and $2, should be $df."
284 > echo "Error on $1 and $2, should be $df."
285 > fi
285 > fi
286 > }
286 > }
287
287
288 assert flag1 flag2 [0-same | 1-different]
288 assert flag1 flag2 [0-same | 1-different]
289
289
290 $ assert "-q" "-mard" 0
290 $ assert "-q" "-mard" 0
291 $ assert "-A" "-marduicC" 0
291 $ assert "-A" "-marduicC" 0
292 $ assert "-qA" "-mardcC" 0
292 $ assert "-qA" "-mardcC" 0
293 $ assert "-qAui" "-A" 0
293 $ assert "-qAui" "-A" 0
294 $ assert "-qAu" "-marducC" 0
294 $ assert "-qAu" "-marducC" 0
295 $ assert "-qAi" "-mardicC" 0
295 $ assert "-qAi" "-mardicC" 0
296 $ assert "-qu" "-u" 0
296 $ assert "-qu" "-u" 0
297 $ assert "-q" "-u" 1
297 $ assert "-q" "-u" 1
298 $ assert "-m" "-a" 1
298 $ assert "-m" "-a" 1
299 $ assert "-r" "-d" 1
299 $ assert "-r" "-d" 1
300 $ cd ..
300 $ cd ..
301
301
302 test 'resolve -l'
302 test 'resolve -l'
303
303
304 $ hg init repo4
304 $ hg init repo4
305 $ cd repo4
305 $ cd repo4
306 $ echo "file a" > a
306 $ echo "file a" > a
307 $ echo "file b" > b
307 $ echo "file b" > b
308 $ hg add a b
308 $ hg add a b
309 $ hg commit -m "initial"
309 $ hg commit -m "initial"
310 $ echo "file a change 1" > a
310 $ echo "file a change 1" > a
311 $ echo "file b change 1" > b
311 $ echo "file b change 1" > b
312 $ hg commit -m "head 1"
312 $ hg commit -m "head 1"
313 $ hg update 0
313 $ hg update 0
314 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
314 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
315 $ echo "file a change 2" > a
315 $ echo "file a change 2" > a
316 $ echo "file b change 2" > b
316 $ echo "file b change 2" > b
317 $ hg commit -m "head 2"
317 $ hg commit -m "head 2"
318 created new head
318 created new head
319 $ hg merge
319 $ hg merge
320 merging a
320 merging a
321 warning: conflicts during merge.
321 warning: conflicts during merge.
322 merging a incomplete! (edit conflicts, then use 'hg resolve --mark')
322 merging a incomplete! (edit conflicts, then use 'hg resolve --mark')
323 merging b
323 merging b
324 warning: conflicts during merge.
324 warning: conflicts during merge.
325 merging b incomplete! (edit conflicts, then use 'hg resolve --mark')
325 merging b incomplete! (edit conflicts, then use 'hg resolve --mark')
326 0 files updated, 0 files merged, 0 files removed, 2 files unresolved
326 0 files updated, 0 files merged, 0 files removed, 2 files unresolved
327 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
327 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
328 [1]
328 [1]
329 $ hg resolve -m b
329 $ hg resolve -m b
330
330
331 hg resolve with one unresolved, one resolved:
331 hg resolve with one unresolved, one resolved:
332
332
333 $ hg resolve --color=always -l
333 $ hg resolve --color=always -l
334 \x1b[0;31;1mU a\x1b[0m (esc)
334 \x1b[0;31;1mU a\x1b[0m (esc)
335 \x1b[0;32;1mR b\x1b[0m (esc)
335 \x1b[0;32;1mR b\x1b[0m (esc)
336
336
337 color coding of error message with current availability of curses
337 color coding of error message with current availability of curses
338
338
339 $ hg unknowncommand > /dev/null
339 $ hg unknowncommand > /dev/null
340 hg: unknown command 'unknowncommand'
340 hg: unknown command 'unknowncommand'
341 [255]
341 [255]
342
342
343 color coding of error message without curses
343 color coding of error message without curses
344
344
345 $ echo 'raise ImportError' > curses.py
345 $ echo 'raise ImportError' > curses.py
346 $ PYTHONPATH=`pwd`:$PYTHONPATH hg unknowncommand > /dev/null
346 $ PYTHONPATH=`pwd`:$PYTHONPATH hg unknowncommand > /dev/null
347 hg: unknown command 'unknowncommand'
347 hg: unknown command 'unknowncommand'
348 [255]
348 [255]
349
349
350 $ cd ..
350 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now