Skip to content

Commit 5d93bb7

Browse files
Merge pull request #1803 from contour-terminal/fix/vi-y0
[Vi] Fix y0 crash.
2 parents b70e893 + b06f37b commit 5d93bb7

File tree

5 files changed

+26
-4
lines changed

5 files changed

+26
-4
lines changed

metainfo.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@
116116
<li>Fixes handling of multiple windows and tabs (#1725)</li>
117117
<li>Fixes crash on scaling down some symbols during font size change</li>
118118
<li>Fixes mouse scrolling speed being too slow</li>
119+
<li>Fixes crash in vi normal mode when using `y0` (#1801)</li>
119120
<li>Enables customizing predefined color palette (#1763)</li>
120121
<li>Ensure inserting new tabs happens right next to the currently active tab (#1695)</li>
121122
<li>Allow glyphs to underflow if they are not bigger than the cell size (#1603)</li>

src/vtbackend/MockTerm.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,13 @@ class MockTerm: public Terminal::NullEvents
6969
std::string windowTitle;
7070
Terminal terminal;
7171

72+
std::string clipboardData;
73+
7274
// Events overrides
7375
void setWindowTitle(std::string_view title) override { windowTitle = title; }
7476

77+
void copyToClipboard(std::string_view data) override { clipboardData = data; }
78+
7579
static vtbackend::Settings createSettings(PageSize pageSize,
7680
LineCount maxHistoryLineCount,
7781
size_t ptyReadBufferSize)

src/vtbackend/ViCommands.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -349,10 +349,8 @@ void ViCommands::executeYank(ViMotion motion, unsigned count)
349349
break;
350350
}
351351
default: {
352-
auto const [from, to] = translateToCellRange(motion, count);
353-
// motion is inclusive but for yank we want to exclude the last cell which is the first cell of
354-
// the next word
355-
executeYank(from, { .line = to.line, .column = to.column - 1 });
352+
auto const [from, to] = translateToCellRange(motion, count).ordered();
353+
executeYank(from, to);
356354
}
357355
break;
358356
}

src/vtbackend/ViCommands_test.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,3 +208,15 @@ TEST_CASE("ViCommands:modeChanged", "[vi]")
208208
}
209209
}
210210
// NOLINTEND(misc-const-correctness)
211+
212+
TEST_CASE("yank", "[vi]")
213+
{
214+
auto mock = setupMockTerminal(
215+
"Hello World", vtbackend::PageSize { vtbackend::LineCount(10), vtbackend::ColumnCount(40) });
216+
217+
mock.sendCharSequence("3l"); // Move cursor to second 'l'
218+
REQUIRE(mock.terminal.normalModeCursorPosition() == 0_lineOffset + 3_columnOffset);
219+
mock.sendCharSequence("y0");
220+
221+
CHECK(mock.clipboardData == "Hell");
222+
}

src/vtbackend/primitives.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ constexpr CellLocation operator-(CellLocation c, ColumnOffset x) noexcept
175175
{
176176
return CellLocation { .line = c.line, .column = c.column - x };
177177
}
178+
178179
// Constructs a top-left and bottom-right coordinate-pair from given input.
179180
constexpr std::pair<CellLocation, CellLocation> orderedPoints(CellLocation a, CellLocation b) noexcept
180181
{
@@ -197,6 +198,12 @@ struct CellLocationRange
197198
CellLocation first;
198199
CellLocation second;
199200

201+
[[nodiscard]] CellLocationRange ordered() const noexcept
202+
{
203+
auto [a, b] = orderedPoints(first, second);
204+
return CellLocationRange { .first = a, .second = b };
205+
}
206+
200207
[[nodiscard]] bool contains(CellLocation location) const noexcept
201208
{
202209
switch (abs(unbox(first.line) - unbox(second.line)))

0 commit comments

Comments
 (0)