From d5d259b0db223ae8ce80075fc039209a5fb95a4e Mon Sep 17 00:00:00 2001 From: Gordon Ball Date: Mon, 17 Oct 2016 15:17:38 +0200 Subject: [PATCH] Add support for path-yielding backticks --- xonsh/built_ins.py | 7 +++++-- xonsh/parsers/base.py | 13 ++++++++----- xonsh/tokenize.py | 7 +++++-- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/xonsh/built_ins.py b/xonsh/built_ins.py index 79c98ef0e..b08d2229c 100644 --- a/xonsh/built_ins.py +++ b/xonsh/built_ins.py @@ -154,16 +154,19 @@ def globsearch(s): sort_result=glob_sorted) -def pathsearch(func, s, pymode=False): +def pathsearch(func, s, pymode=False, pathobj=False): """ Takes a string and returns a list of file paths that match (regex, glob, - or arbitrary search function). + or arbitrary search function). If pathobj=True, the return is a list of + pathlib.Path objects instead of strings. """ if (not callable(func) or len(inspect.signature(func).parameters) != 1): error = "%r is not a known path search function" raise XonshError(error % func) o = func(s) + if pathobj and pymode: #this doesn't make sense in subprocess mode + o = list(map(path_literal, o)) no_match = [] if pymode else [s] return o if len(o) != 0 else no_match diff --git a/xonsh/parsers/base.py b/xonsh/parsers/base.py index 265de58fc..6529d7941 100644 --- a/xonsh/parsers/base.py +++ b/xonsh/parsers/base.py @@ -129,15 +129,18 @@ def xonsh_pathsearch(pattern, pymode=False, lineno=None, col=None): searchfunc, pattern = RE_SEARCHPATH.match(pattern).groups() pattern = ast.Str(s=pattern, lineno=lineno, col_offset=col) - if searchfunc in {'r', ''}: - func = '__xonsh_regexsearch__' - elif searchfunc == 'g': + pathobj = False + if searchfunc.startswith('@'): + func = searchfunc[1:] + elif 'g' in searchfunc: func = '__xonsh_globsearch__' + pathobj = 'p' in searchfunc else: - func = searchfunc[1:] # remove the '@' character + func = '__xonsh_regexsearch__' + pathobj = 'p' in searchfunc func = ast.Name(id=func, ctx=ast.Load(), lineno=lineno, col_offset=col) - return xonsh_call('__xonsh_pathsearch__', args=[func, pattern, pymode], + return xonsh_call('__xonsh_pathsearch__', args=[func, pattern, pymode, pathobj], lineno=lineno, col=col) diff --git a/xonsh/tokenize.py b/xonsh/tokenize.py index e70d0ea3c..4b1837522 100644 --- a/xonsh/tokenize.py +++ b/xonsh/tokenize.py @@ -221,7 +221,7 @@ String = group(StringPrefix + r"'[^\n'\\]*(?:\\.[^\n'\\]*)*'", StringPrefix + r'"[^\n"\\]*(?:\\.[^\n"\\]*)*"') # Xonsh-specific Syntax -SearchPath = r"((?:[rg]|@\w*)?)`([^\n`\\]*(?:\\.[^\n`\\]*)*)`" +SearchPath = r"((?:[rgp]+|@\w*)?)`([^\n`\\]*(?:\\.[^\n`\\]*)*)`" # Because of leftmost-then-longest match semantics, be sure to put the # longest operators first (e.g., if = came before ==, == would get @@ -275,8 +275,9 @@ endpats = {"'": Single, '"': Double, "RB'''": Single3, 'RB"""': Double3, "u'''": Single3, 'u"""': Double3, "U'''": Single3, 'U"""': Double3, + "p'''": Single3, 'p"""': Double3, 'r': None, 'R': None, 'b': None, 'B': None, - 'u': None, 'U': None} + 'u': None, 'U': None, 'p': None} triple_quoted = {} for t in ("'''", '"""', @@ -287,6 +288,7 @@ for t in ("'''", '"""', "rb'''", 'rb"""', "rB'''", 'rB"""', "Rb'''", 'Rb"""', "RB'''", 'RB"""', "u'''", 'u"""', "U'''", 'U"""', + "p'''", 'p""""', ): triple_quoted[t] = t single_quoted = {} @@ -298,6 +300,7 @@ for t in ("'", '"', "rb'", 'rb"', "rB'", 'rB"', "Rb'", 'Rb"', "RB'", 'RB"', "u'", 'u"', "U'", 'U"', + "p'", 'p"', ): single_quoted[t] = t