summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/source/keys.rst9
-rw-r--r--poezio/core/core.py29
2 files changed, 38 insertions, 0 deletions
diff --git a/doc/source/keys.rst b/doc/source/keys.rst
index dc5fa35b..03ab2071 100644
--- a/doc/source/keys.rst
+++ b/doc/source/keys.rst
@@ -374,6 +374,15 @@ Actions list
Similar to F4.
+**_go_to_room_name**: Jump to a tab by unique prefix.
+
+ Similar to :term:`/wup` and the default *Alt-j*. This action will take
+ input as long as there is at least one tab name starting with the input
+ given so far. If there is exactly one tab matching, the action completes
+ and the current tab is switched over to the tab matching the input. If
+ no tab matches, the action completes without any change. This means that
+ you can typically abort the action with Escape.
+
Status actions
~~~~~~~~~~~~~~
diff --git a/poezio/core/core.py b/poezio/core/core.py
index eac9d539..8ac88dd4 100644
--- a/poezio/core/core.py
+++ b/poezio/core/core.py
@@ -209,6 +209,7 @@ class Core:
'_show_plugins': self.command.plugins,
'_show_xmltab': self.command.xml_tab,
'_toggle_pane': self.toggle_left_pane,
+ "_go_to_room_name": self.go_to_room_name,
###### status actions ######
'_available': lambda: self.command.status('available'),
'_away': lambda: self.command.status('away'),
@@ -1108,6 +1109,34 @@ class Core:
keyboard.continuation_keys_callback = read_next_digit
+ def go_to_room_name(self) -> None:
+ room_name_jump = []
+
+ def read_next_letter(s) -> None:
+ nonlocal room_name_jump
+ room_name_jump.append(s)
+ any_matched, unique_tab = self.tabs.find_by_unique_prefix(
+ "".join(room_name_jump)
+ )
+
+ if not any_matched:
+ return
+
+ if unique_tab is not None:
+ self.tabs.set_current_tab(unique_tab)
+ # NOTE: returning here means that as soon as the tab is
+ # matched, normal input resumes. If we do *not* return here,
+ # any further characters matching the prefix of the tab will
+ # be swallowed (and a lot of tab switching will happen...),
+ # until a non-matching character or escape or something is
+ # pressed.
+ # This behaviour *may* be desirable.
+ return
+
+ keyboard.continuation_keys_callback = read_next_letter
+
+ keyboard.continuation_keys_callback = read_next_letter
+
def go_to_roster(self) -> None:
"Select the roster as the current tab"
self.tabs.set_current_tab(self.tabs.first())