Skip to content

fix(tui): v2 theme/clipboard/Shift+Enter, v3 arrow-nav/Shift+EnterFeat/tui v3 improvements#525

Merged
lsdefine merged 8 commits into
lsdefine:mainfrom
nianyucatfish:feat/tui-v3-improvements
May 28, 2026
Merged

fix(tui): v2 theme/clipboard/Shift+Enter, v3 arrow-nav/Shift+EnterFeat/tui v3 improvements#525
lsdefine merged 8 commits into
lsdefine:mainfrom
nianyucatfish:feat/tui-v3-improvements

Conversation

@nianyucatfish
Copy link
Copy Markdown
Contributor

Overview

Small feature additions to tuiapp_v2 / tui_v3 plus a theme-switch bug fix, and a Windows-terminal Shift+Enter consistency pass across both.

tui_v2 (7c9ce6b)

  • /export clip now actually copies to the system clipboard — adds _copy_to_clipboard: Win32 ctypes via CF_UNICODETEXT (sidesteps console codepages),
    macOS pbcopy, Linux Wayland wl-copy, or X11 xclip / xsel. Falls back to printing the payload for manual copy on failure.
  • Windows physical-Shift detection for Enter — some Windows terminals report Shift+Enter as plain Enter; InputArea now consults
    GetAsyncKeyState(VK_SHIFT) so a physically-held Shift inserts a newline instead of submitting.
  • Theme-switch markdown color bug fixwatch_theme previously failed to clear m._seg_render_cache, so existing assistant messages kept the previous
    theme's colors on h1 / list bullets / code blocks / links after switching themes. The cache key didn't include theme, and the Rich theme palette was baked
    into the ANSI of cached _MdRender objects. Now cleared on every theme change.

tui_v3 (468f7e5, d477763)

  • Windows physical-Shift detection for Enter — same idea, applied in _ptk_keypress_to_bytes.
  • Multi-line input ↑/↓ boundary behavior — adds a _line_region helper. With multi-line input:
    • Intermediate logical lines' visual first/last rows → plain visual row movement, doesn't interrupt browsing
    • First logical line's visual first row → jump to line head; press ↑ again to enter history
    • Last logical line's visual last row → jump to line tail; press ↓ again to enter history

Refs

Test plan

  • v2: Ctrl+T cycles themes; existing messages with # headings, code blocks, lists, and links recolor immediately
  • v2: /export clip puts the full payload on the real clipboard (CJK intact, wrap preserved)
  • v2: In Windows Terminal / cmd / PowerShell, InputArea Shift+Enter inserts a newline, plain Enter submits
  • v3: Same Shift+Enter check inside the PTK frontend
  • v3: Paste 5-10 lines, cursor mid-content → ↑/↓ scroll visual rows; cursor on first/last logical line → jump to head/tail first, then next press enters
    history
  • v3: Single-line short input → ↑/↓ enters history directly (boundary = whole buffer)
  • v3: Command palette / picker open → ↑/↓ doesn't trigger input-box logic

/continue previously pushed plan_scan_baseline past every restored
message, so plan_state.is_active() saw an empty slice and hid the card —
even when the prior session's plan.md still had `[ ]` items the user
wanted to keep working on. `working['in_plan_mode']` isn't replayed by
the log restore either, so the card never came back.

Make the baseline conditional: default to 0 so the scanner walks the
full restored history; only push past it when the restored plan.md is
already all-done, suppressing the stale ✓ card. Resolved-path missing
or empty items naturally fall back to "no card".

/stop now also refills the input box with the just-sent user message,
so an interrupted send is one keystroke from edit-and-resend. Only
when the box is empty (don't clobber a half-typed follow-up). Agent
history is untouched — a resend duplicates the turn in LLM context;
/rewind 1 is the manual escape.

Behaviour matrix (/continue):
  unfinished plan  → baseline=0, scanner finds path, card resumes
  completed plan   → baseline=len(msgs), card stays hidden
  plan.md deleted  → resolve_path None, card stays hidden
  fresh enter_plan_mode after continue → working flag re-arms, normal
- /export clip 现在通过 _copy_to_clipboard 直接写系统剪贴板:
  Win32 ctypes(CF_UNICODETEXT,避开控制台 codepage)/ macOS pbcopy /
  Wayland wl-copy / X11 xclip 或 xsel,失败再退回手动复制。
- InputArea 在 Windows 上对 Enter 事件用 GetAsyncKeyState(VK_SHIFT) 兜底,
  终端把 Shift+Enter 报成普通 Enter 时也能正确插入换行而非提交。
- watch_theme 漏清 _seg_render_cache 导致主题切换后 Markdown 的
  h1/列表 bullet/code 块/link 等仍是上一主题的色 —— 缓存 key 不含
  theme,且 ANSI 颜色被烤进了 _MdRender。补上 clear()。

Refs:
- Shift+Enter 物理检测思路 from upstream PR lsdefine#519 by @jlu005807
  lsdefine#519
- _ptk_keypress_to_bytes 在 Windows 上对 Enter 收到 \r 时用
  GetAsyncKeyState(VK_SHIFT) 物理检测 Shift,按下时返回 \n 以触发换行
  (PTK 在某些 Windows 终端区分不出 Shift+Enter 与裸 Enter)。
- 新增 _line_region / _logical_visual_range 辅助函数,↑/↓ 按键:
  不在该逻辑行的视觉首/末行 → 视觉滚行;在视觉首行且光标在行首 →
  历史导航,否则先跳逻辑行首/尾,下次按键再跨行/进历史。多行粘贴
  内部导航更符合直觉。

Refs:
- Shift+Enter 物理检测 from upstream PR lsdefine#519 by @jlu005807
  lsdefine#519
- 多行输入逻辑行边界导航思路 from upstream PR lsdefine#520 by @jlu005807
  lsdefine#520
之前在任意逻辑行的视觉首/末行都会做"先跳行头/尾再跨行/进历史"的
两段式,中间行的两段式不直观。改成:中间逻辑行的视觉首/末行直接
做视觉上下移;只有第一逻辑行的视觉首行/最末逻辑行的视觉末行,才
触发"先跳到行头/尾,下次按键再进历史"。`_logical_visual_range`
因此变成死代码,顺手删掉。
@lsdefine lsdefine merged commit 6733aec into lsdefine:main May 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants