Migration of screen away from ad-hoc lists

This commit is contained in:
ridiculousfish 2011-12-27 18:41:38 -08:00
parent 451399b344
commit 46fa2dd2f0
9 changed files with 228 additions and 229 deletions

View file

@ -531,7 +531,7 @@ void write_screen( const wchar_t *msg, string_buffer_t *buff );
\param out the list in which to place the elements. \param out the list in which to place the elements.
*/ */
void tokenize_variable_array( const wchar_t *val, array_list_t *out ); void tokenize_variable_array( const wchar_t *val, array_list_t *out );
void tokenize_variable_array2( const wcstring &val, std::vector<wcstring> &out); void tokenize_variable_array2( const wcstring &val, wcstring_list_t &out);
/** /**
Make sure the specified direcotry exists. If needed, try to create Make sure the specified direcotry exists. If needed, try to create

41
env.cpp
View file

@ -428,8 +428,9 @@ static void setup_path()
{ {
wchar_t *path; wchar_t *path;
int i, j; size_t i;
array_list_t l; int j;
wcstring_list_t lst;
const wchar_t *path_el[] = const wchar_t *path_el[] =
{ {
@ -441,12 +442,10 @@ static void setup_path()
; ;
path = env_get( L"PATH" ); path = env_get( L"PATH" );
al_init( &l );
if( path ) if( path )
{ {
tokenize_variable_array( path, &l ); tokenize_variable_array2( path, lst );
} }
for( j=0; path_el[j]; j++ ) for( j=0; path_el[j]; j++ )
@ -454,10 +453,10 @@ static void setup_path()
int has_el=0; int has_el=0;
for( i=0; i<al_get_count( &l); i++ ) for( i=0; i<lst.size(); i++ )
{ {
wchar_t * el = (wchar_t *)al_get( &l, i ); wcstring el = lst.at(i);
size_t len = wcslen( el ); size_t len = el.size();
while( (len > 0) && (el[len-1]==L'/') ) while( (len > 0) && (el[len-1]==L'/') )
{ {
@ -465,7 +464,7 @@ static void setup_path()
} }
if( (wcslen( path_el[j] ) == len) && if( (wcslen( path_el[j] ) == len) &&
(wcsncmp( el, path_el[j], len)==0) ) (wcsncmp( el.c_str(), path_el[j], len)==0) )
{ {
has_el = 1; has_el = 1;
} }
@ -473,33 +472,25 @@ static void setup_path()
if( !has_el ) if( !has_el )
{ {
string_buffer_t b; wcstring buffer;
debug( 3, L"directory %ls was missing", path_el[j] ); debug( 3, L"directory %ls was missing", path_el[j] );
sb_init( &b );
if( path ) if( path )
{ {
sb_append( &b, path ); buffer += path;
} }
sb_append( &b, buffer += ARRAY_SEP_STR;
ARRAY_SEP_STR, buffer += path_el[j];
path_el[j] );
env_set( L"PATH", (wchar_t *)b.buff, ENV_GLOBAL | ENV_EXPORT ); env_set( L"PATH", buffer.c_str(), ENV_GLOBAL | ENV_EXPORT );
sb_destroy( &b );
al_foreach( &l, &free );
path = env_get( L"PATH" ); path = env_get( L"PATH" );
al_truncate( &l, 0 ); lst.resize(0);
tokenize_variable_array( path, &l ); tokenize_variable_array2( path, lst );
} }
} }
al_foreach( &l, &free );
al_destroy( &l );
} }
int env_set_pwd() int env_set_pwd()

View file

@ -208,22 +208,17 @@ static void check_connection()
*/ */
static void env_universal_remove_all() static void env_universal_remove_all()
{ {
array_list_t lst; size_t i;
int i;
al_init( &lst ); wcstring_list_t lst;
env_universal_common_get_names2( lst,
env_universal_common_get_names( &lst,
1, 1,
1 ); 1 );
for( i=0; i<lst.size(); i++ )
for( i=0; i<al_get_count( &lst ); i++ )
{ {
wchar_t *key = (wchar_t *)al_get( &lst, i ); const wcstring &key = lst.at(i);
env_universal_common_remove( key ); env_universal_common_remove( key.c_str() );
} }
al_destroy( &lst );
} }
@ -481,3 +476,16 @@ void env_universal_get_names( array_list_t *l,
show_exported, show_exported,
show_unexported ); show_unexported );
} }
void env_universal_get_names2( wcstring_list_t &lst,
int show_exported,
int show_unexported )
{
if( !init )
return;
env_universal_common_get_names2( lst,
show_exported,
show_unexported );
}

