Exemple #1
0
def test_iglobpath():
    with TemporaryDirectory() as test_dir:
        # Create files 00.test to 99.test in unsorted order
        num = 18
        for _ in range(100):
            s = str(num).zfill(2)
            path = os.path.join(test_dir, s + '.test')
            with open(path, 'w') as file:
                file.write(s + '\n')
            num = (num + 37) % 100

        # Create one file not matching the '*.test'
        with open(os.path.join(test_dir, '07'), 'w') as file:
            file.write('test\n')

        with mock_xonsh_env(Env(EXPAND_ENV_VARS=False)):
            builtins.__xonsh_expand_path__ = expand_path

            paths = list(iglobpath(os.path.join(test_dir, '*.test'),
                                   ignore_case=False, sort_result=False))
            assert len(paths) == 100
            paths = list(iglobpath(os.path.join(test_dir, '*'),
                                   ignore_case=True, sort_result=False))
            assert len(paths) == 101

            paths = list(iglobpath(os.path.join(test_dir, '*.test'),
                                   ignore_case=False, sort_result=True))
            assert len(paths) == 100
            assert paths == sorted(paths)
            paths = list(iglobpath(os.path.join(test_dir, '*'),
                                   ignore_case=True, sort_result=True))
            assert len(paths) == 101
            assert paths == sorted(paths)
Exemple #2
0
def complete_path(prefix, line, start, end, ctx, cdpath=True, filtfunc=None):
    """Completes based on a path name."""
    # string stuff for automatic quoting
    path_str_start = ''
    path_str_end = ''
    append_end = True
    p = _path_from_partial_string(line, end)
    lprefix = len(prefix)
    if p is not None:
        lprefix = len(p[0])
        prefix = p[1]
        path_str_start = p[2]
        path_str_end = p[3]
        if len(line) >= end + 1 and line[end] == path_str_end:
            append_end = False
    tilde = '~'
    paths = set()
    env = builtins.__xonsh_env__
    csc = env.get('CASE_SENSITIVE_COMPLETIONS')
    glob_sorted = env.get('GLOB_SORTED')
    prefix = glob.escape(prefix)
    for s in xt.iglobpath(prefix + '*', ignore_case=(not csc),
                          sort_result=glob_sorted):
        paths.add(s)
    if len(paths) == 0 and env.get('SUBSEQUENCE_PATH_COMPLETION'):
        # this block implements 'subsequence' matching, similar to fish and zsh.
        # matches are based on subsequences, not substrings.
        # e.g., ~/u/ro completes to ~/lou/carcolh
        # see above functions for details.
        p = _splitpath(os.path.expanduser(prefix))
        if len(p) != 0:
            if p[0] == '':
                basedir = ('', )
                p = p[1:]
            else:
                basedir = None
            matches_so_far = {basedir}
            for i in p:
                matches_so_far = _expand_one(matches_so_far, i, csc)
            paths |= {_joinpath(i) for i in matches_so_far}
    if len(paths) == 0 and env.get('FUZZY_PATH_COMPLETION'):
        threshold = env.get('SUGGEST_THRESHOLD')
        for s in xt.iglobpath(os.path.dirname(prefix) + '*',
                              ignore_case=(not csc),
                              sort_result=glob_sorted):
            if xt.levenshtein(prefix, s, threshold) < threshold:
                paths.add(s)
    if tilde in prefix:
        home = os.path.expanduser(tilde)
        paths = {s.replace(home, tilde) for s in paths}
    if cdpath:
        _add_cdpaths(paths, prefix)
    paths = set(filter(filtfunc, paths))
    paths, _ = _quote_paths({_normpath(s) for s in paths},
                            path_str_start,
                            path_str_end,
                            append_end)
    paths.update(filter(filtfunc, _dots(prefix)))
    paths.update(filter(filtfunc, _env(prefix)))
    return paths, lprefix
