[PATCH] formatter: make grep command use formatter

Kostia Balytskyi ikostia at fb.com
Tue Mar 8 17:57:38 UTC 2016


# HG changeset patch
# User Kostia Balytskyi <ikostia at fb.com>
# Date 1457459179 28800
#      Tue Mar 08 09:46:19 2016 -0800
# Node ID 2253a514d6a5ff3695f1a8a0583807c3476f4f61
# Parent  70c8fc604d568ab6f31f0f325f16bfd8a96355f5
formatter: make grep command use formatter

Apart from a general goal "make output configurable" this
fix allows a much wanted feature of having `grep` produce
hashes instead of revision numbers.

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -4154,7 +4154,7 @@ def _dograft(ui, repo, *revs, **opts):
      _('only search files changed within revision range'), _('REV')),
     ('u', 'user', None, _('list the author (long with -v)')),
     ('d', 'date', None, _('list the date (short with -q)')),
-    ] + walkopts,
+    ] + walkopts + formatteropts,
     _('[OPTION]... PATTERN [FILE]...'),
     inferrepo=True)
 def grep(ui, repo, pattern, *pats, **opts):
@@ -4254,12 +4254,8 @@ def grep(ui, repo, pattern, *pats, **opt
                 for i in xrange(blo, bhi):
                     yield ('+', b[i])
 
-    def display(fn, ctx, pstates, states):
+    def display(fn, ctx, pstates, states, fm):
         rev = ctx.rev()
-        if ui.quiet:
-            datefunc = util.shortdate
-        else:
-            datefunc = util.datestr
         found = False
         @util.cachefunc
         def binary():
@@ -4271,28 +4267,17 @@ def grep(ui, repo, pattern, *pats, **opt
         else:
             iter = [('', l) for l in states]
         for change, l in iter:
-            cols = [(fn, 'grep.filename'), (str(rev), 'grep.rev')]
-
-            if opts.get('line_number'):
-                cols.append((str(l.linenum), 'grep.linenumber'))
-            if opts.get('all'):
-                cols.append((change, 'grep.change'))
-            if opts.get('user'):
-                cols.append((ui.shortuser(ctx.user()), 'grep.user'))
-            if opts.get('date'):
-                cols.append((datefunc(ctx.date()), 'grep.date'))
-            for col, label in cols[:-1]:
-                ui.write(col, label=label)
-                ui.write(sep, label='grep.sep')
-            ui.write(cols[-1][0], label=cols[-1][1])
-            if not opts.get('files_with_matches'):
-                ui.write(sep, label='grep.sep')
-                if not opts.get('text') and binary():
-                    ui.write(" Binary file matches")
-                else:
-                    for s, label in l:
-                        ui.write(s, label=label)
-            ui.write(eol)
+            fm.startitem()
+            fm.data(filename=fn)
+            fm.data(rev=rev)
+            fm.data(node=ctx.hex())
+            fm.data(desc=ctx.description())
+            fm.data(linenum=str(l.linenum))
+            fm.data(change=change)
+            fm.data(user=ctx.user())
+            fm.data(date=ctx.date())
+            fm.data(binary='true' if binary() else 'false')
+            fm.data(chunks=[{'text': s, 'lbl': lbl} for s, lbl in l])
             found = True
             if opts.get('files_with_matches'):
                 break
@@ -4339,6 +4324,32 @@ def grep(ui, repo, pattern, *pats, **opt
                 except error.LookupError:
                     pass
 
+    tmpl = ["{label('grep.filename', filename)}", "{label('grep.rev', rev)}"]
+    if opts.get('line_number'):
+        tmpl.append("{label('grep.linenumber', linenum)}")
+    if opts.get('all'):
+        tmpl.append("{label('grep.change', change)}")
+    if opts.get('user'):
+        tmpl.append("{label('grep.user', emailuser(user))}")
+    if opts.get('date'):
+        if ui.quiet:
+            tmpl.append("{label('grep.date', shortdate(date))}")
+        else:
+            tmpl.append("{label('grep.date', date(date))}")
+
+    if not opts.get('files_with_matches'):
+        if opts.get('text'):
+            tmpl.append("{chunks % '{label(lbl, text)}'}")
+        else:
+            tmpl.append("{ifeq(binary, 'true',  ' Binary file matches'," +\
+                          " chunks % '{label(lbl, text)}')}")
+    lblsep = "{label('grep.sep', '%s')}" % sep
+    tmpl = lblsep.join(tmpl) + eol
+
+    if not opts.get('template'):
+        opts['template'] = tmpl
+
+    fm = ui.formatter('grep', opts)
     for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
         rev = ctx.rev()
         parent = ctx.p1().rev()
@@ -4351,7 +4362,7 @@ def grep(ui, repo, pattern, *pats, **opt
                 continue
             pstates = matches.get(parent, {}).get(copy or fn, [])
             if pstates or states:
-                r = display(fn, ctx, pstates, states)
+                r = display(fn, ctx, pstates, states, fm)
                 found = found or r
                 if r and not opts.get('all'):
                     skip[fn] = True
@@ -4360,6 +4371,7 @@ def grep(ui, repo, pattern, *pats, **opt
         del matches[rev]
         del revfiles[rev]
 
+    fm.end()
     return not found
 
 @command('heads',
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -276,7 +276,7 @@ Show all commands + options
   debugwireargs: three, four, five, ssh, remotecmd, insecure
   files: rev, print0, include, exclude, template, subrepos
   graft: rev, continue, edit, log, force, currentdate, currentuser, date, user, tool, dry-run
-  grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude
+  grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude, template
   heads: rev, topo, active, closed, style, template
   help: extension, command, keyword, system
   identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure


More information about the Mercurial-devel mailing list