xonsh/xontrib/abbrevs.py

103 lines
3 KiB
Python
Raw Normal View History

2020-03-25 20:12:30 +01:00
"""
Command abbreviations.
This expands input words from `abbrevs` disctionary as you type.
"""
2020-03-20 21:46:35 +01:00
import builtins
from prompt_toolkit.filters import completion_is_selected, IsMultiline
2020-03-25 17:30:28 +01:00
from prompt_toolkit.keys import Keys
from xonsh.built_ins import DynamicAccessProxy
2020-03-25 18:29:05 +01:00
from xonsh.tools import check_for_partial_string
2020-03-20 21:46:35 +01:00
__all__ = ()
builtins.__xonsh__.abbrevs = dict()
proxy = DynamicAccessProxy("abbrevs", "__xonsh__.abbrevs")
setattr(builtins, "abbrevs", proxy)
2020-03-20 21:46:35 +01:00
last_expanded = None
2020-03-25 22:45:12 +01:00
2020-03-20 21:46:35 +01:00
def expand_abbrev(buffer):
global last_expanded
last_expanded = None
abbrevs = getattr(builtins, "abbrevs", None)
if abbrevs is None:
2020-03-20 21:46:35 +01:00
return
2020-03-25 18:29:05 +01:00
document = buffer.document
word = document.get_word_before_cursor(WORD=True)
2020-03-20 21:46:35 +01:00
if word in abbrevs.keys():
2020-03-25 18:29:05 +01:00
partial = document.text[: document.cursor_position]
startix, endix, quote = check_for_partial_string(partial)
if startix is not None and endix is None:
return
2020-03-20 21:46:35 +01:00
buffer.delete_before_cursor(count=len(word))
buffer.insert_text(abbrevs[word])
last_expanded = word
def revert_abbrev(buffer):
global last_expanded
if last_expanded is None:
return False
abbrevs = getattr(builtins, "abbrevs", None)
if abbrevs is None:
return False
if last_expanded not in abbrevs.keys():
return False
document = buffer.document
expansion = abbrevs[last_expanded] + " "
if not document.text_before_cursor.endswith(expansion):
return False
buffer.delete_before_cursor(count=len(expansion))
buffer.insert_text(last_expanded)
last_expanded = None
return True
2020-03-20 21:46:35 +01:00
def set_cursor_position(buffer):
abbrevs = getattr(builtins, "abbrevs", None)
if abbrevs is None:
return False
global last_expanded
abbr = abbrevs[last_expanded]
pos = abbr.rfind("<edit>")
if pos == -1:
return False
buffer.cursor_position = buffer.cursor_position - (len(abbr) - pos)
buffer.delete(6)
last_expanded = None
return True
2020-03-20 21:46:35 +01:00
@events.on_ptk_create
def custom_keybindings(bindings, **kw):
from xonsh.ptk_shell.key_bindings import carriage_return
from prompt_toolkit.filters import EmacsInsertMode, ViInsertMode
2020-03-25 17:30:28 +01:00
handler = bindings.add
insert_mode = ViInsertMode() | EmacsInsertMode()
2020-03-20 21:46:35 +01:00
2020-03-25 17:30:28 +01:00
@handler(" ", filter=IsMultiline() & insert_mode)
def handle_space(event):
2020-03-20 21:46:35 +01:00
buffer = event.app.current_buffer
if not revert_abbrev(buffer):
expand_abbrev(buffer)
if last_expanded is None or not set_cursor_position(buffer):
buffer.insert_text(" ")
2020-03-25 17:30:28 +01:00
@handler(
Keys.ControlJ, filter=IsMultiline() & insert_mode & ~completion_is_selected
)
@handler(
Keys.ControlM, filter=IsMultiline() & insert_mode & ~completion_is_selected
)
2020-03-25 17:30:28 +01:00
def multiline_carriage_return(event):
buffer = event.app.current_buffer
current_char = buffer.document.current_char
if not current_char or current_char.isspace():
expand_abbrev(buffer)
2020-03-25 17:30:28 +01:00
carriage_return(buffer, event.cli)