diff options
Diffstat (limited to 'poezio/windows/info_bar.py')
-rw-r--r-- | poezio/windows/info_bar.py | 103 |
1 files changed, 83 insertions, 20 deletions
diff --git a/poezio/windows/info_bar.py b/poezio/windows/info_bar.py index 15821c10..6e6c3bbd 100644 --- a/poezio/windows/info_bar.py +++ b/poezio/windows/info_bar.py @@ -5,14 +5,19 @@ This window is the one listing the current opened tabs in poezio. The GlobalInfoBar can be either horizontal or vertical (VerticalGlobalInfoBar). """ +import curses +import itertools import logging -log = logging.getLogger(__name__) -import curses +from typing import List, Optional from poezio.config import config from poezio.windows.base_wins import Win from poezio.theming import get_theme, to_curses_attr +from poezio.common import unique_prefix_of +from poezio.colors import ccg_text_to_color + +log = logging.getLogger(__name__) class GlobalInfoBar(Win): @@ -25,42 +30,93 @@ class GlobalInfoBar(Win): def refresh(self) -> None: log.debug('Refresh: %s', self.__class__.__name__) self._win.erase() + theme = get_theme() self.addstr(0, 0, "[", - to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + to_curses_attr(theme.COLOR_INFORMATION_BAR)) - show_names = config.get('show_tab_names') - show_nums = config.get('show_tab_numbers') - use_nicks = config.get('use_tab_nicks') - show_inactive = config.get('show_inactive_tabs') + show_names = config.getbool('show_tab_names') + show_nums = config.getbool('show_tab_numbers') + use_nicks = config.getbool('use_tab_nicks') + show_inactive = config.getbool('show_inactive_tabs') + unique_prefix_tab_names = config.getbool('unique_prefix_tab_names') + autocolor_tab_names = config.getbool('autocolor_tab_names') + + if unique_prefix_tab_names: + unique_prefixes: List[Optional[str]] = [None] * len(self.core.tabs) + sorted_tab_indices = sorted( + (str(tab.name), i) + for i, tab in enumerate(self.core.tabs) + ) + prev_name = "" + for (name, i), next_item in itertools.zip_longest( + sorted_tab_indices, sorted_tab_indices[1:]): + # TODO: should this maybe use something smarter than .lower()? + # something something stringprep? + name = name.lower() + prefix_prev = unique_prefix_of(name, prev_name) + if next_item is not None: + prefix_next = unique_prefix_of(name, next_item[0].lower()) + else: + prefix_next = name[0] + + # to be unique, we have to use the longest prefix + if len(prefix_next) > len(prefix_prev): + prefix = prefix_next + else: + prefix = prefix_prev + + unique_prefixes[i] = prefix + prev_name = name for nb, tab in enumerate(self.core.tabs): if not tab: continue color = tab.color - if not show_inactive and color is get_theme().COLOR_TAB_NORMAL: + if not show_inactive and color is theme.COLOR_TAB_NORMAL and ( + tab.priority < 0): continue + if autocolor_tab_names: + # TODO: in case of private MUC conversations, we should try to + # get hold of more information to make the colour the same as + # the nickname colour in the MUC. + fgcolor, bgcolor, *flags = color + # this is fugly, but I’m not sure how to improve it... since + # apparently the state is only kept in the color -.- + if (color == theme.COLOR_TAB_HIGHLIGHT or + color == theme.COLOR_TAB_PRIVATE): + fgcolor = ccg_text_to_color(theme.ccg_palette, tab.name) + bgcolor = -1 + flags = theme.MODE_TAB_IMPORTANT + elif color == theme.COLOR_TAB_NEW_MESSAGE: + fgcolor = ccg_text_to_color(theme.ccg_palette, tab.name) + bgcolor = -1 + flags = theme.MODE_TAB_NORMAL + + color = (fgcolor, bgcolor) + tuple(flags) try: if show_nums or not show_names: self.addstr("%s" % str(nb), to_curses_attr(color)) if show_names: self.addstr(' ', to_curses_attr(color)) if show_names: - if use_nicks: + if unique_prefix_tab_names: + self.addstr(unique_prefixes[nb], to_curses_attr(color)) + elif use_nicks: self.addstr("%s" % str(tab.get_nick()), to_curses_attr(color)) else: self.addstr("%s" % tab.name, to_curses_attr(color)) self.addstr("|", - to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + to_curses_attr(theme.COLOR_INFORMATION_BAR)) except: # end of line break (y, x) = self._win.getyx() self.addstr(y, x - 1, '] ', - to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + to_curses_attr(theme.COLOR_INFORMATION_BAR)) (y, x) = self._win.getyx() remaining_size = self.width - x self.addnstr(' ' * remaining_size, remaining_size, - to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + to_curses_attr(theme.COLOR_INFORMATION_BAR)) self._refresh() @@ -76,17 +132,24 @@ class VerticalGlobalInfoBar(Win): height, width = self._win.getmaxyx() self._win.erase() sorted_tabs = [tab for tab in self.core.tabs if tab] - if not config.get('show_inactive_tabs'): + theme = get_theme() + if not config.getbool('show_inactive_tabs'): sorted_tabs = [ tab for tab in sorted_tabs - if tab.vertical_color != get_theme().COLOR_VERTICAL_TAB_NORMAL + if ( + tab.vertical_color != theme.COLOR_VERTICAL_TAB_NORMAL or + tab.priority > 0 + ) ] nb_tabs = len(sorted_tabs) - use_nicks = config.get('use_tab_nicks') + use_nicks = config.getbool('use_tab_nicks') if nb_tabs >= height: + # TODO: As sorted_tabs filters out gap tabs this ensures pos is + # always set, preventing UnboundLocalError. Now is this how this + # should be fixed. + pos = 0 for y, tab in enumerate(sorted_tabs): - if tab.vertical_color == get_theme( - ).COLOR_VERTICAL_TAB_CURRENT: + if tab.vertical_color == theme.COLOR_VERTICAL_TAB_CURRENT: pos = y break # center the current tab as much as possible @@ -96,20 +159,20 @@ class VerticalGlobalInfoBar(Win): sorted_tabs = sorted_tabs[-height:] else: sorted_tabs = sorted_tabs[pos - height // 2:pos + height // 2] - asc_sort = (config.get('vertical_tab_list_sort') == 'asc') + asc_sort = (config.getstr('vertical_tab_list_sort') == 'asc') for y, tab in enumerate(sorted_tabs): color = tab.vertical_color if asc_sort: y = height - y - 1 self.addstr(y, 0, "%2d" % tab.nb, - to_curses_attr(get_theme().COLOR_VERTICAL_TAB_NUMBER)) + to_curses_attr(theme.COLOR_VERTICAL_TAB_NUMBER)) self.addstr('.') if use_nicks: self.addnstr("%s" % tab.get_nick(), width - 4, to_curses_attr(color)) else: self.addnstr("%s" % tab.name, width - 4, to_curses_attr(color)) - separator = to_curses_attr(get_theme().COLOR_VERTICAL_SEPARATOR) + separator = to_curses_attr(theme.COLOR_VERTICAL_SEPARATOR) self._win.attron(separator) self._win.vline(0, width - 1, curses.ACS_VLINE, height) self._win.attroff(separator) |