Repository: zulip/zulip-terminal

Issue:
Support 'Narrow to current compose box recipient'
This is useful if starting a new topic - currently we give a notice that the sent message is outside of the current narrow, but there is no easy way of jumping to it.

The web app supports <kbd>ctrl</kbd>+<kbd>.</kbd> for achieving this, so this is a logical feature for us to also add.

Adding the key should show it in the help menu, but we could also show it in the message that is shown when messages are sent outside of the current narrow.

Discussion:
zulipbot: Hello @srdeotarse, it seems like you have referenced #1182 in your pull request description, but you have not referenced them in your commit message description(s). When you reference an issue in a commit message, it automatically closes the corresponding issue when the commit is merged.

Please run `git commit --amend` in your command line client to amend your commit message description with `Fixes #1182.`.

An example of a correctly-formatted commit:

```
commit fabd5e450374c8dde65ec35f02140383940fe146
Author: zulipbot
Date:   Sat Mar 18 13:42:40 2017 -0700

    pull requests: Check PR commits reference when issue is referenced.

    Fixes #51.
```

Thank you for your contributions to Zulip!

<!-- fixCommitWarning -->

zulipbot: Hello @zulip/server-hotkeys members, this pull request was labeled with the "area: hotkeys" label, so you may want to check it out!

<!-- areaLabelAddition -->

zulipbot: Hello @srdeotarse, it seems like you have referenced #1182 in your pull request description, but you have not referenced them in your commit message description(s). When you reference an issue in a commit message, it automatically closes the corresponding issue when the commit is merged.

Please run `git commit --amend` in your command line client to amend your commit message description with `Fixes #1182.`.

An example of a correctly-formatted commit:

```
commit fabd5e450374c8dde65ec35f02140383940fe146
Author: zulipbot
Date:   Sat Mar 18 13:42:40 2017 -0700

    pull requests: Check PR commits reference when issue is referenced.

    Fixes #51.
```

Thank you for your contributions to Zulip!

<!-- fixCommitWarning -->

srdeotarse: @zulipbot add "PR needs review".
srdeotarse: @zulipbot remove "PR needs review".
zulipbot: Hello @srdeotarse, it seems like you have referenced #1182 in your pull request description, but you have not referenced them in your commit message description(s). When you reference an issue in a commit message, it automatically closes the corresponding issue when the commit is merged.

Please run `git commit --amend` in your command line client to amend your commit message description with `Fixes #1182.`.

An example of a correctly-formatted commit:

```
commit fabd5e450374c8dde65ec35f02140383940fe146
Author: zulipbot
Date:   Sat Mar 18 13:42:40 2017 -0700

    pull requests: Check PR commits reference when issue is referenced.

    Fixes #51.
```

Thank you for your contributions to Zulip!

<!-- fixCommitWarning -->

srdeotarse: @zulipbot "PR needs review".
srdeotarse: @zulipbot add "PR needs review".
neiljp: @srdeotarse Thanks for updating this :+1: I adjusted the other conditional to use compose_box_status and will be merging shortly. This is going to be very helpful day to day 🎉 

Patch:
diff --git a/docs/hotkeys.md b/docs/hotkeys.md
index edc75eb..c49cb15 100644
--- a/docs/hotkeys.md
+++ b/docs/hotkeys.md
@@ -80,6 +80,7 @@
 |Save current message as a draft|<kbd>meta</kbd> + <kbd>s</kbd>|
 |Autocomplete @mentions, #stream_names, :emoji: and topics|<kbd>ctrl</kbd> + <kbd>f</kbd>|
 |Cycle through autocomplete suggestions in reverse|<kbd>ctrl</kbd> + <kbd>r</kbd>|
+|Narrow to compose box message recipient|<kbd>meta</kbd> + <kbd>.</kbd>|
 |Jump to the beginning of line|<kbd>ctrl</kbd> + <kbd>a</kbd>|
 |Jump to the end of line|<kbd>ctrl</kbd> + <kbd>e</kbd>|
 |Jump backward one word|<kbd>meta</kbd> + <kbd>b</kbd>|
diff --git a/zulipterminal/config/keys.py b/zulipterminal/config/keys.py
index bd148f0..079fae5 100644
--- a/zulipterminal/config/keys.py
+++ b/zulipterminal/config/keys.py
@@ -164,6 +164,11 @@ KEY_BINDINGS: 'OrderedDict[str, KeyBinding]' = OrderedDict([
         '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 65c61aa..de980f2 100644
--- a/zulipterminal/helper.py
+++ b/zulipterminal/helper.py
@@ -26,6 +26,7 @@ from urllib.parse import unquote
 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 14a12e0..46a3475 100644
--- a/zulipterminal/ui_tools/boxes.py
+++ b/zulipterminal/ui_tools/boxes.py
@@ -773,6 +773,27 @@ class WriteBox(urwid.Pile):
                 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()


Test patch:
diff --git a/tests/helper/test_helper.py b/tests/helper/test_helper.py
index 8c88cad..a9def5b 100644
--- a/tests/helper/test_helper.py
+++ b/tests/helper/test_helper.py
@@ -5,6 +5,7 @@ from pytest import param as case
 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()