Skip to content

Commit b3b7a40

Browse files
committed
boxes/helper: Support typeahead for topic name in recipient box.
Note that this does not work correctly when the search text includes whitespaces, due to lack of urwid-readline support. Test added.
1 parent f10ca74 commit b3b7a40

File tree

4 files changed

+65
-1
lines changed

4 files changed

+65
-1
lines changed

tests/conftest.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,11 @@ def zulip_version(request):
331331
return request.param
332332

333333

334+
@pytest.fixture
335+
def topics():
336+
return ['Topic 1', 'This is a topic', 'Hello there!']
337+
338+
334339
@pytest.fixture
335340
def initial_data(logged_on_user, users_fixture, streams_fixture):
336341
"""

tests/ui_tools/test_boxes.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,44 @@ def test__stream_box_autocomplete_with_spaces(self, mocker, write_box,
298298

299299
assert write_box.contents[0][0][0].edit_text == expected_text
300300

301+
@pytest.mark.parametrize(['text', 'matching_topics'], [
302+
('', ['Topic 1', 'This is a topic', 'Hello there!']),
303+
('Th', ['This is a topic']),
304+
], ids=[
305+
'no_search_text',
306+
'single_word_search_text',
307+
])
308+
def test__topic_box_autocomplete(self, mocker, write_box, text, topics,
309+
matching_topics, state=1):
310+
write_box.model.topics_in_stream.return_value = topics
311+
_process_typeaheads = mocker.patch(BOXES
312+
+ '.WriteBox._process_typeaheads')
313+
314+
write_box._topic_box_autocomplete(text, state)
315+
316+
_process_typeaheads.assert_called_once_with(matching_topics, state,
317+
matching_topics)
318+
319+
@pytest.mark.parametrize('text, expected_text', [
320+
('Th', 'This is a topic'),
321+
pytest.param('This i', 'This is a topic', marks=pytest.mark.xfail(
322+
reason="Lacking urwid-readline support")),
323+
])
324+
def test__topic_box_autocomplete_with_spaces(self, mocker, write_box,
325+
text, expected_text,
326+
topics):
327+
write_box.stream_box_view(1000)
328+
write_box.model.topics_in_stream.return_value = topics
329+
write_box.contents[0][0][1].set_edit_text(text)
330+
write_box.contents[0][0][1].set_edit_pos(len(text))
331+
write_box.focus_position = 0
332+
write_box.contents[0][0].focus_col = 1
333+
size = (20,)
334+
335+
write_box.keypress(size, keys_for_command('AUTOCOMPLETE').pop())
336+
337+
assert write_box.contents[0][0][1].edit_text == expected_text
338+
301339
@pytest.mark.parametrize(['suggestions', 'state', 'expected_state',
302340
'expected_typeahead', 'is_truncated'], [
303341
(['zero', 'one', 'two'], 1, 1, '*one*', False),

zulipterminal/helper.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,11 @@ def match_emoji(emoji: str, text: str) -> bool:
487487
return emoji.lower().startswith(text.lower())
488488

489489

490+
def match_topics(topic_names: List[str], search_text: str) -> List[str]:
491+
return [name for name in topic_names
492+
if name.lower().startswith(search_text.lower())]
493+
494+
490495
DataT = TypeVar('DataT')
491496

492497

zulipterminal/ui_tools/boxes.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
STREAM_TOPIC_SEPARATOR, TIME_MENTION_MARKER,
2121
)
2222
from zulipterminal.helper import (
23-
Message, format_string, match_emoji, match_group, match_stream, match_user,
23+
Message, format_string, match_emoji, match_group, match_stream,
24+
match_topics, match_user,
2425
)
2526
from zulipterminal.ui_tools.tables import render_table
2627
from zulipterminal.urwid_types import urwid_Size
@@ -95,6 +96,11 @@ def stream_box_view(self, stream_id: int, caption: str='', title: str='',
9596
)
9697
self.title_write_box = ReadlineEdit(caption="Topic: ",
9798
edit_text=title)
99+
self.title_write_box.enable_autocomplete(
100+
func=self._topic_box_autocomplete,
101+
key=keys_for_command('AUTOCOMPLETE').pop(),
102+
key_reverse=keys_for_command('AUTOCOMPLETE_REVERSE').pop()
103+
)
98104

99105
header_write_box = urwid.Columns([
100106
urwid.LineBox(
@@ -114,6 +120,16 @@ def stream_box_view(self, stream_id: int, caption: str='', title: str='',
114120
]
115121
self.contents = write_box
116122

123+
def _topic_box_autocomplete(self, text: str, state: Optional[int]
124+
) -> Optional[str]:
125+
topic_names = self.model.topics_in_stream(self.stream_id)
126+
127+
topic_typeaheads = match_topics(topic_names, text)
128+
129+
# Typeaheads and suggestions are the same.
130+
return self._process_typeaheads(topic_typeaheads, state,
131+
topic_typeaheads)
132+
117133
def _stream_box_autocomplete(self, text: str, state: Optional[int]
118134
) -> Optional[str]:
119135
streams_list = self.view.pinned_streams + self.view.unpinned_streams

0 commit comments

Comments
 (0)