Skip to content

Commit bfdafb5

Browse files
committed
feat(command): open in terminal editor command in composing message
On OPEN_IN_TERMINAL_EDITOR command allow to edit the current message in terminal editor with python tempfile.
1 parent b81f30f commit bfdafb5

File tree

3 files changed

+44
-0
lines changed

3 files changed

+44
-0
lines changed

docs/hotkeys.md

+1
Original file line numberDiff line numberDiff line change
@@ -96,4 +96,5 @@
9696
|Jump to the previous line|<kbd>up</kbd> / <kbd>ctrl</kbd> + <kbd>p</kbd>|
9797
|Jump to the next line|<kbd>down</kbd> / <kbd>ctrl</kbd> + <kbd>n</kbd>|
9898
|Clear compose box|<kbd>ctrl</kbd> + <kbd>l</kbd>|
99+
|Open the message in external editor|<kbd>ctrl</kbd> + <kbd>o</kbd>|
99100

zulipterminal/config/keys.py

+5
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,11 @@ class KeyBinding(TypedDict):
385385
'help_text': 'Clear compose box',
386386
'key_category': 'msg_compose',
387387
},
388+
'OPEN_EXTERNAL_EDITOR': {
389+
'keys': ['ctrl o'],
390+
'help_text': 'Open the message in external editor',
391+
'key_category': 'msg_compose',
392+
},
388393
'FULL_RENDERED_MESSAGE': {
389394
'keys': ['f'],
390395
'help_text': 'Show/hide full rendered message (from message information)',

zulipterminal/ui_tools/boxes.py

+38
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@
22
UI boxes for entering text: WriteBox, MessageSearchBox, PanelSearchBox
33
"""
44

5+
import os
56
import re
7+
import shutil
8+
import subprocess
69
import unicodedata
710
from collections import Counter
811
from datetime import datetime, timedelta
12+
from tempfile import NamedTemporaryFile
913
from time import sleep
1014
from typing import Any, Callable, Dict, List, NamedTuple, Optional, Tuple
1115

@@ -810,6 +814,40 @@ def keypress(self, size: urwid_Size, key: str) -> Optional[str]:
810814
elif is_command_key("MARKDOWN_HELP", key):
811815
self.view.controller.show_markdown_help()
812816
return key
817+
elif is_command_key("OPEN_EXTERNAL_EDITOR", key):
818+
editor = os.environ.get("ZULIP_EDITOR_COMMAND", os.environ.get("EDITOR"))
819+
if editor is None:
820+
self.view.controller.report_error(
821+
"Configure $EDITOR or $ZULIP_EDITOR_COMMAND shell environment."
822+
)
823+
return key
824+
editor_splits = editor.split(" ")
825+
if len(editor_splits) >= 1:
826+
fullpath_program = shutil.which(editor_splits[0])
827+
if fullpath_program is None:
828+
self.view.controller.report_error(
829+
"Editor program not found, check $EDITOR "
830+
"or $ZULIP_EDITOR_COMMAND."
831+
)
832+
return key
833+
editor_splits[0] = fullpath_program
834+
edit_tempfile = NamedTemporaryFile(suffix=".md")
835+
with open(edit_tempfile.name, mode="w") as edit_writer:
836+
edit_writer.write(self.msg_write_box.edit_text)
837+
self.view.controller.loop.screen.stop()
838+
if "TEMPFILE" not in editor:
839+
editor_splits.append(edit_tempfile.name)
840+
else:
841+
editor_splits = [
842+
part if part != "TEMPFILE" else edit_tempfile.name
843+
for part in editor_splits
844+
]
845+
subprocess.call(editor_splits)
846+
with open(edit_tempfile.name, mode="r") as edit_reader:
847+
self.msg_write_box.edit_text = edit_reader.read()
848+
edit_tempfile.close()
849+
self.view.controller.loop.screen.start()
850+
return key
813851
elif is_command_key("SAVE_AS_DRAFT", key):
814852
if self.msg_edit_state is None:
815853
if self.compose_box_status == "open_with_private":

0 commit comments

Comments
 (0)