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