Skip to content

Commit 9c94891

Browse files
committed
Add experimental support for gd/gu for visually moving cursor down/up
1 parent 5836413 commit 9c94891

File tree

5 files changed

+37
-10
lines changed

5 files changed

+37
-10
lines changed

src/coord.hh

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,15 @@ struct DisplayCoord : LineAndColumn<DisplayCoord, LineCount, ColumnCount>
7575
struct BufferCoordAndTarget : BufferCoord
7676
{
7777
[[gnu::always_inline]]
78-
constexpr BufferCoordAndTarget(LineCount line = 0, ByteCount column = 0, ColumnCount target = -1)
79-
: BufferCoord{line, column}, target{target} {}
78+
constexpr BufferCoordAndTarget(LineCount line = 0, ByteCount column = 0, ColumnCount target = -1, ColumnCount display_target=-1)
79+
: BufferCoord{line, column}, target{target}, display_target{display_target} {}
8080

8181
[[gnu::always_inline]]
82-
constexpr BufferCoordAndTarget(BufferCoord coord, ColumnCount target = -1)
83-
: BufferCoord{coord}, target{target} {}
82+
constexpr BufferCoordAndTarget(BufferCoord coord, ColumnCount target = -1, ColumnCount display_target=-1)
83+
: BufferCoord{coord}, target{target}, display_target{display_target} {}
8484

8585
ColumnCount target;
86+
ColumnCount display_target;
8687
};
8788

8889
constexpr size_t hash_value(const BufferCoordAndTarget& val)

src/input_handler.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,7 +1494,7 @@ class Insert : public InputMode
14941494
buffer.insert(sel.max().line + inserted_count + 1,
14951495
String{'\n', CharCount{count}});
14961496
for (int i = 0; i < count; ++i)
1497-
new_sels.push_back({sel.max().line + inserted_count + i + 1});
1497+
new_sels.push_back(BufferCoord{sel.max().line + inserted_count + i + 1});
14981498
inserted_count += count;
14991499
}
15001500
selections.set(std::move(new_sels),
@@ -1512,7 +1512,7 @@ class Insert : public InputMode
15121512
buffer.insert(sel.min().line + inserted_count,
15131513
String{'\n', CharCount{count}});
15141514
for (int i = 0; i < count; ++i)
1515-
new_sels.push_back({sel.min().line + inserted_count + i});
1515+
new_sels.push_back(BufferCoord{sel.min().line + inserted_count + i});
15161516
inserted_count += count;
15171517
}
15181518
selections.set(std::move(new_sels),

src/normal.cc

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,12 +234,12 @@ void goto_commands(Context& context, NormalParams params)
234234
else
235235
{
236236
on_next_key_with_autoinfo(context, "goto", KeymapMode::Goto,
237-
[](Key key, Context& context) {
237+
[params](Key key, Context& context) {
238238
auto cp = key.codepoint();
239239
if (not cp or key == Key::Escape)
240240
return;
241241
auto& buffer = context.buffer();
242-
switch (to_lower(*cp))
242+
switch (auto lower_cp = to_lower(*cp); lower_cp)
243243
{
244244
case 'g':
245245
case 'k':
@@ -297,6 +297,30 @@ void goto_commands(Context& context, NormalParams params)
297297
context.change_buffer(*target);
298298
break;
299299
}
300+
case 'd':
301+
case 'u':
302+
{
303+
auto offset = (lower_cp == 'd' ? 1_line : -1_line) * std::max(params.count, 1);
304+
select(context, mode, [&](Context& context, Selection& sel) -> Optional<Selection> {
305+
if (context.has_window())
306+
{
307+
auto& cursor = sel.cursor();
308+
auto& window = context.window();
309+
if (auto display_coord = window.display_coord(cursor))
310+
{
311+
if (cursor.display_target == -1)
312+
cursor.display_target = display_coord->column;
313+
display_coord->column = cursor.display_target;
314+
if (auto buffer_coord = window.buffer_coord(*display_coord + offset))
315+
return Selection{BufferCoordAndTarget{*buffer_coord, -1, cursor.display_target}};
316+
}
317+
}
318+
const ColumnCount tabstop = context.options()["tabstop"].get<int>();
319+
return Selection{context.buffer().offset_coord(sel.cursor(), offset, tabstop)};
320+
});
321+
break;
322+
}
323+
300324
case 'f':
301325
{
302326
static constexpr char forbidden[] = { '\'', '\\', '\0' };

src/selection.hh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ struct BasicSelection
2727

2828
BasicSelection() = default;
2929
BasicSelection(BufferCoord pos) : BasicSelection(pos,pos) {}
30+
BasicSelection(BufferCoordAndTarget pos) : BasicSelection(pos,pos) {}
3031
BasicSelection(BufferCoord anchor, BufferCoordAndTarget cursor)
3132
: m_anchor{anchor}, m_cursor{cursor} {}
3233

@@ -62,6 +63,7 @@ struct Selection : BasicSelection
6263
{
6364
Selection() = default;
6465
Selection(BufferCoord pos) : BasicSelection(pos,pos) {}
66+
Selection(BufferCoordAndTarget pos) : BasicSelection(pos,pos) {}
6567
Selection(BufferCoord anchor, BufferCoordAndTarget cursor, CaptureList captures = {})
6668
: BasicSelection{anchor, cursor}, m_captures(std::move(captures)) {}
6769
CaptureList& captures() { return m_captures; }

src/window.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,9 +303,9 @@ Optional<BufferCoord> Window::buffer_coord(DisplayCoord coord) const
303303
m_display_buffer.lines().empty())
304304
return {};
305305
if (coord <= 0_line)
306-
coord = {};
306+
return {};
307307
if ((size_t)coord.line >= m_display_buffer.lines().size())
308-
coord = DisplayCoord{(int)m_display_buffer.lines().size()-1, INT_MAX};
308+
return {};
309309

310310
return find_buffer_coord(m_display_buffer.lines()[(int)coord.line],
311311
buffer(), coord.column);

0 commit comments

Comments
 (0)