##// END OF EJS Templates
Merge with default
Martin Geisler -
r10477:44b4a2a3 merge stable
parent child Browse files
Show More
@@ -1,368 +1,374 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 and resolve commands to add color to their
21 This extension modifies the status and resolve commands to add color to their
22 output 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
60 resolve.unresolved = red bold
61 resolve.resolved = green bold
61 resolve.resolved = green bold
62
62
63 bookmarks.current = green
63 bookmarks.current = green
64 '''
64 '''
65
65
66 import os, sys
66 import os, sys
67
67
68 from mercurial import cmdutil, commands, extensions
68 from mercurial import cmdutil, commands, extensions
69 from mercurial.i18n import _
69 from mercurial.i18n import _
70
70
71 # start and stop parameters for effects
71 # start and stop parameters for effects
72 _effect_params = {'none': 0,
72 _effect_params = {'none': 0,
73 'black': 30,
73 'black': 30,
74 'red': 31,
74 'red': 31,
75 'green': 32,
75 'green': 32,
76 'yellow': 33,
76 'yellow': 33,
77 'blue': 34,
77 'blue': 34,
78 'magenta': 35,
78 'magenta': 35,
79 'cyan': 36,
79 'cyan': 36,
80 'white': 37,
80 'white': 37,
81 'bold': 1,
81 'bold': 1,
82 'italic': 3,
82 'italic': 3,
83 'underline': 4,
83 'underline': 4,
84 'inverse': 7,
84 'inverse': 7,
85 'black_background': 40,
85 'black_background': 40,
86 'red_background': 41,
86 'red_background': 41,
87 'green_background': 42,
87 'green_background': 42,
88 'yellow_background': 43,
88 'yellow_background': 43,
89 'blue_background': 44,
89 'blue_background': 44,
90 'purple_background': 45,
90 'purple_background': 45,
91 'cyan_background': 46,
91 'cyan_background': 46,
92 'white_background': 47}
92 'white_background': 47}
93
93
94 def render_effects(text, effects):
94 def render_effects(text, effects):
95 'Wrap text in commands to turn on each effect.'
95 'Wrap text in commands to turn on each effect.'
96 start = [str(_effect_params[e]) for e in ['none'] + effects]
96 start = [str(_effect_params[e]) for e in ['none'] + effects]
97 start = '\033[' + ';'.join(start) + 'm'
97 start = '\033[' + ';'.join(start) + 'm'
98 stop = '\033[' + str(_effect_params['none']) + 'm'
98 stop = '\033[' + str(_effect_params['none']) + 'm'
99 return ''.join([start, text, stop])
99 return ''.join([start, text, stop])
100
100
101 def _colorstatuslike(abbreviations, effectdefs, orig, ui, repo, *pats, **opts):
101 def _colorstatuslike(abbreviations, effectdefs, orig, ui, repo, *pats, **opts):
102 '''run a status-like command with colorized output'''
102 '''run a status-like command with colorized output'''
103 delimiter = opts.get('print0') and '\0' or '\n'
103 delimiter = opts.get('print0') and '\0' or '\n'
104
104
105 nostatus = opts.get('no_status')
105 nostatus = opts.get('no_status')
106 opts['no_status'] = False
106 opts['no_status'] = False
107 # run original command and capture its output
107 # run original command and capture its output
108 ui.pushbuffer()
108 ui.pushbuffer()
109 retval = orig(ui, repo, *pats, **opts)
109 retval = orig(ui, repo, *pats, **opts)
110 # filter out empty strings
110 # filter out empty strings
111 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]
112
112
113 if nostatus:
113 if nostatus:
114 lines = [l[2:] for l in lines_with_status]
114 lines = [l[2:] for l in lines_with_status]
115 else:
115 else:
116 lines = lines_with_status
116 lines = lines_with_status
117
117
118 # apply color to output and display it
118 # apply color to output and display it
119 for i in xrange(len(lines)):
119 for i in xrange(len(lines)):
120 try:
120 status = abbreviations[lines_with_status[i][0]]
121 status = abbreviations[lines_with_status[i][0]]
122 except KeyError:
123 # Ignore lines with invalid codes, especially in the case of
124 # of unknown filenames containing newlines (issue2036).
125 pass
126 else:
121 effects = effectdefs[status]
127 effects = effectdefs[status]
122 if effects:
128 if effects:
123 lines[i] = render_effects(lines[i], effects)
129 lines[i] = render_effects(lines[i], effects)
124 ui.write(lines[i] + delimiter)
130 ui.write(lines[i] + delimiter)
125 return retval
131 return retval
126
132
127
133
128 _status_abbreviations = { 'M': 'modified',
134 _status_abbreviations = { 'M': 'modified',
129 'A': 'added',
135 'A': 'added',
130 'R': 'removed',
136 'R': 'removed',
131 '!': 'deleted',
137 '!': 'deleted',
132 '?': 'unknown',
138 '?': 'unknown',
133 'I': 'ignored',
139 'I': 'ignored',
134 'C': 'clean',
140 'C': 'clean',
135 ' ': 'copied', }
141 ' ': 'copied', }
136
142
137 _status_effects = { 'modified': ['blue', 'bold'],
143 _status_effects = { 'modified': ['blue', 'bold'],
138 'added': ['green', 'bold'],
144 'added': ['green', 'bold'],
139 'removed': ['red', 'bold'],
145 'removed': ['red', 'bold'],
140 'deleted': ['cyan', 'bold', 'underline'],
146 'deleted': ['cyan', 'bold', 'underline'],
141 'unknown': ['magenta', 'bold', 'underline'],
147 'unknown': ['magenta', 'bold', 'underline'],
142 'ignored': ['black', 'bold'],
148 'ignored': ['black', 'bold'],
143 'clean': ['none'],
149 'clean': ['none'],
144 'copied': ['none'], }
150 'copied': ['none'], }
145
151
146 def colorstatus(orig, ui, repo, *pats, **opts):
152 def colorstatus(orig, ui, repo, *pats, **opts):
147 '''run the status command with colored output'''
153 '''run the status command with colored output'''
148 return _colorstatuslike(_status_abbreviations, _status_effects,
154 return _colorstatuslike(_status_abbreviations, _status_effects,
149 orig, ui, repo, *pats, **opts)
155 orig, ui, repo, *pats, **opts)
150
156
151
157
152 _resolve_abbreviations = { 'U': 'unresolved',
158 _resolve_abbreviations = { 'U': 'unresolved',
153 'R': 'resolved', }
159 'R': 'resolved', }
154
160
155 _resolve_effects = { 'unresolved': ['red', 'bold'],
161 _resolve_effects = { 'unresolved': ['red', 'bold'],
156 'resolved': ['green', 'bold'], }
162 'resolved': ['green', 'bold'], }
157
163
158 def colorresolve(orig, ui, repo, *pats, **opts):
164 def colorresolve(orig, ui, repo, *pats, **opts):
159 '''run the resolve command with colored output'''
165 '''run the resolve command with colored output'''
160 if not opts.get('list'):
166 if not opts.get('list'):
161 # only colorize for resolve -l
167 # only colorize for resolve -l
162 return orig(ui, repo, *pats, **opts)
168 return orig(ui, repo, *pats, **opts)
163 return _colorstatuslike(_resolve_abbreviations, _resolve_effects,
169 return _colorstatuslike(_resolve_abbreviations, _resolve_effects,
164 orig, ui, repo, *pats, **opts)
170 orig, ui, repo, *pats, **opts)
165
171
166
172
167 _bookmark_effects = { 'current': ['green'] }
173 _bookmark_effects = { 'current': ['green'] }
168
174
169 def colorbookmarks(orig, ui, repo, *pats, **opts):
175 def colorbookmarks(orig, ui, repo, *pats, **opts):
170 def colorize(orig, s):
176 def colorize(orig, s):
171 lines = s.split('\n')
177 lines = s.split('\n')
172 for i, line in enumerate(lines):
178 for i, line in enumerate(lines):
173 if line.startswith(" *"):
179 if line.startswith(" *"):
174 lines[i] = render_effects(line, _bookmark_effects['current'])
180 lines[i] = render_effects(line, _bookmark_effects['current'])
175 orig('\n'.join(lines))
181 orig('\n'.join(lines))
176 oldwrite = extensions.wrapfunction(ui, 'write', colorize)
182 oldwrite = extensions.wrapfunction(ui, 'write', colorize)
177 try:
183 try:
178 orig(ui, repo, *pats, **opts)
184 orig(ui, repo, *pats, **opts)
179 finally:
185 finally:
180 ui.write = oldwrite
186 ui.write = oldwrite
181
187
182 def colorqseries(orig, ui, repo, *dummy, **opts):
188 def colorqseries(orig, ui, repo, *dummy, **opts):
183 '''run the qseries command with colored output'''
189 '''run the qseries command with colored output'''
184 ui.pushbuffer()
190 ui.pushbuffer()
185 retval = orig(ui, repo, **opts)
191 retval = orig(ui, repo, **opts)
186 patchlines = ui.popbuffer().splitlines()
192 patchlines = ui.popbuffer().splitlines()
187 patchnames = repo.mq.series
193 patchnames = repo.mq.series
188
194
189 for patch, patchname in zip(patchlines, patchnames):
195 for patch, patchname in zip(patchlines, patchnames):
190 if opts['missing']:
196 if opts['missing']:
191 effects = _patch_effects['missing']
197 effects = _patch_effects['missing']
192 # Determine if patch is applied.
198 # Determine if patch is applied.
193 elif [applied for applied in repo.mq.applied
199 elif [applied for applied in repo.mq.applied
194 if patchname == applied.name]:
200 if patchname == applied.name]:
195 effects = _patch_effects['applied']
201 effects = _patch_effects['applied']
196 else:
202 else:
197 effects = _patch_effects['unapplied']
203 effects = _patch_effects['unapplied']
198
204
199 patch = patch.replace(patchname, render_effects(patchname, effects), 1)
205 patch = patch.replace(patchname, render_effects(patchname, effects), 1)
200 ui.write(patch + '\n')
206 ui.write(patch + '\n')
201 return retval
207 return retval
202
208
203 _patch_effects = { 'applied': ['blue', 'bold', 'underline'],
209 _patch_effects = { 'applied': ['blue', 'bold', 'underline'],
204 'missing': ['red', 'bold'],
210 'missing': ['red', 'bold'],
205 'unapplied': ['black', 'bold'], }
211 'unapplied': ['black', 'bold'], }
206 def colorwrap(orig, *args):
212 def colorwrap(orig, *args):
207 '''wrap ui.write for colored diff output'''
213 '''wrap ui.write for colored diff output'''
208 def _colorize(s):
214 def _colorize(s):
209 lines = s.split('\n')
215 lines = s.split('\n')
210 for i, line in enumerate(lines):
216 for i, line in enumerate(lines):
211 stripline = line
217 stripline = line
212 if line and line[0] in '+-':
218 if line and line[0] in '+-':
213 # highlight trailing whitespace, but only in changed lines
219 # highlight trailing whitespace, but only in changed lines
214 stripline = line.rstrip()
220 stripline = line.rstrip()
215 for prefix, style in _diff_prefixes:
221 for prefix, style in _diff_prefixes:
216 if stripline.startswith(prefix):
222 if stripline.startswith(prefix):
217 lines[i] = render_effects(stripline, _diff_effects[style])
223 lines[i] = render_effects(stripline, _diff_effects[style])
218 break
224 break
219 if line != stripline:
225 if line != stripline:
220 lines[i] += render_effects(
226 lines[i] += render_effects(
221 line[len(stripline):], _diff_effects['trailingwhitespace'])
227 line[len(stripline):], _diff_effects['trailingwhitespace'])
222 return '\n'.join(lines)
228 return '\n'.join(lines)
223 orig(*[_colorize(s) for s in args])
229 orig(*[_colorize(s) for s in args])
224
230
225 def colorshowpatch(orig, self, node):
231 def colorshowpatch(orig, self, node):
226 '''wrap cmdutil.changeset_printer.showpatch with colored output'''
232 '''wrap cmdutil.changeset_printer.showpatch with colored output'''
227 oldwrite = extensions.wrapfunction(self.ui, 'write', colorwrap)
233 oldwrite = extensions.wrapfunction(self.ui, 'write', colorwrap)
228 try:
234 try:
229 orig(self, node)
235 orig(self, node)
230 finally:
236 finally:
231 self.ui.write = oldwrite
237 self.ui.write = oldwrite
232
238
233 def colordiffstat(orig, s):
239 def colordiffstat(orig, s):
234 lines = s.split('\n')
240 lines = s.split('\n')
235 for i, line in enumerate(lines):
241 for i, line in enumerate(lines):
236 if line and line[-1] in '+-':
242 if line and line[-1] in '+-':
237 name, graph = line.rsplit(' ', 1)
243 name, graph = line.rsplit(' ', 1)
238 graph = graph.replace('-',
244 graph = graph.replace('-',
239 render_effects('-', _diff_effects['deleted']))
245 render_effects('-', _diff_effects['deleted']))
240 graph = graph.replace('+',
246 graph = graph.replace('+',
241 render_effects('+', _diff_effects['inserted']))
247 render_effects('+', _diff_effects['inserted']))
242 lines[i] = ' '.join([name, graph])
248 lines[i] = ' '.join([name, graph])
243 orig('\n'.join(lines))
249 orig('\n'.join(lines))
244
250
245 def colordiff(orig, ui, repo, *pats, **opts):
251 def colordiff(orig, ui, repo, *pats, **opts):
246 '''run the diff command with colored output'''
252 '''run the diff command with colored output'''
247 if opts.get('stat'):
253 if opts.get('stat'):
248 wrapper = colordiffstat
254 wrapper = colordiffstat
249 else:
255 else:
250 wrapper = colorwrap
256 wrapper = colorwrap
251 oldwrite = extensions.wrapfunction(ui, 'write', wrapper)
257 oldwrite = extensions.wrapfunction(ui, 'write', wrapper)
252 try:
258 try:
253 orig(ui, repo, *pats, **opts)
259 orig(ui, repo, *pats, **opts)
254 finally:
260 finally:
255 ui.write = oldwrite
261 ui.write = oldwrite
256
262
257 def colorchurn(orig, ui, repo, *pats, **opts):
263 def colorchurn(orig, ui, repo, *pats, **opts):
258 '''run the churn command with colored output'''
264 '''run the churn command with colored output'''
259 if not opts.get('diffstat'):
265 if not opts.get('diffstat'):
260 return orig(ui, repo, *pats, **opts)
266 return orig(ui, repo, *pats, **opts)
261 oldwrite = extensions.wrapfunction(ui, 'write', colordiffstat)
267 oldwrite = extensions.wrapfunction(ui, 'write', colordiffstat)
262 try:
268 try:
263 orig(ui, repo, *pats, **opts)
269 orig(ui, repo, *pats, **opts)
264 finally:
270 finally:
265 ui.write = oldwrite
271 ui.write = oldwrite
266
272
267 _diff_prefixes = [('diff', 'diffline'),
273 _diff_prefixes = [('diff', 'diffline'),
268 ('copy', 'extended'),
274 ('copy', 'extended'),
269 ('rename', 'extended'),
275 ('rename', 'extended'),
270 ('old', 'extended'),
276 ('old', 'extended'),
271 ('new', 'extended'),
277 ('new', 'extended'),
272 ('deleted', 'extended'),
278 ('deleted', 'extended'),
273 ('---', 'file_a'),
279 ('---', 'file_a'),
274 ('+++', 'file_b'),
280 ('+++', 'file_b'),
275 ('@', 'hunk'),
281 ('@', 'hunk'),
276 ('-', 'deleted'),
282 ('-', 'deleted'),
277 ('+', 'inserted')]
283 ('+', 'inserted')]
278
284
279 _diff_effects = {'diffline': ['bold'],
285 _diff_effects = {'diffline': ['bold'],
280 'extended': ['cyan', 'bold'],
286 'extended': ['cyan', 'bold'],
281 'file_a': ['red', 'bold'],
287 'file_a': ['red', 'bold'],
282 'file_b': ['green', 'bold'],
288 'file_b': ['green', 'bold'],
283 'hunk': ['magenta'],
289 'hunk': ['magenta'],
284 'deleted': ['red'],
290 'deleted': ['red'],
285 'inserted': ['green'],
291 'inserted': ['green'],
286 'changed': ['white'],
292 'changed': ['white'],
287 'trailingwhitespace': ['bold', 'red_background']}
293 'trailingwhitespace': ['bold', 'red_background']}
288
294
289 def extsetup(ui):
295 def extsetup(ui):
290 '''Initialize the extension.'''
296 '''Initialize the extension.'''
291 _setupcmd(ui, 'diff', commands.table, colordiff, _diff_effects)
297 _setupcmd(ui, 'diff', commands.table, colordiff, _diff_effects)
292 _setupcmd(ui, 'incoming', commands.table, None, _diff_effects)
298 _setupcmd(ui, 'incoming', commands.table, None, _diff_effects)
293 _setupcmd(ui, 'log', commands.table, None, _diff_effects)
299 _setupcmd(ui, 'log', commands.table, None, _diff_effects)
294 _setupcmd(ui, 'outgoing', commands.table, None, _diff_effects)
300 _setupcmd(ui, 'outgoing', commands.table, None, _diff_effects)
295 _setupcmd(ui, 'tip', commands.table, None, _diff_effects)
301 _setupcmd(ui, 'tip', commands.table, None, _diff_effects)
296 _setupcmd(ui, 'status', commands.table, colorstatus, _status_effects)
302 _setupcmd(ui, 'status', commands.table, colorstatus, _status_effects)
297 _setupcmd(ui, 'resolve', commands.table, colorresolve, _resolve_effects)
303 _setupcmd(ui, 'resolve', commands.table, colorresolve, _resolve_effects)
298
304
299 try:
305 try:
300 mq = extensions.find('mq')
306 mq = extensions.find('mq')
301 _setupcmd(ui, 'qdiff', mq.cmdtable, colordiff, _diff_effects)
307 _setupcmd(ui, 'qdiff', mq.cmdtable, colordiff, _diff_effects)
302 _setupcmd(ui, 'qseries', mq.cmdtable, colorqseries, _patch_effects)
308 _setupcmd(ui, 'qseries', mq.cmdtable, colorqseries, _patch_effects)
303 except KeyError:
309 except KeyError:
304 mq = None
310 mq = None
305
311
306 try:
312 try:
307 rec = extensions.find('record')
313 rec = extensions.find('record')
308 _setupcmd(ui, 'record', rec.cmdtable, colordiff, _diff_effects)
314 _setupcmd(ui, 'record', rec.cmdtable, colordiff, _diff_effects)
309 except KeyError:
315 except KeyError:
310 rec = None
316 rec = None
311
317
312 if mq and rec:
318 if mq and rec:
313 _setupcmd(ui, 'qrecord', rec.cmdtable, colordiff, _diff_effects)
319 _setupcmd(ui, 'qrecord', rec.cmdtable, colordiff, _diff_effects)
314 try:
320 try:
315 churn = extensions.find('churn')
321 churn = extensions.find('churn')
316 _setupcmd(ui, 'churn', churn.cmdtable, colorchurn, _diff_effects)
322 _setupcmd(ui, 'churn', churn.cmdtable, colorchurn, _diff_effects)
317 except KeyError:
323 except KeyError:
318 churn = None
324 churn = None
319
325
320 try:
326 try:
321 bookmarks = extensions.find('bookmarks')
327 bookmarks = extensions.find('bookmarks')
322 _setupcmd(ui, 'bookmarks', bookmarks.cmdtable, colorbookmarks,
328 _setupcmd(ui, 'bookmarks', bookmarks.cmdtable, colorbookmarks,
323 _bookmark_effects)
329 _bookmark_effects)
324 except KeyError:
330 except KeyError:
325 # The bookmarks extension is not enabled
331 # The bookmarks extension is not enabled
326 pass
332 pass
327
333
328 def _setupcmd(ui, cmd, table, func, effectsmap):
334 def _setupcmd(ui, cmd, table, func, effectsmap):
329 '''patch in command to command table and load effect map'''
335 '''patch in command to command table and load effect map'''
330 def nocolor(orig, *args, **opts):
336 def nocolor(orig, *args, **opts):
331
337
332 if (opts['no_color'] or opts['color'] == 'never' or
338 if (opts['no_color'] or opts['color'] == 'never' or
333 (opts['color'] == 'auto' and (os.environ.get('TERM') == 'dumb'
339 (opts['color'] == 'auto' and (os.environ.get('TERM') == 'dumb'
334 or not sys.__stdout__.isatty()))):
340 or not sys.__stdout__.isatty()))):
335 del opts['no_color']
341 del opts['no_color']
336 del opts['color']
342 del opts['color']
337 return orig(*args, **opts)
343 return orig(*args, **opts)
338
344
339 oldshowpatch = extensions.wrapfunction(cmdutil.changeset_printer,
345 oldshowpatch = extensions.wrapfunction(cmdutil.changeset_printer,
340 'showpatch', colorshowpatch)
346 'showpatch', colorshowpatch)
341 del opts['no_color']
347 del opts['no_color']
342 del opts['color']
348 del opts['color']
343 try:
349 try:
344 if func is not None:
350 if func is not None:
345 return func(orig, *args, **opts)
351 return func(orig, *args, **opts)
346 return orig(*args, **opts)
352 return orig(*args, **opts)
347 finally:
353 finally:
348 cmdutil.changeset_printer.showpatch = oldshowpatch
354 cmdutil.changeset_printer.showpatch = oldshowpatch
349
355
350 entry = extensions.wrapcommand(table, cmd, nocolor)
356 entry = extensions.wrapcommand(table, cmd, nocolor)
351 entry[1].extend([
357 entry[1].extend([
352 ('', 'color', 'auto', _("when to colorize (always, auto, or never)")),
358 ('', 'color', 'auto', _("when to colorize (always, auto, or never)")),
353 ('', 'no-color', None, _("don't colorize output (DEPRECATED)")),
359 ('', 'no-color', None, _("don't colorize output (DEPRECATED)")),
354 ])
360 ])
355
361
356 for status in effectsmap:
362 for status in effectsmap:
357 configkey = cmd + '.' + status
363 configkey = cmd + '.' + status
358 effects = ui.configlist('color', configkey)
364 effects = ui.configlist('color', configkey)
359 if effects:
365 if effects:
360 good = []
366 good = []
361 for e in effects:
367 for e in effects:
362 if e in _effect_params:
368 if e in _effect_params:
363 good.append(e)
369 good.append(e)
364 else:
370 else:
365 ui.warn(_("ignoring unknown color/effect %r "
371 ui.warn(_("ignoring unknown color/effect %r "
366 "(configured in color.%s)\n")
372 "(configured in color.%s)\n")
367 % (e, configkey))
373 % (e, configkey))
368 effectsmap[status] = good
374 effectsmap[status] = good
@@ -1,24 +1,43 b''
1 #!/bin/sh
1 #!/bin/sh
2 # http://mercurial.selenic.com/bts/issue352
2 # http://mercurial.selenic.com/bts/issue352
3
3
4 "$TESTDIR/hghave" eol-in-paths || exit 80
4 "$TESTDIR/hghave" eol-in-paths || exit 80
5
5
6 echo % test issue352
6 hg init foo
7 hg init foo
7 cd foo
8 cd foo
8
9
9 A=`printf 'he\rllo'`
10 A=`printf 'he\rllo'`
10
11
11 echo foo > "$A"
12 echo foo > "$A"
12 hg add
13 hg add
13 hg ci -A -m m
14 hg ci -A -m m
14 rm "$A"
15 rm "$A"
15
16
16 echo foo > "hell
17 echo foo > "hell
17 o"
18 o"
18 hg add
19 hg add
19 hg ci -A -m m
20 hg ci -A -m m
20
21
21 echo foo > "$A"
22 echo foo > "$A"
22 hg debugwalk
23 hg debugwalk
23
24
25 # http://mercurial.selenic.com/bts/issue2036
26 cd ..
27 echo % test issue2039
28
29 hg init bar
30 cd bar
31
32 echo "[extensions]" >> $HGRCPATH
33 echo "color=" >> $HGRCPATH
34
35 A=`printf 'foo\nbar'`
36 B=`printf 'foo\nbar.baz'`
37
38 touch "$A"
39 touch "$B"
40
41 hg status --color=always
42
24 exit 0
43 exit 0
@@ -1,14 +1,20 b''
1 % test issue352
1 adding he llo
2 adding he llo
2 abort: '\n' and '\r' disallowed in filenames: 'he\rllo'
3 abort: '\n' and '\r' disallowed in filenames: 'he\rllo'
3 adding he llo
4 adding he llo
4 abort: '\n' and '\r' disallowed in filenames: 'he\rllo'
5 abort: '\n' and '\r' disallowed in filenames: 'he\rllo'
5 adding hell
6 adding hell
6 o
7 o
7 abort: '\n' and '\r' disallowed in filenames: 'hell\no'
8 abort: '\n' and '\r' disallowed in filenames: 'hell\no'
8 adding hell
9 adding hell
9 o
10 o
10 abort: '\n' and '\r' disallowed in filenames: 'hell\no'
11 abort: '\n' and '\r' disallowed in filenames: 'hell\no'
11 f he llo he llo
12 f he llo he llo
12 f hell
13 f hell
13 o hell
14 o hell
14 o
15 o
16 % test issue2039
17 ? foo
18 bar
19 ? foo
20 bar.baz
General Comments 0
You need to be logged in to leave comments. Login now