Patch by Joshua R. Elsasser:
Implement correctly handling tab stop escape sequences. Resolves ticket #4657. Thanks! git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33326 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -93,7 +93,8 @@ BasicTerminalBuffer::_CursorChanged()
|
|||||||
BasicTerminalBuffer::BasicTerminalBuffer()
|
BasicTerminalBuffer::BasicTerminalBuffer()
|
||||||
:
|
:
|
||||||
fScreen(NULL),
|
fScreen(NULL),
|
||||||
fHistory(NULL)
|
fHistory(NULL),
|
||||||
|
fTabStops(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,12 +103,15 @@ BasicTerminalBuffer::~BasicTerminalBuffer()
|
|||||||
{
|
{
|
||||||
delete fHistory;
|
delete fHistory;
|
||||||
_FreeLines(fScreen, fHeight);
|
_FreeLines(fScreen, fHeight);
|
||||||
|
delete[] fTabStops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BasicTerminalBuffer::Init(int32 width, int32 height, int32 historySize)
|
BasicTerminalBuffer::Init(int32 width, int32 height, int32 historySize)
|
||||||
{
|
{
|
||||||
|
status_t error;
|
||||||
|
|
||||||
fWidth = width;
|
fWidth = width;
|
||||||
fHeight = height;
|
fHeight = height;
|
||||||
|
|
||||||
@@ -133,11 +137,15 @@ BasicTerminalBuffer::Init(int32 width, int32 height, int32 historySize)
|
|||||||
if (fHistory == NULL)
|
if (fHistory == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
status_t error = fHistory->Init(width, historySize);
|
error = fHistory->Init(width, historySize);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
error = _ResetTabStops(fWidth);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
for (int32 i = 0; i < fHeight; i++)
|
for (int32 i = 0; i < fHeight; i++)
|
||||||
fScreen[i]->Clear();
|
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
|
void
|
||||||
BasicTerminalBuffer::InsertLines(int32 numLines)
|
BasicTerminalBuffer::InsertLines(int32 numLines)
|
||||||
{
|
{
|
||||||
@@ -846,6 +871,29 @@ BasicTerminalBuffer::RestoreOriginMode()
|
|||||||
fOriginMode = fSavedOriginMode;
|
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
|
void
|
||||||
BasicTerminalBuffer::NotifyListener()
|
BasicTerminalBuffer::NotifyListener()
|
||||||
@@ -1046,6 +1094,12 @@ BasicTerminalBuffer::_ResizeSimple(int32 width, int32 height,
|
|||||||
_FreeLines(fScreen, fHeight);
|
_FreeLines(fScreen, fHeight);
|
||||||
fScreen = lines;
|
fScreen = lines;
|
||||||
|
|
||||||
|
if (fWidth != width) {
|
||||||
|
status_t error = _ResetTabStops(width);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
fWidth = width;
|
fWidth = width;
|
||||||
fHeight = height;
|
fHeight = height;
|
||||||
|
|
||||||
@@ -1231,6 +1285,12 @@ BasicTerminalBuffer::_ResizeRewrap(int32 width, int32 height,
|
|||||||
fScreen = screen;
|
fScreen = screen;
|
||||||
fHistory = history;
|
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,
|
//debug_printf(" cursor: (%ld, %ld) -> (%ld, %ld)\n", fCursor.x, fCursor.y,
|
||||||
//cursor.x, cursor.y);
|
//cursor.x, cursor.y);
|
||||||
fCursor.x = cursor.x;
|
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
|
void
|
||||||
BasicTerminalBuffer::_Scroll(int32 top, int32 bottom, int32 numLines)
|
BasicTerminalBuffer::_Scroll(int32 top, int32 bottom, int32 numLines)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ public:
|
|||||||
void InsertCR();
|
void InsertCR();
|
||||||
void InsertLF();
|
void InsertLF();
|
||||||
void InsertRI();
|
void InsertRI();
|
||||||
|
void InsertTab();
|
||||||
void SetInsertMode(int flag);
|
void SetInsertMode(int flag);
|
||||||
void InsertSpace(int32 num);
|
void InsertSpace(int32 num);
|
||||||
void InsertLines(int32 numLines);
|
void InsertLines(int32 numLines);
|
||||||
@@ -143,6 +144,9 @@ public:
|
|||||||
void SetOriginMode(bool enabled);
|
void SetOriginMode(bool enabled);
|
||||||
void SaveOriginMode();
|
void SaveOriginMode();
|
||||||
void RestoreOriginMode();
|
void RestoreOriginMode();
|
||||||
|
void SetTabStop(int32 x);
|
||||||
|
void ClearTabStop(int32 x);
|
||||||
|
void ClearAllTabStops();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void NotifyListener();
|
virtual void NotifyListener();
|
||||||
@@ -167,6 +171,7 @@ protected:
|
|||||||
int32 historyCapacity);
|
int32 historyCapacity);
|
||||||
status_t _ResizeRewrap(int32 width, int32 height,
|
status_t _ResizeRewrap(int32 width, int32 height,
|
||||||
int32 historyCapacity);
|
int32 historyCapacity);
|
||||||
|
status_t _ResetTabStops(int32 width);
|
||||||
|
|
||||||
void _Scroll(int32 top, int32 bottom,
|
void _Scroll(int32 top, int32 bottom,
|
||||||
int32 numLines);
|
int32 numLines);
|
||||||
@@ -203,6 +208,7 @@ protected:
|
|||||||
bool fAlternateScreenActive;
|
bool fAlternateScreenActive;
|
||||||
bool fOriginMode;
|
bool fOriginMode;
|
||||||
bool fSavedOriginMode;
|
bool fSavedOriginMode;
|
||||||
|
bool* fTabStops;
|
||||||
|
|
||||||
int fEncoding;
|
int fEncoding;
|
||||||
|
|
||||||
|
|||||||
@@ -152,6 +152,8 @@ enum{
|
|||||||
SCRDOWN
|
SCRDOWN
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define TAB_WIDTH 8
|
||||||
|
|
||||||
#define MIN_COLS 10
|
#define MIN_COLS 10
|
||||||
#define MAX_COLS 256
|
#define MAX_COLS 256
|
||||||
#define MIN_ROWS 10
|
#define MIN_ROWS 10
|
||||||
|
|||||||
@@ -301,7 +301,6 @@ TermParse::DumpState(int *groundtable, int *parsestate, uchar c)
|
|||||||
int32
|
int32
|
||||||
TermParse::EscParse()
|
TermParse::EscParse()
|
||||||
{
|
{
|
||||||
int tmp;
|
|
||||||
int top, bot;
|
int top, bot;
|
||||||
int cs96 = 0;
|
int cs96 = 0;
|
||||||
uchar curess = 0;
|
uchar curess = 0;
|
||||||
@@ -517,9 +516,7 @@ TermParse::EscParse()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CASE_TAB:
|
case CASE_TAB:
|
||||||
tmp = fBuffer->Cursor().x;
|
fBuffer->InsertTab();
|
||||||
tmp %= 8;
|
|
||||||
fBuffer->MoveCursorRight(8 - tmp);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CASE_ESC:
|
case CASE_ESC:
|
||||||
@@ -844,7 +841,16 @@ TermParse::EscParse()
|
|||||||
|
|
||||||
case CASE_HTS:
|
case CASE_HTS:
|
||||||
/* 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;
|
parsestate = groundtable;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -1140,7 +1140,7 @@ CASE_GROUND_STATE,
|
|||||||
CASE_VPA,
|
CASE_VPA,
|
||||||
CASE_GROUND_STATE,
|
CASE_GROUND_STATE,
|
||||||
CASE_CUP,
|
CASE_CUP,
|
||||||
CASE_GROUND_STATE,
|
CASE_TBC,
|
||||||
/* h i j k */
|
/* h i j k */
|
||||||
CASE_SET,
|
CASE_SET,
|
||||||
CASE_GROUND_STATE,
|
CASE_GROUND_STATE,
|
||||||
|
|||||||
Reference in New Issue
Block a user