diff --git a/docs/hotkeys.md b/docs/hotkeys.md
index edc75eb3f9..c49cb15c0f 100644
--- a/docs/hotkeys.md
+++ b/docs/hotkeys.md
@@ -80,6 +80,7 @@
|Save current message as a draft|meta + s|
|Autocomplete @mentions, #stream_names, :emoji: and topics|ctrl + f|
|Cycle through autocomplete suggestions in reverse|ctrl + r|
+|Narrow to compose box message recipient|meta + .|
|Jump to the beginning of line|ctrl + a|
|Jump to the end of line|ctrl + e|
|Jump backward one word|meta + b|
diff --git a/tests/helper/test_helper.py b/tests/helper/test_helper.py
index 8c88cad1e7..a9def5b87c 100644
--- a/tests/helper/test_helper.py
+++ b/tests/helper/test_helper.py
@@ -5,6 +5,7 @@
from pytest_mock import MockerFixture
from zulipterminal.api_types import Composition
+from zulipterminal.config.keys import primary_key_for_command
from zulipterminal.helper import (
Index,
canonicalize_color,
@@ -428,8 +429,10 @@ def test_notify_if_message_sent_outside_narrow(
notify_if_message_sent_outside_narrow(req, controller)
if footer_updated:
+ key = primary_key_for_command("NARROW_MESSAGE_RECIPIENT")
report_success.assert_called_once_with(
- "Message is sent outside of current narrow."
+ f"Message is sent outside of current narrow. Press [{key}] to narrow to conversation.",
+ duration=6,
)
else:
report_success.assert_not_called()
diff --git a/zulipterminal/config/keys.py b/zulipterminal/config/keys.py
index bd148f0be1..079fae5f54 100644
--- a/zulipterminal/config/keys.py
+++ b/zulipterminal/config/keys.py
@@ -164,6 +164,11 @@ class KeyBinding(TypedDict, total=False):
'help_text': 'Narrow to the topic of the current message',
'key_category': 'msg_actions',
}),
+ ('NARROW_MESSAGE_RECIPIENT', {
+ 'keys': ['meta .'],
+ 'help_text': 'Narrow to compose box message recipient',
+ 'key_category': 'msg_compose',
+ }),
('TOGGLE_NARROW', {
'keys': ['z'],
'help_text':
diff --git a/zulipterminal/helper.py b/zulipterminal/helper.py
index 65c61aa9d5..de980f28ed 100644
--- a/zulipterminal/helper.py
+++ b/zulipterminal/helper.py
@@ -26,6 +26,7 @@
from typing_extensions import TypedDict
from zulipterminal.api_types import Composition, EmojiType, Message
+from zulipterminal.config.keys import primary_key_for_command
from zulipterminal.config.regexes import (
REGEX_COLOR_3_DIGIT,
REGEX_COLOR_6_DIGIT,
@@ -652,7 +653,12 @@ def check_narrow_and_notify(
and current_narrow != outer_narrow
and current_narrow != inner_narrow
):
- controller.report_success("Message is sent outside of current narrow.")
+ key = primary_key_for_command("NARROW_MESSAGE_RECIPIENT")
+
+ controller.report_success(
+ f"Message is sent outside of current narrow. Press [{key}] to narrow to conversation.",
+ duration=6,
+ )
def notify_if_message_sent_outside_narrow(
diff --git a/zulipterminal/ui_tools/boxes.py b/zulipterminal/ui_tools/boxes.py
index 14a12e0685..46a3475b9d 100644
--- a/zulipterminal/ui_tools/boxes.py
+++ b/zulipterminal/ui_tools/boxes.py
@@ -773,6 +773,27 @@ def keypress(self, size: urwid_Size, key: str) -> Optional[str]:
if self.msg_edit_state is not None:
self.keypress(size, primary_key_for_command("GO_BACK"))
assert self.msg_edit_state is None
+ elif is_command_key("NARROW_MESSAGE_RECIPIENT", key):
+ if self.compose_box_status == "open_with_stream":
+ self.model.controller.narrow_to_topic(
+ stream_name=self.stream_write_box.edit_text,
+ topic_name=self.title_write_box.edit_text,
+ contextual_message_id=None,
+ )
+ elif self.compose_box_status == "open_with_private":
+ self.recipient_emails = [
+ self.model.user_id_email_dict[user_id]
+ for user_id in self.recipient_user_ids
+ ]
+ if self.recipient_user_ids:
+ self.model.controller.narrow_to_user(
+ recipient_emails=self.recipient_emails,
+ contextual_message_id=None,
+ )
+ else:
+ self.view.controller.report_error(
+ "Cannot narrow to message without specifying recipients."
+ )
elif is_command_key("GO_BACK", key):
self.send_stop_typing_status()
self._set_compose_attributes_to_defaults()