mirror of
https://github.com/kovidgoyal/kitty.git
synced 2024-09-20 19:19:41 +03:00
Add basic editing support for the broadcast kitten
This commit is contained in:
parent
34db18ea0a
commit
00aba7c646
@ -12,11 +12,12 @@
|
||||
from kitty.key_encoding import RELEASE, encode_key_event, key_defs as K
|
||||
from kitty.rc.base import MATCH_TAB_OPTION, MATCH_WINDOW_OPTION
|
||||
from kitty.remote_control import create_basic_command, encode_send
|
||||
from kitty.typing import KeyEventType
|
||||
from kitty.typing import KeyEventType, ScreenSize
|
||||
|
||||
from ..tui.handler import Handler
|
||||
from ..tui.line_edit import LineEdit
|
||||
from ..tui.loop import Loop
|
||||
from ..tui.operations import styled
|
||||
from ..tui.operations import RESTORE_CURSOR, SAVE_CURSOR, styled
|
||||
|
||||
|
||||
class Broadcast(Handler):
|
||||
@ -25,6 +26,7 @@ def __init__(self, opts: BroadcastCLIOptions, initial_strings: List[str]) -> Non
|
||||
self.opts = opts
|
||||
self.initial_strings = initial_strings
|
||||
self.payload = {'exclude_active': True, 'data': '', 'match': opts.match_tab, 'match_tab': opts.match_tab}
|
||||
self.line_edit = LineEdit()
|
||||
if not opts.match and not opts.match_tab:
|
||||
self.payload['all'] = True
|
||||
|
||||
@ -32,10 +34,21 @@ def initialize(self) -> None:
|
||||
self.print('Type the text to broadcast below, press', styled('Ctrl+c', fg='yellow'), 'to quit:')
|
||||
for x in self.initial_strings:
|
||||
self.write_broadcast_text(x)
|
||||
self.write(SAVE_CURSOR)
|
||||
|
||||
def commit_line(self) -> None:
|
||||
self.write(RESTORE_CURSOR + SAVE_CURSOR)
|
||||
self.cmd.clear_to_end_of_screen()
|
||||
self.line_edit.write(self.write, screen_cols=self.screen_size.cols)
|
||||
|
||||
def on_resize(self, screen_size: ScreenSize) -> None:
|
||||
super().on_resize(screen_size)
|
||||
self.commit_line()
|
||||
|
||||
def on_text(self, text: str, in_bracketed_paste: bool = False) -> None:
|
||||
self.write_broadcast_text(text)
|
||||
self.write(text)
|
||||
self.line_edit.on_text(text, in_bracketed_paste)
|
||||
self.commit_line()
|
||||
|
||||
def on_interrupt(self) -> None:
|
||||
self.quit_loop(0)
|
||||
@ -44,19 +57,16 @@ def on_eot(self) -> None:
|
||||
self.write_broadcast_text('\x04')
|
||||
|
||||
def on_key(self, key_event: KeyEventType) -> None:
|
||||
if self.line_edit.on_key(key_event):
|
||||
self.commit_line()
|
||||
if key_event.type is not RELEASE and not key_event.mods:
|
||||
if key_event.key is K['TAB']:
|
||||
self.write_broadcast_text('\t')
|
||||
self.write('\t')
|
||||
return
|
||||
elif key_event.key is K['BACKSPACE']:
|
||||
self.write_broadcast_text('\177')
|
||||
self.write('\x08\x1b[X')
|
||||
return
|
||||
elif key_event.key is K['ENTER']:
|
||||
if key_event.key is K['ENTER']:
|
||||
self.write_broadcast_text('\r')
|
||||
self.print('')
|
||||
self.line_edit.clear()
|
||||
self.write(SAVE_CURSOR)
|
||||
return
|
||||
|
||||
ek = encode_key_event(key_event)
|
||||
self.write_broadcast_data('kitty-key:' + ek)
|
||||
|
||||
|
@ -7,6 +7,8 @@
|
||||
from kitty.fast_data_types import truncate_point_for_length, wcswidth
|
||||
from kitty.key_encoding import RELEASE, KeyEvent, key_defs as K
|
||||
|
||||
from .operations import RESTORE_CURSOR, SAVE_CURSOR, move_cursor_by
|
||||
|
||||
HOME = K['HOME']
|
||||
END = K['END']
|
||||
BACKSPACE = K['BACKSPACE']
|
||||
@ -31,13 +33,28 @@ def split_at_cursor(self, delta: int = 0) -> Tuple[str, str]:
|
||||
before, after = self.current_input[:x], self.current_input[x:]
|
||||
return before, after
|
||||
|
||||
def write(self, write: Callable[[str], None], prompt: str = '') -> None:
|
||||
def write(self, write: Callable[[str], None], prompt: str = '', screen_cols: int = 0) -> None:
|
||||
if self.pending_bell:
|
||||
write('\a')
|
||||
self.pending_bell = False
|
||||
write(prompt)
|
||||
write(self.current_input)
|
||||
write('\r\x1b[{}C'.format(self.cursor_pos + wcswidth(prompt)))
|
||||
text = prompt + self.current_input
|
||||
cursor_pos = self.cursor_pos + wcswidth(prompt)
|
||||
if screen_cols:
|
||||
write(SAVE_CURSOR + text + RESTORE_CURSOR)
|
||||
used_lines, last_line_cursor_pos = divmod(cursor_pos, screen_cols)
|
||||
if used_lines == 0:
|
||||
if last_line_cursor_pos:
|
||||
write(move_cursor_by(last_line_cursor_pos, 'right'))
|
||||
else:
|
||||
if used_lines:
|
||||
write(move_cursor_by(used_lines, 'down'))
|
||||
if last_line_cursor_pos:
|
||||
write(move_cursor_by(last_line_cursor_pos, 'right'))
|
||||
else:
|
||||
write(text)
|
||||
write('\r')
|
||||
if cursor_pos:
|
||||
write(move_cursor_by(cursor_pos, 'right'))
|
||||
|
||||
def add_text(self, text: str) -> None:
|
||||
if self.current_input:
|
||||
|
@ -68,6 +68,11 @@ def clear_screen() -> str:
|
||||
return '\033[H\033[2J'
|
||||
|
||||
|
||||
@cmd
|
||||
def clear_to_end_of_screen() -> str:
|
||||
return '\033[J'
|
||||
|
||||
|
||||
@cmd
|
||||
def clear_to_eol() -> str:
|
||||
return '\033[K'
|
||||
@ -108,6 +113,12 @@ def set_cursor_position(x: int, y: int) -> str: # (0, 0) is top left
|
||||
return '\033[{};{}H'.format(y + 1, x + 1)
|
||||
|
||||
|
||||
@cmd
|
||||
def move_cursor_by(amt: int, direction: str) -> str:
|
||||
suffix = {'up': 'A', 'down': 'B', 'right': 'C', 'left': 'D'}[direction]
|
||||
return f'\033[{amt}{suffix}'
|
||||
|
||||
|
||||
@cmd
|
||||
def set_cursor_shape(shape: str = 'block', blink: bool = True) -> str:
|
||||
val = {'block': 1, 'underline': 3, 'bar': 5}.get(shape, 1)
|
||||
|
Loading…
Reference in New Issue
Block a user