##// END OF EJS Templates
color: colorize output of hg resolve -l
Georg Brandl -
r10223:51421ab5 default
parent child Browse files
Show More
@@ -1,343 +1,368 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 program is free software; you can redistribute it and/or modify it
5 # This program is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by the
6 # under the terms of the GNU General Public License as published by the
7 # Free Software Foundation; either version 2 of the License, or (at your
7 # Free Software Foundation; either version 2 of the License, or (at your
8 # option) any later version.
8 # option) any later version.
9 #
9 #
10 # This program is distributed in the hope that it will be useful, but
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13 # Public License for more details.
13 # Public License for more details.
14 #
14 #
15 # You should have received a copy of the GNU General Public License along
15 # You should have received a copy of the GNU General Public License along
16 # with this program; if not, write to the Free Software Foundation, Inc.,
16 # with this program; if not, write to the Free Software Foundation, Inc.,
17 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
18
19 '''colorize output from some commands
19 '''colorize output from some commands
20
20
21 This extension modifies the status command to add color to its output
21 This extension modifies the status and resolve commands to add color to their
22 to reflect file status, the qseries command to add color to reflect
22 output to reflect file status, the qseries command to add color to reflect
23 patch status (applied, unapplied, missing), and to diff-related
23 patch status (applied, unapplied, missing), and to diff-related
24 commands to highlight additions, removals, diff headers, and trailing
24 commands to highlight additions, removals, diff headers, and trailing
25 whitespace.
25 whitespace.
26
26
27 Other effects in addition to color, like bold and underlined text, are
27 Other effects in addition to color, like bold and underlined text, are
28 also available. Effects are rendered with the ECMA-48 SGR control
28 also available. Effects are rendered with the ECMA-48 SGR control
29 function (aka ANSI escape codes). This module also provides the
29 function (aka ANSI escape codes). This module also provides the
30 render_text function, which can be used to add effects to any text.
30 render_text function, which can be used to add effects to any text.
31
31
32 Default effects may be overridden from the .hgrc file::
32 Default effects may be overridden from the .hgrc file::
33
33
34 [color]
34 [color]
35 status.modified = blue bold underline red_background
35 status.modified = blue bold underline red_background
36 status.added = green bold
36 status.added = green bold
37 status.removed = red bold blue_background
37 status.removed = red bold blue_background
38 status.deleted = cyan bold underline
38 status.deleted = cyan bold underline
39 status.unknown = magenta bold underline
39 status.unknown = magenta bold underline
40 status.ignored = black bold
40 status.ignored = black bold
41
41
42 # 'none' turns off all effects
42 # 'none' turns off all effects
43 status.clean = none
43 status.clean = none
44 status.copied = none
44 status.copied = none
45
45
46 qseries.applied = blue bold underline
46 qseries.applied = blue bold underline
47 qseries.unapplied = black bold
47 qseries.unapplied = black bold
48 qseries.missing = red bold
48 qseries.missing = red bold
49
49
50 diff.diffline = bold
50 diff.diffline = bold
51 diff.extended = cyan bold
51 diff.extended = cyan bold
52 diff.file_a = red bold
52 diff.file_a = red bold
53 diff.file_b = green bold
53 diff.file_b = green bold
54 diff.hunk = magenta
54 diff.hunk = magenta
55 diff.deleted = red
55 diff.deleted = red
56 diff.inserted = green
56 diff.inserted = green
57 diff.changed = white
57 diff.changed = white
58 diff.trailingwhitespace = bold red_background
58 diff.trailingwhitespace = bold red_background
59
59
60 resolve.unresolved = red bold
61 resolve.resolved = green bold
62
60 bookmarks.current = green
63 bookmarks.current = green
61 '''
64 '''
62
65
63 import os, sys
66 import os, sys
64
67
65 from mercurial import cmdutil, commands, extensions, error
68 from mercurial import cmdutil, commands, extensions, error
66 from mercurial.i18n import _
69 from mercurial.i18n import _
67
70
68 # start and stop parameters for effects
71 # start and stop parameters for effects
69 _effect_params = {'none': 0,
72 _effect_params = {'none': 0,
70 'black': 30,
73 'black': 30,
71 'red': 31,
74 'red': 31,
72 'green': 32,
75 'green': 32,
73 'yellow': 33,
76 'yellow': 33,
74 'blue': 34,
77 'blue': 34,
75 'magenta': 35,
78 'magenta': 35,
76 'cyan': 36,
79 'cyan': 36,
77 'white': 37,
80 'white': 37,
78 'bold': 1,
81 'bold': 1,
79 'italic': 3,
82 'italic': 3,
80 'underline': 4,
83 'underline': 4,
81 'inverse': 7,
84 'inverse': 7,
82 'black_background': 40,
85 'black_background': 40,
83 'red_background': 41,
86 'red_background': 41,
84 'green_background': 42,
87 'green_background': 42,
85 'yellow_background': 43,
88 'yellow_background': 43,
86 'blue_background': 44,
89 'blue_background': 44,
87 'purple_background': 45,
90 'purple_background': 45,
88 'cyan_background': 46,
91 'cyan_background': 46,
89 'white_background': 47}
92 'white_background': 47}
90
93
91 def render_effects(text, effects):
94 def render_effects(text, effects):
92 'Wrap text in commands to turn on each effect.'
95 'Wrap text in commands to turn on each effect.'
93 start = [str(_effect_params[e]) for e in ['none'] + effects]
96 start = [str(_effect_params[e]) for e in ['none'] + effects]
94 start = '\033[' + ';'.join(start) + 'm'
97 start = '\033[' + ';'.join(start) + 'm'
95 stop = '\033[' + str(_effect_params['none']) + 'm'
98 stop = '\033[' + str(_effect_params['none']) + 'm'
96 return ''.join([start, text, stop])
99 return ''.join([start, text, stop])
97
100
98 def colorstatus(orig, ui, repo, *pats, **opts):
101 def _colorstatuslike(abbreviations, effectdefs, orig, ui, repo, *pats, **opts):
99 '''run the status command with colored output'''
102 '''run a status-like command with colorized output'''
100
103 delimiter = opts.get('print0') and '\0' or '\n'
101 delimiter = opts['print0'] and '\0' or '\n'
102
104
103 nostatus = opts.get('no_status')
105 nostatus = opts.get('no_status')
104 opts['no_status'] = False
106 opts['no_status'] = False
105 # run status and capture its output
107 # run original command and capture its output
106 ui.pushbuffer()
108 ui.pushbuffer()
107 retval = orig(ui, repo, *pats, **opts)
109 retval = orig(ui, repo, *pats, **opts)
108 # filter out empty strings
110 # filter out empty strings
109 lines_with_status = [line for line in ui.popbuffer().split(delimiter) if line]
111 lines_with_status = [line for line in ui.popbuffer().split(delimiter) if line]
110
112
111 if nostatus:
113 if nostatus:
112 lines = [l[2:] for l in lines_with_status]
114 lines = [l[2:] for l in lines_with_status]
113 else:
115 else:
114 lines = lines_with_status
116 lines = lines_with_status
115
117
116 # apply color to output and display it
118 # apply color to output and display it
117 for i in xrange(len(lines)):
119 for i in xrange(len(lines)):
118 status = _status_abbreviations[lines_with_status[i][0]]
120 status = abbreviations[lines_with_status[i][0]]
119 effects = _status_effects[status]
121 effects = effectdefs[status]
120 if effects:
122 if effects:
121 lines[i] = render_effects(lines[i], effects)
123 lines[i] = render_effects(lines[i], effects)
122 ui.write(lines[i] + delimiter)
124 ui.write(lines[i] + delimiter)
123 return retval
125 return retval
124
126
127
125 _status_abbreviations = { 'M': 'modified',
128 _status_abbreviations = { 'M': 'modified',
126 'A': 'added',
129 'A': 'added',
127 'R': 'removed',
130 'R': 'removed',
128 '!': 'deleted',
131 '!': 'deleted',
129 '?': 'unknown',
132 '?': 'unknown',
130 'I': 'ignored',
133 'I': 'ignored',
131 'C': 'clean',
134 'C': 'clean',
132 ' ': 'copied', }
135 ' ': 'copied', }
133
136
134 _status_effects = { 'modified': ['blue', 'bold'],
137 _status_effects = { 'modified': ['blue', 'bold'],
135 'added': ['green', 'bold'],
138 'added': ['green', 'bold'],
136 'removed': ['red', 'bold'],
139 'removed': ['red', 'bold'],
137 'deleted': ['cyan', 'bold', 'underline'],
140 'deleted': ['cyan', 'bold', 'underline'],
138 'unknown': ['magenta', 'bold', 'underline'],
141 'unknown': ['magenta', 'bold', 'underline'],
139 'ignored': ['black', 'bold'],
142 'ignored': ['black', 'bold'],
140 'clean': ['none'],
143 'clean': ['none'],
141 'copied': ['none'], }
144 'copied': ['none'], }
142
145
146 def colorstatus(orig, ui, repo, *pats, **opts):
147 '''run the status command with colored output'''
148 return _colorstatuslike(_status_abbreviations, _status_effects,
149 orig, ui, repo, *pats, **opts)
150
151
152 _resolve_abbreviations = { 'U': 'unresolved',
153 'R': 'resolved', }
154
155 _resolve_effects = { 'unresolved': ['red', 'bold'],
156 'resolved': ['green', 'bold'], }
157
158 def colorresolve(orig, ui, repo, *pats, **opts):
159 '''run the resolve command with colored output'''
160 if not opts.get('list'):
161 # only colorize for resolve -l
162 return orig(ui, repo, *pats, **opts)
163 return _colorstatuslike(_resolve_abbreviations, _resolve_effects,
164 orig, ui, repo, *pats, **opts)
165
166
143 _bookmark_effects = { 'current': ['green'] }
167 _bookmark_effects = { 'current': ['green'] }
144
168
145 def colorbookmarks(orig, ui, repo, *pats, **opts):
169 def colorbookmarks(orig, ui, repo, *pats, **opts):
146 def colorize(orig, s):
170 def colorize(orig, s):
147 lines = s.split('\n')
171 lines = s.split('\n')
148 for i, line in enumerate(lines):
172 for i, line in enumerate(lines):
149 if line.startswith(" *"):
173 if line.startswith(" *"):
150 lines[i] = render_effects(line, _bookmark_effects['current'])
174 lines[i] = render_effects(line, _bookmark_effects['current'])
151 orig('\n'.join(lines))
175 orig('\n'.join(lines))
152 oldwrite = extensions.wrapfunction(ui, 'write', colorize)
176 oldwrite = extensions.wrapfunction(ui, 'write', colorize)
153 try:
177 try:
154 orig(ui, repo, *pats, **opts)
178 orig(ui, repo, *pats, **opts)
155 finally:
179 finally:
156 ui.write = oldwrite
180 ui.write = oldwrite
157
181
158 def colorqseries(orig, ui, repo, *dummy, **opts):
182 def colorqseries(orig, ui, repo, *dummy, **opts):
159 '''run the qseries command with colored output'''
183 '''run the qseries command with colored output'''
160 ui.pushbuffer()
184 ui.pushbuffer()
161 retval = orig(ui, repo, **opts)
185 retval = orig(ui, repo, **opts)
162 patchlines = ui.popbuffer().splitlines()
186 patchlines = ui.popbuffer().splitlines()
163 patchnames = repo.mq.series
187 patchnames = repo.mq.series
164
188
165 for patch, patchname in zip(patchlines, patchnames):
189 for patch, patchname in zip(patchlines, patchnames):
166 if opts['missing']:
190 if opts['missing']:
167 effects = _patch_effects['missing']
191 effects = _patch_effects['missing']
168 # Determine if patch is applied.
192 # Determine if patch is applied.
169 elif [ applied for applied in repo.mq.applied
193 elif [ applied for applied in repo.mq.applied
170 if patchname == applied.name ]:
194 if patchname == applied.name ]:
171 effects = _patch_effects['applied']
195 effects = _patch_effects['applied']
172 else:
196 else:
173 effects = _patch_effects['unapplied']
197 effects = _patch_effects['unapplied']
174
198
175 patch = patch.replace(patchname, render_effects(patchname, effects), 1)
199 patch = patch.replace(patchname, render_effects(patchname, effects), 1)
176 ui.write(patch + '\n')
200 ui.write(patch + '\n')
177 return retval
201 return retval
178
202
179 _patch_effects = { 'applied': ['blue', 'bold', 'underline'],
203 _patch_effects = { 'applied': ['blue', 'bold', 'underline'],
180 'missing': ['red', 'bold'],
204 'missing': ['red', 'bold'],
181 'unapplied': ['black', 'bold'], }
205 'unapplied': ['black', 'bold'], }
182 def colorwrap(orig, *args):
206 def colorwrap(orig, *args):
183 '''wrap ui.write for colored diff output'''
207 '''wrap ui.write for colored diff output'''
184 def _colorize(s):
208 def _colorize(s):
185 lines = s.split('\n')
209 lines = s.split('\n')
186 for i, line in enumerate(lines):
210 for i, line in enumerate(lines):
187 stripline = line
211 stripline = line
188 if line and line[0] in '+-':
212 if line and line[0] in '+-':
189 # highlight trailing whitespace, but only in changed lines
213 # highlight trailing whitespace, but only in changed lines
190 stripline = line.rstrip()
214 stripline = line.rstrip()
191 for prefix, style in _diff_prefixes:
215 for prefix, style in _diff_prefixes:
192 if stripline.startswith(prefix):
216 if stripline.startswith(prefix):
193 lines[i] = render_effects(stripline, _diff_effects[style])
217 lines[i] = render_effects(stripline, _diff_effects[style])
194 break
218 break
195 if line != stripline:
219 if line != stripline:
196 lines[i] += render_effects(
220 lines[i] += render_effects(
197 line[len(stripline):], _diff_effects['trailingwhitespace'])
221 line[len(stripline):], _diff_effects['trailingwhitespace'])
198 return '\n'.join(lines)
222 return '\n'.join(lines)
199 orig(*[_colorize(s) for s in args])
223 orig(*[_colorize(s) for s in args])
200
224
201 def colorshowpatch(orig, self, node):
225 def colorshowpatch(orig, self, node):
202 '''wrap cmdutil.changeset_printer.showpatch with colored output'''
226 '''wrap cmdutil.changeset_printer.showpatch with colored output'''
203 oldwrite = extensions.wrapfunction(self.ui, 'write', colorwrap)
227 oldwrite = extensions.wrapfunction(self.ui, 'write', colorwrap)
204 try:
228 try:
205 orig(self, node)
229 orig(self, node)
206 finally:
230 finally:
207 self.ui.write = oldwrite
231 self.ui.write = oldwrite
208
232
209 def colordiffstat(orig, s):
233 def colordiffstat(orig, s):
210 lines = s.split('\n')
234 lines = s.split('\n')
211 for i, line in enumerate(lines):
235 for i, line in enumerate(lines):
212 if line and line[-1] in '+-':
236 if line and line[-1] in '+-':
213 name, graph = line.rsplit(' ', 1)
237 name, graph = line.rsplit(' ', 1)
214 graph = graph.replace('-',
238 graph = graph.replace('-',
215 render_effects('-', _diff_effects['deleted']))
239 render_effects('-', _diff_effects['deleted']))
216 graph = graph.replace('+',
240 graph = graph.replace('+',
217 render_effects('+', _diff_effects['inserted']))
241 render_effects('+', _diff_effects['inserted']))
218 lines[i] = ' '.join([name, graph])
242 lines[i] = ' '.join([name, graph])
219 orig('\n'.join(lines))
243 orig('\n'.join(lines))
220
244
221 def colordiff(orig, ui, repo, *pats, **opts):
245 def colordiff(orig, ui, repo, *pats, **opts):
222 '''run the diff command with colored output'''
246 '''run the diff command with colored output'''
223 if opts.get('stat'):
247 if opts.get('stat'):
224 wrapper = colordiffstat
248 wrapper = colordiffstat
225 else:
249 else:
226 wrapper = colorwrap
250 wrapper = colorwrap
227 oldwrite = extensions.wrapfunction(ui, 'write', wrapper)
251 oldwrite = extensions.wrapfunction(ui, 'write', wrapper)
228 try:
252 try:
229 orig(ui, repo, *pats, **opts)
253 orig(ui, repo, *pats, **opts)
230 finally:
254 finally:
231 ui.write = oldwrite
255 ui.write = oldwrite
232
256
233 def colorchurn(orig, ui, repo, *pats, **opts):
257 def colorchurn(orig, ui, repo, *pats, **opts):
234 '''run the churn command with colored output'''
258 '''run the churn command with colored output'''
235 if not opts.get('diffstat'):
259 if not opts.get('diffstat'):
236 return orig(ui, repo, *pats, **opts)
260 return orig(ui, repo, *pats, **opts)
237 oldwrite = extensions.wrapfunction(ui, 'write', colordiffstat)
261 oldwrite = extensions.wrapfunction(ui, 'write', colordiffstat)
238 try:
262 try:
239 orig(ui, repo, *pats, **opts)
263 orig(ui, repo, *pats, **opts)
240 finally:
264 finally:
241 ui.write = oldwrite
265 ui.write = oldwrite
242
266
243 _diff_prefixes = [('diff', 'diffline'),
267 _diff_prefixes = [('diff', 'diffline'),
244 ('copy', 'extended'),
268 ('copy', 'extended'),
245 ('rename', 'extended'),
269 ('rename', 'extended'),
246 ('old', 'extended'),
270 ('old', 'extended'),
247 ('new', 'extended'),
271 ('new', 'extended'),
248 ('deleted', 'extended'),
272 ('deleted', 'extended'),
249 ('---', 'file_a'),
273 ('---', 'file_a'),
250 ('+++', 'file_b'),
274 ('+++', 'file_b'),
251 ('@', 'hunk'),
275 ('@', 'hunk'),
252 ('-', 'deleted'),
276 ('-', 'deleted'),
253 ('+', 'inserted')]
277 ('+', 'inserted')]
254
278
255 _diff_effects = {'diffline': ['bold'],
279 _diff_effects = {'diffline': ['bold'],
256 'extended': ['cyan', 'bold'],
280 'extended': ['cyan', 'bold'],
257 'file_a': ['red', 'bold'],
281 'file_a': ['red', 'bold'],
258 'file_b': ['green', 'bold'],
282 'file_b': ['green', 'bold'],
259 'hunk': ['magenta'],
283 'hunk': ['magenta'],
260 'deleted': ['red'],
284 'deleted': ['red'],
261 'inserted': ['green'],
285 'inserted': ['green'],
262 'changed': ['white'],
286 'changed': ['white'],
263 'trailingwhitespace': ['bold', 'red_background']}
287 'trailingwhitespace': ['bold', 'red_background']}
264
288
265 def extsetup(ui):
289 def extsetup(ui):
266 '''Initialize the extension.'''
290 '''Initialize the extension.'''
267 _setupcmd(ui, 'diff', commands.table, colordiff, _diff_effects)
291 _setupcmd(ui, 'diff', commands.table, colordiff, _diff_effects)
268 _setupcmd(ui, 'incoming', commands.table, None, _diff_effects)
292 _setupcmd(ui, 'incoming', commands.table, None, _diff_effects)
269 _setupcmd(ui, 'log', commands.table, None, _diff_effects)
293 _setupcmd(ui, 'log', commands.table, None, _diff_effects)
270 _setupcmd(ui, 'outgoing', commands.table, None, _diff_effects)
294 _setupcmd(ui, 'outgoing', commands.table, None, _diff_effects)
271 _setupcmd(ui, 'tip', commands.table, None, _diff_effects)
295 _setupcmd(ui, 'tip', commands.table, None, _diff_effects)
272 _setupcmd(ui, 'status', commands.table, colorstatus, _status_effects)
296 _setupcmd(ui, 'status', commands.table, colorstatus, _status_effects)
297 _setupcmd(ui, 'resolve', commands.table, colorresolve, _resolve_effects)
273
298
274 try:
299 try:
275 mq = extensions.find('mq')
300 mq = extensions.find('mq')
276 _setupcmd(ui, 'qdiff', mq.cmdtable, colordiff, _diff_effects)
301 _setupcmd(ui, 'qdiff', mq.cmdtable, colordiff, _diff_effects)
277 _setupcmd(ui, 'qseries', mq.cmdtable, colorqseries, _patch_effects)
302 _setupcmd(ui, 'qseries', mq.cmdtable, colorqseries, _patch_effects)
278 except KeyError:
303 except KeyError:
279 mq = None
304 mq = None
280
305
281 try:
306 try:
282 rec = extensions.find('record')
307 rec = extensions.find('record')
283 _setupcmd(ui, 'record', rec.cmdtable, colordiff, _diff_effects)
308 _setupcmd(ui, 'record', rec.cmdtable, colordiff, _diff_effects)
284 except KeyError:
309 except KeyError:
285 rec = None
310 rec = None
286
311
287 if mq and rec:
312 if mq and rec:
288 _setupcmd(ui, 'qrecord', rec.cmdtable, colordiff, _diff_effects)
313 _setupcmd(ui, 'qrecord', rec.cmdtable, colordiff, _diff_effects)
289 try:
314 try:
290 churn = extensions.find('churn')
315 churn = extensions.find('churn')
291 _setupcmd(ui, 'churn', churn.cmdtable, colorchurn, _diff_effects)
316 _setupcmd(ui, 'churn', churn.cmdtable, colorchurn, _diff_effects)
292 except KeyError:
317 except KeyError:
293 churn = None
318 churn = None
294
319
295 try:
320 try:
296 bookmarks = extensions.find('bookmarks')
321 bookmarks = extensions.find('bookmarks')
297 _setupcmd(ui, 'bookmarks', bookmarks.cmdtable, colorbookmarks,
322 _setupcmd(ui, 'bookmarks', bookmarks.cmdtable, colorbookmarks,
298 _bookmark_effects)
323 _bookmark_effects)
299 except KeyError:
324 except KeyError:
300 # The bookmarks extension is not enabled
325 # The bookmarks extension is not enabled
301 pass
326 pass
302
327
303 def _setupcmd(ui, cmd, table, func, effectsmap):
328 def _setupcmd(ui, cmd, table, func, effectsmap):
304 '''patch in command to command table and load effect map'''
329 '''patch in command to command table and load effect map'''
305 def nocolor(orig, *args, **opts):
330 def nocolor(orig, *args, **opts):
306
331
307 if (opts['no_color'] or opts['color'] == 'never' or
332 if (opts['no_color'] or opts['color'] == 'never' or
308 (opts['color'] == 'auto' and (os.environ.get('TERM') == 'dumb'
333 (opts['color'] == 'auto' and (os.environ.get('TERM') == 'dumb'
309 or not sys.__stdout__.isatty()))):
334 or not sys.__stdout__.isatty()))):
310 del opts['no_color']
335 del opts['no_color']
311 del opts['color']
336 del opts['color']
312 return orig(*args, **opts)
337 return orig(*args, **opts)
313
338
314 oldshowpatch = extensions.wrapfunction(cmdutil.changeset_printer,
339 oldshowpatch = extensions.wrapfunction(cmdutil.changeset_printer,
315 'showpatch', colorshowpatch)
340 'showpatch', colorshowpatch)
316 del opts['no_color']
341 del opts['no_color']
317 del opts['color']
342 del opts['color']
318 try:
343 try:
319 if func is not None:
344 if func is not None:
320 return func(orig, *args, **opts)
345 return func(orig, *args, **opts)
321 return orig(*args, **opts)
346 return orig(*args, **opts)
322 finally:
347 finally:
323 cmdutil.changeset_printer.showpatch = oldshowpatch
348 cmdutil.changeset_printer.showpatch = oldshowpatch
324
349
325 entry = extensions.wrapcommand(table, cmd, nocolor)
350 entry = extensions.wrapcommand(table, cmd, nocolor)
326 entry[1].extend([
351 entry[1].extend([
327 ('', 'color', 'auto', _("when to colorize (always, auto, or never)")),
352 ('', 'color', 'auto', _("when to colorize (always, auto, or never)")),
328 ('', 'no-color', None, _("don't colorize output (DEPRECATED)")),
353 ('', 'no-color', None, _("don't colorize output (DEPRECATED)")),
329 ])
354 ])
330
355
331 for status in effectsmap:
356 for status in effectsmap:
332 configkey = cmd + '.' + status
357 configkey = cmd + '.' + status
333 effects = ui.configlist('color', configkey)
358 effects = ui.configlist('color', configkey)
334 if effects:
359 if effects:
335 good = []
360 good = []
336 for e in effects:
361 for e in effects:
337 if e in _effect_params:
362 if e in _effect_params:
338 good.append(e)
363 good.append(e)
339 else:
364 else:
340 ui.warn(_("ignoring unknown color/effect %r "
365 ui.warn(_("ignoring unknown color/effect %r "
341 "(configured in color.%s)\n")
366 "(configured in color.%s)\n")
342 % (e, configkey))
367 % (e, configkey))
343 effectsmap[status] = good
368 effectsmap[status] = good
@@ -1,100 +1,120 b''
1 #!/bin/sh
1 #!/bin/sh
2
2
3 echo "[extensions]" >> $HGRCPATH
3 echo "[extensions]" >> $HGRCPATH
4 echo "color=" >> $HGRCPATH
4 echo "color=" >> $HGRCPATH
5
5
6 hg init repo1
6 hg init repo1
7 cd repo1
7 cd repo1
8 mkdir a b a/1 b/1 b/2
8 mkdir a b a/1 b/1 b/2
9 touch in_root a/in_a b/in_b a/1/in_a_1 b/1/in_b_1 b/2/in_b_2
9 touch in_root a/in_a b/in_b a/1/in_a_1 b/1/in_b_1 b/2/in_b_2
10 echo "hg status in repo root:"
10 echo "hg status in repo root:"
11 hg status --color=always
11 hg status --color=always
12 echo "hg status . in repo root:"
12 echo "hg status . in repo root:"
13 hg status --color=always .
13 hg status --color=always .
14 for dir in a b a/1 b/1 b/2; do
14 for dir in a b a/1 b/1 b/2; do
15 echo "hg status in $dir:"
15 echo "hg status in $dir:"
16 hg status --color=always --cwd "$dir"
16 hg status --color=always --cwd "$dir"
17 echo "hg status . in $dir:"
17 echo "hg status . in $dir:"
18 hg status --color=always --cwd "$dir" .
18 hg status --color=always --cwd "$dir" .
19 echo "hg status .. in $dir:"
19 echo "hg status .. in $dir:"
20 hg status --color=always --cwd "$dir" ..
20 hg status --color=always --cwd "$dir" ..
21 done
21 done
22 cd ..
22 cd ..
23
23
24 hg init repo2
24 hg init repo2
25 cd repo2
25 cd repo2
26 touch modified removed deleted ignored
26 touch modified removed deleted ignored
27 echo "^ignored$" > .hgignore
27 echo "^ignored$" > .hgignore
28 hg ci -A -m 'initial checkin' -d "1000000 0"
28 hg ci -A -m 'initial checkin' -d "1000000 0"
29 touch modified added unknown ignored
29 touch modified added unknown ignored
30 hg add added
30 hg add added
31 hg remove removed
31 hg remove removed
32 rm deleted
32 rm deleted
33 echo "hg status:"
33 echo "hg status:"
34 hg status --color=always
34 hg status --color=always
35 echo "hg status modified added removed deleted unknown never-existed ignored:"
35 echo "hg status modified added removed deleted unknown never-existed ignored:"
36 hg status --color=always modified added removed deleted unknown never-existed ignored
36 hg status --color=always modified added removed deleted unknown never-existed ignored
37 hg copy modified copied
37 hg copy modified copied
38 echo "hg status -C:"
38 echo "hg status -C:"
39 hg status --color=always -C
39 hg status --color=always -C
40 echo "hg status -A:"
40 echo "hg status -A:"
41 hg status --color=always -A
41 hg status --color=always -A
42 echo "^ignoreddir$" > .hgignore
42 echo "^ignoreddir$" > .hgignore
43 mkdir ignoreddir
43 mkdir ignoreddir
44 touch ignoreddir/file
44 touch ignoreddir/file
45 echo "hg status ignoreddir/file:"
45 echo "hg status ignoreddir/file:"
46 hg status --color=always ignoreddir/file
46 hg status --color=always ignoreddir/file
47 echo "hg status -i ignoreddir/file:"
47 echo "hg status -i ignoreddir/file:"
48 hg status --color=always -i ignoreddir/file
48 hg status --color=always -i ignoreddir/file
49 cd ..
49 cd ..
50
50
51 # check 'status -q' and some combinations
51 # check 'status -q' and some combinations
52 hg init repo3
52 hg init repo3
53 cd repo3
53 cd repo3
54 touch modified removed deleted ignored
54 touch modified removed deleted ignored
55 echo "^ignored$" > .hgignore
55 echo "^ignored$" > .hgignore
56 hg commit -A -m 'initial checkin'
56 hg commit -A -m 'initial checkin'
57 touch added unknown ignored
57 touch added unknown ignored
58 hg add added
58 hg add added
59 echo "test" >> modified
59 echo "test" >> modified
60 hg remove removed
60 hg remove removed
61 rm deleted
61 rm deleted
62 hg copy modified copied
62 hg copy modified copied
63
63
64 echo "% test unknown color"
64 echo "% test unknown color"
65 hg --config color.status.modified=periwinkle status --color=always
65 hg --config color.status.modified=periwinkle status --color=always
66
66
67 # Run status with 2 different flags.
67 # Run status with 2 different flags.
68 # Check if result is the same or different.
68 # Check if result is the same or different.
69 # If result is not as expected, raise error
69 # If result is not as expected, raise error
70 assert() {
70 assert() {
71 hg status --color=always $1 > ../a
71 hg status --color=always $1 > ../a
72 hg status --color=always $2 > ../b
72 hg status --color=always $2 > ../b
73 out=`diff ../a ../b`
73 out=`diff ../a ../b`
74 if [ $? -ne 0 ]; then
74 if [ $? -ne 0 ]; then
75 out=1
75 out=1
76 else
76 else
77 out=0
77 out=0
78 fi
78 fi
79 if [ $3 -eq 0 ]; then
79 if [ $3 -eq 0 ]; then
80 df="same"
80 df="same"
81 else
81 else
82 df="different"
82 df="different"
83 fi
83 fi
84 if [ $out -ne $3 ]; then
84 if [ $out -ne $3 ]; then
85 echo "Error on $1 and $2, should be $df."
85 echo "Error on $1 and $2, should be $df."
86 fi
86 fi
87 }
87 }
88
88
89 # assert flag1 flag2 [0-same | 1-different]
89 # assert flag1 flag2 [0-same | 1-different]
90 assert "-q" "-mard" 0
90 assert "-q" "-mard" 0
91 assert "-A" "-marduicC" 0
91 assert "-A" "-marduicC" 0
92 assert "-qA" "-mardcC" 0
92 assert "-qA" "-mardcC" 0
93 assert "-qAui" "-A" 0
93 assert "-qAui" "-A" 0
94 assert "-qAu" "-marducC" 0
94 assert "-qAu" "-marducC" 0
95 assert "-qAi" "-mardicC" 0
95 assert "-qAi" "-mardicC" 0
96 assert "-qu" "-u" 0
96 assert "-qu" "-u" 0
97 assert "-q" "-u" 1
97 assert "-q" "-u" 1
98 assert "-m" "-a" 1
98 assert "-m" "-a" 1
99 assert "-r" "-d" 1
99 assert "-r" "-d" 1
100
100
101 cd ..
102
103 # test 'resolve -l'
104 hg init repo4
105 cd repo4
106 echo "file a" > a
107 echo "file b" > b
108 hg add a b
109 hg commit -m "initial"
110 echo "file a change 1" > a
111 echo "file b change 1" > b
112 hg commit -m "head 1"
113 hg update 0
114 echo "file a change 2" > a
115 echo "file b change 2" > b
116 hg commit -m "head 2"
117 hg merge
118 hg resolve -m b
119 echo "hg resolve with one unresolved, one resolved:"
120 hg resolve --color=always -l
@@ -1,134 +1,147 b''
1 hg status in repo root:
1 hg status in repo root:
2 ? a/1/in_a_1
2 ? a/1/in_a_1
3 ? a/in_a
3 ? a/in_a
4 ? b/1/in_b_1
4 ? b/1/in_b_1
5 ? b/2/in_b_2
5 ? b/2/in_b_2
6 ? b/in_b
6 ? b/in_b
7 ? in_root
7 ? in_root
8 hg status . in repo root:
8 hg status . in repo root:
9 ? a/1/in_a_1
9 ? a/1/in_a_1
10 ? a/in_a
10 ? a/in_a
11 ? b/1/in_b_1
11 ? b/1/in_b_1
12 ? b/2/in_b_2
12 ? b/2/in_b_2
13 ? b/in_b
13 ? b/in_b
14 ? in_root
14 ? in_root
15 hg status in a:
15 hg status in a:
16 ? a/1/in_a_1
16 ? a/1/in_a_1
17 ? a/in_a
17 ? a/in_a
18 ? b/1/in_b_1
18 ? b/1/in_b_1
19 ? b/2/in_b_2
19 ? b/2/in_b_2
20 ? b/in_b
20 ? b/in_b
21 ? in_root
21 ? in_root
22 hg status . in a:
22 hg status . in a:
23 ? 1/in_a_1
23 ? 1/in_a_1
24 ? in_a
24 ? in_a
25 hg status .. in a:
25 hg status .. in a:
26 ? 1/in_a_1
26 ? 1/in_a_1
27 ? in_a
27 ? in_a
28 ? ../b/1/in_b_1
28 ? ../b/1/in_b_1
29 ? ../b/2/in_b_2
29 ? ../b/2/in_b_2
30 ? ../b/in_b
30 ? ../b/in_b
31 ? ../in_root
31 ? ../in_root
32 hg status in b:
32 hg status in b:
33 ? a/1/in_a_1
33 ? a/1/in_a_1
34 ? a/in_a
34 ? a/in_a
35 ? b/1/in_b_1
35 ? b/1/in_b_1
36 ? b/2/in_b_2
36 ? b/2/in_b_2
37 ? b/in_b
37 ? b/in_b
38 ? in_root
38 ? in_root
39 hg status . in b:
39 hg status . in b:
40 ? 1/in_b_1
40 ? 1/in_b_1
41 ? 2/in_b_2
41 ? 2/in_b_2
42 ? in_b
42 ? in_b
43 hg status .. in b:
43 hg status .. in b:
44 ? ../a/1/in_a_1
44 ? ../a/1/in_a_1
45 ? ../a/in_a
45 ? ../a/in_a
46 ? 1/in_b_1
46 ? 1/in_b_1
47 ? 2/in_b_2
47 ? 2/in_b_2
48 ? in_b
48 ? in_b
49 ? ../in_root
49 ? ../in_root
50 hg status in a/1:
50 hg status in a/1:
51 ? a/1/in_a_1
51 ? a/1/in_a_1
52 ? a/in_a
52 ? a/in_a
53 ? b/1/in_b_1
53 ? b/1/in_b_1
54 ? b/2/in_b_2
54 ? b/2/in_b_2
55 ? b/in_b
55 ? b/in_b
56 ? in_root
56 ? in_root
57 hg status . in a/1:
57 hg status . in a/1:
58 ? in_a_1
58 ? in_a_1
59 hg status .. in a/1:
59 hg status .. in a/1:
60 ? in_a_1
60 ? in_a_1
61 ? ../in_a
61 ? ../in_a
62 hg status in b/1:
62 hg status in b/1:
63 ? a/1/in_a_1
63 ? a/1/in_a_1
64 ? a/in_a
64 ? a/in_a
65 ? b/1/in_b_1
65 ? b/1/in_b_1
66 ? b/2/in_b_2
66 ? b/2/in_b_2
67 ? b/in_b
67 ? b/in_b
68 ? in_root
68 ? in_root
69 hg status . in b/1:
69 hg status . in b/1:
70 ? in_b_1
70 ? in_b_1
71 hg status .. in b/1:
71 hg status .. in b/1:
72 ? in_b_1
72 ? in_b_1
73 ? ../2/in_b_2
73 ? ../2/in_b_2
74 ? ../in_b
74 ? ../in_b
75 hg status in b/2:
75 hg status in b/2:
76 ? a/1/in_a_1
76 ? a/1/in_a_1
77 ? a/in_a
77 ? a/in_a
78 ? b/1/in_b_1
78 ? b/1/in_b_1
79 ? b/2/in_b_2
79 ? b/2/in_b_2
80 ? b/in_b
80 ? b/in_b
81 ? in_root
81 ? in_root
82 hg status . in b/2:
82 hg status . in b/2:
83 ? in_b_2
83 ? in_b_2
84 hg status .. in b/2:
84 hg status .. in b/2:
85 ? ../1/in_b_1
85 ? ../1/in_b_1
86 ? in_b_2
86 ? in_b_2
87 ? ../in_b
87 ? ../in_b
88 adding .hgignore
88 adding .hgignore
89 adding deleted
89 adding deleted
90 adding modified
90 adding modified
91 adding removed
91 adding removed
92 hg status:
92 hg status:
93 A added
93 A added
94 R removed
94 R removed
95 ! deleted
95 ! deleted
96 ? unknown
96 ? unknown
97 hg status modified added removed deleted unknown never-existed ignored:
97 hg status modified added removed deleted unknown never-existed ignored:
98 never-existed: No such file or directory
98 never-existed: No such file or directory
99 A added
99 A added
100 R removed
100 R removed
101 ! deleted
101 ! deleted
102 ? unknown
102 ? unknown
103 hg status -C:
103 hg status -C:
104 A added
104 A added
105 A copied
105 A copied
106  modified
106  modified
107 R removed
107 R removed
108 ! deleted
108 ! deleted
109 ? unknown
109 ? unknown
110 hg status -A:
110 hg status -A:
111 A added
111 A added
112 A copied
112 A copied
113  modified
113  modified
114 R removed
114 R removed
115 ! deleted
115 ! deleted
116 ? unknown
116 ? unknown
117 I ignored
117 I ignored
118 C .hgignore
118 C .hgignore
119 C modified
119 C modified
120 hg status ignoreddir/file:
120 hg status ignoreddir/file:
121 hg status -i ignoreddir/file:
121 hg status -i ignoreddir/file:
122 I ignoreddir/file
122 I ignoreddir/file
123 adding .hgignore
123 adding .hgignore
124 adding deleted
124 adding deleted
125 adding modified
125 adding modified
126 adding removed
126 adding removed
127 % test unknown color
127 % test unknown color
128 ignoring unknown color/effect 'periwinkle' (configured in color.status.modified)
128 ignoring unknown color/effect 'periwinkle' (configured in color.status.modified)
129 M modified
129 M modified
130 A added
130 A added
131 A copied
131 A copied
132 R removed
132 R removed
133 ! deleted
133 ! deleted
134 ? unknown
134 ? unknown
135 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
136 created new head
137 merging a
138 warning: conflicts during merge.
139 merging a failed!
140 merging b
141 warning: conflicts during merge.
142 merging b failed!
143 0 files updated, 0 files merged, 0 files removed, 2 files unresolved
144 use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
145 hg resolve with one unresolved, one resolved:
146 U a
147 R b
General Comments 0
You need to be logged in to leave comments. Login now