diff mercurial/scmutil.py @ 45854:4b4160a83303

dispatch: move some helper functions down into scmutil I plan to reuse `formatparse()` in the next patch. Differential Revision: https://phab.mercurial-scm.org/D9331
author Martin von Zweigbergk <martinvonz@google.com>
date Mon, 16 Nov 2020 16:00:13 -0800
parents f96fa4de5055
children ac362d5a7893
line wrap: on
line diff
--- a/mercurial/scmutil.py	Mon Nov 16 15:11:51 2020 -0800
+++ b/mercurial/scmutil.py	Mon Nov 16 16:00:13 2020 -0800
@@ -7,6 +7,7 @@
 
 from __future__ import absolute_import
 
+import difflib
 import errno
 import glob
 import os
@@ -142,6 +143,38 @@
         ui.status(_(b"no changes found\n"))
 
 
+def getsimilar(symbols, value):
+    sim = lambda x: difflib.SequenceMatcher(None, value, x).ratio()
+    # The cutoff for similarity here is pretty arbitrary. It should
+    # probably be investigated and tweaked.
+    return [s for s in symbols if sim(s) > 0.6]
+
+
+def reportsimilar(write, similar):
+    if len(similar) == 1:
+        write(_(b"(did you mean %s?)\n") % similar[0])
+    elif similar:
+        ss = b", ".join(sorted(similar))
+        write(_(b"(did you mean one of %s?)\n") % ss)
+
+
+def formatparse(write, inst):
+    similar = []
+    if isinstance(inst, error.UnknownIdentifier):
+        # make sure to check fileset first, as revset can invoke fileset
+        similar = getsimilar(inst.symbols, inst.function)
+    if inst.location is not None:
+        write(
+            _(b"hg: parse error at %s: %s\n")
+            % (pycompat.bytestr(inst.location), inst.message)
+        )
+    else:
+        write(_(b"hg: parse error: %s\n") % inst.message)
+        reportsimilar(write, similar)
+    if inst.hint:
+        write(_(b"(%s)\n") % inst.hint)
+
+
 def callcatch(ui, func):
     """call func() with global exception handling