Exemple #3
0
def complete_path(prefix, line, start, end, ctx, cdpath=True, filtfunc=None):
    """Completes based on a path name."""
    # string stuff for automatic quoting
    path_str_start = ''
    path_str_end = ''
    append_end = True
    p = _path_from_partial_string(line, end)
    lprefix = len(prefix)
    if p is not None:
        lprefix = len(p[0])
        prefix = p[1]
        path_str_start = p[2]
        path_str_end = p[3]
        if len(line) >= end + 1 and line[end] == path_str_end:
            append_end = False
    tilde = '~'
    paths = set()
    env = builtins.__xonsh_env__
    csc = env.get('CASE_SENSITIVE_COMPLETIONS')
    glob_sorted = env.get('GLOB_SORTED')
    prefix = glob.escape(prefix)
    for s in xt.iglobpath(prefix + '*',
                          ignore_case=(not csc),
                          sort_result=glob_sorted):
        paths.add(s)
    if len(paths) == 0 and env.get('SUBSEQUENCE_PATH_COMPLETION'):
        # this block implements 'subsequence' matching, similar to fish and zsh.
        # matches are based on subsequences, not substrings.
        # e.g., ~/u/ro completes to ~/lou/carcolh
        # see above functions for details.
        p = _splitpath(os.path.expanduser(prefix))
        if len(p) != 0:
            if p[0] == '':
                basedir = ('', )
                p = p[1:]
            else:
                basedir = None
            matches_so_far = {basedir}
            for i in p:
                matches_so_far = _expand_one(matches_so_far, i, csc)
            paths |= {_joinpath(i) for i in matches_so_far}
    if len(paths) == 0 and env.get('FUZZY_PATH_COMPLETION'):
        threshold = env.get('SUGGEST_THRESHOLD')
        for s in xt.iglobpath(os.path.dirname(prefix) + '*',
                              ignore_case=(not csc),
                              sort_result=glob_sorted):
            if xt.levenshtein(prefix, s, threshold) < threshold:
                paths.add(s)
    if tilde in prefix:
        home = os.path.expanduser(tilde)
        paths = {s.replace(home, tilde) for s in paths}
    if cdpath:
        _add_cdpaths(paths, prefix)
    paths = set(filter(filtfunc, paths))
    paths = _quote_paths({_normpath(s)
                          for s in paths}, path_str_start, path_str_end,
                         append_end)
    paths.update(filter(filtfunc, _dots(prefix)))
    paths.update(filter(filtfunc, _env(prefix)))
    return paths, lprefix
Exemple #4
0
def complete_path(prefix, line, start, end, ctx, cdpath=True):
    """Completes based on a path name."""
    # string stuff for automatic quoting
    path_str_start = ""
    path_str_end = ""
    p = _path_from_partial_string(line, end)
    lprefix = len(prefix)
    if p is not None:
        lprefix = len(p[0])
        prefix = p[1]
        path_str_start = p[2]
        path_str_end = p[3]
    tilde = "~"
    paths = set()
    csc = builtins.__xonsh_env__.get("CASE_SENSITIVE_COMPLETIONS")
    for s in iglobpath(prefix + "*", ignore_case=(not csc)):
        paths.add(s)
    if tilde in prefix:
        home = os.path.expanduser(tilde)
        paths = {s.replace(home, tilde) for s in paths}
    if cdpath:
        _add_cdpaths(paths, prefix)
    paths = _quote_paths({_normpath(s) for s in paths}, path_str_start, path_str_end)
    _add_env(paths, prefix)
    _add_dots(paths, prefix)
    return paths, lprefix
Exemple #5
0
def complete_path(prefix, line, start, end, ctx, cdpath=True):
    """Completes based on a path name."""
    # string stuff for automatic quoting
    path_str_start = ''
    path_str_end = ''
    p = _path_from_partial_string(line, end)
    lprefix = len(prefix)
    if p is not None:
        lprefix = len(p[0])
        prefix = p[1]
        path_str_start = p[2]
        path_str_end = p[3]
    tilde = '~'
    paths = set()
    csc = builtins.__xonsh_env__.get('CASE_SENSITIVE_COMPLETIONS')
    for s in iglobpath(prefix + '*', ignore_case=(not csc)):
        paths.add(s)
    if tilde in prefix:
        home = os.path.expanduser(tilde)
        paths = {s.replace(home, tilde) for s in paths}
    if cdpath:
        _add_cdpaths(paths, prefix)
    paths = _quote_paths({_normpath(s)
                          for s in paths}, path_str_start, path_str_end)
    _add_env(paths, prefix)
    _add_dots(paths, prefix)
    return paths, lprefix
Exemple #6
0
def _add_cdpaths(paths, prefix):
    """Completes current prefix using CDPATH"""
    env = builtins.__xonsh_env__
    csc = env.get('CASE_SENSITIVE_COMPLETIONS')
    for cdp in env.get('CDPATH'):
        test_glob = os.path.join(cdp, prefix) + '*'
        for s in iglobpath(test_glob, ignore_case=(not csc)):
            if os.path.isdir(s):
                paths.add(os.path.basename(s))
Exemple #7
0
def _expand_one(sofar, nextone, csc):
    out = set()
    for i in sofar:
        _glob = os.path.join(_joinpath(i), '*') if i is not None else '*'
        for j in iglobpath(_glob):
            j = os.path.basename(j)
            if subsequence_match(j, nextone, csc):
                out.add((i or ()) + (j, ))
    return out
