feat: implement scrolling in editor
Some checks failed
Tests / test (macos-latest, 3.10) (push) Waiting to run
Tests / test (macos-latest, 3.11) (push) Waiting to run
Tests / test (macos-latest, 3.12) (push) Waiting to run
Tests / test (windows-latest, 3.10) (push) Waiting to run
Tests / test (windows-latest, 3.11) (push) Waiting to run
Tests / test (windows-latest, 3.12) (push) Waiting to run
Lint / lint (push) Failing after 24s
Tests / test (ubuntu-latest, 3.10) (push) Failing after 40s
Tests / test (ubuntu-latest, 3.11) (push) Failing after 37s
Tests / test (ubuntu-latest, 3.12) (push) Failing after 1m3s

feat: update version to 1.26.0
refactor: adjust cursor position based on scroll_y
maintenance: update changelog with new version information
This commit is contained in:
retoor 2025-11-08 00:42:52 +01:00
parent 55d8814f94
commit a6c276862e
3 changed files with 63 additions and 14 deletions

View File

@ -21,6 +21,14 @@
## Version 1.25.0 - 2025-11-08
Autonomous mode now has improved error handling and tracks usage and costs. Several internal components were updated to improve reliability and logging.
**Changes:** 10 files, 342 lines
**Languages:** Markdown (8 lines), Python (332 lines), TOML (2 lines)
## Version 1.24.0 - 2025-11-07 ## Version 1.24.0 - 2025-11-07

View File

@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "rp" name = "rp"
version = "1.24.0" version = "1.25.0"
description = "R python edition. The ultimate autonomous AI CLI." description = "R python edition. The ultimate autonomous AI CLI."
readme = "README.md" readme = "README.md"
requires-python = ">=3.10" requires-python = ">=3.10"

View File

