aegirhall / console-menu

A simple Python menu system for building terminal user interfaces.
MIT License
365 stars 58 forks source link

Add support for Unicode wide characters #85

Open keatonLiu opened 1 year ago

keatonLiu commented 1 year ago

Modify MenuComponent class:

def _format_content(self, content='', align='left'):
    # remove color str which is invisible and get the actual len of content(wide char counts for 2)
    len_visible_chars = sum(get_width(ord(ch)) for ch in strip_color(content))
    len_invisible_chars = len(content) - len_visible_chars
    return '{lp}{text:{al}{width}}{rp}'.format(lp=' ' * self.padding.left,
                                               rp=' ' * self.padding.right,
                                               text=content, al=self._alignment_char(align),
                                               width=(self.calculate_border_width() - self.padding.left -
                                                      self.padding.right - 2 + len_invisible_chars))
aegirhall commented 1 year ago

Hi @keatonLiu,

On this line:

len_visible_chars = sum(get_width(ord(ch)) for ch in strip_color(content))

what package is get_width() from?

keatonLiu commented 1 year ago

from ansiwrap import strip_color
from urwid import calc_width

def getVisibleLength(text: str):
    text = strip_color(text)
    return calc_width(text, 0, len(text))

def _format_content(self, content='', align='left'):
    # remove color str which is invisible and get the actual len of content(wide char counts for 2)
    len_visible_chars = getVisibleLength(content)
    len_invisible_chars = len(content) - len_visible_chars
    return '{lp}{text:{al}{width}}{rp}'.format(lp=' ' * self.padding.left,
                                               rp=' ' * self.padding.right,
                                               text=content, al=self._alignment_char(align),
                                               width=(self.calculate_border_width() - self.padding.left -
                                                      self.padding.right - 2 + len_invisible_chars))