View file

@ -63,6 +63,9 @@ int env_universal_read_all();
void env_universal_get_names( array_list_t *l, void env_universal_get_names( array_list_t *l,
int show_exported, int show_exported,
int show_unexported ); int show_unexported );
void env_universal_get_names2( wcstring_list_t &list,
int show_exported,
int show_unexported );
/** /**
Synchronize with fishd Synchronize with fishd

View file

@ -907,6 +907,17 @@ static void add_key_to_hash( void *key,
al_push( (array_list_t *)aux, key ); al_push( (array_list_t *)aux, key );
} }
static void add_key_to_hash2( void *key,
void *data,
void *aux )
{
wcstring_list_t &lst = *(wcstring_list_t *)aux;
var_uni_entry_t *e = (var_uni_entry_t *)data;
if( ( e->exportv && get_names_show_exported) ||
( !e->exportv && get_names_show_unexported) )
lst.push_back((wchar_t *)key);
}
void env_universal_common_get_names( array_list_t *l, void env_universal_common_get_names( array_list_t *l,
int show_exported, int show_exported,
int show_unexported ) int show_unexported )
@ -919,6 +930,19 @@ void env_universal_common_get_names( array_list_t *l,
l ); l );
} }
void env_universal_common_get_names2( wcstring_list_t &lst,
int show_exported,
int show_unexported )
{
get_names_show_exported = show_exported;
get_names_show_unexported = show_unexported;
hash_foreach2( &env_universal_var,
add_key_to_hash2,
&lst );
}
wchar_t *env_universal_common_get( const wchar_t *name ) wchar_t *env_universal_common_get( const wchar_t *name )
{ {
var_uni_entry_t *e = (var_uni_entry_t *)hash_get( &env_universal_var, name ); var_uni_entry_t *e = (var_uni_entry_t *)hash_get( &env_universal_var, name );

View file

@ -152,6 +152,9 @@ void env_universal_common_destroy();
void env_universal_common_get_names( array_list_t *l, void env_universal_common_get_names( array_list_t *l,
int show_exported, int show_exported,
int show_unexported ); int show_unexported );
void env_universal_common_get_names2( wcstring_list_t &lst,
int show_exported,
int show_unexported );
/** /**
Perform the specified variable assignment. Perform the specified variable assignment.

View file

@ -177,8 +177,10 @@ commence.
states can be stacked, in case reader_readline() calls are states can be stacked, in case reader_readline() calls are
nested. This happens when the 'read' builtin is used. nested. This happens when the 'read' builtin is used.
*/ */
typedef struct reader_data class reader_data_t
{ {
public:
/** /**
Buffer containing the whole current commandline Buffer containing the whole current commandline
*/ */
@ -289,7 +291,7 @@ typedef struct reader_data
/** /**
Pointer to previous reader_data Pointer to previous reader_data
*/ */
struct reader_data *next; reader_data_t *next;
/** /**
This variable keeps state on if we are in search mode, and This variable keeps state on if we are in search mode, and
@ -302,8 +304,7 @@ typedef struct reader_data
which is known to require a repaint. which is known to require a repaint.
*/ */
int repaint_needed; int repaint_needed;
} };
reader_data_t;
/** /**
The current interactive reading context The current interactive reading context
@ -2267,20 +2268,20 @@ static int default_test( wchar_t *b )
void reader_push( const wchar_t *name ) void reader_push( const wchar_t *name )
{ {
reader_data_t *n = (reader_data_t *)calloc( 1, sizeof( reader_data_t ) ); // use placement new to guarantee zero initialization :(
void *buff = calloc(1, sizeof(reader_data_t));
if( !n ) if( !buff )
{ {
DIE_MEM(); DIE_MEM();
} }
reader_data_t *n = new(buff) reader_data_t;
n->name = wcsdup( name ); n->name = wcsdup( name );
n->next = data; n->next = data;
sb_init( &n->kill_item ); sb_init( &n->kill_item );
data=n; data=n;
s_init( &data->screen );
sb_init( &data->prompt_buff ); sb_init( &data->prompt_buff );
check_size(); check_size();
@ -2324,7 +2325,6 @@ void reader_pop()
sb_destroy( &n->search_buff ); sb_destroy( &n->search_buff );
sb_destroy( &n->kill_item ); sb_destroy( &n->kill_item );
s_destroy( &n->screen );
sb_destroy( &n->prompt_buff ); sb_destroy( &n->prompt_buff );
/* /*
@ -2334,6 +2334,8 @@ void reader_pop()
al_destroy( &n->search_prev ); al_destroy( &n->search_prev );
free( (void *)n->token_history_buff); free( (void *)n->token_history_buff);
/* Invoke the destructor to balance our placement new */
n->~reader_data_t();
free(n); free(n);
if( data == 0 ) if( data == 0 )

