From: Simon Tatham Date: Fri, 8 Dec 2023 12:59:59 +0000 (+0000) Subject: ^K and ^Y for copy and paste to end of line. X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?a=commitdiff_plain;h=3710d1381669531623e35315226fc05bb0cdd0a6;p=mastodonochrome.git ^K and ^Y for copy and paste to end of line. Well, end of _paragraph_, for the moment. Perhaps end of line would be better. But my immediate use cases won't care about the difference: - ^W^K to delete the last word I typed at the end of a paragraph - dealing with code snippets which don't wrap anyway --- diff --git a/cursesclient.py b/cursesclient.py index 716a4bd..3a8479f 100644 --- a/cursesclient.py +++ b/cursesclient.py @@ -870,6 +870,7 @@ class Composer(Activity): self.text = initial_text self.point = len(self.text) self.goal_column = None + self.ctrl_k_paste_buffer = "" self.mode = 'normal' instance_data = self.cc.get("instance") @@ -922,6 +923,15 @@ class Composer(Activity): def move_to(self, pos): self.point = max(0, min(len(self.text), pos)) + def word_boundary(self, pos): + if pos == 0 or pos == len(self.text): + return True + if self.text[pos-1] == '\n' or self.text[pos] == '\n': + return True + if self.text[pos-1] == ' ' and self.text[pos] != ' ': + return True + return False + def handle_key(self, ch): is_updown = ch in {ctrl('n'), ctrl('p'), curses.KEY_DOWN, curses.KEY_UP} @@ -931,15 +941,12 @@ class Composer(Activity): if self.mode == 'normal': # TODO: # - # ^W,^T are Mono's keys for moving back/forward a word. - # - # Not sure what to do about ^K/^Y for one-line cut-paste, given - # that the autowrap makes the semantics a bit weird compared to - # the original setup. + # Might still want to change ^K so that it stops at end of + # current screen line, instead of end of paragraph. # - # Probably don't want to exactly replicate the block - # operations either. Perhaps I should invent my own more sensible - # approach to cut, copy and paste. + # Maybe an extra copy/paste approach with explicit + # selection start/end points? Probably don't want to + # replicate Mono's underpowered [^O][B] business. if ch in {ctrl('b'), curses.KEY_LEFT}: self.move_to(self.point - 1) @@ -1004,6 +1011,24 @@ class Composer(Activity): self.point += 1 if self.word_boundary(self.point): break + elif ch in {ctrl('k')}: + if self.point < len(self.text): + if self.text[self.point] == '\n': + self.text = (self.text[:self.point] + + self.text[self.point+1:]) + else: + try: + endpos = self.text.index('\n', self.point) + except ValueError: + endpos = len(self.text) + self.ctrl_k_paste_buffer = self.text[self.point:endpos] + self.text = (self.text[:self.point] + + self.text[endpos:]) + elif ch in {ctrl('y')}: + self.text = ( + self.text[:self.point] + self.ctrl_k_paste_buffer + + self.text[self.point:]) + self.point += len(self.ctrl_k_paste_buffer) elif ch in {'\r', '\n'}: self.text = (self.text[:self.point] + '\n' + self.text[self.point:])