mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-27 20:25:12 +00:00
Migration of screen away from ad-hoc lists
This commit is contained in:
parent
451399b344
commit
46fa2dd2f0
9 changed files with 228 additions and 229 deletions
2
common.h
2
common.h
|
@ -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.
|
||||
*/
|
||||
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
|
||||
|
|
39
env.cpp
39
env.cpp
|
@ -428,8 +428,9 @@ static void setup_path()
|
|||
{
|
||||
wchar_t *path;
|
||||
|
||||
int i, j;
|
||||
array_list_t l;
|
||||
size_t i;
|
||||
int j;
|
||||
wcstring_list_t lst;
|
||||
|
||||
const wchar_t *path_el[] =
|
||||
{
|
||||
|
@ -442,11 +443,9 @@ static void setup_path()
|
|||
|
||||
path = env_get( L"PATH" );
|
||||
|
||||
al_init( &l );
|
||||
|
||||
if( path )
|
||||
{
|
||||
tokenize_variable_array( path, &l );
|
||||
tokenize_variable_array2( path, lst );
|
||||
}
|
||||
|
||||
for( j=0; path_el[j]; j++ )
|
||||
|
@ -454,10 +453,10 @@ static void setup_path()
|
|||
|
||||
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 );
|
||||
size_t len = wcslen( el );
|
||||
wcstring el = lst.at(i);
|
||||
size_t len = el.size();
|
||||
|
||||
while( (len > 0) && (el[len-1]==L'/') )
|
||||
{
|
||||
|
@ -465,7 +464,7 @@ static void setup_path()
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -473,33 +472,25 @@ static void setup_path()
|
|||
|
||||
if( !has_el )
|
||||
{
|
||||
string_buffer_t b;
|
||||
wcstring buffer;
|
||||
|
||||
debug( 3, L"directory %ls was missing", path_el[j] );
|
||||
|
||||
sb_init( &b );
|
||||
if( path )
|
||||
{
|
||||
sb_append( &b, path );
|
||||
buffer += path;
|
||||
}
|
||||
|
||||
sb_append( &b,
|
||||
ARRAY_SEP_STR,
|
||||
path_el[j] );
|
||||
buffer += ARRAY_SEP_STR;
|
||||
buffer += 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" );
|
||||
al_truncate( &l, 0 );
|
||||
tokenize_variable_array( path, &l );
|
||||
lst.resize(0);
|
||||
tokenize_variable_array2( path, lst );
|
||||
}
|
||||
}
|
||||
|
||||
al_foreach( &l, &free );
|
||||
al_destroy( &l );
|
||||
}
|
||||
|
||||
int env_set_pwd()
|
||||
|
|
|
@ -208,23 +208,18 @@ static void check_connection()
|
|||
*/
|
||||
static void env_universal_remove_all()
|
||||
{
|
||||
array_list_t lst;
|
||||
int i;
|
||||
size_t i;
|
||||
|
||||
al_init( &lst );
|
||||
|
||||
env_universal_common_get_names( &lst,
|
||||
wcstring_list_t lst;
|
||||
env_universal_common_get_names2( lst,
|
||||
1,
|
||||
1 );
|
||||
|
||||
for( i=0; i<al_get_count( &lst ); i++ )
|
||||
for( i=0; i<lst.size(); i++ )
|
||||
{
|
||||
wchar_t *key = (wchar_t *)al_get( &lst, i );
|
||||
env_universal_common_remove( key );
|
||||
const wcstring &key = lst.at(i);
|
||||
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_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 );
|
||||
}
|
||||
|
|
|
@ -63,6 +63,9 @@ int env_universal_read_all();
|
|||
void env_universal_get_names( array_list_t *l,
|
||||
int show_exported,
|
||||
int show_unexported );
|
||||
void env_universal_get_names2( wcstring_list_t &list,
|
||||
int show_exported,
|
||||
int show_unexported );
|
||||
|
||||
/**
|
||||
Synchronize with fishd
|
||||
|
|
|
@ -907,6 +907,17 @@ static void add_key_to_hash( void *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,
|
||||
int show_exported,
|
||||
int show_unexported )
|
||||
|
@ -919,6 +930,19 @@ void env_universal_common_get_names( array_list_t *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 )
|
||||
{
|
||||
var_uni_entry_t *e = (var_uni_entry_t *)hash_get( &env_universal_var, name );
|
||||
|
|
|
@ -152,6 +152,9 @@ void env_universal_common_destroy();
|
|||
void env_universal_common_get_names( array_list_t *l,
|
||||
int show_exported,
|
||||
int show_unexported );
|
||||
void env_universal_common_get_names2( wcstring_list_t &lst,
|
||||
int show_exported,
|
||||
int show_unexported );
|
||||
|
||||
/**
|
||||
Perform the specified variable assignment.
|
||||
|
|
20
reader.cpp
20
reader.cpp
|
@ -177,8 +177,10 @@ commence.
|
|||
states can be stacked, in case reader_readline() calls are
|
||||
nested. This happens when the 'read' builtin is used.
|
||||
*/
|
||||
typedef struct reader_data
|
||||
class reader_data_t
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
Buffer containing the whole current commandline
|
||||
*/
|
||||
|
@ -289,7 +291,7 @@ typedef struct 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
|
||||
|
@ -302,8 +304,7 @@ typedef struct reader_data
|
|||
which is known to require a repaint.
|
||||
*/
|
||||
int repaint_needed;
|
||||
}
|
||||
reader_data_t;
|
||||
};
|
||||
|
||||
/**
|
||||
The current interactive reading context
|
||||
|
@ -2267,12 +2268,13 @@ static int default_test( wchar_t *b )
|
|||
|
||||
void reader_push( const wchar_t *name )
|
||||
{
|
||||
reader_data_t *n = (reader_data_t *)calloc( 1, sizeof( reader_data_t ) );
|
||||
|
||||
if( !n )
|
||||
// use placement new to guarantee zero initialization :(
|
||||
void *buff = calloc(1, sizeof(reader_data_t));
|
||||
if( !buff )
|
||||
{
|
||||
DIE_MEM();
|
||||
}
|
||||
reader_data_t *n = new(buff) reader_data_t;
|
||||
|
||||
n->name = wcsdup( name );
|
||||
n->next = data;
|
||||
|
@ -2280,7 +2282,6 @@ void reader_push( const wchar_t *name )
|
|||
|
||||
data=n;
|
||||
|
||||
s_init( &data->screen );
|
||||
sb_init( &data->prompt_buff );
|
||||
|
||||
check_size();
|
||||
|
@ -2324,7 +2325,6 @@ void reader_pop()
|
|||
sb_destroy( &n->search_buff );
|
||||
sb_destroy( &n->kill_item );
|
||||
|
||||
s_destroy( &n->screen );
|
||||
sb_destroy( &n->prompt_buff );
|
||||
|
||||
/*
|
||||
|
@ -2334,6 +2334,8 @@ void reader_pop()
|
|||
al_destroy( &n->search_prev );
|
||||
free( (void *)n->token_history_buff);
|
||||
|
||||
/* Invoke the destructor to balance our placement new */
|
||||
n->~reader_data_t();
|
||||
free(n);
|
||||
|
||||
if( data == 0 )
|
||||
|
|
208
screen.cpp
208
screen.cpp
|
@ -340,64 +340,13 @@ static void s_check_status( screen_t *s)
|
|||
earlier value.
|
||||
*/
|
||||
|
||||
int prev_line = s->actual_cursor[1];
|
||||
int prev_line = s->actual.cursor[1];
|
||||
write_loop( 1, "\r", 1 );
|
||||
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( ¤t->text );
|
||||
al_init( ¤t->color );
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
Appends a character to the end of the line that the output cursor is
|
||||
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 prompt_width )
|
||||
{
|
||||
int line_no = s->desired_cursor[1];
|
||||
int line_no = s->desired.cursor[1];
|
||||
|
||||
switch( b )
|
||||
{
|
||||
case L'\n':
|
||||
{
|
||||
int i;
|
||||
line_t *current = s_create_line();
|
||||
al_push( &s->desired, current );
|
||||
s->desired_cursor[1]++;
|
||||
s->desired_cursor[0]=0;
|
||||
s->desired.add_line();
|
||||
s->desired.cursor[1]++;
|
||||
s->desired.cursor[0]=0;
|
||||
for( i=0; i < prompt_width+indent*INDENT_STEP; i++ )
|
||||
{
|
||||
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':
|
||||
{
|
||||
line_t *current;
|
||||
current = (line_t *)al_get( &s->desired, line_no );
|
||||
al_truncate( ¤t->text, 0 );
|
||||
al_truncate( ¤t->color, 0 );
|
||||
s->desired_cursor[0]=0;
|
||||
line_t ¤t = s->desired.line(line_no);
|
||||
current.resize(0);
|
||||
s->desired.cursor[0] = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
line_t *current;
|
||||
int screen_width = common_get_width();
|
||||
int cw = wcwidth(b);
|
||||
int ew = wcwidth( ellipsis_char );
|
||||
int i;
|
||||
|
||||
current = (line_t *)al_get( &s->desired, line_no );
|
||||
|
||||
if( !current )
|
||||
{
|
||||
current = s_create_line();
|
||||
al_push( &s->desired, current );
|
||||
}
|
||||
s->desired.create_line(line_no);
|
||||
|
||||
/*
|
||||
Check if we are at the end of the line. If so, print an
|
||||
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( ¤t->text, s->desired_cursor[0], ellipsis_char );
|
||||
al_set_long( ¤t->color, s->desired_cursor[0], HIGHLIGHT_COMMENT );
|
||||
line_entry_t &entry = s->desired.line(line_no).create_entry(s->desired.cursor[0]);
|
||||
entry.text = ellipsis_char;
|
||||
entry.color = HIGHLIGHT_COMMENT;
|
||||
|
||||
current = s_create_line();
|
||||
al_push( &s->desired, current );
|
||||
s->desired_cursor[1]++;
|
||||
s->desired_cursor[0]=0;
|
||||
line_no = s->desired.line_count();
|
||||
s->desired.add_line();
|
||||
s->desired.cursor[1]++;
|
||||
s->desired.cursor[0]=0;
|
||||
for( i=0; i < (prompt_width-ew); i++ )
|
||||
{
|
||||
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 );
|
||||
}
|
||||
|
||||
al_set_long( ¤t->text, s->desired_cursor[0], b );
|
||||
al_set_long( ¤t->color, s->desired_cursor[0], c );
|
||||
s->desired_cursor[0]+= cw;
|
||||
line_t &line = s->desired.line(line_no);
|
||||
line.create_entry(s->desired.cursor[0]).text = b;
|
||||
line.create_entry(s->desired.cursor[0]).color = c;
|
||||
s->desired.cursor[0]+= cw;
|
||||
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 );
|
||||
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))
|
||||
{
|
||||
|
@ -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
|
||||
behaviour...
|
||||
*/
|
||||
s->actual_cursor[0]=0;
|
||||
s->actual.cursor[0]=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 )
|
||||
{
|
||||
|
@ -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[1] = new_y;
|
||||
s->actual.cursor[0] = new_x;
|
||||
s->actual.cursor[1] = new_y;
|
||||
|
||||
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 );
|
||||
s_writeb_buffer = b;
|
||||
s->actual_cursor[0]+=wcwidth( c );
|
||||
s->actual.cursor[0]+=wcwidth( c );
|
||||
|
||||
writech( c );
|
||||
|
||||
|
@ -669,19 +610,18 @@ static void s_update( screen_t *scr, wchar_t *prompt )
|
|||
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_write_str( &output, prompt );
|
||||
sb_clear( &scr->actual_prompt );
|
||||
sb_append( &scr->actual_prompt, prompt );
|
||||
scr->actual_cursor[0] = prompt_width;
|
||||
scr->actual_prompt = prompt;
|
||||
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 *s_line = (line_t *)al_get( &scr->actual, i );
|
||||
line_t &o_line = scr->desired.line(i);
|
||||
line_t &s_line = scr->actual.create_line(i);
|
||||
int start_pos = (i==0?prompt_width:0);
|
||||
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_write_mbs( &output, clr_eol);
|
||||
if( s_line )
|
||||
{
|
||||
al_truncate( &s_line->text, 0 );
|
||||
al_truncate( &s_line->color, 0 );
|
||||
}
|
||||
s_line.resize(0);
|
||||
}
|
||||
|
||||
if( !s_line )
|
||||
for( j=start_pos; j<o_line.entry_count(); j++)
|
||||
{
|
||||
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 );
|
||||
|
||||
|
||||
line_entry_t &entry = o_line.entry(j);
|
||||
wchar_t o = entry.text;
|
||||
int o_c = entry.color;
|
||||
if( !o )
|
||||
continue;
|
||||
|
||||
if( al_get_count( &s_line->text ) == j )
|
||||
if( s_line.entry_count() == j )
|
||||
{
|
||||
s_move( scr, &output, current_width, i );
|
||||
s_set_color( scr, &output, o_c );
|
||||
s_write_char( scr, &output, o );
|
||||
al_set_long( &s_line->text, j, o );
|
||||
al_set_long( &s_line->color, j, o_c );
|
||||
s_line.create_entry(j).text = o;
|
||||
s_line.create_entry(j).color = o_c;
|
||||
}
|
||||
else
|
||||
{
|
||||
wchar_t s = (wchar_t)(intptr_t)al_get( &s_line->text, j );
|
||||
int s_c = (int)(intptr_t)al_get( &s_line->color, j );
|
||||
line_entry_t &entry = s_line.create_entry(j);
|
||||
wchar_t s = entry.text;
|
||||
int s_c = entry.color;
|
||||
|
||||
if( o != s || o_c != s_c )
|
||||
{
|
||||
s_move( scr, &output, current_width, i );
|
||||
s_set_color( scr, &output, o_c );
|
||||
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++ )
|
||||
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 );
|
||||
}
|
||||
|
||||
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_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_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);
|
||||
|
||||
|
@ -864,8 +796,8 @@ void s_write( screen_t *s,
|
|||
if( current_line_width > max_line_width )
|
||||
max_line_width = current_line_width;
|
||||
|
||||
s_reset_arr( &s->desired );
|
||||
s->desired_cursor[0] = s->desired_cursor[1] = 0;
|
||||
s->desired.resize(0);
|
||||
s->desired.cursor[0] = s->desired.cursor[1] = 0;
|
||||
|
||||
/*
|
||||
If overflowing, give the prompt its own line to improve the
|
||||
|
@ -897,13 +829,13 @@ void s_write( screen_t *s,
|
|||
|
||||
if( i == cursor )
|
||||
{
|
||||
cursor_arr[0] = s->desired_cursor[0];
|
||||
cursor_arr[1] = s->desired_cursor[1];
|
||||
cursor_arr[0] = s->desired.cursor[0];
|
||||
cursor_arr[1] = s->desired.cursor[1];
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -911,17 +843,17 @@ void s_write( screen_t *s,
|
|||
cursor won't be on the ellipsis which looks
|
||||
unintuitive.
|
||||
*/
|
||||
cursor_arr[0] = s->desired_cursor[0] - wcwidth(b[i]);
|
||||
cursor_arr[1] = s->desired_cursor[1];
|
||||
cursor_arr[0] = s->desired.cursor[0] - wcwidth(b[i]);
|
||||
cursor_arr[1] = s->desired.cursor[1];
|
||||
}
|
||||
|
||||
}
|
||||
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_save_status( s );
|
||||
}
|
||||
|
@ -930,10 +862,10 @@ void s_reset( screen_t *s, int reset_cursor )
|
|||
{
|
||||
CHECK( s, );
|
||||
|
||||
int prev_line = s->actual_cursor[1];
|
||||
s_reset_arr( &s->actual );
|
||||
s->actual_cursor[0] = s->actual_cursor[1] = 0;
|
||||
sb_clear( &s->actual_prompt );
|
||||
int prev_line = s->actual.cursor[1];
|
||||
s->actual.resize(0);
|
||||
s->actual.cursor[0] = s->actual.cursor[1] = 0;
|
||||
s->actual_prompt = L"";
|
||||
s->need_clear=1;
|
||||
|
||||
if( !reset_cursor )
|
||||
|
@ -943,7 +875,7 @@ void s_reset( screen_t *s, int reset_cursor )
|
|||
next repaint.
|
||||
*/
|
||||
write_loop( 1, "\r", 1 );
|
||||
s->actual_cursor[1] = prev_line;
|
||||
s->actual.cursor[1] = prev_line;
|
||||
}
|
||||
fstat( 1, &s->prev_buff_1 );
|
||||
fstat( 2, &s->prev_buff_2 );
|
||||
|
|
120
screen.h
120
screen.h
|
@ -12,6 +12,79 @@
|
|||
#ifndef 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.
|
||||
*/
|
||||
|
@ -20,24 +93,17 @@ typedef struct
|
|||
/**
|
||||
The internal representation of the desired screen contents.
|
||||
*/
|
||||
array_list_t desired;
|
||||
screen_data_t desired;
|
||||
/**
|
||||
The internal representation of the actual screen contents.
|
||||
*/
|
||||
array_list_t actual;
|
||||
screen_data_t actual;
|
||||
|
||||
/**
|
||||
The desired cursor position.
|
||||
*/
|
||||
int desired_cursor[2];
|
||||
/**
|
||||
The actual cursor position.
|
||||
*/
|
||||
int actual_cursor[2];
|
||||
/**
|
||||
A stringbuffer containing the prompt which was last printed to
|
||||
A string containing the prompt which was last printed to
|
||||
the screen.
|
||||
*/
|
||||
string_buffer_t actual_prompt;
|
||||
wcstring actual_prompt;
|
||||
|
||||
/**
|
||||
The actual width of the screen at the time of the last screen
|
||||
|
@ -61,36 +127,6 @@ typedef struct
|
|||
}
|
||||
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
|
||||
to define the desired contents of the screen. The screen command
|
||||
|
|
Loading…
Reference in a new issue