Exemple #8
0
def _expand_one(sofar, nextone, csc):
    out = set()
    for i in sofar:
        _glob = os.path.join(_joinpath(i), '*') if i is not None else '*'
        for j in iglobpath(_glob):
            j = os.path.basename(j)
            if subsequence_match(j, nextone, csc):
                out.add((i or ()) + (j, ))
    return out
Exemple #9
0
def _add_cdpaths(paths, prefix):
    """Completes current prefix using CDPATH"""
    env = builtins.__xonsh_env__
    csc = env.get("CASE_SENSITIVE_COMPLETIONS")
    for cdp in env.get("CDPATH"):
        test_glob = os.path.join(cdp, prefix) + "*"
        for s in iglobpath(test_glob, ignore_case=(not csc)):
            if os.path.isdir(s):
                paths.add(os.path.basename(s))
Exemple #10
0
def _expand_one(sofar, nextone, csc):
    out = set()
    glob_sorted = XSH.env.get("GLOB_SORTED")
    for i in sofar:
        _glob = os.path.join(_joinpath(i), "*") if i is not None else "*"
        for j in xt.iglobpath(_glob, sort_result=glob_sorted):
            j = os.path.basename(j)
            if subsequence_match(j, nextone, csc):
                out.add((i or ()) + (j, ))
    return out
Exemple #11
0
def _expand_one(sofar, nextone, csc):
    out = set()
    glob_sorted = builtins.__xonsh_env__.get('GLOB_SORTED')
    for i in sofar:
        _glob = os.path.join(_joinpath(i), '*') if i is not None else '*'
        for j in xt.iglobpath(_glob, sort_result=glob_sorted):
            j = os.path.basename(j)
            if subsequence_match(j, nextone, csc):
                out.add((i or ()) + (j, ))
    return out
Exemple #12
0
def _expand_one(sofar, nextone, csc):
    out = set()
    glob_sorted = builtins.__xonsh_env__.get('GLOB_SORTED')
    for i in sofar:
        _glob = os.path.join(_joinpath(i), '*') if i is not None else '*'
        for j in xt.iglobpath(_glob, sort_result=glob_sorted):
            j = os.path.basename(j)
            if subsequence_match(j, nextone, csc):
                out.add((i or ()) + (j, ))
    return out
Exemple #13
0
def _add_cdpaths(paths, prefix):
    """Completes current prefix using CDPATH"""
    env = builtins.__xonsh_env__
    csc = env.get('CASE_SENSITIVE_COMPLETIONS')
    glob_sorted = env.get('GLOB_SORTED')
    for cdp in env.get('CDPATH'):
        test_glob = os.path.join(cdp, prefix) + '*'
        for s in xt.iglobpath(test_glob, ignore_case=(not csc),
                              sort_result=glob_sorted):
            if os.path.isdir(s):
                paths.add(os.path.basename(s))
Exemple #14
0
def test_iglobpath_empty_str(monkeypatch, xonsh_builtins):
    # makes sure that iglobpath works, even when os.scandir() and os.listdir()
    # fail to return valid results, like an empty filename
    def mockscandir(path):
        yield ''
    if hasattr(os, 'scandir'):
        monkeypatch.setattr(os, 'scandir', mockscandir)
    def mocklistdir(path):
        return ['']
    monkeypatch.setattr(os, 'listdir', mocklistdir)
    paths = list(iglobpath('some/path'))
    assert len(paths) == 0
Exemple #15
0
def _add_cdpaths(paths, prefix):
    """Completes current prefix using CDPATH"""
    env = builtins.__xonsh__.env
    csc = env.get("CASE_SENSITIVE_COMPLETIONS")
    glob_sorted = env.get("GLOB_SORTED")
    for cdp in env.get("CDPATH"):
        test_glob = os.path.join(cdp, prefix) + "*"
        for s in xt.iglobpath(
            test_glob, ignore_case=(not csc), sort_result=glob_sorted
        ):
            if os.path.isdir(s):
                paths.add(os.path.relpath(s, cdp))
Exemple #16
0
def test_iglobpath_empty_str(monkeypatch, xession):
    # makes sure that iglobpath works, even when os.scandir() and os.listdir()
    # fail to return valid results, like an empty filename
    def mockscandir(path):
        yield ""

    if hasattr(os, "scandir"):
        monkeypatch.setattr(os, "scandir", mockscandir)

    def mocklistdir(path):
        return [""]

    monkeypatch.setattr(os, "listdir", mocklistdir)
    paths = list(iglobpath("some/path"))
    assert len(paths) == 0
