Skip to content

Commit

Permalink
Merge pull request #847 from Yaraslaut/master
Browse files Browse the repository at this point in the history
Add support for infinite grid
  • Loading branch information
christianparpart authored Oct 16, 2022
2 parents 4122f9c + f657a29 commit 6e047fd
Show file tree
Hide file tree
Showing 10 changed files with 87 additions and 29 deletions.
12 changes: 8 additions & 4 deletions src/contour/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ using terminal::Width;

using terminal::CellRGBColorAndAlphaPair;
using terminal::ColumnCount;
using terminal::Infinite;
using terminal::LineCount;
using terminal::PageSize;

Expand Down Expand Up @@ -1522,12 +1523,15 @@ TerminalProfile loadTerminalProfile(UsedKeys& _usedKeys,
else
errorlog()("Invalid render_mode \"{}\" in configuration.", strValue);

auto intValue = profile.maxHistoryLineCount;
auto intValue = LineCount();
tryLoadChildRelative(_usedKeys, _profile, basePath, "history.limit", intValue);
if (unbox<int>(intValue) < 0)
profile.maxHistoryLineCount = LineCount(0);
// value -1 is used for infinite grid
if (unbox<int>(intValue) == -1)
profile.maxHistoryLineCount = Infinite();
else if (unbox<int>(intValue) > -1)
profile.maxHistoryLineCount = LineCount(intValue);
else
profile.maxHistoryLineCount = intValue;
profile.maxHistoryLineCount = LineCount(0);

strValue = fmt::format("{}", ScrollBarPosition::Right);
if (tryLoadChildRelative(_usedKeys, _profile, basePath, "scrollbar.position", strValue))
Expand Down
2 changes: 1 addition & 1 deletion src/contour/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ struct TerminalProfile
terminal::PageSize terminalSize = { terminal::LineCount(10), terminal::ColumnCount(40) };
terminal::VTType terminalId = terminal::VTType::VT525;

terminal::LineCount maxHistoryLineCount;
terminal::MaxHistoryLineCount maxHistoryLineCount;
terminal::LineCount historyScrollMultiplier = terminal::LineCount(3);
ScrollBarPosition scrollbarPosition = ScrollBarPosition::Right;
bool hideScrollbarInAltScreen = true;
Expand Down
40 changes: 28 additions & 12 deletions src/terminal/Grid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
*/
#include <terminal/Cell.h>
#include <terminal/Grid.h>
#include <terminal/primitives.h>

#include <crispy/assert.h>
#include <crispy/logstore.h>
Expand Down Expand Up @@ -120,25 +121,33 @@ namespace detail
} // namespace detail
// {{{ Grid impl
template <typename Cell>
Grid<Cell>::Grid(PageSize _pageSize, bool _reflowOnResize, LineCount _maxHistoryLineCount):
Grid<Cell>::Grid(PageSize _pageSize, bool _reflowOnResize, MaxHistoryLineCount _maxHistoryLineCount):
pageSize_ { _pageSize },
reflowOnResize_ { _reflowOnResize },
maxHistoryLineCount_ { _maxHistoryLineCount },
historyLimit_ { _maxHistoryLineCount },
lines_ { detail::createLines<Cell>(
_pageSize, _maxHistoryLineCount, _reflowOnResize, GraphicsAttributes {}) },
_pageSize,
[_maxHistoryLineCount]() -> LineCount {
if (auto const* maxLineCount = std::get_if<LineCount>(&_maxHistoryLineCount))
return *maxLineCount;
else
return LineCount::cast_from(0);
}(),
_reflowOnResize,
GraphicsAttributes {}) },
linesUsed_ { _pageSize.lines }
{
verifyState();
}

