Skip to content

Commit 663c269

Browse files
author
SqlRush
committed
Preserve cursor report params
1 parent 9d300d9 commit 663c269

5 files changed

Lines changed: 21 additions & 15 deletions

File tree

docs/claude-code-go-rewrite-plan.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,7 @@ test/parity/ # golden tests against TS/official behavior
414414
- 本轮补充:terminal CSI parser 现在保留 DECRQM mode-request 的完整参数列表,例如 `CSI ?25;1000$p` 会同时暴露首个 mode code 和原始 params。
415415
- 本轮补充:terminal CSI parser 把 CPR cursor-position responses (`CSI row;col R` / DEC private `CSI ? row;col R`) 归入 report action,结构化暴露 row/column 并保持 visible-text stripping。
416416
- 本轮补充:terminal CSI parser 继续补齐 DEC 私有 DSR/CPR,`CSI ?6n` 现在归入 cursor-position report query,`CSI ?row;col;page R` 会保留 page 元数据。
417+
- 本轮补充:terminal CSI parser 现在保留 CPR cursor-position response 的完整参数列表,例如 `CSI ?12;34;2R` 会同时暴露 row/column/page 和原始 params。
417418
- 本轮补充:terminal CSI parser 现在保留 DSR/device-status report 的完整参数列表,例如 `CSI ?6;1n` 会同时暴露首个 report code 和原始 params。
418419
- 本轮补充:terminal CSI parser 把 xterm window manipulation/report (`CSI t`) 归入 report action,覆盖常见 `CSI 14t`/`CSI 18t` 查询,并把 `CSI 4;height;width t``CSI 8;rows;cols t` 的 pixel/text-area 尺寸参数结构化暴露。
419420
- 本轮补充:terminal CSI parser 现在保留 xterm window report 的完整参数列表,例如 `CSI 3;x;y t``CSI 4;height;width t``CSI 8;rows;cols t` 不再丢失 report code 后面的原始字段。

docs/first-second-parity-audit.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ M7 progress now includes:
326326
- `internal/tui`: terminal CSI parsing now preserves complete DSR/device-status parameter lists such as `CSI ?6;1n` while keeping the existing first-code and private-marker fields.
327327
- `internal/tui`: terminal CSI parser now emits report actions for CPR cursor-position responses such as `CSI row;col R` and DEC private `CSI ? row;col R`, preserving row/column metadata while keeping visible text clean.
328328
- `internal/tui`: terminal CSI parser now treats DEC private `CSI ?6n` as a cursor-position report query and preserves the optional page field from `CSI ?row;col;page R` CPR responses.
329+
- `internal/tui`: terminal CSI parsing now preserves complete CPR cursor-position response parameter lists such as `CSI ?12;34;2R` while keeping the existing structured row/column/page fields.
329330
- `internal/tui`: terminal sequence dispatcher and parser now classify DCS/APC/PM/SOS string-control sequences as `stringControl` actions with payload, terminator, and incomplete-flush state while keeping visible text extraction free of those invisible payloads.
330331
- `internal/tui`: terminal CSI parser now recognizes DEC X10, highlight, UTF-8, urxvt numeric, and xterm SGR-pixels mouse modes (`?9h/l`, `?1001h/l`, `?1005h/l`, `?1015h/l`, `?1016h/l`) as mouse-tracking mode actions.
331332
- `internal/tui`: terminal CSI parser now recognizes xterm alternate scroll mode (`?1007h/l`) as a structured mode action instead of an unknown sequence.

internal/tui/terminal_csi.go

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ func ParseCSISequence(sequence string) (CSIAction, bool) {
464464
case CSICommandDeleteCharacters:
465465
return csiEdit(CSIEditActionDeleteChars, p0), true
466466
case CSICommandCursorPosReport:
467-
return csiCursorPositionReport(p0, p1, p2, privateMode), true
467+
return csiCursorPositionReport(p0, p1, p2, params, privateMode), true
468468
case CSICommandInsertLines:
469469
return csiEdit(CSIEditActionInsertLines, p0), true
470470
case CSICommandDeleteLines:
@@ -600,16 +600,20 @@ func csiReport(code int, params []int, privateMode byte) CSIAction {
600600
}
601601
}
602602

