From bef38385429c33cda98d3cc6bf1a706402b8b1df Mon Sep 17 00:00:00 2001 From: Maarten van Gompel Date: Tue, 13 Dec 2022 00:16:03 +0100 Subject: [PATCH] implementing the ability to edit messages rather than cancel them unexpectedly on certain keypresses #293 This is a bit hacky... left arrow does the same as delete, other control character open up the editor for further message editing --- tg/controllers.py | 2 +- tg/views.py | 36 +++++++++++++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/tg/controllers.py b/tg/controllers.py index ef3f6a6..3220a72 100644 --- a/tg/controllers.py +++ b/tg/controllers.py @@ -318,7 +318,7 @@ def write_short_msg(self) -> None: self.present_info("Can't send msg in this chat") return self.tg.send_chat_action(chat_id, ChatAction.chatActionTyping) - if msg := self.view.status.get_input(): + if msg := self.view.status.get_input(view=self.view): self.model.send_message(text=msg) self.present_info("Message sent") else: diff --git a/tg/views.py b/tg/views.py index 3facfc2..5c69342 100644 --- a/tg/views.py +++ b/tg/views.py @@ -2,6 +2,8 @@ import logging from datetime import datetime from typing import Any, Dict, List, Optional, Tuple, Union, cast +from tempfile import NamedTemporaryFile +import shlex from _curses import window # type: ignore @@ -10,7 +12,7 @@ from tg.models import Model, UserModel from tg.msg import MsgProxy from tg.tdlib import ChatType, get_chat_type, is_group -from tg.utils import get_color_by_str, num, string_len_dwc, truncate_to_len +from tg.utils import get_color_by_str, num, string_len_dwc, truncate_to_len, suspend log = logging.getLogger(__name__) @@ -124,7 +126,7 @@ def draw(self, msg: str = "") -> None: self.win.addstr(0, 0, msg.replace("\n", " ")[: self.w]) self._refresh() - def get_input(self, prefix: str = "") -> Optional[str]: + def get_input(self, prefix: str = "", view: Optional[View] = None) -> Optional[str]: curses.curs_set(1) buff = "" @@ -140,10 +142,38 @@ def get_input(self, prefix: str = "") -> Optional[str]: key = ord(key) if key == 10: # return break - elif key == 127 or key == 8: # del + elif key in (127, 8): # del if buff: buff = buff[:-1] elif key in (7, 27): # (^G, ) cancel + self.win.nodelay(True) + extra = [] + while True: + c = self.win.getch() + if c == -1: + break + else: + extra.append(c) + self.win.nodelay(False) + curses.flushinp() + if len(extra) >= 2 and extra[0] == 91: + if extra[1] == 68: #left arrow, treat as delete + if buff: + buff = buff[:-1] + continue + elif view: #another control key, open editor + with NamedTemporaryFile("w+", suffix=".txt") as f, suspend( + view + ) as s: + f.write(buff) + f.seek(0) + proc = s.call(config.LONG_MSG_CMD.format(file_path=shlex.quote(f.name))) + if proc.returncode == 0: + with open(f.name) as f: + buff = f.read().strip() + continue + else: + continue #ignore return None elif chr(key).isprintable(): buff += chr(key)