mercurial/revsetlang.py
changeset 36685 2a258985ffeb
parent 35882 87416288be98
child 36691 1b179d151578
--- a/mercurial/revsetlang.py	Sat Mar 03 11:07:46 2018 -0800
+++ b/mercurial/revsetlang.py	Sat Mar 03 15:31:37 2018 -0800
@@ -539,7 +539,21 @@
         return tuple(foldconcat(t) for t in tree)
 
 def parse(spec, lookup=None):
-    return _parsewith(spec, lookup=lookup)
+    try:
+        return _parsewith(spec, lookup=lookup)
+    except error.ParseError as inst:
+        if len(inst.args) > 1:  # has location
+            # Add 1 to location because unlike templates, revset parse errors
+            # point to the char where the error happened, not the char after.
+            loc = inst.args[1] + 1
+            # Remove newlines -- spaces are equivalent whitespace.
+            spec = spec.replace('\n', ' ')
+            # We want the caret to point to the place in the template that
+            # failed to parse, but in a hint we get a open paren at the
+            # start. Therefore, we print "loc + 1" spaces (instead of "loc")
+            # to line up the caret with the location of the error.
+            inst.hint = spec + '\n' + ' ' * loc + '^ ' + _('here')
+        raise
 
 def _quote(s):
     r"""Quote a value in order to make it safe for the revset engine.