diff --git a/common.cpp b/common.cpp index b8dc4ceb7..de1c06124 100644 --- a/common.cpp +++ b/common.cpp @@ -88,6 +88,8 @@ struct termios shell_modes; static pthread_t main_thread_id = 0; static bool thread_assertions_configured_for_testing = false; +wchar_t ellipsis_char; + char *profile=0; const wchar_t *program_name; @@ -502,6 +504,12 @@ wcstring wsetlocale(int category, const wchar_t *locale) char * res = setlocale(category,lang); free( lang ); + /* + Use ellipsis if on known unicode system, otherwise use $ + */ + char *ctype = setlocale( LC_CTYPE, NULL ); + ellipsis_char = (strstr( ctype, ".UTF")||strstr( ctype, ".utf") )?L'\x2026':L'$'; + if( !res ) return wcstring(); else @@ -753,6 +761,7 @@ void write_screen( const wcstring &msg, wcstring &buff ) int line_width = 0; int tok_width = 0; int screen_width = common_get_width(); + if( screen_width ) { start = pos = msg.c_str(); diff --git a/common.h b/common.h index 313ffba75..b0bf0593c 100644 --- a/common.h +++ b/common.h @@ -89,6 +89,12 @@ void exit_without_destructors(int code) __attribute__ ((noreturn)); */ extern struct termios shell_modes; +/** + The character to use where the text has been truncated. Is an + ellipsis on unicode system and a $ on other systems. +*/ +extern wchar_t ellipsis_char; + /** The verbosity level of fish. If a call to debug has a severity level higher than \c debug_level, it will not be printed. @@ -564,7 +570,9 @@ void error_reset(); /** This function behaves exactly like a wide character equivalent of - the C function setlocale. + the C function setlocale, except that it will also try to detect if + the user is using a Unicode character set, and if so, use the + unicode ellipsis character as ellipsis, instead of '$'. */ wcstring wsetlocale( int category, const wchar_t *locale ); diff --git a/fish_pager.cpp b/fish_pager.cpp index 764ca1818..4fc0a44cc 100644 --- a/fish_pager.cpp +++ b/fish_pager.cpp @@ -377,6 +377,8 @@ static int print_max( const wchar_t *str, int max, int has_more ) break; if( ( written + wcwidth(str[i]) == max) && (has_more || str[i+1]) ) { + writech( ellipsis_char ); + written += wcwidth(ellipsis_char ); break; } diff --git a/output.cpp b/output.cpp index 9ce7f7ab3..b061693e4 100644 --- a/output.cpp +++ b/output.cpp @@ -489,6 +489,43 @@ void writestr( const wchar_t *str ) delete[] buffer; } + +void writestr_ellipsis( const wchar_t *str, int max_width ) +{ + int written=0; + int tot; + + CHECK( str, ); + + tot = my_wcswidth(str); + + if( tot <= max_width ) + { + writestr( str ); + return; + } + + while( *str != 0 ) + { + int w = fish_wcwidth( *str ); + if( written+w+fish_wcwidth( ellipsis_char )>max_width ) + { + break; + } + written+=w; + writech( *(str++) ); + } + + written += fish_wcwidth( ellipsis_char ); + writech( ellipsis_char ); + + while( written < max_width ) + { + written++; + writestr( L" " ); + } +} + int write_escaped_str( const wchar_t *str, int max_len ) { @@ -509,6 +546,8 @@ int write_escaped_str( const wchar_t *str, int max_len ) writech( out[i] ); written += fish_wcwidth( out[i] ); } + writech( ellipsis_char ); + written += fish_wcwidth( ellipsis_char ); for( i=written; i &comp ) else { // append just the end of the string + prefix = wcstring(&ellipsis_char, 1); prefix.append(data->command_line, prefix_start + len - PREFIX_MAX_LEN, wcstring::npos); } diff --git a/screen.cpp b/screen.cpp index 9c53decb2..0bc102d1f 100644 --- a/screen.cpp +++ b/screen.cpp @@ -968,6 +968,7 @@ void s_write( screen_t *s, assert(screen_width - prompt_width >= 1); max_line_width = screen_width - prompt_width - 1; truncated_autosuggestion_line = wcstring(commandline, 0, last_char_that_fits); + truncated_autosuggestion_line.push_back(ellipsis_char); commandline = truncated_autosuggestion_line.c_str(); } for( size_t i=0; idesired.cursor.y != cursor_arr.y && commandline[i] != L'\n' ) + { + /* + Ugh. We are placed exactly at the wrapping point of a + wrapped line, move cursor to the line below so the + cursor won't be on the ellipsis which looks + unintuitive. + */ + cursor_arr.x = s->desired.cursor.x - fish_wcwidth(commandline[i]); + cursor_arr.y = s->desired.cursor.y; + } } if( i == cursor_pos ) {