mirror of
https://github.com/xonsh/xonsh.git
synced 2025-03-04 00:14:41 +01:00
Support deletion in whole_word_jumping xontrib (#4788)
This binds Alt/Control+Delete/Backspace to support deletion matching the motion bindings in `whole_word_jumping`. Should work mostly out of the box on terminals that generate `\x7f` when `backspace` is pressed and `\x08` when `control+backspace` is pressed. Tested to work on Microsoft Terminal (WSL2). For incompatible terminals, users can set `$XONSH_WHOLE_WORD_CTRL_BKSP = False` to avoid configuration of the `control+backspace` binding.
This commit is contained in:
parent
347bf201de
commit
1e81146bd6
2 changed files with 84 additions and 6 deletions
26
news/extend-whole-word-jumping.rst
Normal file
26
news/extend-whole-word-jumping.rst
Normal file
|
@ -0,0 +1,26 @@
|
|||
**Added:**
|
||||
|
||||
* <news item>
|
||||
|
||||
**Changed:**
|
||||
|
||||
* Extended `whole_word_jumping` xontrib with matching bindings for
|
||||
`delete` and `backspace`. The `XONSH_WHOLE_WORD_CTRL_BKSP` environment
|
||||
variable can be set to `False` to avoid binding `control+backspace` in
|
||||
incompatible terminals.
|
||||
|
||||
**Deprecated:**
|
||||
|
||||
* <news item>
|
||||
|
||||
**Removed:**
|
||||
|
||||
* <news item>
|
||||
|
||||
**Fixed:**
|
||||
|
||||
* <news item>
|
||||
|
||||
**Security:**
|
||||
|
||||
* <news item>
|
|
@ -1,14 +1,33 @@
|
|||
"""Jumping across whole words (non-whitespace) with Ctrl+Left/Right.
|
||||
"""Jump/delete across whole (non-whitespace) words with Ctrl+Left/Right/Delete/Backspace.
|
||||
|
||||
Alt+Left/Right remains unmodified to jump over smaller word segments.
|
||||
Shift+Delete removes the whole word.
|
||||
Control+left/right: Jump to previous/next whole word
|
||||
Control+backspace: Delete to beginning of whole word
|
||||
Control+delete: Delete to end of whole word
|
||||
Shift+delete: Delete whole word
|
||||
|
||||
Alt+Left/Right/Delete/Backspace remain unmodified:
|
||||
|
||||
Alt+left/right: Jump to previous/next token
|
||||
Alt+backspace: Delete to beginning of token
|
||||
Alt+delete: Delete to end of token
|
||||
|
||||
Some terminals cannot differentiate between Backspace and Control+Backspace.
|
||||
In this case, users can set `$XONSH_WHOLE_WORD_CTRL_BKSP = False` to skip
|
||||
configuration of the Control+Backspace key binding.
|
||||
"""
|
||||
|
||||
import prompt_toolkit.input.ansi_escape_sequences as ansiseq
|
||||
import prompt_toolkit.input.win32 as ptk_win32
|
||||
from prompt_toolkit.filters import EmacsInsertMode, ViInsertMode
|
||||
from prompt_toolkit.key_binding.bindings.named_commands import get_by_name
|
||||
from prompt_toolkit.keys import Keys
|
||||
|
||||
from xonsh.built_ins import XonshSession
|
||||
from xonsh.built_ins import XSH, XonshSession
|
||||
from xonsh.platform import ON_WINDOWS
|
||||
|
||||
|
||||
def custom_keybindings(bindings, **kw):
|
||||
insert_mode = ViInsertMode() | EmacsInsertMode()
|
||||
|
||||
# Key bindings for jumping over whole words (everything that's not
|
||||
# white space) using Ctrl+Left and Ctrl+Right;
|
||||
|
@ -29,8 +48,8 @@ def custom_keybindings(bindings, **kw):
|
|||
if pos:
|
||||
buff.cursor_position += pos
|
||||
|
||||
@bindings.add(Keys.ShiftDelete)
|
||||
def shift_delete(event):
|
||||
@bindings.add(Keys.ShiftDelete, filter=insert_mode)
|
||||
def delete_surrounding_big_word(event):
|
||||
buff = event.current_buffer
|
||||
startpos, endpos = buff.document.find_boundaries_of_current_word(WORD=True)
|
||||
startpos = buff.cursor_position + startpos - 1
|
||||
|
@ -40,6 +59,39 @@ def custom_keybindings(bindings, **kw):
|
|||
buff.text = buff.text[:startpos] + buff.text[endpos:]
|
||||
buff.cursor_position = startpos
|
||||
|
||||
@bindings.add(Keys.ControlDelete, filter=insert_mode)
|
||||
def delete_big_word(event):
|
||||
buff = event.current_buffer
|
||||
pos = buff.document.find_next_word_ending(count=event.arg, WORD=True)
|
||||
if pos:
|
||||
buff.delete(count=pos)
|
||||
|
||||
@bindings.add(Keys.Escape, Keys.Delete, filter=insert_mode)
|
||||
def delete_small_word(event):
|
||||
get_by_name("kill-word").call(event)
|
||||
|
||||
# PTK sets both "\x7f" (^?) and "\x08" (^H) to the same behavior. Refs:
|
||||
# https://github.com/prompt-toolkit/python-prompt-toolkit/blob/65c3d0607c69c19d80abb052a18569a2546280e5/src/prompt_toolkit/input/ansi_escape_sequences.py#L65
|
||||
# https://github.com/prompt-toolkit/python-prompt-toolkit/issues/257#issuecomment-190328366
|
||||
# We patch the ANSI sequences used by PTK. This requires a terminal
|
||||
# that sends different codes for <backspace> and <control-h>.
|
||||
# PTK sets Keys.Backspace = Keys.ControlH, so we hardcode the code.
|
||||
# Windows has the codes reversed, see https://github.com/xonsh/xonsh/commit/406d20f78f18af39d9bbaf9580b0a763df78a0db
|
||||
if XSH.env.get("XONSH_WHOLE_WORD_CTRL_BKSP", True):
|
||||
CONTROL_BKSP = "\x08"
|
||||
if ON_WINDOWS:
|
||||
# On windows BKSP is "\x08" and CTRL-BKSP is "\x7f"
|
||||
CONTROL_BKSP = "\x7f"
|
||||
ptk_win32.ConsoleInputReader.mappings[b"\x7f"] = CONTROL_BKSP
|
||||
ansiseq.ANSI_SEQUENCES[CONTROL_BKSP] = CONTROL_BKSP
|
||||
ansiseq.REVERSE_ANSI_SEQUENCES[CONTROL_BKSP] = CONTROL_BKSP
|
||||
|
||||
@bindings.add(CONTROL_BKSP, filter=insert_mode)
|
||||
def backward_delete_big_word(event):
|
||||
get_by_name("unix-word-rubout").call(event)
|
||||
|
||||
# backward_delete_small_word works on Alt+Backspace by default
|
||||
|
||||
|
||||
def _load_xontrib_(xsh: XonshSession, **_):
|
||||
xsh.builtins.events.on_ptk_create(custom_keybindings)
|
||||
|
|
Loading…
Add table
Reference in a new issue