mirror of
https://github.com/xonsh/xonsh.git
synced 2025-03-05 17:00:58 +01:00
Merge branch 'master' into timeit
This commit is contained in:
commit
eeb2c5c03d
10 changed files with 156 additions and 63 deletions
19
docs/aliases.rst
Normal file
19
docs/aliases.rst
Normal file
|
@ -0,0 +1,19 @@
|
|||
.. _aliases:
|
||||
|
||||
********************
|
||||
Aliases
|
||||
********************
|
||||
|
||||
xonsh builtin aliases.
|
||||
|
||||
xexec
|
||||
====================
|
||||
xexec uses the ``os.execvpe()`` function to replace the xonsh process with
|
||||
the specified program. This provides the functionality of the bash ``exec``
|
||||
builtin.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
>>> xexec bash
|
||||
bash $
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
package:
|
||||
name: xonsh
|
||||
version: "0.1.4"
|
||||
version: "0.1.5"
|
||||
|
||||
source:
|
||||
fn: xonsh.tar.gz
|
||||
|
|
|
@ -481,20 +481,26 @@ def test_setcomp_if_setcomp_if():
|
|||
def test_dictcomp():
|
||||
yield check_ast, '{x: x for x in "mom"}'
|
||||
|
||||
def test_dictcomp_unpack_parens():
|
||||
yield check_ast, '{k: v for (k, v) in {"x": 42}.items()}'
|
||||
|
||||
def test_dictcomp_unpack_no_parens():
|
||||
yield check_ast, '{k: v for k, v in {"x": 42}.items()}'
|
||||
|
||||
def test_dictcomp_if():
|
||||
yield check_ast, '{x:x for x in "mom" if True}'
|
||||
yield check_ast, '{x: x for x in "mom" if True}'
|
||||
|
||||
def test_dictcomp_if_and():
|
||||
yield check_ast, '{x:x for x in "mom" if True and x == "m"}'
|
||||
yield check_ast, '{x: x for x in "mom" if True and x == "m"}'
|
||||
|
||||
def test_dbl_dictcomp():
|
||||
yield check_ast, '{x:y for x in "mom" for y in "dad"}'
|
||||
yield check_ast, '{x: y for x in "mom" for y in "dad"}'
|
||||
|
||||
def test_dictcomp_if_dictcomp():
|
||||
yield check_ast, '{x:y for x in "mom" if True for y in "dad"}'
|
||||
yield check_ast, '{x: y for x in "mom" if True for y in "dad"}'
|
||||
|
||||
def test_dictcomp_if_dictcomp_if():
|
||||
yield check_ast, '{x:y for x in "mom" if True for y in "dad" if y == "d"}'
|
||||
yield check_ast, '{x: y for x in "mom" if True for y in "dad" if y == "d"}'
|
||||
|
||||
def test_lambda():
|
||||
yield check_ast, 'lambda: 42'
|
||||
|
|
|
@ -1 +1 @@
|
|||
__version__ = '0.1.4'
|
||||
__version__ = '0.1.5'
|
||||
|
|
|
@ -9,37 +9,10 @@ import itertools
|
|||
import subprocess
|
||||
from warnings import warn
|
||||
|
||||
from xonsh.dirstack import dirs, pushd, popd
|
||||
from xonsh.dirstack import cd, pushd, popd, dirs
|
||||
from xonsh.jobs import jobs, fg, bg, kill_all_jobs
|
||||
|
||||
|
||||
def cd(args, stdin=None):
|
||||
"""Changes the directory.
|
||||
|
||||
If no directory is specified (i.e. if `args` is None) then this
|
||||
changes to the current user's home directory.
|
||||
"""
|
||||
env = builtins.__xonsh_env__
|
||||
cur_oldpwd = env.get('OLDPWD', os.getcwd())
|
||||
if len(args) == 0:
|
||||
d = os.path.expanduser('~')
|
||||
elif len(args) == 1:
|
||||
d = os.path.expanduser(args[0])
|
||||
if d == '-':
|
||||
d = cur_oldpwd
|
||||
else:
|
||||
return '', 'cd takes 0 or 1 arguments, not {0}\n'.format(len(args))
|
||||
if not os.path.exists(d):
|
||||
return '', 'cd: no such file or directory: {0}\n'.format(d)
|
||||
if not os.path.isdir(d):
|
||||
return '', 'cd: {0} is not a directory\n'.format(d)
|
||||
|
||||
env['OLDPWD'] = os.getcwd()
|
||||
os.chdir(d)
|
||||
env['PWD'] = os.getcwd()
|
||||
return None, None
|
||||
|
||||
|
||||
def exit(args, stdin=None): # pylint:disable=redefined-builtin,W0622
|
||||
"""Sends signal to exit shell."""
|
||||
builtins.__xonsh_exit__ = True
|
||||
|
@ -115,6 +88,22 @@ def source_bash(args, stdin=None):
|
|||
return
|
||||
|
||||
|
||||
def xexec(args, stdin=None):
|
||||
"""
|
||||
Replaces current process with command specified and passes in the
|
||||
current xonsh environment.
|
||||
"""
|
||||
env = builtins.__xonsh_env__
|
||||
denv = env.detype()
|
||||
if (len(args) > 0):
|
||||
try:
|
||||
os.execvpe(args[0], args, denv)
|
||||
except FileNotFoundError as e:
|
||||
return "xonsh: " + e.args[1] + ": " + args[0] + "\n"
|
||||
else:
|
||||
return "xonsh: exec: no args specified\n"
|
||||
|
||||
|
||||
def bash_aliases():
|
||||
"""Computes a dictionary of aliases based on Bash's aliases."""
|
||||
try:
|
||||
|
@ -150,6 +139,7 @@ DEFAULT_ALIASES = {
|
|||
'EOF': exit,
|
||||
'exit': exit,
|
||||
'quit': exit,
|
||||
'xexec': xexec,
|
||||
'source-bash': source_bash,
|
||||
'grep': ['grep', '--color=auto'],
|
||||
'scp-resume': ['rsync', '--partial', '-h', '--progress', '--rsh=ssh'],
|
||||
|
|
|
@ -4,7 +4,6 @@ not to be confused with the special Python builtins module.
|
|||
import os
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
import shlex
|
||||
import signal
|
||||
import locale
|
||||
|
@ -22,7 +21,7 @@ from xonsh.tools import suggest_commands, XonshError
|
|||
from xonsh.inspectors import Inspector
|
||||
from xonsh.environ import default_env
|
||||
from xonsh.aliases import DEFAULT_ALIASES, bash_aliases
|
||||
from xonsh.jobs import print_one_job, get_next_job_number, wait_for_active_job
|
||||
from xonsh.jobs import add_job, wait_for_active_job
|
||||
from xonsh.jobs import ProcProxy
|
||||
|
||||
ENV = None
|
||||
|
@ -508,21 +507,14 @@ def run_subproc(cmds, captured=True):
|
|||
prev_proc = proc
|
||||
for proc in procs[:-1]:
|
||||
proc.stdout.close()
|
||||
num = get_next_job_number()
|
||||
pids = [i.pid for i in procs]
|
||||
if not isinstance(prev_proc, ProcProxy):
|
||||
builtins.__xonsh_active_job__ = num
|
||||
builtins.__xonsh_all_jobs__[num] = {
|
||||
add_job({
|
||||
'cmds': cmds,
|
||||
'pids': pids,
|
||||
'pids': [i.pid for i in procs],
|
||||
'obj': prev_proc,
|
||||
'started': time.time(),
|
||||
'pgrp': os.getpgid(prev_proc.pid),
|
||||
'status': 'running',
|
||||
'bg': background
|
||||
}
|
||||
})
|
||||
if background:
|
||||
print_one_job(num)
|
||||
return
|
||||
wait_for_active_job()
|
||||
if write_target is None:
|
||||
|
|
|
@ -10,6 +10,73 @@ A list containing the currently remembered directories.
|
|||
"""
|
||||
|
||||
|
||||
def _get_cwd():
|
||||
try:
|
||||
return os.getcwd()
|
||||
except (OSError, FileNotFoundError):
|
||||
return None
|
||||
|
||||
|
||||
def _change_working_directory(newdir):
|
||||
env = builtins.__xonsh_env__
|
||||
old = _get_cwd()
|
||||
try:
|
||||
os.chdir(newdir)
|
||||
except (OSError, FileNotFoundError):
|
||||
return
|
||||
new = _get_cwd()
|
||||
if old is not None:
|
||||
env['OLDPWD'] = old
|
||||
if new is not None:
|
||||
env['PWD'] = new
|
||||
|
||||
|
||||
def cd(args, stdin=None):
|
||||
"""Changes the directory.
|
||||
|
||||
If no directory is specified (i.e. if `args` is None) then this
|
||||
changes to the current user's home directory.
|
||||
"""
|
||||
env = builtins.__xonsh_env__
|
||||
oldpwd = env.get('OLDPWD', None)
|
||||
cwd = _get_cwd()
|
||||
if len(args) == 0:
|
||||
d = os.path.expanduser('~')
|
||||
elif len(args) == 1:
|
||||
d = os.path.expanduser(args[0])
|
||||
if not os.path.isdir(d):
|
||||
if d == '-':
|
||||
if oldpwd is not None:
|
||||
d = oldpwd
|
||||
else:
|
||||
return '', 'cd: no previous directory stored\n'
|
||||
elif d.startswith('-'):
|
||||
try:
|
||||
num = int(d[1:])
|
||||
except ValueError:
|
||||
return '', 'cd: Invalid destination: {0}\n'.format(d)
|
||||
if num == 0:
|
||||
return
|
||||
elif num < 0:
|
||||
return '', 'cd: Invalid destination: {0}\n'.format(d)
|
||||
elif num > len(DIRSTACK):
|
||||
e = 'cd: Too few elements in dirstack ({0} elements)\n'
|
||||
return '', e.format(len(DIRSTACK))
|
||||
else:
|
||||
d = DIRSTACK[num - 1]
|
||||
else:
|
||||
return '', 'cd takes 0 or 1 arguments, not {0}\n'.format(len(args))
|
||||
if not os.path.exists(d):
|
||||
return '', 'cd: no such file or directory: {0}\n'.format(d)
|
||||
if not os.path.isdir(d):
|
||||
return '', 'cd: {0} is not a directory\n'.format(d)
|
||||
# now, push the directory onto the dirstack if AUTO_PUSHD is set
|
||||
if cwd is not None and env.get('AUTO_PUSHD', False):
|
||||
pushd(['-n', '-q', cwd])
|
||||
_change_working_directory(os.path.abspath(d))
|
||||
return None, None
|
||||
|
||||
|
||||
def pushd(args, stdin=None):
|
||||
"""
|
||||
xonsh command: pushd
|
||||
|
@ -71,16 +138,12 @@ def pushd(args, stdin=None):
|
|||
e = 'Invalid argument to pushd: {0}\n'
|
||||
return None, e.format(args.dir)
|
||||
if new_pwd is not None:
|
||||
e = None
|
||||
if args.cd:
|
||||
DIRSTACK.insert(0, os.path.expanduser(pwd))
|
||||
_, e = builtins.default_aliases['cd']([new_pwd], None)
|
||||
_change_working_directory(os.path.abspath(new_pwd))
|
||||
else:
|
||||
DIRSTACK.insert(0, os.path.expanduser(os.path.abspath(new_pwd)))
|
||||
|
||||
if e is not None:
|
||||
return None, e
|
||||
|
||||
maxsize = env.get('DIRSTACK_SIZE', 20)
|
||||
if len(DIRSTACK) > maxsize:
|
||||
DIRSTACK = DIRSTACK[:maxsize]
|
||||
|
@ -152,10 +215,7 @@ def popd(args, stdin=None):
|
|||
if new_pwd is not None:
|
||||
e = None
|
||||
if args.cd:
|
||||
_, e = builtins.default_aliases['cd']([new_pwd], None)
|
||||
|
||||
if e is not None:
|
||||
return None, e
|
||||
_change_working_directory(os.path.abspath(new_pwd))
|
||||
|
||||
if not args.quiet and not env.get('PUSHD_SILENT', False):
|
||||
return dirs([], None)
|
||||
|
|
|
@ -12,6 +12,7 @@ from warnings import warn
|
|||
|
||||
from xonsh import __version__ as XONSH_VERSION
|
||||
from xonsh.tools import TERM_COLORS
|
||||
from xonsh.dirstack import _get_cwd
|
||||
|
||||
|
||||
def current_branch(cwd=None, pad=True):
|
||||
|
@ -20,7 +21,9 @@ def current_branch(cwd=None, pad=True):
|
|||
bust should be extended in the future.
|
||||
"""
|
||||
branch = None
|
||||
cwd = os.getcwd() if cwd is None else cwd
|
||||
cwd = _get_cwd() if cwd is None else cwd
|
||||
if cwd is None:
|
||||
return ''
|
||||
|
||||
# step out completely if git is not installed
|
||||
try:
|
||||
|
@ -64,7 +67,7 @@ def current_branch(cwd=None, pad=True):
|
|||
|
||||
if pad and branch is not None:
|
||||
branch = ' ' + branch
|
||||
return branch
|
||||
return branch or ''
|
||||
|
||||
|
||||
DEFAULT_PROMPT = ('{BOLD_GREEN}{user}@{hostname}{BOLD_BLUE} '
|
||||
|
@ -78,7 +81,7 @@ def _replace_home(x):
|
|||
FORMATTER_DICT = dict(user=os.environ.get('USER', '<user>'),
|
||||
hostname=socket.gethostname().split('.', 1)[0],
|
||||
cwd=lambda: _replace_home(builtins.__xonsh_env__['PWD']),
|
||||
curr_branch=lambda: current_branch() or '',
|
||||
curr_branch=lambda: current_branch(),
|
||||
**TERM_COLORS)
|
||||
|
||||
_formatter = string.Formatter()
|
||||
|
|
|
@ -3,6 +3,7 @@ Job control for the xonsh shell.
|
|||
"""
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import signal
|
||||
import builtins
|
||||
from collections import namedtuple
|
||||
|
@ -56,7 +57,10 @@ def _give_terminal_to(pgid):
|
|||
|
||||
def print_one_job(num):
|
||||
"""Print a line describing job number ``num``."""
|
||||
job = builtins.__xonsh_all_jobs__[num]
|
||||
try:
|
||||
job = builtins.__xonsh_all_jobs__[num]
|
||||
except KeyError:
|
||||
return
|
||||
act = '*' if num == builtins.__xonsh_active_job__ else ' '
|
||||
status = job['status']
|
||||
cmd = [' '.join(i) if isinstance(i, list) else i for i in job['cmds']]
|
||||
|
@ -76,6 +80,23 @@ def get_next_job_number():
|
|||
return i
|
||||
|
||||
|
||||
def add_job(info):
|
||||
"""
|
||||
Add a new job to the jobs dictionary.
|
||||
"""
|
||||
info['started'] = time.time()
|
||||
info['status'] = 'running'
|
||||
try:
|
||||
info['pgrp'] = os.getpgid(info['obj'].pid)
|
||||
except ProcessLookupError:
|
||||
return
|
||||
num = get_next_job_number()
|
||||
builtins.__xonsh_all_jobs__[num] = info
|
||||
builtins.__xonsh_active_job__ = num
|
||||
if info['bg']:
|
||||
print_one_job(num)
|
||||
|
||||
|
||||
def _default_sigint_handler(num, frame):
|
||||
raise KeyboardInterrupt
|
||||
|
||||
|
|
|
@ -2045,9 +2045,11 @@ class Parser(object):
|
|||
def p_comp_for(self, p):
|
||||
"""comp_for : FOR exprlist IN or_test comp_iter_opt"""
|
||||
targs, it, p5 = p[2], p[4], p[5]
|
||||
if len(targs) != 1:
|
||||
assert False
|
||||
targ = targs[0]
|
||||
if len(targs) == 1:
|
||||
targ = targs[0]
|
||||
else:
|
||||
targ = ensure_has_elts(targs, lineno=self.lineno,
|
||||
col_offset=self.col)
|
||||
store_ctx(targ)
|
||||
comp = ast.comprehension(target=targ, iter=it, ifs=[])
|
||||
comps = [comp]
|
||||
|
|
Loading…
Add table
Reference in a new issue