603-
func csiCursorPositionReport(row int, column int, page int, privateMode byte) CSIAction {
603+
func csiCursorPositionReport(row int, column int, page int, params []int, privateMode byte) CSIAction {
604+
report := CSIReportAction{
605+
Type: CSIReportActionCursorPosition,
606+
PrivateMode: privateMode,
607+
Row: row,
608+
Column: column,
609+
Page: page,
610+
}
611+
if len(params) > 1 {
612+
report.Params = append([]int(nil), params...)
613+
}
604614
return CSIAction{
605-
Type: CSIActionReport,
606-
Report: CSIReportAction{
607-
Type: CSIReportActionCursorPosition,
608-
PrivateMode: privateMode,
609-
Row: row,
610-
Column: column,
611-
Page: page,
612-
},
615+
Type: CSIActionReport,
616+
Report: report,
613617
}
614618
}
615619

internal/tui/terminal_parser_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ func TestTerminalParserDispatchesCursorPositionReports(t *testing.T) {
502502
if len(actions) != 3 {
503503
t.Fatalf("actions = %#v", actions)
504504
}
505-
if actions[1].Type != TerminalActionReport || actions[1].Report.Type != CSIReportActionCursorPosition || actions[1].Report.PrivateMode != '?' || actions[1].Report.Row != 12 || actions[1].Report.Column != 34 || actions[1].Report.Page != 2 {
505+
if actions[1].Type != TerminalActionReport || actions[1].Report.Type != CSIReportActionCursorPosition || actions[1].Report.PrivateMode != '?' || actions[1].Report.Row != 12 || actions[1].Report.Column != 34 || actions[1].Report.Page != 2 || !reflect.DeepEqual(actions[1].Report.Params, []int{12, 34, 2}) {
506506
t.Fatalf("cursor position report action = %#v", actions[1])
507507
}
508508
if got := TerminalVisibleText(input); got != "ab" {

internal/tui/tui_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5284,10 +5284,10 @@ func TestParseCSISequenceActions(t *testing.T) {
52845284
{seq: CSISequence("?6n"), want: CSIReportAction{Type: CSIReportActionCursorPosition, Code: 6, PrivateMode: '?'}},
52855285
{seq: CSISequence("?6;1n"), want: CSIReportAction{Type: CSIReportActionCursorPosition, Code: 6, Params: []int{6, 1}, PrivateMode: '?'}},
52865286
{seq: CSISequence("?25n"), want: CSIReportAction{Type: CSIReportActionUnknown, Code: 25, PrivateMode: '?'}},
5287-
{seq: CSISequence(12, 34, "R"), want: CSIReportAction{Type: CSIReportActionCursorPosition, Row: 12, Column: 34}},
5288-
{seq: CSISequence("0;0R"), want: CSIReportAction{Type: CSIReportActionCursorPosition, Row: 1, Column: 1}},
5289-
{seq: CSISequence("?7;8R"), want: CSIReportAction{Type: CSIReportActionCursorPosition, PrivateMode: '?', Row: 7, Column: 8}},
5290-
{seq: CSISequence("?7;8;2R"), want: CSIReportAction{Type: CSIReportActionCursorPosition, PrivateMode: '?', Row: 7, Column: 8, Page: 2}},
5287+
{seq: CSISequence(12, 34, "R"), want: CSIReportAction{Type: CSIReportActionCursorPosition, Params: []int{12, 34}, Row: 12, Column: 34}},
5288+
{seq: CSISequence("0;0R"), want: CSIReportAction{Type: CSIReportActionCursorPosition, Params: []int{0, 0}, Row: 1, Column: 1}},
5289+
{seq: CSISequence("?7;8R"), want: CSIReportAction{Type: CSIReportActionCursorPosition, Params: []int{7, 8}, PrivateMode: '?', Row: 7, Column: 8}},
5290+
{seq: CSISequence("?7;8;2R"), want: CSIReportAction{Type: CSIReportActionCursorPosition, Params: []int{7, 8, 2}, PrivateMode: '?', Row: 7, Column: 8, Page: 2}},
52915291
{seq: CSISequence("4$p"), want: CSIReportAction{Type: CSIReportActionModeRequest, Code: 4}},
52925292
{seq: CSISequence("?25$p"), want: CSIReportAction{Type: CSIReportActionModeRequest, Code: 25, PrivateMode: '?'}},
52935293
{seq: CSISequence("?25;1000$p"), want: CSIReportAction{Type: CSIReportActionModeRequest, Code: 25, Params: []int{25, 1000}, PrivateMode: '?'}},

0 commit comments

Comments
 (0)