Exemple #17
0
def complete_path(prefix, line, start, end, ctx, cdpath=True, filtfunc=None):
    """Completes based on a path name."""
    # string stuff for automatic quoting
    path_str_start = ""
    path_str_end = ""
    append_end = True
    p = _path_from_partial_string(line, end)
    lprefix = len(prefix)
    if p is not None:
        lprefix = len(p[0])
        # Compensate for 'p' if p-string variant
        pstring_pre = _get_normalized_pstring_quote(p[2])[0]
        if pstring_pre in ("pr", "p"):
            lprefix += 1
        prefix = p[1]
        path_str_start = p[2]
        path_str_end = p[3]
        if len(line) >= end + 1 and line[end] == path_str_end:
            append_end = False
    tilde = "~"
    paths = set()
    env = builtins.__xonsh__.env
    csc = env.get("CASE_SENSITIVE_COMPLETIONS")
    glob_sorted = env.get("GLOB_SORTED")
    prefix = glob.escape(prefix)
    for s in xt.iglobpath(prefix + "*", ignore_case=(not csc), sort_result=glob_sorted):
        paths.add(s)
    if len(paths) == 0 and env.get("SUBSEQUENCE_PATH_COMPLETION"):
        # this block implements 'subsequence' matching, similar to fish and zsh.
        # matches are based on subsequences, not substrings.
        # e.g., ~/u/ro completes to ~/lou/carcolh
        # see above functions for details.
        p = _splitpath(os.path.expanduser(prefix))
        p_len = len(p)
        if p_len != 0:
            relative_char = ["", ".", ".."]
            if p[0] in relative_char:
                i = 0
                while i < p_len and p[i] in relative_char:
                    i += 1
                basedir = p[:i]
                p = p[i:]
            else:
                basedir = None
            matches_so_far = {basedir}
            for i in p:
                matches_so_far = _expand_one(matches_so_far, i, csc)
            paths |= {_joinpath(i) for i in matches_so_far}
    if len(paths) == 0 and env.get("FUZZY_PATH_COMPLETION"):
        threshold = env.get("SUGGEST_THRESHOLD")
        for s in xt.iglobpath(
            os.path.dirname(prefix) + "*",
            ignore_case=(not csc),
            sort_result=glob_sorted,
        ):
            if xt.levenshtein(prefix, s, threshold) < threshold:
                paths.add(s)
    if cdpath and cd_in_command(line):
        _add_cdpaths(paths, prefix)
    paths = set(filter(filtfunc, paths))
    if tilde in prefix:
        home = os.path.expanduser(tilde)
        paths = {s.replace(home, tilde) for s in paths}
    paths, _ = _quote_paths(
        {_normpath(s) for s in paths}, path_str_start, path_str_end, append_end, cdpath
    )
    paths.update(filter(filtfunc, _dots(prefix)))
    paths.update(filter(filtfunc, _env(prefix)))
    return paths, lprefix
Exemple #18
0
def test_iglobpath_no_dotfiles_recursive(xession):
    d = os.path.dirname(__file__)
    g = d + "/**"
    files = list(iglobpath(g, include_dotfiles=False))
    assert d + "/bin/.someotherdotfile" not in files
Exemple #19
0
def test_iglobpath_dotfiles(xonsh_builtins):
    d = os.path.dirname(__file__)
    g = d + "/*"
    files = list(iglobpath(g, include_dotfiles=True))
    assert d + "/.somedotfile" in files
Exemple #20
0
def test_iglobpath_dotfiles_recursive(xonsh_builtins):
    d = os.path.dirname(__file__)
    g = d + "/**"
    files = list(iglobpath(g, include_dotfiles=True))
    assert d + "/bin/.someotherdotfile" in files
Exemple #21
0
def test_iglobpath_dotfiles(xonsh_builtins):
    d = os.path.dirname(__file__)
    g = d + "/*"
    files = list(iglobpath(g, include_dotfiles=True))
    assert d + "/.somedotfile" in files
Exemple #22
0
def test_iglobpath_dotfiles_recursive(xonsh_builtins):
    d = os.path.dirname(__file__)
    g = d + "/**"
    files = list(iglobpath(g, include_dotfiles=True))
    assert d + "/bin/.someotherdotfile" in files
Exemple #23
0
def test_iglobpath_no_dotfiles(xession):
    d = os.path.dirname(__file__)
    g = d + "/*"
    files = list(iglobpath(g, include_dotfiles=False))
    assert d + "/.somedotfile" not in files