Final tab-related bugfix (of the morning). Now matches xterm more closely.

This commit is contained in:
Keith Winstein
2012-04-16 11:31:37 -04:00
parent 0293e579d2
commit bfa0999089
3 changed files with 31 additions and 28 deletions
+15 -23
View File
@@ -32,19 +32,25 @@ void Cell::reset( int background_color )
wrap = false; wrap = false;
} }
void DrawState::reinitialize_tabs( unsigned int start )
{
assert( default_tabs );
for ( unsigned int i = start; i < tabs.size(); i++ ) {
tabs[ i ] = ( (i % 8) == 0 );
}
}
DrawState::DrawState( int s_width, int s_height ) DrawState::DrawState( int s_width, int s_height )
: width( s_width ), height( s_height ), : width( s_width ), height( s_height ),
cursor_col( 0 ), cursor_row( 0 ), cursor_col( 0 ), cursor_row( 0 ),
combining_char_col( 0 ), combining_char_row( 0 ), tabs( s_width ), combining_char_col( 0 ), combining_char_row( 0 ), default_tabs( true ), tabs( s_width ),
scrolling_region_top_row( 0 ), scrolling_region_bottom_row( height - 1 ), scrolling_region_top_row( 0 ), scrolling_region_bottom_row( height - 1 ),
renditions( 0 ), save(), renditions( 0 ), save(),
next_print_will_wrap( false ), origin_mode( false ), auto_wrap_mode( true ), next_print_will_wrap( false ), origin_mode( false ), auto_wrap_mode( true ),
insert_mode( false ), cursor_visible( true ), reverse_video( false ), insert_mode( false ), cursor_visible( true ), reverse_video( false ),
application_mode_cursor_keys( false ) application_mode_cursor_keys( false )
{ {
for ( int i = 0; i < width; i++ ) { reinitialize_tabs( 0 );
tabs[ i ] = ( (i % 8) == 0 );
}
} }
Framebuffer::Framebuffer( int s_width, int s_height ) Framebuffer::Framebuffer( int s_width, int s_height )
@@ -204,19 +210,6 @@ int DrawState::limit_bottom( void )
return origin_mode ? scrolling_region_bottom_row : height - 1; return origin_mode ? scrolling_region_bottom_row : height - 1;
} }
std::vector<int> DrawState::get_tabs( void )
{
std::vector<int> ret;
for ( int i = 0; i < width; i++ ) {
if ( tabs[ i ] ) {
ret.push_back( i );
}
}
return ret;
}
void Framebuffer::apply_renditions_to_current_cell( void ) void Framebuffer::apply_renditions_to_current_cell( void )
{ {
get_mutable_cell()->renditions = ds.get_renditions(); get_mutable_cell()->renditions = ds.get_renditions();
@@ -361,17 +354,16 @@ void DrawState::resize( int s_width, int s_height )
scrolling_region_bottom_row = s_height - 1; scrolling_region_bottom_row = s_height - 1;
} }
tabs.resize( s_width );
if ( default_tabs ) {
reinitialize_tabs( width );
}
width = s_width; width = s_width;
height = s_height; height = s_height;
snap_cursor_to_border(); snap_cursor_to_border();
/* reset tab stops */
tabs = std::vector< bool >( width );
for ( int i = 0; i < width; i++ ) {
tabs[ i ] = ( (i % 8) == 0 );
}
/* saved cursor will be snapped to border on restore */ /* saved cursor will be snapped to border on restore */
/* invalidate combining char cell if necessary */ /* invalidate combining char cell if necessary */
+5 -2
View File
@@ -157,8 +157,11 @@ namespace Terminal {
int cursor_col, cursor_row; int cursor_col, cursor_row;
int combining_char_col, combining_char_row; int combining_char_col, combining_char_row;
bool default_tabs;
std::vector<bool> tabs; std::vector<bool> tabs;
void reinitialize_tabs( unsigned int start );
int scrolling_region_top_row, scrolling_region_bottom_row; int scrolling_region_top_row, scrolling_region_bottom_row;
Renditions renditions; Renditions renditions;
@@ -189,10 +192,10 @@ namespace Terminal {
void set_tab( void ); void set_tab( void );
void clear_tab( int col ); void clear_tab( int col );
void clear_default_tabs( void ) { default_tabs = false; }
/* Default tabs can't be restored without resetting the draw state. */
int get_next_tab( void ); int get_next_tab( void );
std::vector<int> get_tabs( void );
void set_scrolling_region( int top, int bottom ); void set_scrolling_region( int top, int bottom );
int get_scrolling_region_top_row( void ) const { return scrolling_region_top_row; } int get_scrolling_region_top_row( void ) const { return scrolling_region_top_row; }
+11 -3
View File
@@ -191,13 +191,20 @@ void Ctrl_HT( Framebuffer *fb, Dispatcher *dispatch __attribute((unused)) )
{ {
int col = fb->ds.get_next_tab(); int col = fb->ds.get_next_tab();
if ( col == -1 ) { /* no tabs, go to end of line */ if ( col == -1 ) { /* no tabs, go to end of line */
fb->ds.move_col( fb->ds.get_width() - 1 ); /* A horizontal tab is the only operation that (1) can keep the wrap
flag but (2) starts a new grapheme. */
if ( fb->ds.get_cursor_col() == fb->ds.get_width() - 1 ) {
fb->ds.move_col( fb->ds.get_width() - 1, false );
fb->ds.move_col( 1, true, true );
} else {
fb->ds.move_col( fb->ds.get_width() - 1, false );
}
} else { } else {
fb->ds.move_col( col ); fb->ds.move_col( col, false );
} }
} }
static Function func_Ctrl_HT( CONTROL, "\x09", Ctrl_HT ); static Function func_Ctrl_HT( CONTROL, "\x09", Ctrl_HT, false );
/* horizontal tab set */ /* horizontal tab set */
void Ctrl_HTS( Framebuffer *fb, Dispatcher *dispatch __attribute((unused)) ) void Ctrl_HTS( Framebuffer *fb, Dispatcher *dispatch __attribute((unused)) )
@@ -216,6 +223,7 @@ void CSI_TBC( Framebuffer *fb, Dispatcher *dispatch )
fb->ds.clear_tab( fb->ds.get_cursor_col() ); fb->ds.clear_tab( fb->ds.get_cursor_col() );
break; break;
case 3: /* clear all tab stops */ case 3: /* clear all tab stops */
fb->ds.clear_default_tabs();
for ( int x = 0; x < fb->ds.get_width(); x++ ) { for ( int x = 0; x < fb->ds.get_width(); x++ ) {
fb->ds.clear_tab( x ); fb->ds.clear_tab( x );
} }