Merge PR #520
This commit is contained in:
commit
3a9e90bbba
1 file changed
+55
-2
+55
-2
@@ -2542,6 +2542,27 @@ class SB:
|
||||
return i, p - st
|
||||
return len(segs) - 1, len(segs[-1][1])
|
||||
|
||||
def _line_region(self, pos: int | None = None) -> tuple[int, int, int, int]:
|
||||
"""(行号, 总行数, 行起始偏移, 行结束偏移) 基于逻辑行(\\n分割)"""
|
||||
p = self.pos if pos is None else pos
|
||||
ls = self.buf.rfind('\n', 0, p) + 1
|
||||
le = self.buf.find('\n', p)
|
||||
if le == -1:
|
||||
le = len(self.buf)
|
||||
line_no = self.buf[:p].count('\n')
|
||||
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
|
||||
@@ -5154,7 +5175,23 @@ class SB:
|
||||
self._pending_drain_t = 0.0
|
||||
self._render_live()
|
||||
else:
|
||||
self._sel = None; self._cur_v(-1)
|
||||
self._sel = None
|
||||
line_no, total, ls, le = self._line_region()
|
||||
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 # 跳到该行行首
|
||||
else:
|
||||
self._cur_v(-1)
|
||||
elif o == 0x13: # Ctrl+S stash/restore draft
|
||||
self._stash_draft()
|
||||
elif o == 0x0e: # ↓ visual-row down (history at bottom)
|
||||
@@ -5162,7 +5199,23 @@ class SB:
|
||||
n = len(self._cmd_matches(self.buf))
|
||||
self._palette_sel = min(n - 1, self._palette_sel + 1) if n else 0
|
||||
else:
|
||||
self._sel = None; self._cur_v(1)
|
||||
self._sel = None
|
||||
line_no, total, ls, le = self._line_region()
|
||||
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 # 跳到该行行末
|
||||
else:
|
||||
self._cur_v(1)
|
||||
elif o == 0x02: # ← caret left
|
||||
self._sel = None; self.pos = max(0, self.pos - 1)
|
||||
elif o == 0x06: # → caret right
|
||||
|
||||
Reference in new issue
Block a user