mirror of
https://github.com/xonsh/xonsh.git
synced 2025-03-04 08:24:40 +01:00
Add configuring cursor shape for prompt toolkit (#5785)
* env: add `PROMPT_TOOLKIT_CURSOR_SHAPE` for configuring `prompt_toolkit` cursor shape * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * accepting prompt_toolkit.cursor_shapes.CursorShape as value * rename PROMPT_TOOLKIT_CURSOR_SHAPE => XONSH_PROMPT_CURSOR_SHAPE --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
62edf9e381
commit
e7426ce709
4 changed files with 97 additions and 9 deletions
23
news/config-cursor-shape.rst
Normal file
23
news/config-cursor-shape.rst
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
**Added:**
|
||||||
|
|
||||||
|
* env: add ``$XONSH_PROMPT_CURSOR_SHAPE`` for configuring prompt cursor shape.
|
||||||
|
|
||||||
|
**Changed:**
|
||||||
|
|
||||||
|
* <news item>
|
||||||
|
|
||||||
|
**Deprecated:**
|
||||||
|
|
||||||
|
* <news item>
|
||||||
|
|
||||||
|
**Removed:**
|
||||||
|
|
||||||
|
* <news item>
|
||||||
|
|
||||||
|
**Fixed:**
|
||||||
|
|
||||||
|
* <news item>
|
||||||
|
|
||||||
|
**Security:**
|
||||||
|
|
||||||
|
* <news item>
|
|
@ -98,6 +98,8 @@ from xonsh.tools import (
|
||||||
to_int_or_none,
|
to_int_or_none,
|
||||||
to_itself,
|
to_itself,
|
||||||
to_logfile_opt,
|
to_logfile_opt,
|
||||||
|
to_ptk_cursor_shape,
|
||||||
|
to_ptk_cursor_shape_display_value,
|
||||||
to_repr_pretty_,
|
to_repr_pretty_,
|
||||||
to_shlvl,
|
to_shlvl,
|
||||||
to_tok_color_dict,
|
to_tok_color_dict,
|
||||||
|
@ -1743,6 +1745,19 @@ class PTKSetting(PromptSetting): # sub-classing -> sub-group
|
||||||
"``DEPTH_1_BIT``, ``DEPTH_4_BIT``, ``DEPTH_8_BIT``, ``DEPTH_24_BIT`` "
|
"``DEPTH_1_BIT``, ``DEPTH_4_BIT``, ``DEPTH_8_BIT``, ``DEPTH_24_BIT`` "
|
||||||
"colors. Default is an empty string which means that prompt toolkit decide.",
|
"colors. Default is an empty string which means that prompt toolkit decide.",
|
||||||
)
|
)
|
||||||
|
XONSH_PROMPT_CURSOR_SHAPE = Var(
|
||||||
|
always_false,
|
||||||
|
to_ptk_cursor_shape,
|
||||||
|
to_ptk_cursor_shape_display_value,
|
||||||
|
to_ptk_cursor_shape("modal-vi-mode-only"),
|
||||||
|
"The cursor shape. Possible values for prompt toolkit are: "
|
||||||
|
"``block``, ``beam``, ``underline``, "
|
||||||
|
"``blinking-block``, ``blinking-beam``, ``blinking-underline``, "
|
||||||
|
"``modal``, ``modal-vi-mode-only``, ``never-change``. "
|
||||||
|
"Default value is ``modal-vi-mode-only`` which means "
|
||||||
|
"``modal`` if in vi mode and ``never-change`` if not in vi mode.",
|
||||||
|
doc_default="modal-vi-mode-only",
|
||||||
|
)
|
||||||
PTK_STYLE_OVERRIDES = Var(
|
PTK_STYLE_OVERRIDES = Var(
|
||||||
is_tok_color_dict,
|
is_tok_color_dict,
|
||||||
to_tok_color_dict,
|
to_tok_color_dict,
|
||||||
|
|
|
@ -46,13 +46,6 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
HAVE_SYS_CLIPBOARD = False
|
HAVE_SYS_CLIPBOARD = False
|
||||||
|
|
||||||
try:
|
|
||||||
from prompt_toolkit.cursor_shapes import ModalCursorShapeConfig
|
|
||||||
|
|
||||||
HAVE_CURSOR_SHAPE = True
|
|
||||||
except ImportError:
|
|
||||||
HAVE_CURSOR_SHAPE = False
|
|
||||||
|
|
||||||
CAPITAL_PATTERN = re.compile(r"([a-z])([A-Z])")
|
CAPITAL_PATTERN = re.compile(r"([a-z])([A-Z])")
|
||||||
Token = _TokenType()
|
Token = _TokenType()
|
||||||
|
|
||||||
|
@ -377,8 +370,10 @@ class PromptToolkitShell(BaseShell):
|
||||||
for attr, val in self.get_lazy_ptk_kwargs():
|
for attr, val in self.get_lazy_ptk_kwargs():
|
||||||
prompt_args[attr] = val
|
prompt_args[attr] = val
|
||||||
|
|
||||||
if editing_mode == EditingMode.VI and HAVE_CURSOR_SHAPE:
|
cursor_shape = env.get("XONSH_PROMPT_CURSOR_SHAPE")
|
||||||
prompt_args["cursor"] = ModalCursorShapeConfig()
|
if cursor_shape:
|
||||||
|
prompt_args["cursor"] = cursor_shape
|
||||||
|
|
||||||
events.on_pre_prompt.fire()
|
events.on_pre_prompt.fire()
|
||||||
line = self.prompter.prompt(**prompt_args)
|
line = self.prompter.prompt(**prompt_args)
|
||||||
events.on_post_prompt.fire()
|
events.on_post_prompt.fire()
|
||||||
|
|
|
@ -41,6 +41,19 @@ import typing as tp
|
||||||
import warnings
|
import warnings
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
|
|
||||||
|
try:
|
||||||
|
from prompt_toolkit.cursor_shapes import (
|
||||||
|
CursorShape,
|
||||||
|
CursorShapeConfig,
|
||||||
|
DynamicCursorShapeConfig,
|
||||||
|
ModalCursorShapeConfig,
|
||||||
|
SimpleCursorShapeConfig,
|
||||||
|
)
|
||||||
|
|
||||||
|
HAVE_CURSOR_SHAPE = True
|
||||||
|
except ImportError:
|
||||||
|
HAVE_CURSOR_SHAPE = False
|
||||||
|
|
||||||
# adding imports from further xonsh modules is discouraged to avoid circular
|
# adding imports from further xonsh modules is discouraged to avoid circular
|
||||||
# dependencies
|
# dependencies
|
||||||
from xonsh import __version__
|
from xonsh import __version__
|
||||||
|
@ -1728,6 +1741,48 @@ def ptk2_color_depth_setter(x):
|
||||||
return x
|
return x
|
||||||
|
|
||||||
|
|
||||||
|
def ptk_cursor_shape_vi_modal():
|
||||||
|
if xsh.env.get("VI_MODE"):
|
||||||
|
return ModalCursorShapeConfig()
|
||||||
|
else:
|
||||||
|
return SimpleCursorShapeConfig()
|
||||||
|
|
||||||
|
|
||||||
|
def to_ptk_cursor_shape(x):
|
||||||
|
if not HAVE_CURSOR_SHAPE:
|
||||||
|
return None
|
||||||
|
if isinstance(x, (CursorShape, CursorShapeConfig)):
|
||||||
|
return x
|
||||||
|
if not isinstance(x, str):
|
||||||
|
raise ValueError("invalid cursor shape")
|
||||||
|
x = str(x).upper().replace("-", "_")
|
||||||
|
if x == "MODAL":
|
||||||
|
return ModalCursorShapeConfig()
|
||||||
|
elif x == "MODAL_VI_MODE_ONLY":
|
||||||
|
return DynamicCursorShapeConfig(ptk_cursor_shape_vi_modal)
|
||||||
|
try:
|
||||||
|
return CursorShape[x]
|
||||||
|
except KeyError:
|
||||||
|
return SimpleCursorShapeConfig()
|
||||||
|
|
||||||
|
|
||||||
|
def to_ptk_cursor_shape_display_value(x):
|
||||||
|
if not x:
|
||||||
|
return ""
|
||||||
|
if isinstance(x, SimpleCursorShapeConfig):
|
||||||
|
x = x.get_cursor_shape(None)
|
||||||
|
if isinstance(x, CursorShape):
|
||||||
|
x = x.value.lower().replace("_", "-")
|
||||||
|
if x.startswith("-"):
|
||||||
|
x = x[1:]
|
||||||
|
return x
|
||||||
|
if isinstance(x, ModalCursorShapeConfig):
|
||||||
|
return "modal"
|
||||||
|
if isinstance(x, DynamicCursorShapeConfig):
|
||||||
|
return "modal-vi-mode-only"
|
||||||
|
return "unknown"
|
||||||
|
|
||||||
|
|
||||||
def is_completions_display_value(x):
|
def is_completions_display_value(x):
|
||||||
"""Enumerated values of ``$COMPLETIONS_DISPLAY``"""
|
"""Enumerated values of ``$COMPLETIONS_DISPLAY``"""
|
||||||
return x in {"none", "single", "multi"}
|
return x in {"none", "single", "multi"}
|
||||||
|
|
Loading…
Add table
Reference in a new issue