5 # This software may be used and distributed according to the terms of the |
5 # This software may be used and distributed according to the terms of the |
6 # GNU General Public License version 2 or any later version. |
6 # GNU General Public License version 2 or any later version. |
7 |
7 |
8 from i18n import _ |
8 from i18n import _ |
9 import os, sys, atexit, signal, pdb, socket, errno, shlex, time, traceback, re |
9 import os, sys, atexit, signal, pdb, socket, errno, shlex, time, traceback, re |
|
10 import difflib |
10 import util, commands, hg, fancyopts, extensions, hook, error |
11 import util, commands, hg, fancyopts, extensions, hook, error |
11 import cmdutil, encoding |
12 import cmdutil, encoding |
12 import ui as uimod |
13 import ui as uimod |
13 |
14 |
14 class request(object): |
15 class request(object): |
25 |
26 |
26 def run(): |
27 def run(): |
27 "run the command in sys.argv" |
28 "run the command in sys.argv" |
28 sys.exit((dispatch(request(sys.argv[1:])) or 0) & 255) |
29 sys.exit((dispatch(request(sys.argv[1:])) or 0) & 255) |
29 |
30 |
|
31 def _getsimilar(symbols, value): |
|
32 sim = lambda x: difflib.SequenceMatcher(None, value, x).ratio() |
|
33 # The cutoff for similarity here is pretty arbitrary. It should |
|
34 # probably be investigated and tweaked. |
|
35 return [s for s in symbols if sim(s) > 0.6] |
|
36 |
30 def _formatparse(write, inst): |
37 def _formatparse(write, inst): |
|
38 similar = [] |
|
39 if isinstance(inst, error.UnknownIdentifier): |
|
40 # make sure to check fileset first, as revset can invoke fileset |
|
41 similar = _getsimilar(inst.symbols, inst.function) |
31 if len(inst.args) > 1: |
42 if len(inst.args) > 1: |
32 write(_("hg: parse error at %s: %s\n") % |
43 write(_("hg: parse error at %s: %s\n") % |
33 (inst.args[1], inst.args[0])) |
44 (inst.args[1], inst.args[0])) |
34 if (inst.args[0][0] == ' '): |
45 if (inst.args[0][0] == ' '): |
35 write(_("unexpected leading whitespace\n")) |
46 write(_("unexpected leading whitespace\n")) |
36 else: |
47 else: |
37 write(_("hg: parse error: %s\n") % inst.args[0]) |
48 write(_("hg: parse error: %s\n") % inst.args[0]) |
|
49 if similar: |
|
50 if len(similar) == 1: |
|
51 write(_("(did you mean %r?)\n") % similar[0]) |
|
52 else: |
|
53 ss = ", ".join(sorted(similar)) |
|
54 write(_("(did you mean one of %s?)\n") % ss) |
38 |
55 |
39 def dispatch(req): |
56 def dispatch(req): |
40 "run the command specified in req.args" |
57 "run the command specified in req.args" |
41 if req.ferr: |
58 if req.ferr: |
42 ferr = req.ferr |
59 ferr = req.ferr |