Various fixes to make double-wide characters (e.g. asian characters) work with the new multiline editing code

darcs-hash:20061001232136-ac50b-9bd771b382c00b71c5e2ee75df77ba2594b2a738.gz
This commit is contained in:
axel 2006-10-02 09:21:36 +10:00
parent 44ff9956b9
commit 13b1ea3f50
2 changed files with 36 additions and 15 deletions

View file

@ -306,8 +306,8 @@ static void s_desired_append_char( screen_t *s,
*/ */
if( s->desired_cursor[0] + cw + ew > screen_width ) if( s->desired_cursor[0] + cw + ew > screen_width )
{ {
al_push_long( &current->text, ellipsis_char ); al_set_long( &current->text, s->desired_cursor[0], ellipsis_char );
al_push_long( &current->color, 0 ); al_set_long( &current->color, s->desired_cursor[0], 0 );
current = s_create_line(); current = s_create_line();
al_push( &s->desired, current ); al_push( &s->desired, current );
@ -320,8 +320,8 @@ static void s_desired_append_char( screen_t *s,
s_desired_append_char( s, ellipsis_char, 0, prompt_width ); s_desired_append_char( s, ellipsis_char, 0, prompt_width );
} }
al_push_long( &current->text, b ); al_set_long( &current->text, s->desired_cursor[0], b );
al_push_long( &current->color, c ); al_set_long( &current->color, s->desired_cursor[0], c );
s->desired_cursor[0]+= cw; s->desired_cursor[0]+= cw;
break; break;
} }
@ -487,8 +487,9 @@ static void s_write_str( buffer_t *b, wchar_t *s )
*/ */
static void s_update( screen_t *scr, wchar_t *prompt ) static void s_update( screen_t *scr, wchar_t *prompt )
{ {
int i, j; int i, j, k;
int prompt_width = calc_prompt_width( prompt ); int prompt_width = calc_prompt_width( prompt );
int current_width=0;
buffer_t output; buffer_t output;
b_init( &output ); b_init( &output );
@ -506,19 +507,26 @@ static void s_update( screen_t *scr, wchar_t *prompt )
{ {
line_t *o_line = (line_t *)al_get( &scr->desired, i ); line_t *o_line = (line_t *)al_get( &scr->desired, i );
line_t *s_line = (line_t *)al_get( &scr->actual, i ); line_t *s_line = (line_t *)al_get( &scr->actual, i );
int start_pos = (i==0?prompt_width:0);
current_width = start_pos;
if( !s_line ) if( !s_line )
{ {
s_line = s_create_line(); s_line = s_create_line();
al_push( &scr->actual, s_line ); al_push( &scr->actual, s_line );
} }
for( j=(i==0?prompt_width:0); j<al_get_count( &o_line->text ); j++ )
for( j=start_pos; j<al_get_count( &o_line->text ); j++ )
{ {
wchar_t o = (wchar_t)al_get( &o_line->text, j ); wchar_t o = (wchar_t)al_get( &o_line->text, j );
int o_c = (int)al_get( &o_line->color, j ); int o_c = (int)al_get( &o_line->color, j );
if( !o )
continue;
if( al_get_count( &s_line->text ) == j ) if( al_get_count( &s_line->text ) == j )
{ {
s_move( scr, &output, j, i ); s_move( scr, &output, current_width, i );
s_set_color( scr, &output, o_c ); s_set_color( scr, &output, o_c );
s_write_char( scr, &output, o ); s_write_char( scr, &output, o );
al_set_long( &s_line->text, j, o ); al_set_long( &s_line->text, j, o );
@ -530,18 +538,22 @@ static void s_update( screen_t *scr, wchar_t *prompt )
int s_c = (int)al_get( &s_line->color, j ); int s_c = (int)al_get( &s_line->color, j );
if( o != s || o_c != s_c ) if( o != s || o_c != s_c )
{ {
s_move( scr, &output, j, i ); s_move( scr, &output, current_width, i );
s_set_color( scr, &output, o_c ); s_set_color( scr, &output, o_c );
s_write_char( scr, &output, o ); s_write_char( scr, &output, o );
al_set_long( &s_line->text, j, o ); al_set_long( &s_line->text, current_width, o );
al_set_long( &s_line->color, j, o_c ); al_set_long( &s_line->color, current_width, o_c );
for( k=1; k<wcwidth(o); k++ )
al_set_long( &s_line->text, current_width+k, L'\0' );
} }
} }
current_width += wcwidth( o );
} }
if( al_get_count( &s_line->text ) > al_get_count( &o_line->text ) ) if( al_get_count( &s_line->text ) > al_get_count( &o_line->text ) )
{ {
s_move( scr, &output, al_get_count( &o_line->text ), i ); s_move( scr, &output, current_width, i );
s_write_mbs( &output, clr_eol); s_write_mbs( &output, clr_eol);
al_truncate( &s_line->text, al_get_count( &o_line->text ) ); al_truncate( &s_line->text, al_get_count( &o_line->text ) );
} }
@ -612,11 +624,17 @@ void s_write( screen_t *s,
if( i == cursor ) if( i == cursor )
{ {
memcpy(cursor_arr, s->desired_cursor, sizeof(int)*2);
col = 0; col = 0;
} }
s_desired_append_char( s, b[i], col, prompt_width ); s_desired_append_char( s, b[i], col, prompt_width );
if( i == cursor )
{
cursor_arr[0] = s->desired_cursor[0] - wcwidth(b[i]);
cursor_arr[1] = s->desired_cursor[1];
}
} }
if( i == cursor ) if( i == cursor )

View file

@ -44,7 +44,10 @@ typedef struct
typedef struct typedef struct
{ {
/** /**
The text contents of the line The text contents of the line. Each element of the array
represents on column of output. Because some characters are two
columns wide, it is perfectly possible for some of the comumns
to be empty.
*/ */
array_list_t text; array_list_t text;
/** /**