Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Grid refactor #342

Merged
merged 5 commits into from
Dec 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@ include(EnableCcache)
include(ClangTidy)
include(CIncludeMe)

if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE
STRING "Choose the build mode." FORCE)
if(NOT WIN32 AND NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the build mode." FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS Debug Release MinSizeRel RelWithDebInfo)
endif()
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS Debug Release MinSizeRel RelWithDebInfo)

find_package(Threads)

Expand Down
7 changes: 7 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
### 0.3.0 (unreleased)

#### Grid-PR induced changes

- Improved VT backend performance (#342).
- Improved text selection behaviour.
- Adds new configuration option `mouse_block_selection_modifier`.
- Adds new configuration option `profiles.*.copy_last_mark_range_offset` (default `0`) to adjust where to start looking upwards for the `CopyPreviousMarkRange` action. This is useful for multi-line prompts.

### 0.2.3 (2021-12-12)

**Important: It is recommended to also use the latest `contour` termcap file if you are already using one
Expand Down
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,6 @@ sudo apt install libkf5windowsystem-dev

And set pass `-DCONTOUR_BLUR_PLATFORM_KWIN=ON` to cmake when configuring the project.

In case you want to improve performance slightly and run at at least Linux, you can add
`-DLIBTERMINAL_EXECUTION_PAR=ON` to the cmake configuration and make sure to have `libtbb-dev`
installed beforehand.

### Prerequisites Windows 10

For Windows, you must have Windows 10, 2018 Fall Creators Update, and Visual Studio 2019, installed.
Expand Down
14 changes: 10 additions & 4 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
- [x] box drawing (e.g. helping fira code to not look shit w/ p10k zsh prompts): https://github.com/s417-lama/terminal-glyph-patcher#preset-glyphs
- [ ] dump creation should create (overwrite) symlink to always point to the latest dump (`.../dump/latest` -> `.../dump/TIMESTAMP`)
- [ ] reduce font cache key capacity. `notcurses-demo u` generates 10 atlases just for glyphs. That's too much and makes it slow. what makes it slow exactly?
- [ ] enusre LRU rolling works on the atlas-side, too
- [ ] [FEATURE;PERF] Do not evict ASCII (32..127?) from cache! Aka. have a speed-optimization code path for ASCII in glyph image caching.

- [x] get screenshot before exit working
- [ ] CI: notcureses test for each scene
- [ ] rolling local state dump dir? (configurable to last N=10 dumps)

# TODO requirements before merge

- [ ] line reflow seems to be broken on shrink "sometimes"?
- [ ] ring: add negative and overflowing (r)iterator tests (should wrap around & succeed)
- [ ] frontend: scrolling up/down works as expected (currently overflowing and inverted)
- [ ] Terminal: Writing text, leading to page-scroll properly updates scrollbar.
- [ ] Terminal: Writing text, leading to page-scroll properly updates active selection.
- [ ] grid: revive logical line iterators, try to make them zero-copy
- [ ] notify on dirty screen regions should become an area-test: `is (x,y) within ((x0,y0), (x1,y1))`
- [x] frontend: scrolling up/down works as expected (currently overflowing and inverted)
- [x] Terminal: Writing text, leading to page-scroll properly updates active selection.
- [x] grid: revive logical line iterators, try to make them zero-copy
- [x] Terminal: Writing text, leading to page-scroll properly updates scrollbar.

# FIXMEs / CODEHALTH checklist

Expand Down
2 changes: 1 addition & 1 deletion cmake/ThirdParties.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ set(3rdparty_libunicode_version "3c59a3a0eb0c57c3081d48ea77c22809ac7c2d6e" CAC
set(3rdparty_mimalloc_version "0be71a2cac17062bd8913cbd272c472a44331b7f" CACHE STRING "mimalloc: commit hash")
set(3rdparty_range_v3_version "83783f578e0e6666d68a3bf17b0038a80e62530e" CACHE STRING "range_v3: commit hash")
set(3rdparty_yaml_cpp_version "1713859b054b0a7fd867a59905dfbb0d3f774d54" CACHE STRING "yaml-cpp: commit hash")
set(3rdparty_termbenchpro_version "513cc8a7eb15b3b1a7940816944056d168d2c22a" CACHE STRING "termbench-pro: commit hash")
set(3rdparty_termbenchpro_version "5a79261fbf5d26c9bf9d9a0d31f22ef4556cdd3b" CACHE STRING "termbench-pro: commit hash")

if(CONTOUR_TESTING OR CRISPY_TESTING OR LIBTERMINAL_TESTING)
set(CATCH_BUILD_EXAMPLES OFF CACHE INTERNAL "")
Expand Down
89 changes: 89 additions & 0 deletions docs/grid-redesign.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Grid (re)design

## grid properties

- line and column positions are given in offsets (0-based indices!)
- grid cells of the full scrollback + main page area are stored in dense linear space
- `Line` is just a view into the ring buffer
- logical lines above main page area's line count cannot be edited
- scroll offset represents the *bottom* line of the viewport.
- maybe make scroll offset negative (to have all ops being additions)

## corollary

- the VT screen line/column position to offset translation (minus 1)
happens as early as possible in the `Sequencer`.
- `Line::Wrapped`-flag can be removed.
- writing an overlong line does not need to care about auto-wrapping
- because `lineLength / pageWidth == numberOfLinesWriten`
- the new cursor position can be computed analogous to the above
- because of the meaning of the scroll-offset, reflow can be O(1) implemented
with a `Line()` being arbitrary long(!) and the top screen line being
computed by subtracting `(PageLineCount - 1) * PageColumnCount)`,
then *just* lineary walking forward until the bottom right.
- this enables relative jumps (`CUU` etc) to jump up logical lines.
- we could make the cursor jump behavior configurable, via DEC mode.
- On char write overflow
- if Reflow DEC mode is enabled, then continue appending character
- else if AutoWrap DEC mode is enabled, then linefeed()
- else overwrite character on right margin
- I think with the above approach we do not need DEC mode 2027 for disabling
reflow in order to protect command prompts. as they're automatically protected
by the grid line architecture.

### Notes

Suppose only a single overly long line is written and ocupies the full screen
(many page counts).

```
bottomRightOffset = line(cursor.line + realOffset(scrollOffset_)).right_offset;
topLeftOffset = bottomRightOffset - pageSize.lines * pageSize.columns;

def renderViewport():
{
for (auto i = topLeftOffset, k = 0; i < bottomRightOffset; ++i, ++k)
{
auto rowNr = k / pageSize.columns;
auto colNr = k % pageSize.columns;
renderCell(buffer_[i], rowNr, colNr);
}
}
```

## shrink columns

page size: 6x2
lines: 2
line.1: 0..5 abcdef
line.2: 6..11 ABCDEF

shrink to pageSize: 4x2

line.1: 0..3 abcd
line.2: 4..5 ef Wrapped
line.3: 6..9 ABCD
line.4: 10..11 EF Wrapped

Shrinking does not destroy, as it always reflows.
`CUU` will move by logical line numbers.

## overlong lines

4x2


line.1 ABCDEFabcdef
line.2 ABCD

view:

history.line.-1 ABCD
history.line.0 EFAB
logical.line.1 cdef
logical.line.2 ABCD

## Rendering a wrapped line

- the scroll-offset represents the number of real lines scrolled up
-
1 change: 1 addition & 0 deletions src/contour/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ if(CONTOUR_FRONTEND_GUI)
ContourGuiApp.cpp ContourGuiApp.h
Controller.cpp Controller.h
FileChangeWatcher.cpp FileChangeWatcher.h
ScrollableDisplay.cpp ScrollableDisplay.h
TerminalSession.cpp TerminalSession.h
TerminalWindow.cpp TerminalWindow.h
helper.cpp helper.h
Expand Down
17 changes: 14 additions & 3 deletions src/contour/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1108,6 +1108,7 @@ TerminalProfile loadTerminalProfile(UsedKeys& _usedKeys,
tryLoadChild(_usedKeys, _doc, basePath, "maximized", profile.maximized);
tryLoadChild(_usedKeys, _doc, basePath, "fullscreen", profile.fullscreen);
tryLoadChild(_usedKeys, _doc, basePath, "refresh_rate", profile.refreshRate);
tryLoadChild(_usedKeys, _doc, basePath, "copy_last_mark_range_offset", profile.copyLastMarkRangeOffset);

tryLoadChild(_usedKeys, _doc, basePath, "wm_class", profile.wmClass);

Expand Down Expand Up @@ -1331,10 +1332,10 @@ TerminalProfile loadTerminalProfile(UsedKeys& _usedKeys,
else
errorlog()("Invalid render_mode \"{}\" in configuration.", renderModeStr);

auto intValue = profile.maxHistoryLineCount.value_or(std::numeric_limits<LineCount>::max());
auto intValue = profile.maxHistoryLineCount;
tryLoadChild(_usedKeys, _doc, basePath, "history.limit", intValue);
if (unbox<int>(intValue) < 0 || intValue == std::numeric_limits<LineCount>::max())
profile.maxHistoryLineCount = nullopt;
if (unbox<int>(intValue) < 0)
profile.maxHistoryLineCount = LineCount(0);
else
profile.maxHistoryLineCount = intValue;

Expand Down Expand Up @@ -1406,6 +1407,11 @@ void loadConfigFromFile(Config& _config, FileSystem::path const& _fileName)
doc["bypass_mouse_protocol_modifier"]); opt.has_value())
_config.bypassMouseProtocolModifier = opt.value();

if (auto opt = parseModifier(usedKeys,
"mouse_block_selection_modifier",
doc["mouse_block_selection_modifier"]); opt.has_value())
_config.mouseBlockSelectionModifier = opt.value();

if (doc["on_mouse_select"].IsDefined())
{
auto const value = toUpper(doc["on_mouse_select"].as<string>());
Expand Down Expand Up @@ -1472,6 +1478,11 @@ void loadConfigFromFile(Config& _config, FileSystem::path const& _fileName)
}

tryLoadValue(usedKeys, doc, "read_buffer_size", _config.ptyReadBufferSize);
if ((_config.ptyReadBufferSize % 16) != 0)
{
// For improved performance ...
LOGSTORE(ConfigLog)("read_buffer_size must be a multiple of 16.");
}

tryLoadValue(usedKeys, doc, "reflow_on_resize", _config.reflowOnResize);

Expand Down
6 changes: 5 additions & 1 deletion src/contour/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,14 @@ struct TerminalProfile {
bool maximized = false;
bool fullscreen = false;
double refreshRate = 0.0; // 0=auto
terminal::LineOffset copyLastMarkRangeOffset = terminal::LineOffset(0);

std::string wmClass;

terminal::PageSize terminalSize = {terminal::LineCount(10), terminal::ColumnCount(40)};
terminal::VTType terminalId = terminal::VTType::VT525;

std::optional<terminal::LineCount> maxHistoryLineCount;
terminal::LineCount maxHistoryLineCount;
terminal::LineCount historyScrollMultiplier;
ScrollBarPosition scrollbarPosition = ScrollBarPosition::Right;
bool hideScrollbarInAltScreen = true;
Expand Down Expand Up @@ -177,6 +178,8 @@ struct Config {

// Configures the size of the PTY read buffer.
// Changing this value may result in better or worse throughput performance.
//
// This value must be integer-devisable by 16.
int ptyReadBufferSize = 16384;

bool reflowOnResize = true;
Expand Down Expand Up @@ -206,6 +209,7 @@ struct Config {
std::string wordDelimiters;
terminal::Modifier bypassMouseProtocolModifier = terminal::Modifier::Shift;
SelectionAction onMouseSelection = SelectionAction::CopyToSelectionClipboard;
terminal::Modifier mouseBlockSelectionModifier = terminal::Modifier::Control;

// input mapping
InputMappings inputMappings;
Expand Down
5 changes: 4 additions & 1 deletion src/contour/ContourApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,10 @@ namespace // {{{ helper
// it may very well be that the memory was corrupted too.
std::string crashLogDir;

void segvHandler(int)
void segvHandler(int signum)
{
signal(signum, SIG_DFL);

std::stringstream sstr;
crashLogger(sstr);
string crashLog = sstr.str();
Expand Down Expand Up @@ -183,6 +185,7 @@ ContourApp::ContourApp() :
FileSystem::create_directories(crashLogDirPath);
crashLogDir = crashLogDirPath.string();
signal(SIGSEGV, segvHandler);
signal(SIGABRT, segvHandler);
#endif

#if defined(_WIN32)
Expand Down
Loading