template <typename Cell>
void Grid<Cell>::setMaxHistoryLineCount(LineCount _maxHistoryLineCount)
void Grid<Cell>::setMaxHistoryLineCount(MaxHistoryLineCount _maxHistoryLineCount)
{
verifyState();
rezeroBuffers();
lines_.resize(unbox<size_t>(pageSize_.lines + _maxHistoryLineCount));
linesUsed_ = min(linesUsed_, pageSize_.lines + _maxHistoryLineCount);
maxHistoryLineCount_ = _maxHistoryLineCount;
historyLimit_ = _maxHistoryLineCount;
lines_.resize(unbox<size_t>(pageSize_.lines + maxHistoryLineCount()));
linesUsed_ = min(linesUsed_, pageSize_.lines + maxHistoryLineCount());
verifyState();
}

Expand Down Expand Up @@ -360,6 +369,13 @@ LineCount Grid<Cell>::scrollUp(LineCount linesCountToScrollUp, GraphicsAttribute
verifyState();
if (unbox<size_t>(linesUsed_) == lines_.size()) // with all grid lines in-use
{
if (std::get_if<Infinite>(&historyLimit_))
{
for ([[maybe_unused]] auto const _: ranges::views::iota(0, unbox<int>(linesCountToScrollUp)))
lines_.emplace_back(defaultLineFlags(),
TrivialLineBuffer { pageSize_.columns, GraphicsAttributes {} });
return scrollUp(linesCountToScrollUp, _defaultAttributes);
}
// TODO: ensure explicit test for this case
rotateBuffersLeft(linesCountToScrollUp);

Expand Down Expand Up @@ -608,7 +624,7 @@ CellLocation Grid<Cell>::growLines(LineCount _newHeight, CellLocation _cursor)
Require(*totalLinesToExtend >= 0);
// ? Require(linesToTakeFromSavedLines == LineCount(0));

auto const newTotalLineCount = maxHistoryLineCount_ + _newHeight;
auto const newTotalLineCount = maxHistoryLineCount() + _newHeight;
auto const currentTotalLineCount = LineCount::cast_from(lines_.size());
auto const linesToFill = max(0, *newTotalLineCount - *currentTotalLineCount);

Expand All @@ -619,7 +635,7 @@ CellLocation Grid<Cell>::growLines(LineCount _newHeight, CellLocation _cursor)
linesUsed_ = min(linesUsed_ + totalLinesToExtend, LineCount::cast_from(lines_.size()));

Ensures(pageSize_.lines == _newHeight);
Ensures(lines_.size() >= unbox<size_t>(maxHistoryLineCount_ + pageSize_.lines));
Ensures(lines_.size() >= unbox<size_t>(maxHistoryLineCount() + pageSize_.lines));
verifyState();

return cursorMove;
Expand Down Expand Up @@ -653,7 +669,7 @@ CellLocation Grid<Cell>::resize(PageSize _newSize, CellLocation _currentCursorPo
pageSize_.lines - boxed_cast<LineCount>(_cursor.line + 1);
auto const cutoffCount = min(numLinesToShrink, linesAvailableBelowCursorBeforeShrink);
auto const numLinesToPushUp = numLinesToShrink - cutoffCount;
auto const numLinesToPushUpCapped = min(numLinesToPushUp, maxHistoryLineCount_);
auto const numLinesToPushUpCapped = min(numLinesToPushUp, maxHistoryLineCount());

GridLog()(" -> shrink lines: numLinesToShrink {}, linesAvailableBelowCursorBeforeShrink {}, "
"cutoff {}, pushUp "
Expand Down Expand Up @@ -782,7 +798,7 @@ CellLocation Grid<Cell>::resize(PageSize _newSize, CellLocation _currentCursorPo
linesUsed_ = LineCount::cast_from(grownLines.size());

// Fill scrollback lines.
auto const totalLineCount = unbox<size_t>(pageSize_.lines + maxHistoryLineCount_);
auto const totalLineCount = unbox<size_t>(pageSize_.lines + maxHistoryLineCount());
while (grownLines.size() < totalLineCount)
grownLines.emplace_back(
defaultLineFlags(),
Expand Down Expand Up @@ -845,7 +861,7 @@ CellLocation Grid<Cell>::resize(PageSize _newSize, CellLocation _currentCursorPo
LineBuffer wrappedColumns;
LineFlags previousFlags = lines_.front().inheritableFlags();

auto const totalLineCount = unbox<size_t>(pageSize_.lines + maxHistoryLineCount_);
auto const totalLineCount = unbox<size_t>(pageSize_.lines + maxHistoryLineCount());
shrinkedLines.reserve(totalLineCount);
Require(totalLineCount == unbox<size_t>(this->totalLineCount()));

Expand Down
22 changes: 16 additions & 6 deletions src/terminal/Grid.h
Original file line number Diff line number Diff line change
Expand Up @@ -383,21 +383,31 @@ class Grid
{
// TODO: Rename all "History" to "Scrollback"?
public:
Grid(PageSize _pageSize, bool _reflowOnResize, LineCount _maxHistoryLineCount);
Grid(PageSize _pageSize, bool _reflowOnResize, MaxHistoryLineCount _maxHistoryLineCount);

Grid(): Grid(PageSize { LineCount(25), ColumnCount(80) }, false, LineCount(0)) {}

void reset();

// {{{ grid global properties
[[nodiscard]] LineCount maxHistoryLineCount() const noexcept { return maxHistoryLineCount_; }
void setMaxHistoryLineCount(LineCount _maxHistoryLineCount);
[[nodiscard]] LineCount maxHistoryLineCount() const noexcept
{
if (auto const* maxLineCount = std::get_if<LineCount>(&historyLimit_))
return *maxLineCount;
else
return LineCount::cast_from(lines_.size()) - pageSize_.lines;
}

[[nodiscard]] LineCount totalLineCount() const noexcept { return maxHistoryLineCount_ + pageSize_.lines; }
void setMaxHistoryLineCount(MaxHistoryLineCount _maxHistoryLineCount);

[[nodiscard]] LineCount totalLineCount() const noexcept
{
return maxHistoryLineCount() + pageSize_.lines;
}

[[nodiscard]] LineCount historyLineCount() const noexcept
{
return std::min(maxHistoryLineCount_, linesUsed_ - pageSize_.lines);
return std::min(maxHistoryLineCount(), linesUsed_ - pageSize_.lines);
}

[[nodiscard]] bool reflowOnResize() const noexcept { return reflowOnResize_; }
Expand Down Expand Up @@ -567,7 +577,7 @@ class Grid
//
PageSize pageSize_;
bool reflowOnResize_ = false;
LineCount maxHistoryLineCount_;
MaxHistoryLineCount historyLimit_;

// Number of lines is at least the sum of maxHistoryLineCount_ + pageSize_.lines,
// because shrinking the page height does not necessarily
Expand Down
20 changes: 20 additions & 0 deletions src/terminal/Grid_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -846,4 +846,24 @@ TEST_CASE("Grid.reflow.tripple", "[grid]")
// }}}
}
}

TEST_CASE("Grid infinite", "[grid]")
{
auto grid_finite = Grid<Cell>(PageSize { LineCount(2), ColumnCount(8) }, true, LineCount(0));
grid_finite.setLineText(LineOffset { 0 }, "ABCDEFGH"sv);
grid_finite.setLineText(LineOffset { 1 }, "abcdefgh"sv);
grid_finite.scrollUp(LineCount { 1 });
REQUIRE(grid_finite.lineText(LineOffset(0)) == "abcdefgh");
REQUIRE(grid_finite.lineText(LineOffset(-1)) == std::string(8, ' '));

auto grid_infinite = Grid<Cell>(PageSize { LineCount(2), ColumnCount(8) }, true, Infinite());
grid_infinite.setLineText(LineOffset { 0 }, "ABCDEFGH"sv);
grid_infinite.setLineText(LineOffset { 1 }, "abcdefgh"sv);
grid_infinite.scrollUp(LineCount { 1 });
REQUIRE(grid_infinite.lineText(LineOffset(0)) == "abcdefgh");
REQUIRE(grid_infinite.lineText(LineOffset(-1)) == "ABCDEFGH");
grid_infinite.scrollUp(LineCount { 97 });
REQUIRE(grid_infinite.lineText(LineOffset(-97)) == "abcdefgh");
REQUIRE(grid_infinite.lineText(LineOffset(-98)) == "ABCDEFGH");
}
// }}}
4 changes: 2 additions & 2 deletions src/terminal/Terminal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Terminal::Terminal(unique_ptr<Pty> _pty,
size_t ptyBufferObjectSize,
size_t _ptyReadBufferSize,
Terminal::Events& _eventListener,
LineCount _maxHistoryLineCount,
MaxHistoryLineCount _maxHistoryLineCount,
LineOffset _copyLastMarkRangeOffset,
chrono::milliseconds _cursorBlinkInterval,
chrono::steady_clock::time_point _now,
Expand Down Expand Up @@ -1715,7 +1715,7 @@ void Terminal::onBufferScrolled(LineCount _n) noexcept
}
// }}}

void Terminal::setMaxHistoryLineCount(LineCount _maxHistoryLineCount)
void Terminal::setMaxHistoryLineCount(MaxHistoryLineCount _maxHistoryLineCount)
{
primaryScreen_.grid().setMaxHistoryLineCount(_maxHistoryLineCount);
}
Expand Down
4 changes: 2 additions & 2 deletions src/terminal/Terminal.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ class Terminal
size_t ptyBufferObjectSize,
size_t _ptyReadBufferSize,
Events& _eventListener,
LineCount _maxHistoryLineCount = LineCount(0),
MaxHistoryLineCount _maxHistoryLineCount = LineCount(0),
LineOffset _copyLastMarkRangeOffset = LineOffset(0),
std::chrono::milliseconds _cursorBlinkInterval = std::chrono::milliseconds { 500 },
std::chrono::steady_clock::time_point _now = std::chrono::steady_clock::now(),
Expand All @@ -113,7 +113,7 @@ class Terminal
void setRefreshRate(double _refreshRate);
void setLastMarkRangeOffset(LineOffset _value) noexcept;

void setMaxHistoryLineCount(LineCount _maxHistoryLineCount);
void setMaxHistoryLineCount(MaxHistoryLineCount _maxHistoryLineCount);
LineCount maxHistoryLineCount() const noexcept;

void setTerminalId(VTType _id) noexcept { state_.terminalId = _id; }
Expand Down
2 changes: 1 addition & 1 deletion src/terminal/TerminalState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class Terminal;

TerminalState::TerminalState(Terminal& _terminal,
PageSize _pageSize,
LineCount _maxHistoryLineCount,
MaxHistoryLineCount _maxHistoryLineCount,
ImageSize _maxImageSize,
unsigned _maxImageColorRegisters,
bool _sixelCursorConformance,
Expand Down
2 changes: 1 addition & 1 deletion src/terminal/TerminalState.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ struct TerminalState
{
TerminalState(Terminal& _terminal,
PageSize _pageSize,
LineCount _maxHistoryLineCount,
MaxHistoryLineCount _maxHistoryLineCount,
ImageSize _maxImageSize,
unsigned _maxImageColorRegisters,
bool _sixelCursorConformance,
Expand Down
8 changes: 8 additions & 0 deletions src/terminal/primitives.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <limits>
#include <ostream>
#include <type_traits>
#include <variant>

// TODO
// - [ ] rename all History to Scrollback
Expand Down Expand Up @@ -82,6 +83,13 @@ using ColumnOffset = crispy::boxed<int, detail::tags::ColumnOffset>;
/// LineCount represents a number of lines.
using LineCount = crispy::boxed<int, detail::tags::LineCount>;

// clang-format off
/// Special structure for inifinite history of Grid
struct Infinite {};
// clang-format on
/// MaxHistoryLineCount represents type that are used to store number
/// of lines that can be stored in history
using MaxHistoryLineCount = std::variant<LineCount, Infinite>;
/// Represents the line offset relative to main-page top.
///
/// * 0 is top-most line on main page
Expand Down

0 comments on commit 6e047fd

Please sign in to comment.