From 133c2feecfa47527b648e71daa596b91c3ed4dc0 Mon Sep 17 00:00:00 2001 From: jlu005807 <1289406660@qq.com> Date: Thu, 28 May 2026 12:57:34 +0800 Subject: [PATCH] refine(tui-v3): remove redundant \n guard, visual row is sufficient --- frontends/tui_v3.py | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/frontends/tui_v3.py b/frontends/tui_v3.py index 044b4797..faf783fd 100644 --- a/frontends/tui_v3.py +++ b/frontends/tui_v3.py @@ -2553,6 +2553,16 @@ class SB: total = self.buf.count('\n') + 1 return line_no, total, ls, le + def _logical_visual_range(self, segs, line_no): + """返回第 line_no 个逻辑行在 segs 中的 (first_vi, last_vi)""" + lines = self.buf.split('\n') + iw = max(1, _term()[0] - 6) + first = 0 + for i in range(line_no): + first += max(1, len(_wrap_cells(lines[i], iw))) + cnt = max(1, len(_wrap_cells(lines[line_no], iw))) + return first, first + cnt - 1 + def _cur_v(self, d: int) -> None: """↑/↓ roam by VISUAL row (a long single-line paste wraps to many rows yet stays one logical line — must still roam). At the top/bottom visual @@ -5170,11 +5180,19 @@ class SB: else: self._sel = None line_no, total, ls, le = self._line_region() - if line_no == 0: - if self.pos == ls: - self._nav_hist(-1) + segs = self._segs(max(1, _term()[0] - 6)) + vi, _ = self._seg_at(segs) + first_vi, _ = self._logical_visual_range(segs, line_no) + if vi == first_vi: # 在视觉首行 + if line_no == 0: + if self.pos == ls: + self._nav_hist(-1) + else: + self.pos = ls + elif self.pos == ls: + self._cur_v(-1) # 已在行首 → 正常上移 else: - self.pos = ls + self.pos = ls # 跳到该行行首 else: self._cur_v(-1) elif o == 0x13: # Ctrl+S stash/restore draft @@ -5186,11 +5204,19 @@ class SB: else: self._sel = None line_no, total, ls, le = self._line_region() - if line_no == total - 1: - if self.pos == le: - self._nav_hist(1) + segs = self._segs(max(1, _term()[0] - 6)) + vi, _ = self._seg_at(segs) + first_vi, last_vi = self._logical_visual_range(segs, line_no) + if vi == last_vi: # 在视觉末行 + if line_no == total - 1: + if self.pos == le: + self._nav_hist(1) + else: + self.pos = le + elif self.pos == le: + self._cur_v(1) # 已在行末 → 正常下移 else: - self.pos = le + self.pos = le # 跳到该行行末 else: self._cur_v(1) elif o == 0x02: # ← caret left