mirror of
https://github.com/xonsh/xonsh.git
synced 2025-03-04 16:34:47 +01:00
Merge branch 'master' into environment_fixes
This commit is contained in:
commit
06986fc0d4
11 changed files with 218 additions and 30 deletions
|
@ -55,9 +55,9 @@ line is ``#!/usr/bin/env xonsh``.
|
||||||
- ``_.rtn``
|
- ``_.rtn``
|
||||||
- Returns the exit code, or status, of the previous command.
|
- Returns the exit code, or status, of the previous command.
|
||||||
* - ``N=V command``
|
* - ``N=V command``
|
||||||
- ``with ${...}.swap(N=V): command``
|
- ``$N=V command`` or ``with ${...}.swap(N=V): command``
|
||||||
- Set temporary environment variable(s) and execute for command.
|
- Set temporary environment variable(s) and execute the command.
|
||||||
Use an indented block to execute many commands in the same context.
|
Use the second notation with an indented block to execute many commands in the same context.
|
||||||
* - ``!$``
|
* - ``!$``
|
||||||
- ``__xonsh__.history[-1, -1]``
|
- ``__xonsh__.history[-1, -1]``
|
||||||
- Get the last argument of the last command
|
- Get the last argument of the last command
|
||||||
|
|
23
news/argcomplete.rst
Normal file
23
news/argcomplete.rst
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
**Added:**
|
||||||
|
|
||||||
|
* Added xontrib-argcomplete to support kislyuk/argcomplete - tab completion for argparse.
|
||||||
|
|
||||||
|
**Changed:**
|
||||||
|
|
||||||
|
* <news item>
|
||||||
|
|
||||||
|
**Deprecated:**
|
||||||
|
|
||||||
|
* <news item>
|
||||||
|
|
||||||
|
**Removed:**
|
||||||
|
|
||||||
|
* <news item>
|
||||||
|
|
||||||
|
**Fixed:**
|
||||||
|
|
||||||
|
* <news item>
|
||||||
|
|
||||||
|
**Security:**
|
||||||
|
|
||||||
|
* <news item>
|
23
news/shift-arrow.rst
Normal file
23
news/shift-arrow.rst
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
**Added:**
|
||||||
|
|
||||||
|
* Borrow shift-selection from prompt-toolkit. Shift-arrow (selects a letter) and control-shift-arrow (selects a word) should now be supported.
|
||||||
|
|
||||||
|
**Changed:**
|
||||||
|
|
||||||
|
* <news item>
|
||||||
|
|
||||||
|
**Deprecated:**
|
||||||
|
|
||||||
|
* <news item>
|
||||||
|
|
||||||
|
**Removed:**
|
||||||
|
|
||||||
|
* <news item>
|
||||||
|
|
||||||
|
**Fixed:**
|
||||||
|
|
||||||
|
* <news item>
|
||||||
|
|
||||||
|
**Security:**
|
||||||
|
|
||||||
|
* <news item>
|
24
news/simple-variables.rst
Normal file
24
news/simple-variables.rst
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
**Added:**
|
||||||
|
|
||||||
|
* Xonsh now supports bash-style variable assignments preceding
|
||||||
|
subprocess commands (e.g. ``$FOO = "bar" bash -c r"echo $FOO"``).
|
||||||
|
|
||||||
|
**Changed:**
|
||||||
|
|
||||||
|
* <news item>
|
||||||
|
|
||||||
|
**Deprecated:**
|
||||||
|
|
||||||
|
* <news item>
|
||||||
|
|
||||||
|
**Removed:**
|
||||||
|
|
||||||
|
* <news item>
|
||||||
|
|
||||||
|
**Fixed:**
|
||||||
|
|
||||||
|
* <news item>
|
||||||
|
|
||||||
|
**Security:**
|
||||||
|
|
||||||
|
* <news item>
|
|
@ -499,6 +499,7 @@ def test_script_stderr(case):
|
||||||
("pwd", None, lambda: os.getcwd() + "\n"),
|
("pwd", None, lambda: os.getcwd() + "\n"),
|
||||||
("echo WORKING", None, "WORKING\n"),
|
("echo WORKING", None, "WORKING\n"),
|
||||||
("ls -f", lambda out: out.splitlines().sort(), os.listdir().sort()),
|
("ls -f", lambda out: out.splitlines().sort(), os.listdir().sort()),
|
||||||
|
("$FOO='foo' $BAR=2 xonsh -c r'echo -n $FOO$BAR'", None, "foo2",),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_single_command_no_windows(cmd, fmt, exp):
|
def test_single_command_no_windows(cmd, fmt, exp):
|
||||||
|
|
|
@ -2501,6 +2501,10 @@ def test_ls_quotes_3_space():
|
||||||
check_xonsh_ast({}, '$[ls "wakka jawaka baraka"]', False)
|
check_xonsh_ast({}, '$[ls "wakka jawaka baraka"]', False)
|
||||||
|
|
||||||
|
|
||||||
|
def test_leading_envvar_assignment():
|
||||||
|
check_xonsh_ast({}, "![$FOO= 'foo' $BAR =2 echo r'$BAR']", False)
|
||||||
|
|
||||||
|
|
||||||
def test_echo_comma():
|
def test_echo_comma():
|
||||||
check_xonsh_ast({}, "![echo ,]", False)
|
check_xonsh_ast({}, "![echo ,]", False)
|
||||||
|
|
||||||
|
|
|
@ -390,6 +390,7 @@ class SubprocSpec:
|
||||||
universal_newlines=False,
|
universal_newlines=False,
|
||||||
close_fds=False,
|
close_fds=False,
|
||||||
captured=False,
|
captured=False,
|
||||||
|
env=None,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Parameters
|
Parameters
|
||||||
|
@ -413,6 +414,8 @@ class SubprocSpec:
|
||||||
The flag for if the subprocess is captured, may be one of:
|
The flag for if the subprocess is captured, may be one of:
|
||||||
False for $[], 'stdout' for $(), 'hiddenobject' for ![], or
|
False for $[], 'stdout' for $(), 'hiddenobject' for ![], or
|
||||||
'object' for !().
|
'object' for !().
|
||||||
|
env : dict
|
||||||
|
Replacement environment to run the subporcess in.
|
||||||
|
|
||||||
Attributes
|
Attributes
|
||||||
----------
|
----------
|
||||||
|
@ -451,6 +454,13 @@ class SubprocSpec:
|
||||||
self.universal_newlines = universal_newlines
|
self.universal_newlines = universal_newlines
|
||||||
self.close_fds = close_fds
|
self.close_fds = close_fds
|
||||||
self.captured = captured
|
self.captured = captured
|
||||||
|
if env is not None:
|
||||||
|
self.env = {
|
||||||
|
k: v if not (isinstance(v, list)) or len(v) > 1 else v[0]
|
||||||
|
for (k, v) in env.items()
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
self.env = None
|
||||||
# pure attrs
|
# pure attrs
|
||||||
self.args = list(cmd)
|
self.args = list(cmd)
|
||||||
self.alias = None
|
self.alias = None
|
||||||
|
@ -579,7 +589,8 @@ class SubprocSpec:
|
||||||
|
|
||||||
def prep_env(self, kwargs):
|
def prep_env(self, kwargs):
|
||||||
"""Prepares the environment to use in the subprocess."""
|
"""Prepares the environment to use in the subprocess."""
|
||||||
denv = builtins.__xonsh__.env.detype()
|
with builtins.__xonsh__.env.swap(self.env) as env:
|
||||||
|
denv = env.detype()
|
||||||
if ON_WINDOWS:
|
if ON_WINDOWS:
|
||||||
# Over write prompt variable as xonsh's $PROMPT does
|
# Over write prompt variable as xonsh's $PROMPT does
|
||||||
# not make much sense for other subprocs
|
# not make much sense for other subprocs
|
||||||
|
@ -878,7 +889,7 @@ def _update_last_spec(last):
|
||||||
last.captured_stderr = last.captured_stdout
|
last.captured_stderr = last.captured_stdout
|
||||||
|
|
||||||
|
|
||||||
def cmds_to_specs(cmds, captured=False):
|
def cmds_to_specs(cmds, captured=False, envs=None):
|
||||||
"""Converts a list of cmds to a list of SubprocSpec objects that are
|
"""Converts a list of cmds to a list of SubprocSpec objects that are
|
||||||
ready to be executed.
|
ready to be executed.
|
||||||
"""
|
"""
|
||||||
|
@ -886,11 +897,12 @@ def cmds_to_specs(cmds, captured=False):
|
||||||
i = 0
|
i = 0
|
||||||
specs = []
|
specs = []
|
||||||
redirects = []
|
redirects = []
|
||||||
for cmd in cmds:
|
for i, cmd in enumerate(cmds):
|
||||||
if isinstance(cmd, str):
|
if isinstance(cmd, str):
|
||||||
redirects.append(cmd)
|
redirects.append(cmd)
|
||||||
else:
|
else:
|
||||||
spec = SubprocSpec.build(cmd, captured=captured)
|
env = envs[i] if envs is not None else None
|
||||||
|
spec = SubprocSpec.build(cmd, captured=captured, env=env)
|
||||||
spec.pipeline_index = i
|
spec.pipeline_index = i
|
||||||
specs.append(spec)
|
specs.append(spec)
|
||||||
i += 1
|
i += 1
|
||||||
|
@ -921,7 +933,7 @@ def _should_set_title(captured=False):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def run_subproc(cmds, captured=False):
|
def run_subproc(cmds, captured=False, envs=None):
|
||||||
"""Runs a subprocess, in its many forms. This takes a list of 'commands,'
|
"""Runs a subprocess, in its many forms. This takes a list of 'commands,'
|
||||||
which may be a list of command line arguments or a string, representing
|
which may be a list of command line arguments or a string, representing
|
||||||
a special connecting character. For example::
|
a special connecting character. For example::
|
||||||
|
@ -937,7 +949,7 @@ def run_subproc(cmds, captured=False):
|
||||||
if builtins.__xonsh__.env.get("XONSH_TRACE_SUBPROC"):
|
if builtins.__xonsh__.env.get("XONSH_TRACE_SUBPROC"):
|
||||||
print("TRACE SUBPROC: %s" % str(cmds), file=sys.stderr)
|
print("TRACE SUBPROC: %s" % str(cmds), file=sys.stderr)
|
||||||
|
|
||||||
specs = cmds_to_specs(cmds, captured=captured)
|
specs = cmds_to_specs(cmds, captured=captured, envs=envs)
|
||||||
captured = specs[-1].captured
|
captured = specs[-1].captured
|
||||||
if captured == "hiddenobject":
|
if captured == "hiddenobject":
|
||||||
command = HiddenCommandPipeline(specs)
|
command = HiddenCommandPipeline(specs)
|
||||||
|
@ -982,20 +994,20 @@ def run_subproc(cmds, captured=False):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def subproc_captured_stdout(*cmds):
|
def subproc_captured_stdout(*cmds, envs=None):
|
||||||
"""Runs a subprocess, capturing the output. Returns the stdout
|
"""Runs a subprocess, capturing the output. Returns the stdout
|
||||||
that was produced as a str.
|
that was produced as a str.
|
||||||
"""
|
"""
|
||||||
return run_subproc(cmds, captured="stdout")
|
return run_subproc(cmds, captured="stdout", envs=envs)
|
||||||
|
|
||||||
|
|
||||||
def subproc_captured_inject(*cmds):
|
def subproc_captured_inject(*cmds, envs=None):
|
||||||
"""Runs a subprocess, capturing the output. Returns a list of
|
"""Runs a subprocess, capturing the output. Returns a list of
|
||||||
whitespace-separated strings of the stdout that was produced.
|
whitespace-separated strings of the stdout that was produced.
|
||||||
The string is split using xonsh's lexer, rather than Python's str.split()
|
The string is split using xonsh's lexer, rather than Python's str.split()
|
||||||
or shlex.split().
|
or shlex.split().
|
||||||
"""
|
"""
|
||||||
o = run_subproc(cmds, captured="object")
|
o = run_subproc(cmds, captured="object", envs=envs)
|
||||||
o.end()
|
o.end()
|
||||||
toks = []
|
toks = []
|
||||||
for line in o:
|
for line in o:
|
||||||
|
@ -1004,26 +1016,26 @@ def subproc_captured_inject(*cmds):
|
||||||
return toks
|
return toks
|
||||||
|
|
||||||
|
|
||||||
def subproc_captured_object(*cmds):
|
def subproc_captured_object(*cmds, envs=None):
|
||||||
"""
|
"""
|
||||||
Runs a subprocess, capturing the output. Returns an instance of
|
Runs a subprocess, capturing the output. Returns an instance of
|
||||||
CommandPipeline representing the completed command.
|
CommandPipeline representing the completed command.
|
||||||
"""
|
"""
|
||||||
return run_subproc(cmds, captured="object")
|
return run_subproc(cmds, captured="object", envs=envs)
|
||||||
|
|
||||||
|
|
||||||
def subproc_captured_hiddenobject(*cmds):
|
def subproc_captured_hiddenobject(*cmds, envs=None):
|
||||||
"""Runs a subprocess, capturing the output. Returns an instance of
|
"""Runs a subprocess, capturing the output. Returns an instance of
|
||||||
HiddenCommandPipeline representing the completed command.
|
HiddenCommandPipeline representing the completed command.
|
||||||
"""
|
"""
|
||||||
return run_subproc(cmds, captured="hiddenobject")
|
return run_subproc(cmds, captured="hiddenobject", envs=envs)
|
||||||
|
|
||||||
|
|
||||||
def subproc_uncaptured(*cmds):
|
def subproc_uncaptured(*cmds, envs=None):
|
||||||
"""Runs a subprocess, without capturing the output. Returns the stdout
|
"""Runs a subprocess, without capturing the output. Returns the stdout
|
||||||
that was produced as a str.
|
that was produced as a str.
|
||||||
"""
|
"""
|
||||||
return run_subproc(cmds, captured=False)
|
return run_subproc(cmds, captured=False, envs=envs)
|
||||||
|
|
||||||
|
|
||||||
def ensure_list_of_strs(x):
|
def ensure_list_of_strs(x):
|
||||||
|
|
|
@ -2885,6 +2885,26 @@ class BaseParser(object):
|
||||||
# subprocess
|
# subprocess
|
||||||
#
|
#
|
||||||
|
|
||||||
|
def _get_envvars(self, p, lineno, col):
|
||||||
|
"""Get replacement environment from subproc_atoms, return None or
|
||||||
|
ast.List containing ast.Dict for each subproc_atom in the pipeline.
|
||||||
|
"""
|
||||||
|
if not isinstance(p, list):
|
||||||
|
return None
|
||||||
|
has_env = False
|
||||||
|
envs = empty_list(lineno=lineno, col=col)
|
||||||
|
for subproc in p:
|
||||||
|
if hasattr(subproc, "_xenvvars"):
|
||||||
|
has_env = True
|
||||||
|
envs.elts.append(subproc._xenvvars)
|
||||||
|
else:
|
||||||
|
envs.elts.append(
|
||||||
|
ast.Constant(
|
||||||
|
value=None, lineno=subproc.lineno, col_offset=subproc.col_offset
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return envs if has_env else None
|
||||||
|
|
||||||
def _dollar_rules(self, p):
|
def _dollar_rules(self, p):
|
||||||
"""These handle the special xonsh $ shell atoms by looking up
|
"""These handle the special xonsh $ shell atoms by looking up
|
||||||
in a special __xonsh__.env dictionary injected in the __builtin__.
|
in a special __xonsh__.env dictionary injected in the __builtin__.
|
||||||
|
@ -2920,6 +2940,11 @@ class BaseParser(object):
|
||||||
p0 = xonsh_call("__xonsh__.subproc_uncaptured", p2, lineno=lineno, col=col)
|
p0 = xonsh_call("__xonsh__.subproc_uncaptured", p2, lineno=lineno, col=col)
|
||||||
else:
|
else:
|
||||||
assert False
|
assert False
|
||||||
|
|
||||||
|
envs = self._get_envvars(p2, lineno, col)
|
||||||
|
if envs is not None:
|
||||||
|
p0.keywords.append(ast.keyword(arg="envs", value=envs))
|
||||||
|
|
||||||
return p0
|
return p0
|
||||||
|
|
||||||
def _envvar_getter_by_name(self, var, lineno=None, col=None):
|
def _envvar_getter_by_name(self, var, lineno=None, col=None):
|
||||||
|
@ -2974,6 +2999,8 @@ class BaseParser(object):
|
||||||
else:
|
else:
|
||||||
raise ValueError("action not understood: " + action)
|
raise ValueError("action not understood: " + action)
|
||||||
del arg._cliarg_action
|
del arg._cliarg_action
|
||||||
|
if hasattr(args[0], "_xenvvars"):
|
||||||
|
setattr(cliargs, "_xenvvars", args[0]._xenvvars)
|
||||||
return cliargs
|
return cliargs
|
||||||
|
|
||||||
def p_pipe(self, p):
|
def p_pipe(self, p):
|
||||||
|
@ -3043,6 +3070,18 @@ class BaseParser(object):
|
||||||
arg._cliarg_action = "append"
|
arg._cliarg_action = "append"
|
||||||
p[0] = p0
|
p[0] = p0
|
||||||
|
|
||||||
|
def p_envvar_assign_subproc_atoms(self, p):
|
||||||
|
"""subproc_atoms : envvar_assign subproc_atoms
|
||||||
|
| envvar_assign subproc_atoms WS
|
||||||
|
"""
|
||||||
|
p1, p20 = p[1], p[2][0]
|
||||||
|
if hasattr(p20, "_xenvvars"):
|
||||||
|
p20._xenvvars.keys.append(p1.keys[0])
|
||||||
|
p20._xenvvars.values.append(p1.values[0])
|
||||||
|
else:
|
||||||
|
setattr(p20, "_xenvvars", p1)
|
||||||
|
p[0] = p[2]
|
||||||
|
|
||||||
#
|
#
|
||||||
# Subproc atom rules
|
# Subproc atom rules
|
||||||
#
|
#
|
||||||
|
@ -3142,11 +3181,14 @@ class BaseParser(object):
|
||||||
"""subproc_atom : atdollar_lparen_tok subproc RPAREN
|
"""subproc_atom : atdollar_lparen_tok subproc RPAREN
|
||||||
subproc_arg_part : atdollar_lparen_tok subproc RPAREN
|
subproc_arg_part : atdollar_lparen_tok subproc RPAREN
|
||||||
"""
|
"""
|
||||||
p1 = p[1]
|
p1, p2 = p[1], p[2]
|
||||||
p0 = xonsh_call(
|
p0 = xonsh_call(
|
||||||
"__xonsh__.subproc_captured_inject", p[2], lineno=p1.lineno, col=p1.lexpos
|
"__xonsh__.subproc_captured_inject", p2, lineno=p1.lineno, col=p1.lexpos
|
||||||
)
|
)
|
||||||
p0._cliarg_action = "extend"
|
p0._cliarg_action = "extend"
|
||||||
|
envs = self._get_envvars(p2, lineno=p2[0].lineno, col=p2[0].col_offset)
|
||||||
|
if envs is not None:
|
||||||
|
p0.keywords.append(ast.keyword(arg="envs", value=envs))
|
||||||
p[0] = p0
|
p[0] = p0
|
||||||
|
|
||||||
def p_subproc_atom_subproc_inject_bang_empty(self, p):
|
def p_subproc_atom_subproc_inject_bang_empty(self, p):
|
||||||
|
@ -3282,6 +3324,28 @@ class BaseParser(object):
|
||||||
p1 = p[1]
|
p1 = p[1]
|
||||||
p[0] = ast.Str(s=p1.value, lineno=p1.lineno, col_offset=p1.lexpos)
|
p[0] = ast.Str(s=p1.value, lineno=p1.lineno, col_offset=p1.lexpos)
|
||||||
|
|
||||||
|
def p_envvar_assign_left(self, p):
|
||||||
|
"""envvar_assign_left : dollar_name_tok EQUALS
|
||||||
|
| dollar_name_tok WS EQUALS
|
||||||
|
| dollar_name_tok EQUALS WS
|
||||||
|
| dollar_name_tok WS EQUALS WS
|
||||||
|
"""
|
||||||
|
p[0] = p[1]
|
||||||
|
|
||||||
|
def p_envvar_assign(self, p):
|
||||||
|
"""envvar_assign : envvar_assign_left test WS
|
||||||
|
| envvar_assign_left subproc_atom WS
|
||||||
|
"""
|
||||||
|
p1, p2 = p[1], p[2]
|
||||||
|
p[0] = ast.Dict(
|
||||||
|
keys=[
|
||||||
|
ast.Constant(value=p1.value[1:], lineno=p1.lineno, col_offset=p1.lexpos)
|
||||||
|
],
|
||||||
|
values=[p2],
|
||||||
|
lineno=p1.lineno,
|
||||||
|
col_offset=p1.lexpos,
|
||||||
|
)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Helpers
|
# Helpers
|
||||||
#
|
#
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
import builtins
|
import builtins
|
||||||
|
|
||||||
from prompt_toolkit import search
|
from prompt_toolkit import search
|
||||||
|
from prompt_toolkit.application.current import get_app
|
||||||
from prompt_toolkit.enums import DEFAULT_BUFFER
|
from prompt_toolkit.enums import DEFAULT_BUFFER
|
||||||
from prompt_toolkit.filters import (
|
from prompt_toolkit.filters import (
|
||||||
Condition,
|
Condition,
|
||||||
|
@ -13,7 +14,8 @@ from prompt_toolkit.filters import (
|
||||||
IsSearching,
|
IsSearching,
|
||||||
)
|
)
|
||||||
from prompt_toolkit.keys import Keys
|
from prompt_toolkit.keys import Keys
|
||||||
from prompt_toolkit.application.current import get_app
|
from prompt_toolkit.key_binding.key_bindings import KeyBindings, KeyBindingsBase
|
||||||
|
from prompt_toolkit.key_binding.bindings.named_commands import get_by_name
|
||||||
|
|
||||||
from xonsh.aliases import xonsh_exit
|
from xonsh.aliases import xonsh_exit
|
||||||
from xonsh.tools import check_for_partial_string, get_line_continuation
|
from xonsh.tools import check_for_partial_string, get_line_continuation
|
||||||
|
@ -165,7 +167,7 @@ def autopair_condition():
|
||||||
@Condition
|
@Condition
|
||||||
def whitespace_or_bracket_before():
|
def whitespace_or_bracket_before():
|
||||||
"""Check if there is whitespace or an opening
|
"""Check if there is whitespace or an opening
|
||||||
bracket to the left of the cursor"""
|
bracket to the left of the cursor"""
|
||||||
d = get_app().current_buffer.document
|
d = get_app().current_buffer.document
|
||||||
return bool(
|
return bool(
|
||||||
d.cursor_position == 0
|
d.cursor_position == 0
|
||||||
|
@ -177,7 +179,7 @@ def whitespace_or_bracket_before():
|
||||||
@Condition
|
@Condition
|
||||||
def whitespace_or_bracket_after():
|
def whitespace_or_bracket_after():
|
||||||
"""Check if there is whitespace or a closing
|
"""Check if there is whitespace or a closing
|
||||||
bracket to the right of the cursor"""
|
bracket to the right of the cursor"""
|
||||||
d = get_app().current_buffer.document
|
d = get_app().current_buffer.document
|
||||||
return bool(
|
return bool(
|
||||||
d.is_cursor_at_the_end_of_line
|
d.is_cursor_at_the_end_of_line
|
||||||
|
@ -186,10 +188,11 @@ def whitespace_or_bracket_after():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def load_xonsh_bindings(key_bindings):
|
def load_xonsh_bindings() -> KeyBindingsBase:
|
||||||
"""
|
"""
|
||||||
Load custom key bindings.
|
Load custom key bindings.
|
||||||
"""
|
"""
|
||||||
|
key_bindings = KeyBindings()
|
||||||
handle = key_bindings.add
|
handle = key_bindings.add
|
||||||
has_selection = HasSelection()
|
has_selection = HasSelection()
|
||||||
insert_mode = ViInsertMode() | EmacsInsertMode()
|
insert_mode = ViInsertMode() | EmacsInsertMode()
|
||||||
|
@ -357,3 +360,25 @@ def load_xonsh_bindings(key_bindings):
|
||||||
during the previous command.
|
during the previous command.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@handle(Keys.ControlX, Keys.ControlX, filter=has_selection)
|
||||||
|
def _cut(event):
|
||||||
|
""" Cut selected text. """
|
||||||
|
data = event.current_buffer.cut_selection()
|
||||||
|
event.app.clipboard.set_data(data)
|
||||||
|
|
||||||
|
@handle(Keys.ControlX, Keys.ControlC, filter=has_selection)
|
||||||
|
def _copy(event):
|
||||||
|
""" Copy selected text. """
|
||||||
|
data = event.current_buffer.copy_selection()
|
||||||
|
event.app.clipboard.set_data(data)
|
||||||
|
|
||||||
|
@handle(Keys.ControlV, filter=insert_mode | has_selection)
|
||||||
|
def _yank(event):
|
||||||
|
""" Paste selected text. """
|
||||||
|
buff = event.current_buffer
|
||||||
|
if buff.selection_state:
|
||||||
|
buff.cut_selection()
|
||||||
|
get_by_name("yank").call(event)
|
||||||
|
|
||||||
|
return key_bindings
|
||||||
|
|
|
@ -21,7 +21,10 @@ from prompt_toolkit import ANSI
|
||||||
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
|
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
|
||||||
from prompt_toolkit.lexers import PygmentsLexer
|
from prompt_toolkit.lexers import PygmentsLexer
|
||||||
from prompt_toolkit.enums import EditingMode
|
from prompt_toolkit.enums import EditingMode
|
||||||
from prompt_toolkit.key_binding import KeyBindings
|
from prompt_toolkit.key_binding.bindings.emacs import (
|
||||||
|
load_emacs_shift_selection_bindings,
|
||||||
|
)
|
||||||
|
from prompt_toolkit.key_binding.key_bindings import merge_key_bindings
|
||||||
from prompt_toolkit.history import ThreadedHistory
|
from prompt_toolkit.history import ThreadedHistory
|
||||||
from prompt_toolkit.shortcuts import print_formatted_text as ptk_print
|
from prompt_toolkit.shortcuts import print_formatted_text as ptk_print
|
||||||
from prompt_toolkit.shortcuts import CompleteStyle
|
from prompt_toolkit.shortcuts import CompleteStyle
|
||||||
|
@ -91,8 +94,13 @@ class PromptToolkitShell(BaseShell):
|
||||||
self.history = ThreadedHistory(PromptToolkitHistory())
|
self.history = ThreadedHistory(PromptToolkitHistory())
|
||||||
self.prompter = PromptSession(history=self.history)
|
self.prompter = PromptSession(history=self.history)
|
||||||
self.pt_completer = PromptToolkitCompleter(self.completer, self.ctx, self)
|
self.pt_completer = PromptToolkitCompleter(self.completer, self.ctx, self)
|
||||||
self.key_bindings = KeyBindings()
|
self.key_bindings = merge_key_bindings(
|
||||||
load_xonsh_bindings(self.key_bindings)
|
[
|
||||||
|
load_xonsh_bindings(),
|
||||||
|
load_emacs_shift_selection_bindings(),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
# Store original `_history_matches` in case we need to restore it
|
# Store original `_history_matches` in case we need to restore it
|
||||||
self._history_matches_orig = self.prompter.default_buffer._history_matches
|
self._history_matches_orig = self.prompter.default_buffer._history_matches
|
||||||
# This assumes that PromptToolkitShell is a singleton
|
# This assumes that PromptToolkitShell is a singleton
|
||||||
|
@ -282,8 +290,7 @@ class PromptToolkitShell(BaseShell):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def bottom_toolbar_tokens(self):
|
def bottom_toolbar_tokens(self):
|
||||||
"""Returns self._bottom_toolbar_tokens if it would yield a result
|
"""Returns self._bottom_toolbar_tokens if it would yield a result"""
|
||||||
"""
|
|
||||||
if builtins.__xonsh__.env.get("BOTTOM_TOOLBAR"):
|
if builtins.__xonsh__.env.get("BOTTOM_TOOLBAR"):
|
||||||
return self._bottom_toolbar_tokens
|
return self._bottom_toolbar_tokens
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,11 @@
|
||||||
"url": "https://github.com/DangerOnTheRanger/xonsh-apt-tabcomplete",
|
"url": "https://github.com/DangerOnTheRanger/xonsh-apt-tabcomplete",
|
||||||
"description": ["Adds tabcomplete functionality to apt-get/apt-cache inside of xonsh."]
|
"description": ["Adds tabcomplete functionality to apt-get/apt-cache inside of xonsh."]
|
||||||
},
|
},
|
||||||
|
{"name": "argcomplete",
|
||||||
|
"package": "xontrib-argcomplete",
|
||||||
|
"url": "https://github.com/anki-code/xontrib-argcomplete",
|
||||||
|
"description": ["Adding support of kislyuk/argcomplete to xonsh."]
|
||||||
|
},
|
||||||
{"name": "autojump",
|
{"name": "autojump",
|
||||||
"package": "xontrib-autojump",
|
"package": "xontrib-autojump",
|
||||||
"url": "https://github.com/sagartewari01/autojump-xonsh",
|
"url": "https://github.com/sagartewari01/autojump-xonsh",
|
||||||
|
|
Loading…
Add table
Reference in a new issue