lineedit: fix column display for wide and combining chars in TAB completion

function                                             old     new   delta
unicode_strwidth                                       -      20     +20
read_line_input                                     4945    4953      +8
unicode_strlen                                        31       -     -31
------------------------------------------------------------------------------
(add/remove: 1/1 grow/shrink: 1/0 up/down: 28/-31)             Total: -3 bytes

Signed-off-by: Tomas Heinrich <heinrich.tomas@gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Tomas Heinrich 2010-06-01 08:33:18 +02:00 committed by Denys Vlasenko
parent 39a04f71ca
commit 11bcf4b224
3 changed files with 25 additions and 7 deletions

View File

@ -24,6 +24,7 @@ enum {
#if !ENABLE_UNICODE_SUPPORT #if !ENABLE_UNICODE_SUPPORT
# define unicode_strlen(string) strlen(string) # define unicode_strlen(string) strlen(string)
# define unicode_strwidth(string) strlen(string)
# define unicode_status UNICODE_OFF # define unicode_status UNICODE_OFF
# define init_unicode() ((void)0) # define init_unicode() ((void)0)
@ -49,7 +50,10 @@ enum {
# define ENABLE_UNICODE_BIDI_SUPPORT 0 # define ENABLE_UNICODE_BIDI_SUPPORT 0
# endif # endif
/* Number of unicode chars. Falls back to strlen() on invalid unicode */
size_t FAST_FUNC unicode_strlen(const char *string); size_t FAST_FUNC unicode_strlen(const char *string);
/* Width on terminal */
size_t FAST_FUNC unicode_strwidth(const char *string);
enum { enum {
UNI_FLAG_PAD = (1 << 0), UNI_FLAG_PAD = (1 << 0),
}; };

View File

@ -992,7 +992,7 @@ static void showfiles(void)
/* find the longest file name - use that as the column width */ /* find the longest file name - use that as the column width */
for (row = 0; row < nrows; row++) { for (row = 0; row < nrows; row++) {
l = unicode_strlen(matches[row]); l = unicode_strwidth(matches[row]);
if (column_width < l) if (column_width < l)
column_width = l; column_width = l;
} }
@ -1012,9 +1012,12 @@ static void showfiles(void)
for (nc = 1; nc < ncols && n+nrows < nfiles; n += nrows, nc++) { for (nc = 1; nc < ncols && n+nrows < nfiles; n += nrows, nc++) {
printf("%s%-*s", matches[n], printf("%s%-*s", matches[n],
(int)(column_width - unicode_strlen(matches[n])), "" (int)(column_width - unicode_strwidth(matches[n])), ""
); );
} }
if (ENABLE_UNICODE_SUPPORT)
puts(printable_string(NULL, matches[n]));
else
puts(matches[n]); puts(matches[n]);
} }
} }

View File

@ -25,13 +25,15 @@ uint8_t unicode_status;
void FAST_FUNC init_unicode(void) void FAST_FUNC init_unicode(void)
{ {
/* In unicode, this is a one character string */
static const char unicode_0x394[] = { 0xce, 0x94, 0 }; static const char unicode_0x394[] = { 0xce, 0x94, 0 };
size_t width;
if (unicode_status != UNICODE_UNKNOWN) if (unicode_status != UNICODE_UNKNOWN)
return; return;
/* In unicode, this is a one character string */
unicode_status = unicode_strlen(unicode_0x394) == 1 ? UNICODE_ON : UNICODE_OFF; // can use unicode_strlen(string) too, but otherwise unicode_strlen() is unused
width = mbstowcs(NULL, unicode_0x394, INT_MAX);
unicode_status = (width == 1 ? UNICODE_ON : UNICODE_OFF);
} }
#else #else
@ -954,6 +956,7 @@ int FAST_FUNC unicode_bidi_is_neutral_wchar(wint_t wc)
/* The rest is mostly same for libc and for "homegrown" support */ /* The rest is mostly same for libc and for "homegrown" support */
#if 0 // UNUSED
size_t FAST_FUNC unicode_strlen(const char *string) size_t FAST_FUNC unicode_strlen(const char *string)
{ {
size_t width = mbstowcs(NULL, string, INT_MAX); size_t width = mbstowcs(NULL, string, INT_MAX);
@ -961,6 +964,14 @@ size_t FAST_FUNC unicode_strlen(const char *string)
return strlen(string); return strlen(string);
return width; return width;
} }
#endif
size_t FAST_FUNC unicode_strwidth(const char *string)
{
uni_stat_t uni_stat;
printable_string(&uni_stat, string);
return uni_stat.unicode_width;
}
static char* FAST_FUNC unicode_conv_to_printable2(uni_stat_t *stats, const char *src, unsigned width, int flags) static char* FAST_FUNC unicode_conv_to_printable2(uni_stat_t *stats, const char *src, unsigned width, int flags)
{ {