BasicTerminalBuffer: Add {Previous,Next}LinePos()
This commit is contained in:
parent
bda35ef5dc
commit
314e8a20c6
@ -431,48 +431,31 @@ BasicTerminalBuffer::FindWord(const TermPos& pos,
|
||||
TermPos start(x, y);
|
||||
TermPos end(x + (IS_WIDTH(line->cells[x].attributes)
|
||||
? FULL_WIDTH : HALF_WIDTH), y);
|
||||
while (true) {
|
||||
if (--x < 0) {
|
||||
// Hit the beginning of the line -- continue at the end of the
|
||||
// previous line, if it soft-breaks.
|
||||
y--;
|
||||
if ((line = _HistoryLineAt(y, lineBuffer)) == NULL
|
||||
|| !line->softBreak || line->length == 0) {
|
||||
break;
|
||||
}
|
||||
x = line->length - 1;
|
||||
}
|
||||
if (x > 0 && IS_WIDTH(line->cells[x - 1].attributes))
|
||||
x--;
|
||||
|
||||
if (classifier->Classify(line->cells[x].character) != type)
|
||||
for (;;) {
|
||||
TermPos previousPos = start;
|
||||
if (!_PreviousLinePos(lineBuffer, line, previousPos)
|
||||
|| classifier->Classify(line->cells[previousPos.x].character)
|
||||
!= type) {
|
||||
break;
|
||||
}
|
||||
|
||||
start.SetTo(x, y);
|
||||
start = previousPos;
|
||||
}
|
||||
|
||||
// find the end
|
||||
x = end.x;
|
||||
y = end.y;
|
||||
line = _HistoryLineAt(y, lineBuffer);
|
||||
line = _HistoryLineAt(end.y, lineBuffer);
|
||||
|
||||
while (true) {
|
||||
if (x >= line->length) {
|
||||
// Hit the end of the line -- if it soft-breaks continue with the
|
||||
// next line.
|
||||
if (!line->softBreak)
|
||||
break;
|
||||
y++;
|
||||
x = 0;
|
||||
if ((line = _HistoryLineAt(y, lineBuffer)) == NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
if (classifier->Classify(line->cells[x].character) != type)
|
||||
for (;;) {
|
||||
TermPos nextPos = end;
|
||||
if (!_NormalizeLinePos(lineBuffer, line, nextPos))
|
||||
break;
|
||||
|
||||
x += IS_WIDTH(line->cells[x].attributes) ? FULL_WIDTH : HALF_WIDTH;
|
||||
end.SetTo(x, y);
|
||||
if (classifier->Classify(line->cells[nextPos.x].character) != type)
|
||||
break;
|
||||
|
||||
nextPos.x += IS_WIDTH(line->cells[nextPos.x].attributes)
|
||||
? FULL_WIDTH : HALF_WIDTH;
|
||||
end = nextPos;
|
||||
}
|
||||
|
||||
_start = start;
|
||||
@ -481,6 +464,34 @@ BasicTerminalBuffer::FindWord(const TermPos& pos,
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BasicTerminalBuffer::PreviousLinePos(TermPos& pos) const
|
||||
{
|
||||
TerminalLine* lineBuffer = ALLOC_LINE_ON_STACK(fWidth);
|
||||
TerminalLine* line = _HistoryLineAt(pos.y, lineBuffer);
|
||||
if (line == NULL || pos.x < 0 || pos.x >= fWidth)
|
||||
return false;
|
||||
|
||||
return _PreviousLinePos(lineBuffer, line, pos);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BasicTerminalBuffer::NextLinePos(TermPos& pos, bool normalize) const
|
||||
{
|
||||
TerminalLine* lineBuffer = ALLOC_LINE_ON_STACK(fWidth);
|
||||
TerminalLine* line = _HistoryLineAt(pos.y, lineBuffer);
|
||||
if (line == NULL || pos.x < 0 || pos.x > fWidth)
|
||||
return false;
|
||||
|
||||
if (!_NormalizeLinePos(lineBuffer, line, pos))
|
||||
return false;
|
||||
|
||||
pos.x += IS_WIDTH(line->cells[pos.x].attributes) ? FULL_WIDTH : HALF_WIDTH;
|
||||
return !normalize || _NormalizeLinePos(lineBuffer, line, pos);
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
BasicTerminalBuffer::LineLength(int32 index) const
|
||||
{
|
||||
@ -1692,6 +1703,46 @@ BasicTerminalBuffer::_NextChar(TermPos& pos, UTF8Char& c) const
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BasicTerminalBuffer::_PreviousLinePos(TerminalLine* lineBuffer,
|
||||
TerminalLine*& line, TermPos& pos) const
|
||||
{
|
||||
if (--pos.x < 0) {
|
||||
// Hit the beginning of the line -- continue at the end of the
|
||||
// previous line, if it soft-breaks.
|
||||
pos.y--;
|
||||
if ((line = _HistoryLineAt(pos.y, lineBuffer)) == NULL
|
||||
|| !line->softBreak || line->length == 0) {
|
||||
return false;
|
||||
}
|
||||
pos.x = line->length - 1;
|
||||
}
|
||||
if (pos.x > 0 && IS_WIDTH(line->cells[pos.x - 1].attributes))
|
||||
pos.x--;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BasicTerminalBuffer::_NormalizeLinePos(TerminalLine* lineBuffer,
|
||||
TerminalLine*& line, TermPos& pos) const
|
||||
{
|
||||
if (pos.x < line->length)
|
||||
return true;
|
||||
|
||||
// Hit the end of the line -- if it soft-breaks continue with the
|
||||
// next line.
|
||||
if (!line->softBreak)
|
||||
return false;
|
||||
|
||||
pos.y++;
|
||||
pos.x = 0;
|
||||
line = _HistoryLineAt(pos.y, lineBuffer);
|
||||
return line != NULL;
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_DEBUG_SNAPSHOTS
|
||||
|
||||
void
|
||||
|
@ -107,6 +107,14 @@ public:
|
||||
int32 LineLength(int32 index) const;
|
||||
int32 GetLineColor(int32 index) const;
|
||||
|
||||
bool PreviousLinePos(TermPos& pos) const;
|
||||
bool NextLinePos(TermPos& pos, bool normalize) const;
|
||||
// normalize specifies that the returned
|
||||
// position must be a valid position, i.e.
|
||||
// actually point to a character (as opposed
|
||||
// to just pointing to the position after a
|
||||
// character).
|
||||
|
||||
bool Find(const char* pattern, const TermPos& start,
|
||||
bool forward, bool caseSensitive,
|
||||
bool matchWord, TermPos& matchStart,
|
||||
@ -205,6 +213,11 @@ protected:
|
||||
bool _PreviousChar(TermPos& pos, UTF8Char& c) const;
|
||||
bool _NextChar(TermPos& pos, UTF8Char& c) const;
|
||||
|
||||
bool _PreviousLinePos(TerminalLine* lineBuffer,
|
||||
TerminalLine*& line, TermPos& pos) const;
|
||||
bool _NormalizeLinePos(TerminalLine* lineBuffer,
|
||||
TerminalLine*& line, TermPos& pos) const;
|
||||
|
||||
protected:
|
||||
// screen width/height
|
||||
int32 fWidth;
|
||||
|
Loading…
x
Reference in New Issue
Block a user