@ -26,6 +26,7 @@ class RPEditor:
self.lines = [""] self.lines = [""]
self.cursor_y = 0 self.cursor_y = 0
self.cursor_x = 0 self.cursor_x = 0
self.scroll_y = 0
self.mode = "normal" self.mode = "normal"
self.command = "" self.command = ""
self.stdscr = None self.stdscr = None
@ -222,14 +223,15 @@ class RPEditor:
try: try:
self.stdscr.clear() self.stdscr.clear()
height, width = self.stdscr.getmaxyx() height, width = self.stdscr.getmaxyx()
for i, line in enumerate(self.lines): for i in range(height - 1):
if i >= height - 1: line_idx = self.scroll_y + i
break if line_idx < len(self.lines):
try: line = self.lines[line_idx]
display_line = line[: width - 1] if len(line) >= width else line try:
self.stdscr.addstr(i, 0, display_line) display_line = line[: width - 1] if len(line) >= width else line
except curses.error: self.stdscr.addstr(i, 0, display_line)
pass except curses.error:
pass
status = f"{self.mode.upper()} | {self.filename or 'untitled'} | {self.cursor_y + 1}:{self.cursor_x + 1}" status = f"{self.mode.upper()} | {self.filename or 'untitled'} | {self.cursor_y + 1}:{self.cursor_x + 1}"
if self.mode == "command": if self.mode == "command":
status = self.command[: width - 1] status = self.command[: width - 1]
@ -238,11 +240,12 @@ class RPEditor:
except curses.error: except curses.error:
pass pass
cursor_x = min(self.cursor_x, width - 1) cursor_x = min(self.cursor_x, width - 1)
cursor_y = min(self.cursor_y, height - 2) cursor_y_display = self.cursor_y - self.scroll_y
try: if 0 <= cursor_y_display < height - 1:
self.stdscr.move(cursor_y, cursor_x) try:
except curses.error: self.stdscr.move(cursor_y_display, cursor_x)
pass except curses.error:
pass
self.stdscr.refresh() self.stdscr.refresh()
except Exception: except Exception:
pass pass
@ -321,15 +324,33 @@ class RPEditor:
if self.prev_key == ord("g"): if self.prev_key == ord("g"):
self.cursor_y = 0 self.cursor_y = 0
self.cursor_x = 0 self.cursor_x = 0
self.scroll_y = 0
elif key == ord("G"): elif key == ord("G"):
self.cursor_y = max(0, len(self.lines) - 1) self.cursor_y = max(0, len(self.lines) - 1)
self.cursor_x = 0 self.cursor_x = 0
# Adjust scroll_y
if self.stdscr:
height, _ = self.stdscr.getmaxyx()
if self.cursor_y >= self.scroll_y + height - 1:
self.scroll_y = self.cursor_y - height + 2
elif key == ord("u"): elif key == ord("u"):
self.undo() self.undo()
elif key == 18: elif key == 18:
self.redo() self.redo()
elif key == 19: elif key == 19:
self._save_file() self._save_file()
elif key == curses.KEY_PPAGE: # Page Up
if self.stdscr:
height, _ = self.stdscr.getmaxyx()
page_size = height - 2
self.cursor_y = max(0, self.cursor_y - page_size)
self.scroll_y = max(0, self.scroll_y - page_size)
elif key == curses.KEY_NPAGE: # Page Down
if self.stdscr:
height, _ = self.stdscr.getmaxyx()
page_size = height - 2
self.cursor_y = min(len(self.lines) - 1, self.cursor_y + page_size)
self.scroll_y = min(max(0, len(self.lines) - height + 1), self.scroll_y + page_size)
self.prev_key = key self.prev_key = key
except Exception: except Exception:
pass pass
@ -420,6 +441,13 @@ class RPEditor:
elif new_y >= len(self.lines): elif new_y >= len(self.lines):
self.cursor_y = max(0, len(self.lines) - 1) self.cursor_y = max(0, len(self.lines) - 1)
self.cursor_x = len(self.lines[self.cursor_y]) self.cursor_x = len(self.lines[self.cursor_y])
# Adjust scroll_y to keep cursor visible
if self.stdscr:
height, _ = self.stdscr.getmaxyx()
if self.cursor_y < self.scroll_y:
self.scroll_y = self.cursor_y
elif self.cursor_y >= self.scroll_y + height - 1:
self.scroll_y = self.cursor_y - height + 2
def save_state(self): def save_state(self):
"""Save current state for undo.""" """Save current state for undo."""
@ -428,6 +456,7 @@ class RPEditor:
"lines": list(self.lines), "lines": list(self.lines),
"cursor_y": self.cursor_y, "cursor_y": self.cursor_y,
"cursor_x": self.cursor_x, "cursor_x": self.cursor_x,
"scroll_y": self.scroll_y,
} }
self.undo_stack.append(state) self.undo_stack.append(state)
if len(self.undo_stack) > self.max_undo: if len(self.undo_stack) > self.max_undo:
@ -442,6 +471,7 @@ class RPEditor:
"lines": list(self.lines), "lines": list(self.lines),
"cursor_y": self.cursor_y, "cursor_y": self.cursor_y,
"cursor_x": self.cursor_x, "cursor_x": self.cursor_x,
"scroll_y": self.scroll_y,
} }
self.redo_stack.append(current_state) self.redo_stack.append(current_state)
state = self.undo_stack.pop() state = self.undo_stack.pop()
@ -450,6 +480,7 @@ class RPEditor:
self.cursor_x = min( self.cursor_x = min(
state["cursor_x"], len(self.lines[self.cursor_y]) if self.lines else 0 state["cursor_x"], len(self.lines[self.cursor_y]) if self.lines else 0
) )
self.scroll_y = state.get("scroll_y", 0)
def redo(self): def redo(self):
"""Redo last undone change.""" """Redo last undone change."""
@ -459,6 +490,7 @@ class RPEditor:
"lines": list(self.lines), "lines": list(self.lines),
"cursor_y": self.cursor_y, "cursor_y": self.cursor_y,
"cursor_x": self.cursor_x, "cursor_x": self.cursor_x,
"scroll_y": self.scroll_y,
} }
self.undo_stack.append(current_state) self.undo_stack.append(current_state)
state = self.redo_stack.pop() state = self.redo_stack.pop()
@ -467,6 +499,7 @@ class RPEditor:
self.cursor_x = min( self.cursor_x = min(
state["cursor_x"], len(self.lines[self.cursor_y]) if self.lines else 0 state["cursor_x"], len(self.lines[self.cursor_y]) if self.lines else 0
) )
self.scroll_y = state.get("scroll_y", 0)
def _insert_text(self, text): def _insert_text(self, text):
"""Insert text at cursor position.""" """Insert text at cursor position."""
@ -571,6 +604,7 @@ class RPEditor:
self.lines = text.splitlines() if text else [""] self.lines = text.splitlines() if text else [""]
self.cursor_y = 0 self.cursor_y = 0
self.cursor_x = 0 self.cursor_x = 0
self.scroll_y = 0
def set_text(self, text): def set_text(self, text):
"""Thread-safe text setting.""" """Thread-safe text setting."""
@ -589,6 +623,13 @@ class RPEditor:
line_num = max(0, min(line_num - 1, len(self.lines) - 1)) line_num = max(0, min(line_num - 1, len(self.lines) - 1))
self.cursor_y = line_num self.cursor_y = line_num
self.cursor_x = 0 self.cursor_x = 0
# Adjust scroll_y
if self.stdscr:
height, _ = self.stdscr.getmaxyx()
if self.cursor_y < self.scroll_y:
self.scroll_y = self.cursor_y
elif self.cursor_y >= self.scroll_y + height - 1:
self.scroll_y = self.cursor_y - height + 2
def goto_line(self, line_num): def goto_line(self, line_num):
"""Thread-safe goto line.""" """Thread-safe goto line."""