diff --git a/src/apps/terminal/BasicTerminalBuffer.cpp b/src/apps/terminal/BasicTerminalBuffer.cpp index f33b898a7b..8bddca35a5 100644 --- a/src/apps/terminal/BasicTerminalBuffer.cpp +++ b/src/apps/terminal/BasicTerminalBuffer.cpp @@ -93,7 +93,8 @@ BasicTerminalBuffer::_CursorChanged() BasicTerminalBuffer::BasicTerminalBuffer() : fScreen(NULL), - fHistory(NULL) + fHistory(NULL), + fTabStops(NULL) { } @@ -102,12 +103,15 @@ BasicTerminalBuffer::~BasicTerminalBuffer() { delete fHistory; _FreeLines(fScreen, fHeight); + delete[] fTabStops; } status_t BasicTerminalBuffer::Init(int32 width, int32 height, int32 historySize) { + status_t error; + fWidth = width; fHeight = height; @@ -133,11 +137,15 @@ BasicTerminalBuffer::Init(int32 width, int32 height, int32 historySize) if (fHistory == NULL) return B_NO_MEMORY; - status_t error = fHistory->Init(width, historySize); + error = fHistory->Init(width, historySize); if (error != B_OK) return error; } + error = _ResetTabStops(fWidth); + if (error != B_OK) + return error; + for (int32 i = 0; i < fHeight; i++) fScreen[i]->Clear(); @@ -643,6 +651,23 @@ BasicTerminalBuffer::InsertRI() } } +void +BasicTerminalBuffer::InsertTab() +{ + int32 x; + + fSoftWrappedCursor = false; + + for (x = fCursor.x + 1; x < fWidth && !fTabStops[x]; x++) + ; // no body + x = restrict_value(x, 0, fWidth - 1); + + if (x != fCursor.x) { + fCursor.x = x; + _CursorChanged(); + } +} + void BasicTerminalBuffer::InsertLines(int32 numLines) { @@ -846,6 +871,29 @@ BasicTerminalBuffer::RestoreOriginMode() fOriginMode = fSavedOriginMode; } +void +BasicTerminalBuffer::SetTabStop(int32 x) +{ + x = restrict_value(x, 0, fWidth - 1); + fTabStops[x] = true; +} + + +void +BasicTerminalBuffer::ClearTabStop(int32 x) +{ + x = restrict_value(x, 0, fWidth - 1); + fTabStops[x] = false; +} + + +void +BasicTerminalBuffer::ClearAllTabStops() +{ + for (int32 i = 0; i < fWidth; i++) + fTabStops[i] = false; +} + void BasicTerminalBuffer::NotifyListener() @@ -1046,6 +1094,12 @@ BasicTerminalBuffer::_ResizeSimple(int32 width, int32 height, _FreeLines(fScreen, fHeight); fScreen = lines; + if (fWidth != width) { + status_t error = _ResetTabStops(width); + if (error != B_OK) + return error; + } + fWidth = width; fHeight = height; @@ -1231,6 +1285,12 @@ BasicTerminalBuffer::_ResizeRewrap(int32 width, int32 height, fScreen = screen; fHistory = history; + if (fWidth != width) { + status_t error = _ResetTabStops(width); + if (error != B_OK) + return error; + } + //debug_printf(" cursor: (%ld, %ld) -> (%ld, %ld)\n", fCursor.x, fCursor.y, //cursor.x, cursor.y); fCursor.x = cursor.x; @@ -1251,6 +1311,21 @@ BasicTerminalBuffer::_ResizeRewrap(int32 width, int32 height, } +status_t +BasicTerminalBuffer::_ResetTabStops(int32 width) +{ + if (fTabStops != NULL) + delete[] fTabStops; + + fTabStops = new(std::nothrow) bool[width]; + if (fTabStops == NULL) + return B_NO_MEMORY; + + for (int32 i = 0; i < width; i++) + fTabStops[i] = (i % TAB_WIDTH) == 0; + return B_OK; +} + void BasicTerminalBuffer::_Scroll(int32 top, int32 bottom, int32 numLines) { diff --git a/src/apps/terminal/BasicTerminalBuffer.h b/src/apps/terminal/BasicTerminalBuffer.h index 08ef1d844c..0d9fe205b7 100644 --- a/src/apps/terminal/BasicTerminalBuffer.h +++ b/src/apps/terminal/BasicTerminalBuffer.h @@ -108,6 +108,7 @@ public: void InsertCR(); void InsertLF(); void InsertRI(); + void InsertTab(); void SetInsertMode(int flag); void InsertSpace(int32 num); void InsertLines(int32 numLines); @@ -143,6 +144,9 @@ public: void SetOriginMode(bool enabled); void SaveOriginMode(); void RestoreOriginMode(); + void SetTabStop(int32 x); + void ClearTabStop(int32 x); + void ClearAllTabStops(); protected: virtual void NotifyListener(); @@ -167,6 +171,7 @@ protected: int32 historyCapacity); status_t _ResizeRewrap(int32 width, int32 height, int32 historyCapacity); + status_t _ResetTabStops(int32 width); void _Scroll(int32 top, int32 bottom, int32 numLines); @@ -203,6 +208,7 @@ protected: bool fAlternateScreenActive; bool fOriginMode; bool fSavedOriginMode; + bool* fTabStops; int fEncoding; diff --git a/src/apps/terminal/TermConst.h b/src/apps/terminal/TermConst.h index d9a62500f0..cb5bee120c 100644 --- a/src/apps/terminal/TermConst.h +++ b/src/apps/terminal/TermConst.h @@ -152,6 +152,8 @@ enum{ SCRDOWN }; +#define TAB_WIDTH 8 + #define MIN_COLS 10 #define MAX_COLS 256 #define MIN_ROWS 10 diff --git a/src/apps/terminal/TermParse.cpp b/src/apps/terminal/TermParse.cpp index 87a027619a..6c8bde0e92 100644 --- a/src/apps/terminal/TermParse.cpp +++ b/src/apps/terminal/TermParse.cpp @@ -301,7 +301,6 @@ TermParse::DumpState(int *groundtable, int *parsestate, uchar c) int32 TermParse::EscParse() { - int tmp; int top, bot; int cs96 = 0; uchar curess = 0; @@ -517,9 +516,7 @@ TermParse::EscParse() break; case CASE_TAB: - tmp = fBuffer->Cursor().x; - tmp %= 8; - fBuffer->MoveCursorRight(8 - tmp); + fBuffer->InsertTab(); break; case CASE_ESC: @@ -844,7 +841,16 @@ TermParse::EscParse() case CASE_HTS: /* HTS */ - // TabSet(term->tabs, screen->cur_col); + fBuffer->SetTabStop(fBuffer->Cursor().x); + parsestate = groundtable; + break; + + case CASE_TBC: + /* TBC */ + if (param[0] < 1) + fBuffer->ClearTabStop(fBuffer->Cursor().x); + else if (param[0] == 3) + fBuffer->ClearAllTabStops(); parsestate = groundtable; break; diff --git a/src/apps/terminal/VTPrsTbl.c b/src/apps/terminal/VTPrsTbl.c index 9816ff6c8a..6ba0a0bdf1 100644 --- a/src/apps/terminal/VTPrsTbl.c +++ b/src/apps/terminal/VTPrsTbl.c @@ -1140,7 +1140,7 @@ CASE_GROUND_STATE, CASE_VPA, CASE_GROUND_STATE, CASE_CUP, -CASE_GROUND_STATE, +CASE_TBC, /* h i j k */ CASE_SET, CASE_GROUND_STATE,