From 92d80accf9957f5b568d7eb9857d53c1a12a2ada Mon Sep 17 00:00:00 2001 From: Keith Winstein Date: Mon, 31 Jan 2011 06:10:02 -0500 Subject: [PATCH] Implement tabs --- templates.cpp | 1 + terminal.cpp | 2 +- terminalframebuffer.cpp | 24 ++++++++++++++++++++++-- terminalframebuffer.hpp | 7 +++++++ terminalfunctions.cpp | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 63 insertions(+), 3 deletions(-) diff --git a/templates.cpp b/templates.cpp index 78eeb82..4cf6b79 100644 --- a/templates.cpp +++ b/templates.cpp @@ -16,3 +16,4 @@ template class std::vector; template class std::vector; template class std::vector; template class std::map; +template class std::vector; diff --git a/terminal.cpp b/terminal.cpp index 8953f9f..fb5d3b4 100644 --- a/terminal.cpp +++ b/terminal.cpp @@ -63,7 +63,7 @@ void Emulator::print( Parser::Print *act ) switch ( chwidth ) { case 1: /* normal character */ case 2: /* wide character */ - if ( fb.ds.next_print_will_wrap ) { + if ( fb.ds.auto_wrap_mode && fb.ds.next_print_will_wrap ) { fb.ds.move_col( 0 ); fb.move_rows_autoscroll( 1 ); } diff --git a/terminalframebuffer.cpp b/terminalframebuffer.cpp index e9e7193..b6b74ad 100644 --- a/terminalframebuffer.cpp +++ b/terminalframebuffer.cpp @@ -56,8 +56,8 @@ void Cell::reset( void ) DrawState::DrawState( int s_width, int s_height ) : width( s_width ), height( s_height ), cursor_col( 0 ), cursor_row( 0 ), - combining_char_col( 0 ), combining_char_row( 0 ), - next_print_will_wrap( false ) + combining_char_col( 0 ), combining_char_row( 0 ), tabs( s_width ), + next_print_will_wrap( false ), auto_wrap_mode( true ) {} Framebuffer::Framebuffer( int s_width, int s_height ) @@ -179,3 +179,23 @@ void Framebuffer::claim_overlap( int row, int col ) } } } + +void DrawState::set_tab( void ) +{ + tabs[ cursor_col ] = true; +} + +void DrawState::clear_tab( int col ) +{ + tabs[ col ] = false; +} + +int DrawState::get_next_tab( void ) +{ + for ( int i = cursor_col + 1; i < width; i++ ) { + if ( tabs[ i ] ) { + return i; + } + } + return -1; +} diff --git a/terminalframebuffer.hpp b/terminalframebuffer.hpp index d2ea01e..91b4ff6 100644 --- a/terminalframebuffer.hpp +++ b/terminalframebuffer.hpp @@ -40,8 +40,11 @@ namespace Terminal { int cursor_col, cursor_row; int combining_char_col, combining_char_row; + std::vector tabs; + public: bool next_print_will_wrap; + bool auto_wrap_mode; /* bold, etc. */ @@ -55,6 +58,10 @@ namespace Terminal { int get_width( void ) { return width; } int get_height( void ) { return height; } + void set_tab( void ); + void clear_tab( int col ); + int get_next_tab( void ); + DrawState( int s_width, int s_height ); }; diff --git a/terminalfunctions.cpp b/terminalfunctions.cpp index 6e5b3a2..443aed5 100644 --- a/terminalfunctions.cpp +++ b/terminalfunctions.cpp @@ -141,3 +141,35 @@ void Ctrl_NEL( Framebuffer *fb, Dispatcher *dispatch __attribute((unused)) ) } static Function func_Ctrl_NEL( CONTROL, "\x85", Ctrl_NEL ); + +void Ctrl_HT( Framebuffer *fb, Dispatcher *dispatch __attribute((unused)) ) +{ + int col = fb->ds.get_next_tab(); + if ( col == -1 ) { /* no tabs, go to end of line */ + fb->ds.move_col( fb->ds.get_width() - 1 ); + } else { + fb->ds.move_col( col ); + } +} + +static Function func_Ctrl_HT( CONTROL, "\x09", Ctrl_HT ); + +void Ctrl_HTS( Framebuffer *fb, Dispatcher *dispatch __attribute((unused)) ) +{ + fb->ds.set_tab(); +} + +static Function func_Ctrl_HTS( CONTROL, "\x88", Ctrl_HT ); + +void CSI_TBC( Framebuffer *fb, Dispatcher *dispatch ) +{ + if ( dispatch->getparam( 0, 0 ) == 3 ) { /* clear all tab stops */ + for ( int x = 0; x < fb->ds.get_width(); x++ ) { + fb->ds.clear_tab( x ); + } + } else { + fb->ds.clear_tab( fb->ds.get_cursor_col() ); + } +} + +static Function func_CSI_TBC( CSI, "g", CSI_TBC );