mirror of
https://github.com/xonsh/xonsh.git
synced 2025-03-04 16:34:47 +01:00
remove typo completion, add subsequence completion
This commit is contained in:
parent
cf3105e1ab
commit
d027432e3b
3 changed files with 70 additions and 12 deletions
|
@ -13,6 +13,8 @@ Current Developments
|
||||||
attempted to load.
|
attempted to load.
|
||||||
* Only show the prompt for the wizard if we did not attempt to load any run
|
* Only show the prompt for the wizard if we did not attempt to load any run
|
||||||
control files (as opposed to if none were successfully loaded).
|
control files (as opposed to if none were successfully loaded).
|
||||||
|
* Tab completion of paths now includes zsh-style path expansion (subsequence
|
||||||
|
matching)
|
||||||
|
|
||||||
**Deprecated:** None
|
**Deprecated:** None
|
||||||
|
|
||||||
|
|
|
@ -151,9 +151,57 @@ def _quote_paths(paths, start, end):
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
def fuzzy_match(ref, typed):
|
def joinpath(path):
|
||||||
thresh = builtins.__xonsh_env__['SUGGEST_THRESHOLD']
|
if path is None:
|
||||||
return levenshtein(ref, typed, thresh) <= thresh
|
return ''
|
||||||
|
if len(path) == 0:
|
||||||
|
return ''
|
||||||
|
if path == ('',):
|
||||||
|
return get_sep()
|
||||||
|
elif path[0] == '':
|
||||||
|
return get_sep() + _normpath(os.path.join(*path))
|
||||||
|
else:
|
||||||
|
return _normpath(os.path.join(*path))
|
||||||
|
|
||||||
|
|
||||||
|
def splitpath(path):
|
||||||
|
path = _normpath(path)
|
||||||
|
if path.startswith(get_sep()):
|
||||||
|
pre = ('', )
|
||||||
|
else:
|
||||||
|
pre = ()
|
||||||
|
return pre + _splitpath(path, ())
|
||||||
|
|
||||||
|
|
||||||
|
def _splitpath(path, sofar=()):
|
||||||
|
folder, path = os.path.split(path)
|
||||||
|
if path == "":
|
||||||
|
return sofar[::-1]
|
||||||
|
elif folder == "":
|
||||||
|
return (sofar + (path, ))[::-1]
|
||||||
|
else:
|
||||||
|
return _splitpath(folder, sofar + (path, ))
|
||||||
|
|
||||||
|
|
||||||
|
def expanded_match(ref, typed):
|
||||||
|
if len(typed) == 0:
|
||||||
|
return True
|
||||||
|
elif len(ref) == 0:
|
||||||
|
return False
|
||||||
|
elif ref[0] == typed[0]:
|
||||||
|
return expanded_match(ref[1:], typed[1:])
|
||||||
|
else:
|
||||||
|
return expanded_match(ref[1:], typed)
|
||||||
|
|
||||||
|
|
||||||
|
def _expand_one(sofar, nextone):
|
||||||
|
out = set()
|
||||||
|
for i in sofar:
|
||||||
|
for j in iglobpath(os.path.join(joinpath(i), '*') if i is not None else '*'):
|
||||||
|
j = os.path.basename(j)
|
||||||
|
if expanded_match(j, nextone):
|
||||||
|
out.add((i or ()) + (j, ))
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
def complete_path(prefix, line, start, end, ctx, cdpath=True):
|
def complete_path(prefix, line, start, end, ctx, cdpath=True):
|
||||||
|
@ -174,15 +222,18 @@ def complete_path(prefix, line, start, end, ctx, cdpath=True):
|
||||||
csc = env.get('CASE_SENSITIVE_COMPLETIONS')
|
csc = env.get('CASE_SENSITIVE_COMPLETIONS')
|
||||||
for s in iglobpath(prefix + '*', ignore_case=(not csc)):
|
for s in iglobpath(prefix + '*', ignore_case=(not csc)):
|
||||||
paths.add(s)
|
paths.add(s)
|
||||||
if len(paths) == 0:
|
if env.get('FUZZY_PATH_COMPLETION'):
|
||||||
for s in iglobpath(os.path.join(os.path.dirname(prefix), '*'),
|
p = splitpath(prefix)
|
||||||
ignore_case=(not csc)):
|
if len(p) != 0:
|
||||||
bname = os.path.basename(prefix)
|
if p[0] == '':
|
||||||
lenb = len(bname)
|
basedir = ('', )
|
||||||
if csc and fuzzy_match(s, bname):
|
p = p[1:]
|
||||||
paths.add(os.path.join(os.path.dirname(prefix), s))
|
else:
|
||||||
if (not csc) and fuzzy_match(s.lower(), prefix.lower()):
|
basedir = None
|
||||||
paths.add(os.path.join(os.path.dirname(prefix), s))
|
matches_so_far = {basedir}
|
||||||
|
for i in p:
|
||||||
|
matches_so_far = _expand_one(matches_so_far, i)
|
||||||
|
paths |= {joinpath(i) for i in matches_so_far}
|
||||||
if tilde in prefix:
|
if tilde in prefix:
|
||||||
home = os.path.expanduser(tilde)
|
home = os.path.expanduser(tilde)
|
||||||
paths = {s.replace(home, tilde) for s in paths}
|
paths = {s.replace(home, tilde) for s in paths}
|
||||||
|
|
|
@ -92,6 +92,7 @@ DEFAULT_ENSURERS = {
|
||||||
'DYNAMIC_CWD_WIDTH': (is_dynamic_cwd_width, to_dynamic_cwd_tuple,
|
'DYNAMIC_CWD_WIDTH': (is_dynamic_cwd_width, to_dynamic_cwd_tuple,
|
||||||
dynamic_cwd_tuple_to_str),
|
dynamic_cwd_tuple_to_str),
|
||||||
'FORCE_POSIX_PATHS': (is_bool, to_bool, bool_to_str),
|
'FORCE_POSIX_PATHS': (is_bool, to_bool, bool_to_str),
|
||||||
|
'FUZZY_PATH_COMPLETION': (is_bool, to_bool, bool_to_str),
|
||||||
'HISTCONTROL': (is_string_set, csv_to_set, set_to_csv),
|
'HISTCONTROL': (is_string_set, csv_to_set, set_to_csv),
|
||||||
'IGNOREEOF': (is_bool, to_bool, bool_to_str),
|
'IGNOREEOF': (is_bool, to_bool, bool_to_str),
|
||||||
'INTENSIFY_COLORS_ON_WIN':(always_false, intensify_colors_on_win_setter,
|
'INTENSIFY_COLORS_ON_WIN':(always_false, intensify_colors_on_win_setter,
|
||||||
|
@ -202,6 +203,7 @@ DEFAULT_VALUES = {
|
||||||
'DYNAMIC_CWD_WIDTH': (float('inf'), 'c'),
|
'DYNAMIC_CWD_WIDTH': (float('inf'), 'c'),
|
||||||
'EXPAND_ENV_VARS': True,
|
'EXPAND_ENV_VARS': True,
|
||||||
'FORCE_POSIX_PATHS': False,
|
'FORCE_POSIX_PATHS': False,
|
||||||
|
'FUZZY_PATH_COMPLETION': True,
|
||||||
'HISTCONTROL': set(),
|
'HISTCONTROL': set(),
|
||||||
'IGNOREEOF': False,
|
'IGNOREEOF': False,
|
||||||
'INDENT': ' ',
|
'INDENT': ' ',
|
||||||
|
@ -350,6 +352,9 @@ DEFAULT_DOCS = {
|
||||||
"and $TITLE. See 'Customizing the Prompt' "
|
"and $TITLE. See 'Customizing the Prompt' "
|
||||||
'http://xon.sh/tutorial.html#customizing-the-prompt',
|
'http://xon.sh/tutorial.html#customizing-the-prompt',
|
||||||
configurable=False, default='xonsh.environ.FORMATTER_DICT'),
|
configurable=False, default='xonsh.environ.FORMATTER_DICT'),
|
||||||
|
'FUZZY_PATH_COMPLETION': VarDocs(
|
||||||
|
"Causes path completion to use subsequence matching rather than "
|
||||||
|
"substring matching."),
|
||||||
'HISTCONTROL': VarDocs(
|
'HISTCONTROL': VarDocs(
|
||||||
'A set of strings (comma-separated list in string form) of options '
|
'A set of strings (comma-separated list in string form) of options '
|
||||||
'that determine what commands are saved to the history list. By '
|
'that determine what commands are saved to the history list. By '
|
||||||
|
|
Loading…
Add table
Reference in a new issue