View file

@ -340,64 +340,13 @@ static void s_check_status( screen_t *s)
earlier value. earlier value.
*/ */
int prev_line = s->actual_cursor[1]; int prev_line = s->actual.cursor[1];
write_loop( 1, "\r", 1 ); write_loop( 1, "\r", 1 );
s_reset( s, 0 ); s_reset( s, 0 );
s->actual_cursor[1] = prev_line; s->actual.cursor[1] = prev_line;
} }
} }
/**
Free all memory used by one line_t struct.
*/
static void free_line( void *l )
{
line_t *line = (line_t *)l;
al_destroy( &line->text );
al_destroy( &line->color );
free( line );
}
/**
Clear the specified array of line_t structs.
*/
static void s_reset_arr( array_list_t *l )
{
al_foreach( l, &free_line );
al_truncate( l, 0 );
}
void s_init( screen_t *s )
{
CHECK( s, );
memset( s, 0, sizeof(screen_t));
sb_init( &s->actual_prompt );
}
void s_destroy( screen_t *s )
{
CHECK( s, );
s_reset_arr( &s->actual );
al_destroy( &s->actual );
s_reset_arr( &s->desired );
al_destroy( &s->desired );
sb_destroy( &s->actual_prompt );
}
/**
Allocate a new line_t struct.
*/
static line_t *s_create_line()
{
line_t *current = (line_t *)malloc( sizeof( line_t ));
al_init( &current->text );
al_init( &current->color );
return current;
}
/** /**
Appends a character to the end of the line that the output cursor is Appends a character to the end of the line that the output cursor is
on. This function automatically handles linebreaks and lines longer on. This function automatically handles linebreaks and lines longer
@ -409,17 +358,16 @@ static void s_desired_append_char( screen_t *s,
int indent, int indent,
int prompt_width ) int prompt_width )
{ {
int line_no = s->desired_cursor[1]; int line_no = s->desired.cursor[1];
switch( b ) switch( b )
{ {
case L'\n': case L'\n':
{ {
int i; int i;
line_t *current = s_create_line(); s->desired.add_line();
al_push( &s->desired, current ); s->desired.cursor[1]++;
s->desired_cursor[1]++; s->desired.cursor[0]=0;
s->desired_cursor[0]=0;
for( i=0; i < prompt_width+indent*INDENT_STEP; i++ ) for( i=0; i < prompt_width+indent*INDENT_STEP; i++ )
{ {
s_desired_append_char( s, L' ', 0, indent, prompt_width ); s_desired_append_char( s, L' ', 0, indent, prompt_width );
@ -429,43 +377,35 @@ static void s_desired_append_char( screen_t *s,
case L'\r': case L'\r':
{ {
line_t *current; line_t &current = s->desired.line(line_no);
current = (line_t *)al_get( &s->desired, line_no ); current.resize(0);
al_truncate( &current->text, 0 ); s->desired.cursor[0] = 0;
al_truncate( &current->color, 0 );
s->desired_cursor[0]=0;
break; break;
} }
default: default:
{ {
line_t *current;
int screen_width = common_get_width(); int screen_width = common_get_width();
int cw = wcwidth(b); int cw = wcwidth(b);
int ew = wcwidth( ellipsis_char ); int ew = wcwidth( ellipsis_char );
int i; int i;
current = (line_t *)al_get( &s->desired, line_no ); s->desired.create_line(line_no);
if( !current )
{
current = s_create_line();
al_push( &s->desired, current );
}
/* /*
Check if we are at the end of the line. If so, print an Check if we are at the end of the line. If so, print an
ellipsis character and continue on the next line. ellipsis character and continue on the next line.
*/ */
if( s->desired_cursor[0] + cw + ew > screen_width ) if( s->desired.cursor[0] + cw + ew > screen_width )
{ {
al_set_long( &current->text, s->desired_cursor[0], ellipsis_char ); line_entry_t &entry = s->desired.line(line_no).create_entry(s->desired.cursor[0]);
al_set_long( &current->color, s->desired_cursor[0], HIGHLIGHT_COMMENT ); entry.text = ellipsis_char;
entry.color = HIGHLIGHT_COMMENT;
current = s_create_line();
al_push( &s->desired, current ); line_no = s->desired.line_count();
s->desired_cursor[1]++; s->desired.add_line();
s->desired_cursor[0]=0; s->desired.cursor[1]++;
s->desired.cursor[0]=0;
for( i=0; i < (prompt_width-ew); i++ ) for( i=0; i < (prompt_width-ew); i++ )
{ {
s_desired_append_char( s, L' ', 0, indent, prompt_width ); s_desired_append_char( s, L' ', 0, indent, prompt_width );
@ -473,9 +413,10 @@ static void s_desired_append_char( screen_t *s,
s_desired_append_char( s, ellipsis_char, HIGHLIGHT_COMMENT, indent, prompt_width ); s_desired_append_char( s, ellipsis_char, HIGHLIGHT_COMMENT, indent, prompt_width );
} }
al_set_long( &current->text, s->desired_cursor[0], b ); line_t &line = s->desired.line(line_no);
al_set_long( &current->color, s->desired_cursor[0], c ); line.create_entry(s->desired.cursor[0]).text = b;
s->desired_cursor[0]+= cw; line.create_entry(s->desired.cursor[0]).color = c;
s->desired.cursor[0]+= cw;
break; break;
} }
} }
@ -517,7 +458,7 @@ static void s_move( screen_t *s, buffer_t *b, int new_x, int new_y )
output_set_writer( &s_writeb ); output_set_writer( &s_writeb );
s_writeb_buffer = b; s_writeb_buffer = b;
y_steps = new_y - s->actual_cursor[1]; y_steps = new_y - s->actual.cursor[1];
if( y_steps > 0 && (strcmp( cursor_down, "\n")==0)) if( y_steps > 0 && (strcmp( cursor_down, "\n")==0))
{ {
@ -528,7 +469,7 @@ static void s_move( screen_t *s, buffer_t *b, int new_x, int new_y )
as moving it down one step. The cursor_up does not have this as moving it down one step. The cursor_up does not have this
behaviour... behaviour...
*/ */
s->actual_cursor[0]=0; s->actual.cursor[0]=0;
} }
if( y_steps < 0 ) if( y_steps < 0 )
@ -547,7 +488,7 @@ static void s_move( screen_t *s, buffer_t *b, int new_x, int new_y )
} }
x_steps = new_x - s->actual_cursor[0]; x_steps = new_x - s->actual.cursor[0];
if( x_steps && new_x == 0 ) if( x_steps && new_x == 0 )
{ {
@ -570,8 +511,8 @@ static void s_move( screen_t *s, buffer_t *b, int new_x, int new_y )
} }
s->actual_cursor[0] = new_x; s->actual.cursor[0] = new_x;
s->actual_cursor[1] = new_y; s->actual.cursor[1] = new_y;
output_set_writer( writer_old ); output_set_writer( writer_old );
@ -605,7 +546,7 @@ static void s_write_char( screen_t *s, buffer_t *b, wchar_t c )
output_set_writer( &s_writeb ); output_set_writer( &s_writeb );
s_writeb_buffer = b; s_writeb_buffer = b;
s->actual_cursor[0]+=wcwidth( c ); s->actual.cursor[0]+=wcwidth( c );
writech( c ); writech( c );
@ -669,19 +610,18 @@ static void s_update( screen_t *scr, wchar_t *prompt )
s_reset( scr, 0 ); s_reset( scr, 0 );
} }
if( wcscmp( prompt, (wchar_t *)scr->actual_prompt.buff ) ) if( wcscmp( prompt, scr->actual_prompt.c_str() ) )
{ {
s_move( scr, &output, 0, 0 ); s_move( scr, &output, 0, 0 );
s_write_str( &output, prompt ); s_write_str( &output, prompt );
sb_clear( &scr->actual_prompt ); scr->actual_prompt = prompt;
sb_append( &scr->actual_prompt, prompt ); scr->actual.cursor[0] = prompt_width;
scr->actual_cursor[0] = prompt_width;
} }
for( i=0; i< al_get_count( &scr->desired ); i++ ) for (i=0; i < scr->desired.line_count(); i++)
{ {
line_t *o_line = (line_t *)al_get( &scr->desired, i ); line_t &o_line = scr->desired.line(i);
line_t *s_line = (line_t *)al_get( &scr->actual, i ); line_t &s_line = scr->actual.create_line(i);
int start_pos = (i==0?prompt_width:0); int start_pos = (i==0?prompt_width:0);
current_width = start_pos; current_width = start_pos;
@ -689,72 +629,64 @@ static void s_update( screen_t *scr, wchar_t *prompt )
{ {
s_move( scr, &output, start_pos, i ); s_move( scr, &output, start_pos, i );
s_write_mbs( &output, clr_eol); s_write_mbs( &output, clr_eol);
if( s_line ) s_line.resize(0);
{
al_truncate( &s_line->text, 0 );
al_truncate( &s_line->color, 0 );
}
} }
if( !s_line )
{
s_line = s_create_line();
al_push( &scr->actual, s_line );
}
for( j=start_pos; j<al_get_count( &o_line->text ); j++ )
{
wchar_t o = (wchar_t)(intptr_t)al_get( &o_line->text, j );
int o_c = (int)(intptr_t)al_get( &o_line->color, j );
for( j=start_pos; j<o_line.entry_count(); j++)
{
line_entry_t &entry = o_line.entry(j);
wchar_t o = entry.text;
int o_c = entry.color;
if( !o ) if( !o )
continue; continue;
if( al_get_count( &s_line->text ) == j ) if( s_line.entry_count() == j )
{ {
s_move( scr, &output, current_width, 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 ); s_line.create_entry(j).text = o;
al_set_long( &s_line->color, j, o_c ); s_line.create_entry(j).color = o_c;
} }
else else
{ {
wchar_t s = (wchar_t)(intptr_t)al_get( &s_line->text, j ); line_entry_t &entry = s_line.create_entry(j);
int s_c = (int)(intptr_t)al_get( &s_line->color, j ); wchar_t s = entry.text;
int s_c = entry.color;
if( o != s || o_c != s_c ) if( o != s || o_c != s_c )
{ {
s_move( scr, &output, current_width, 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, current_width, o );
al_set_long( &s_line->color, current_width, o_c ); s_line.create_entry(current_width).text = o;
s_line.create_entry(current_width).color = o_c;
for( k=1; k<wcwidth(o); k++ ) for( k=1; k<wcwidth(o); k++ )
al_set_long( &s_line->text, current_width+k, L'\0' ); s_line.create_entry(current_width+k).text = L'\0';
} }
} }
current_width += wcwidth( o ); current_width += wcwidth( o );
} }
if( al_get_count( &s_line->text ) > al_get_count( &o_line->text ) ) if ( s_line.entry_count() > o_line.entry_count() )
{ {
s_move( scr, &output, current_width, 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 ) ); s_line.resize(o_line.entry_count());
} }
} }
for( i=al_get_count( &scr->desired ); i< al_get_count( &scr->actual ); i++ ) for( i=scr->desired.line_count(); i < scr->actual.line_count(); i++ )
{ {
line_t *s_line = (line_t *)al_get( &scr->actual, i ); line_t &s_line = scr->actual.create_line(i);
s_move( scr, &output, 0, i ); s_move( scr, &output, 0, i );
s_write_mbs( &output, clr_eol); s_write_mbs( &output, clr_eol);
al_truncate( &s_line->text, 0 ); s_line.resize(0);
} }
s_move( scr, &output, scr->desired_cursor[0], scr->desired_cursor[1] ); s_move( scr, &output, scr->desired.cursor[0], scr->desired.cursor[1] );
s_set_color( scr, &output, 0xffffffff); s_set_color( scr, &output, 0xffffffff);
@ -864,8 +796,8 @@ void s_write( screen_t *s,
if( current_line_width > max_line_width ) if( current_line_width > max_line_width )
max_line_width = current_line_width; max_line_width = current_line_width;
s_reset_arr( &s->desired ); s->desired.resize(0);
s->desired_cursor[0] = s->desired_cursor[1] = 0; s->desired.cursor[0] = s->desired.cursor[1] = 0;
/* /*
If overflowing, give the prompt its own line to improve the If overflowing, give the prompt its own line to improve the
@ -897,13 +829,13 @@ void s_write( screen_t *s,
if( i == cursor ) if( i == cursor )
{ {
cursor_arr[0] = s->desired_cursor[0]; cursor_arr[0] = s->desired.cursor[0];
cursor_arr[1] = s->desired_cursor[1]; cursor_arr[1] = s->desired.cursor[1];
} }
s_desired_append_char( s, b[i], col, indent[i], prompt_width ); s_desired_append_char( s, b[i], col, indent[i], prompt_width );
if( i== cursor && s->desired_cursor[1] != cursor_arr[1] && b[i] != L'\n' ) if( i== cursor && s->desired.cursor[1] != cursor_arr[1] && b[i] != L'\n' )
{ {
/* /*
Ugh. We are placed exactly at the wrapping point of a Ugh. We are placed exactly at the wrapping point of a
@ -911,17 +843,17 @@ void s_write( screen_t *s,
cursor won't be on the ellipsis which looks cursor won't be on the ellipsis which looks
unintuitive. unintuitive.
*/ */
cursor_arr[0] = s->desired_cursor[0] - wcwidth(b[i]); cursor_arr[0] = s->desired.cursor[0] - wcwidth(b[i]);
cursor_arr[1] = s->desired_cursor[1]; cursor_arr[1] = s->desired.cursor[1];
} }
} }
if( i == cursor ) if( i == cursor )
{ {
memcpy(cursor_arr, s->desired_cursor, sizeof(int)*2); memcpy(cursor_arr, s->desired.cursor, sizeof(int)*2);
} }
memcpy( s->desired_cursor, cursor_arr, sizeof(int)*2 ); memcpy( s->desired.cursor, cursor_arr, sizeof(int)*2 );
s_update( s, prompt ); s_update( s, prompt );
s_save_status( s ); s_save_status( s );
} }
@ -930,10 +862,10 @@ void s_reset( screen_t *s, int reset_cursor )
{ {
CHECK( s, ); CHECK( s, );
int prev_line = s->actual_cursor[1]; int prev_line = s->actual.cursor[1];
s_reset_arr( &s->actual ); s->actual.resize(0);
s->actual_cursor[0] = s->actual_cursor[1] = 0; s->actual.cursor[0] = s->actual.cursor[1] = 0;
sb_clear( &s->actual_prompt ); s->actual_prompt = L"";
s->need_clear=1; s->need_clear=1;
if( !reset_cursor ) if( !reset_cursor )
@ -943,7 +875,7 @@ void s_reset( screen_t *s, int reset_cursor )
next repaint. next repaint.
*/ */
write_loop( 1, "\r", 1 ); write_loop( 1, "\r", 1 );
s->actual_cursor[1] = prev_line; s->actual.cursor[1] = prev_line;
} }
fstat( 1, &s->prev_buff_1 ); fstat( 1, &s->prev_buff_1 );
fstat( 2, &s->prev_buff_2 ); fstat( 2, &s->prev_buff_2 );

