Patchwork D2609: templater: provide hint for multi-line templates with parse errors

login
register
mail settings
Submitter phabricator
Date March 3, 2018, 11:40 p.m.
Message ID <28711ad9b7eb835fc6d5561cd0c2d0e7@localhost.localdomain>
Download mbox | patch
Permalink /patch/28873/
State Not Applicable
Headers show

Comments

phabricator - March 3, 2018, 11:40 p.m.
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG5d1bae328b7d: templater: provide hint for multi-line templates with parse errors (authored by ryanmce, committed by ).

CHANGED PRIOR TO COMMIT
  https://phab.mercurial-scm.org/D2609?vs=6487&id=6510#toc

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D2609?vs=6487&id=6510

REVISION DETAIL
  https://phab.mercurial-scm.org/D2609

AFFECTED FILES
  mercurial/templater.py
  tests/test-log.t

CHANGE DETAILS




To: ryanmce, #hg-reviewers, durin42
Cc: mercurial-devel

Patch

diff --git a/tests/test-log.t b/tests/test-log.t
--- a/tests/test-log.t
+++ b/tests/test-log.t
@@ -2304,6 +2304,8 @@ 
   > {shortest(node}
   > line4\nline5'
   hg: parse error at 28: unexpected token: end
+  (line 1\nline2\n{shortest(node}\nline4\nline5
+                                ^ here)
   [255]
 
   $ cd ..
diff --git a/mercurial/templater.py b/mercurial/templater.py
--- a/mercurial/templater.py
+++ b/mercurial/templater.py
@@ -246,14 +246,16 @@ 
     except error.ParseError as inst:
         if len(inst.args) > 1:  # has location
             loc = inst.args[1]
-            # TODO: Opportunity for improvement! If there is a newline in the
-            # template, this hint does not point to the right place, so skip.
-            if '\n' not in tmpl:
-                # 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" spaces (instead of "loc - 1")
-                # to line up the caret with the location of the error.
-                inst.hint = tmpl + '\n' + ' ' * (loc) + '^ ' + _('here')
+            # Offset the caret location by the number of newlines before the
+            # location of the error, since we will replace one-char newlines
+            # with the two-char literal r'\n'.
+            offset = tmpl[:loc].count('\n')
+            tmpl = tmpl.replace('\n', br'\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" spaces (instead of "loc - 1")
+            # to line up the caret with the location of the error.
+            inst.hint = tmpl + '\n' + ' ' * (loc + offset) + '^ ' + _('here')
         raise
     yield ('end', None, pos)