Skip to content
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* Disabled continuous deployment in GHA. See `.github/workflows/build_artifact.yml`
for details

* Resolve crash when user tries to switch top or bottom line outside of scope
* Resolved crash when the user tries to `delete word` past the end of a line

### v0.0.3 | 17/Mar/2026
Expand Down
8 changes: 4 additions & 4 deletions src/action.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,17 +267,17 @@ template <typename T, typename U>
auto logger = spdlog::get("basic_logger");
if (logger != nullptr) { logger->info("Action called: MoveLineDown"); }

v->get_active_model()->move_line_down();
v->cursor_down();
bool actionable = v->get_active_model()->move_line_down();
if (actionable) { v->cursor_down(); }
return {};
} break;

case ActionType::MoveLineUp: {
auto logger = spdlog::get("basic_logger");
if (logger != nullptr) { logger->info("Action called: MoveLineUp"); }

v->get_active_model()->move_line_up();
v->cursor_up();
bool actionable = v->get_active_model()->move_line_up();
if (actionable) { v->cursor_up(); }
return {};
} break;

Expand Down
8 changes: 6 additions & 2 deletions src/model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -424,12 +424,16 @@ void Model::toggle_case() {
return false;
}

void Model::move_line_down() {
[[nodiscard]] bool Model::move_line_down() {
if (current_line == buf.size() - 1) { return false; }
std::iter_swap(buf.begin() + current_line, buf.begin() + current_line + 1);
return true;
}

void Model::move_line_up() {
[[nodiscard]] bool Model::move_line_up() {
if (!current_line) { return false; }
std::iter_swap(buf.begin() + current_line, buf.begin() + current_line - 1);
return true;
}

void Model::set_read_only(std::string_view file) {
Expand Down
4 changes: 2 additions & 2 deletions src/model.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ struct Model {
[[nodiscard]] bool undo(const int);
[[nodiscard]] char get_current_char() const;
[[nodiscard]] bool redo(const int);
void move_line_down();
void move_line_up();
[[nodiscard]] bool move_line_down();
[[nodiscard]] bool move_line_up();
void set_read_only(std::string_view);
void delete_current_line();
[[nodiscard]] const std::optional<WordPos> current_word() const;
Expand Down
21 changes: 21 additions & 0 deletions tests/integration/normal_mode_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,27 @@ def test_upper_k_key(r: TmuxRunner):
assert "here is a newline and a tab" in r.lines()[2]


@setup("tests/fixture/test_file_1.txt")
def test_upper_j_key_end_of_file(r: TmuxRunner):
r.press("G")
r.press("J")

# Check nothing has changed
# TODO: replace with r.MODIFIED_MARKER
assert "[X]" not in r.statusbar_parts()
assert len(r.statusbar_parts())


@setup("tests/fixture/test_file_1.txt")
def test_upper_k_key_start_of_file(r: TmuxRunner):
r.press("K")

# Check nothing has changed
# TODO: replace with r.MODIFIED_MARKER
assert "[X]" not in r.statusbar_parts()
assert len(r.statusbar_parts())


@setup("tests/fixture/test_file_1.txt")
def test_tt_key(r: TmuxRunner):
r.type_str("tt")
Expand Down
Loading