120
screen.h
View file

@ -12,6 +12,79 @@
#ifndef FISH_SCREEN_H #ifndef FISH_SCREEN_H
#define FISH_SCREEN_H #define FISH_SCREEN_H
#include <vector>
struct line_entry_t
{
wchar_t text;
int color;
};
/**
A class representing a single line of a screen.
*/
class line_t
{
public:
std::vector<struct line_entry_t> entries;
void resize(size_t size) {
entries.resize(size);
}
line_entry_t &entry(size_t idx) {
return entries.at(idx);
}
line_entry_t &create_entry(size_t idx) {
if (idx >= entries.size()) {
entries.resize(idx + 1);
}
return entries.at(idx);
}
size_t entry_count(void) {
return entries.size();
}
};
/**
A class representing screen contents.
*/
class screen_data_t
{
std::vector<line_t> line_datas;
public:
int cursor[2];
line_t &add_line(void) {
line_datas.resize(line_datas.size() + 1);
return line_datas.back();
}
void resize(size_t size) {
line_datas.resize(size);
}
line_t &create_line(size_t idx) {
if (idx >= line_datas.size()) {
line_datas.resize(idx + 1);
}
return line_datas.at(idx);
}
line_t &line(size_t idx) {
return line_datas.at(idx);
}
size_t line_count(void) {
return line_datas.size();
}
};
/** /**
The struct representing the current and desired screen contents. The struct representing the current and desired screen contents.
*/ */
@ -20,24 +93,17 @@ typedef struct
/** /**
The internal representation of the desired screen contents. The internal representation of the desired screen contents.
*/ */
array_list_t desired; screen_data_t desired;
/** /**
The internal representation of the actual screen contents. The internal representation of the actual screen contents.
*/ */
array_list_t actual; screen_data_t actual;
/** /**
The desired cursor position. A string containing the prompt which was last printed to
*/
int desired_cursor[2];
/**
The actual cursor position.
*/
int actual_cursor[2];
/**
A stringbuffer containing the prompt which was last printed to
the screen. the screen.
*/ */
string_buffer_t actual_prompt; wcstring actual_prompt;
/** /**
The actual width of the screen at the time of the last screen The actual width of the screen at the time of the last screen
@ -61,36 +127,6 @@ typedef struct
} }
screen_t; screen_t;
/**
A struct representing a single line of a screen. Consists of two
array_lists, which must always be of the same length.
*/
typedef struct
{
/**
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;
/**
Highlight information for the line
*/
array_list_t color;
}
line_t;
/**
Initialize a new screen struct
*/
void s_init( screen_t *s );
/**
Free all memory used by the specified screen struct
*/
void s_destroy( screen_t *s );
/** /**
This is the main function for the screen putput library. It is used This is the main function for the screen putput library. It is used
to define the desired contents of the screen. The screen command to define the desired contents of the screen. The screen command