diff mercurial/revset.py @ 30804:4227f80f72b2

revset: abuse x:y syntax to specify line range of followlines() This slightly complicates the parsing (see the previous patch), but the overall result seems not bad. I keep x:, :y and : for future extension.
author Yuya Nishihara <yuya@tcha.org>
date Mon, 09 Jan 2017 17:58:19 +0900
parents d389f19f14aa
children 41e31a6f5296
line wrap: on
line diff
--- a/mercurial/revset.py	Mon Jan 09 16:55:56 2017 +0900
+++ b/mercurial/revset.py	Mon Jan 09 17:58:19 2017 +0900
@@ -329,6 +329,20 @@
         return list(x[1:])
     return [x]
 
+def getrange(x, err):
+    if not x:
+        raise error.ParseError(err)
+    op = x[0]
+    if op == 'range':
+        return x[1], x[2]
+    elif op == 'rangepre':
+        return None, x[1]
+    elif op == 'rangepost':
+        return x[1], None
+    elif op == 'rangeall':
+        return None, None
+    raise error.ParseError(err)
+
 def getargs(x, min, max, err):
     l = getlist(x)
     if len(l) < min or (max >= 0 and len(l) > max):
@@ -1083,7 +1097,7 @@
     # of every revisions or files revisions.
     return _follow(repo, subset, x, '_followfirst', followfirst=True)
 
-@predicate('followlines(file, fromline, toline[, startrev=.])', safe=True)
+@predicate('followlines(file, fromline:toline[, startrev=.])', safe=True)
 def followlines(repo, subset, x):
     """Changesets modifying `file` in line range ('fromline', 'toline').
 
@@ -1094,8 +1108,8 @@
     from . import context  # avoid circular import issues
 
     args = getargsdict(x, 'followlines', 'file *lines startrev')
-    if len(args['lines']) != 2:
-        raise error.ParseError(_("followlines takes at least three arguments"))
+    if len(args['lines']) != 1:
+        raise error.ParseError(_("followlines requires a line range"))
 
     rev = '.'
     if 'startrev' in args:
@@ -1115,8 +1129,9 @@
             raise error.ParseError(_("followlines expects exactly one file"))
         fname = files[0]
 
+    lr = getrange(args['lines'][0], _("followlines expects a line range"))
     fromline, toline = [getinteger(a, _("line range bounds must be integers"))
-                        for a in args['lines']]
+                        for a in lr]
     if toline - fromline < 0:
         raise error.ParseError(_("line range must be positive"))
     if fromline < 1: