2016-11-15 01:01:34 -05:00
|
|
|
"""Bash-like interface extensions for xonsh."""
|
2017-04-22 10:52:34 +10:00
|
|
|
import shlex
|
|
|
|
import sys
|
2019-03-16 01:36:28 -04:00
|
|
|
import re
|
2019-10-05 16:37:45 -04:00
|
|
|
import builtins
|
2017-04-22 10:52:34 +10:00
|
|
|
|
2018-07-20 12:50:00 -04:00
|
|
|
|
2017-04-22 10:52:34 +10:00
|
|
|
__all__ = ()
|
|
|
|
|
2016-11-20 18:49:26 -05:00
|
|
|
|
2017-01-01 19:59:12 -05:00
|
|
|
@events.on_transform_command
|
2017-01-14 18:13:27 -05:00
|
|
|
def bash_preproc(cmd, **kw):
|
2019-03-16 01:36:28 -04:00
|
|
|
bang_previous = {
|
2019-04-26 11:11:11 -04:00
|
|
|
"!": lambda x: x,
|
|
|
|
"$": lambda x: shlex.split(x)[-1],
|
|
|
|
"^": lambda x: shlex.split(x)[0],
|
|
|
|
"*": lambda x: " ".join(shlex.split(x)[1:]),
|
2019-03-16 01:36:28 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
def replace_bang(m):
|
|
|
|
arg = m.group(1)
|
|
|
|
inputs = __xonsh__.history.inps
|
|
|
|
|
|
|
|
# Dissect the previous command.
|
|
|
|
if arg in bang_previous:
|
|
|
|
try:
|
|
|
|
return bang_previous[arg](inputs[-1])
|
|
|
|
except IndexError:
|
2019-03-16 11:18:48 -04:00
|
|
|
print("xonsh: no history for '!{}'".format(arg))
|
2019-04-26 11:11:11 -04:00
|
|
|
return ""
|
2019-03-16 01:36:28 -04:00
|
|
|
|
|
|
|
# Look back in history for a matching command.
|
|
|
|
else:
|
|
|
|
try:
|
|
|
|
return next((x for x in reversed(inputs) if x.startswith(arg)))
|
|
|
|
except StopIteration:
|
2019-03-16 11:18:48 -04:00
|
|
|
print("xonsh: no previous commands match '!{}'".format(arg))
|
2019-04-26 11:11:11 -04:00
|
|
|
return ""
|
2019-03-16 01:36:28 -04:00
|
|
|
|
2019-05-10 07:18:40 -04:00
|
|
|
return re.sub(r"!([!$^*]|[\w]+)", replace_bang, cmd)
|
2017-03-11 11:59:56 -05:00
|
|
|
|
|
|
|
|
2017-04-22 10:52:34 +10:00
|
|
|
def alias(args, stdin=None):
|
|
|
|
ret = 0
|
|
|
|
|
|
|
|
if args:
|
|
|
|
for arg in args:
|
2019-04-26 11:11:11 -04:00
|
|
|
if "=" in arg:
|
2017-04-22 10:52:34 +10:00
|
|
|
# shlex.split to remove quotes, e.g. "foo='echo hey'" into
|
|
|
|
# "foo=echo hey"
|
2019-04-26 11:11:11 -04:00
|
|
|
name, cmd = shlex.split(arg)[0].split("=", 1)
|
2017-04-22 10:52:34 +10:00
|
|
|
aliases[name] = shlex.split(cmd)
|
|
|
|
elif arg in aliases:
|
2019-04-26 11:11:11 -04:00
|
|
|
print("{}={}".format(arg, aliases[arg]))
|
2017-04-22 10:52:34 +10:00
|
|
|
else:
|
|
|
|
print("alias: {}: not found".format(arg), file=sys.stderr)
|
|
|
|
ret = 1
|
|
|
|
else:
|
|
|
|
for alias, cmd in aliases.items():
|
2019-04-26 11:11:11 -04:00
|
|
|
print("{}={}".format(alias, cmd))
|
2017-04-22 10:52:34 +10:00
|
|
|
|
|
|
|
return ret
|
|
|
|
|
|
|
|
|
2019-04-26 11:11:11 -04:00
|
|
|
aliases["alias"] = alias
|
2019-10-05 20:51:30 -04:00
|
|
|
builtins.__xonsh__.env["THREAD_SUBPROCS"] = False
|
2020-09-24 23:13:20 +03:00
|
|
|
|
|
|
|
|
|
|
|
def _unset(args):
|
|
|
|
if not args:
|
2020-09-24 23:28:41 +03:00
|
|
|
print("Usage: unset ENV_VARIABLE", file=sys.stderr)
|
|
|
|
|
2020-09-24 23:13:20 +03:00
|
|
|
for v in args:
|
|
|
|
try:
|
|
|
|
__xonsh__.env.pop(v)
|
2020-09-25 00:00:56 +03:00
|
|
|
except KeyError:
|
2020-09-24 23:28:41 +03:00
|
|
|
print(f"{v} not found", file=sys.stderr)
|
|
|
|
|
|
|
|
|
|
|
|
aliases["unset"] = _unset
|
2020-09-24 23:13:20 +03:00
|
|
|
|
|
|
|
|
|
|
|
def _export(args):
|
|
|
|
if not args:
|
2020-09-24 23:28:41 +03:00
|
|
|
print("Usage: export ENV_VARIABLE=VALUE", file=sys.stderr)
|
|
|
|
|
2020-09-24 23:13:20 +03:00
|
|
|
for eq in args:
|
|
|
|
if "=" in eq:
|
|
|
|
name, val = shlex.split(eq)[0].split("=", 1)
|
|
|
|
__xonsh__.env[name] = val
|
|
|
|
else:
|
2020-09-24 23:28:41 +03:00
|
|
|
print(f"{eq} equal sign not found", file=sys.stderr)
|
|
|
|
|
2020-09-24 23:13:20 +03:00
|
|
|
|
2020-09-24 23:28:41 +03:00
|
|
|
aliases["export"] = _export
|
2020-09-24 23:13:20 +03:00
|
|
|
|
|
|
|
|
|
|
|
def _set(args):
|
|
|
|
arg = args[0]
|
2020-09-24 23:28:41 +03:00
|
|
|
if arg == "-e":
|
|
|
|
__xonsh__.env["RAISE_SUBPROC_ERROR"] = True
|
|
|
|
elif arg == "+e":
|
|
|
|
__xonsh__.env["RAISE_SUBPROC_ERROR"] = False
|
|
|
|
elif arg == "-x":
|
|
|
|
__xonsh__.env["XONSH_TRACE_SUBPROC"] = True
|
|
|
|
elif arg == "+x":
|
|
|
|
__xonsh__.env["XONSH_TRACE_SUBPROC"] = False
|
2020-09-24 23:13:20 +03:00
|
|
|
else:
|
2020-09-24 23:28:41 +03:00
|
|
|
print(
|
|
|
|
"Not supported in xontrib bashisms.\nPRs are welcome - https://github.com/xonsh/xonsh/blob/master/xontrib/bashisms.py",
|
|
|
|
file=sys.stderr,
|
|
|
|
)
|
|
|
|
|
2020-09-24 23:13:20 +03:00
|
|
|
|
2020-09-24 23:28:41 +03:00
|
|
|
aliases["set"] = _set
|
2020-09-25 09:57:36 +03:00
|
|
|
|
|
|
|
|
|
|
|
def _shopt(args):
|
|
|
|
|
|
|
|
supported_shopt = ["DOTGLOB"]
|
|
|
|
|
|
|
|
args_len = len(args)
|
|
|
|
if args_len == 0:
|
|
|
|
for so in supported_shopt:
|
|
|
|
onoff = "on" if so in __xonsh__.env and __xonsh__.env[so] else "off"
|
|
|
|
print(f"dotglob\t{onoff}")
|
|
|
|
return
|
|
|
|
elif args_len < 2 or args[0] in ["-h", "--help"]:
|
|
|
|
print(f'Usage: shopt <-s|-u> <{"|".join(supported_shopt).lower()}>')
|
|
|
|
return
|
|
|
|
|
|
|
|
opt = args[0]
|
|
|
|
optname = args[1]
|
|
|
|
|
|
|
|
if opt == "-s" and optname == "dotglob":
|
|
|
|
__xonsh__.env["DOTGLOB"] = True
|
|
|
|
elif opt == "-u" and optname == "dotglob":
|
|
|
|
__xonsh__.env["DOTGLOB"] = False
|
|
|
|
else:
|
|
|
|
print(
|
|
|
|
"Not supported in xontrib bashisms.\nPRs are welcome - https://github.com/xonsh/xonsh/blob/master/xontrib/bashisms.py",
|
|
|
|
file=sys.stderr,
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
aliases["shopt"] = _shopt
|
|
|
|
|
|
|
|
|
|
|
|
aliases["complete"] = "completer list"
|