Skip to content

Commit b7a438c

Browse files
committed
fix: add count support for gg and reorder commands
1 parent c31ab82 commit b7a438c

File tree

3 files changed

+49
-21
lines changed

3 files changed

+49
-21
lines changed

sqlit/domains/query/ui/mixins/query_editing_cursor.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,17 @@ def action_g_leader_key(self: QueryMixinHost) -> None:
3838
self._start_leader_pending("g")
3939

4040
def action_g_first_line(self: QueryMixinHost) -> None:
41-
"""Go to first line (gg)."""
41+
"""Go to first line (gg), or to line N with count prefix (e.g., 3gg)."""
4242
self._clear_leader_pending()
43-
self.query_input.cursor_location = (0, 0)
43+
count = self._get_and_clear_count()
44+
if count is not None:
45+
lines = self.query_input.text.split("\n")
46+
num_lines = len(lines)
47+
target_row = min(count - 1, num_lines - 1)
48+
target_row = max(0, target_row)
49+
self.query_input.cursor_location = (target_row, 0)
50+
else:
51+
self.query_input.cursor_location = (0, 0)
4452

4553
def action_g_word_end_back(self: QueryMixinHost) -> None:
4654
"""Go to end of previous word (ge)."""

sqlit/domains/shell/app/main.py

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,22 @@ def _show_command_list(self) -> None:
748748
("Appearance", ":theme", "Open theme selection", ""),
749749
("Query", ":run, :r", "Execute query", ""),
750750
("Query", ":run!, :r!", "Execute query (stay in INSERT)", ""),
751+
(
752+
"Navigation",
753+
":<number>",
754+
"Go to line number",
755+
"Jump to specified line in query editor (e.g., :25 goes to line 25).",
756+
),
757+
(
758+
"Navigation",
759+
"<count>G",
760+
"Go to line with count prefix",
761+
"In NORMAL mode, type a number then G to go to that line (e.g., 25G).",
762+
),
763+
("Editor", ":set number, :set nu", "Show line numbers", ""),
764+
("Editor", ":set nonumber, :set nonu", "Hide line numbers", ""),
765+
("Editor", ":set relativenumber, :set rnu", "Show relative line numbers", ""),
766+
("Editor", ":set norelativenumber, :set nornu", "Show absolute line numbers", ""),
751767
(
752768
"Worker",
753769
":process-worker, :worker",
@@ -760,6 +776,9 @@ def _show_command_list(self) -> None:
760776
"Show process worker status",
761777
"Displays worker mode, active state, and last activity.",
762778
),
779+
("Settings", ":set process_worker_warm on|off", "Warm worker on idle", ""),
780+
("Settings", ":set process_worker_lazy on|off", "Lazy worker start", ""),
781+
("Settings", ":set process_worker_auto_shutdown <seconds>", "Auto-shutdown worker", ""),
763782
(
764783
"Watchdog",
765784
":wd <ms|off>",
@@ -777,25 +796,6 @@ def _show_command_list(self) -> None:
777796
("Debug", ":debug", "Show debug status", ""),
778797
("Debug", ":debug list", "Show debug events", ""),
779798
("Debug", ":debug clear", "Clear debug event log", ""),
780-
("Settings", ":set process_worker_warm on|off", "Warm worker on idle", ""),
781-
("Settings", ":set process_worker_lazy on|off", "Lazy worker start", ""),
782-
("Settings", ":set process_worker_auto_shutdown <seconds>", "Auto-shutdown worker", ""),
783-
("Editor", ":set number, :set nu", "Show line numbers", ""),
784-
("Editor", ":set nonumber, :set nonu", "Hide line numbers", ""),
785-
("Editor", ":set relativenumber, :set rnu", "Show relative line numbers", ""),
786-
("Editor", ":set norelativenumber, :set nornu", "Show absolute line numbers", ""),
787-
(
788-
"Navigation",
789-
":<number>",
790-
"Go to line number",
791-
"Jump to specified line in query editor (e.g., :25 goes to line 25).",
792-
),
793-
(
794-
"Navigation",
795-
"<count>G",
796-
"Go to line with count prefix",
797-
"In NORMAL mode, type a number then G to go to that line (e.g., 25G).",
798-
),
799799
]
800800
if hasattr(self, "_replace_results_table"):
801801
self._replace_results_table(columns, rows)

tests/ui/keybindings/test_vim_motions.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,26 @@ async def test_25G_goes_to_line_25(self) -> None:
513513
# 25G goes to line 25 (0-indexed: row 24)
514514
assert app.query_input.cursor_location[0] == 24, f"Expected row 24, got {app.query_input.cursor_location[0]}"
515515

516+
@pytest.mark.asyncio
517+
async def test_3gg_goes_to_line_3(self) -> None:
518+
"""3gg should go to line 3 (0-indexed: row 2)."""
519+
app = _make_app()
520+
521+
async with app.run_test(size=(100, 35)) as pilot:
522+
app.action_focus_query()
523+
await pilot.pause()
524+
525+
# Create 10 lines
526+
lines = [f"line{i+1}" for i in range(10)]
527+
app.query_input.text = "\n".join(lines)
528+
app.query_input.cursor_location = (7, 0)
529+
await pilot.pause()
530+
531+
await pilot.press("3", "g", "g")
532+
await pilot.pause()
533+
534+
assert app.query_input.cursor_location[0] == 2, f"Expected row 2, got {app.query_input.cursor_location[0]}"
535+
516536
@pytest.mark.asyncio
517537
async def test_colon_25_goes_to_line_25(self) -> None:
518538
""":25 command should go to line 25."""

0 commit comments

Comments
 (0)