hgext/color.py
changeset 10223 51421ab573de
parent 10222 98f630e15d82
child 10282 08a0f04b56bd
equal deleted inserted replaced
10222:98f630e15d82 10223:51421ab573de
    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
    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 
       
    60   resolve.unresolved = red bold
       
    61   resolve.resolved = green bold
    59 
    62 
    60   bookmarks.current = green
    63   bookmarks.current = green
    61 '''
    64 '''
    62 
    65 
    63 import os, sys
    66 import os, sys
    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 
   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
       
   126 
   124 
   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',
   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'], }
       
   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 
   142 
   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):
   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)