chiark / gitweb /
Experimental ^K change of behaviour.
authorSimon Tatham <anakin@pobox.com>
Thu, 14 Dec 2023 18:20:24 +0000 (18:20 +0000)
committerSimon Tatham <anakin@pobox.com>
Thu, 14 Dec 2023 18:50:30 +0000 (18:50 +0000)
If you press ^K to delete to end of line and you're in mid-paragraph,
I think not a bad answer is to _insert_ a paragraph break, so that the
text on the next line doesn't unexpectedly wrap.

This is intuitively as close as possible to the behaviour in the
non-auto-wrapping 'me'. The only thing I don't like about it is that
pasting the text back in again with ^Y doesn't delete the line break,
but I haven't thought of a less astonishing answer to that yet.

cursesclient.py

index 7c7d45b32736c618b0487612af94d588c69afb26..87f64ded9843c249234528051baf7766ad9026ee 100644 (file)
@@ -880,19 +880,6 @@ class EditorCommon:
                     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 +
@@ -936,6 +923,10 @@ class BottomLinePrompt(Activity, EditorCommon):
             self.move_to(0)
         elif ch in {ctrl('e'), curses.KEY_END}:
             self.move_to(len(self.text))
+        elif ch in {ctrl('k')}:
+            if self.point < len(self.text):
+                self.ctrl_k_paste_buffer = self.text[self.point:]
+                self.text = (self.text[:self.point])
         elif ch in {'\r', '\n'}:
             self.callback(self.text)
             self.chain_to(self.parent_activity)
@@ -1201,6 +1192,26 @@ class Composer(Activity, EditorCommon):
                                              self.point)
                     if yx[0] == self.cy)
                 self.move_to(new_point)
+            elif ch in {ctrl('k')}:
+                if self.point < len(self.text):
+                    line_end = util.last(
+                        i for i, yx in enumerate(self.dtext.yx[self.point:],
+                                                 self.point)
+                        if yx[0] == self.cy)
+                    end_of_para = self.text[line_end:line_end+1] in {'', '\n'}
+                    if not end_of_para and line_end < len(self.text):
+                        line_end += 1
+
+                    if line_end == self.point:
+                        if end_of_para:
+                            self.text = (self.text[:self.point] +
+                                         self.text[self.point+1:])
+                    else:
+                        self.ctrl_k_paste_buffer = self.text[
+                            self.point:line_end]
+                        self.text = (self.text[:self.point] +
+                                     ("\n" if not end_of_para else "") +
+                                     self.text[line_end:])
             elif ch in {'\r', '\n'}:
                 self.text = (self.text[:self.point] + '\n' +
                              self.text[self.point:])
@@ -1397,6 +1408,20 @@ class testComposerLayout(unittest.TestCase):
         t.handle_key(ctrl('k'))
         self.assertEqual(t.text, "abc def ghi jklmno pqr stu vwx")
 
+        # On a non-final line of a paragraph: delete up to the next
+        # line break, and _insert_ a newline. (Logically weird but
+        # intuitive in use, given that 'me' would leave a miswrapped
+        # paragraph)
+        t = setup(4)
+        t.handle_key(ctrl('k'))
+        self.assertEqual(t.text, "abc \nghi jkl\nmno pqr stu vwx")
+
+        # If you're at the very end of the non-final line, this
+        # translates to _just_ replacing a space with a newline.
+        t = setup(7)
+        t.handle_key(ctrl('k'))
+        self.assertEqual(t.text, "abc def\nghi jkl\nmno pqr stu vwx")
+
         # At the very end of the buffer: do nothing, including not
         # crashing
         t = setup(31)