Skip to content

feat(preview): line numbers, quotePath handling, synthetic untracked diff - #42

Merged
linletian merged 3 commits into
developfrom
feature/text-file-preview
Jun 20, 2026
Merged

feat(preview): line numbers, quotePath handling, synthetic untracked diff#42
linletian merged 3 commits into
developfrom
feature/text-file-preview

Conversation

@linletian

Copy link
Copy Markdown
Owner

Summary

Iteration on the text file preview feature landed in #XX, adding three pieces of functionality called out by code review:

  • Line-numbered rendering in preview.html: single-row flex containers (.code-line) replace the original two-column <pre> layout, eliminating baseline drift between line-number and code gutters. splitHighlightedLines tracks unclosed <span> across lines so multi-line tokens (block comments, raw strings) keep their colour.
  • core.quotePath handling in app.go: every git invocation now passes -c core.quotePath=false, with unquoteGitPath as a defense-in-depth safety net for non-ASCII paths (e.g. Chinese filenames in Safari bug reports).
  • Synthetic full-addition diff for untracked files: when git diff returns empty, handleWorktreeFileDiff reads the file and constructs a standard unified diff (incl. \ No newline at end of file marker), with os.Stat pre-check + post-build re-check honouring the 500KB cap.

Test plan

  • go test ./... passes (16 packages, no failures)
  • go vet ./... clean
  • go build ./... clean
  • TestUnquoteGitPath — 12 cases covering plain paths, C-style escapes, octal UTF-8, mixed escapes, real-world examples (Safari卡死分析报告.md)
  • TestHandleWorktreeFileDiffSynthetic — verifies @@ -0,0 +1,N @@ format and absence of no-newline marker for files ending in \n
  • TestHandleWorktreeFileDiffSyntheticNoNewline — verifies \ No newline at end of file for files without trailing newline
  • TestHandleWorktreeFileDiffSyntheticTooLarge — pins the silent-skip behaviour when file >500KB
  • Manual: open /preview against an untracked file and verify Diff tab shows full content as additions
  • Manual: open /preview against a file with Chinese path and verify title bar shows the decoded path

Docs

  • docs/API.md: documents both new endpoints (/api/worktree/file/diff, /api/worktree/file/content), including the synthetic diff contract for untracked files
  • docs/plans/text-file-preview/FEASIBILITY.md: adds "实际实现偏差" table covering layout, line numbers, diff colouring, code highlighting, tab style, synthetic diff, Chinese-path handling, size guard
  • docs/plans/text-file-preview/TASK.md: adds Phase 6 "审阅回顾与补充改动" summarising the iteration

Out of scope

No changes to the XSS surface (cd.innerHTML still trusts hljs output, consistent with existing architecture). No CSP changes (project has no CSP today).

Add Diff and Content APIs, preview.html, highlight.js/marked.js vendors, security helpers, and 16 test cases. Based on docs/plans/text-file-preview/.
…ked diff

Build on the text file preview feature with three iteration-driven
additions (FEASIBILITY/TASK updated to record design deviations):

- preview.html: per-line flex containers with line-number gutter; hljs
  splitHighlightedLines tracks unclosed <span> across lines so
  multi-line tokens (block comments, raw strings) keep their colour.
  Diff keeps hljs token-level text + CSS row-level background.
- app.go: pass -c core.quotePath=false to every git call and add
  unquoteGitPath as defense-in-depth, so non-ASCII paths survive
  core.quotePath quoting in numstat, status, and diff outputs.
- app.go: handleWorktreeFileDiff synthesises a full unified diff when
  git returns empty (untracked file), with Stat pre-check + post-build
  re-check to honour the 500KB cap and \ No newline at end of file.
- app_test.go: TestUnquoteGitPath (12 cases incl. UTF-8), plus
  Synthetic / SyntheticNoNewline / SyntheticTooLarge for the new path.
- docs/API.md: document the two endpoints and the synthetic diff
  behaviour so external consumers know what to expect.
gofmt -l flagged both files for missing final newline.
Pure whitespace fix; no behavioural change.
@linletian
linletian merged commit 944c42d into develop Jun 20, 2026
linletian added a commit that referenced this pull request Jun 20, 2026
PR #40 (GitHub sidebar link) and PR #42 (branch divergence detection) both
inlined a ~10-line `git remote` parser in their respective files. Git's
content-level merge cannot detect duplicate top-level symbols across files,
so the collision only surfaced as a Go compiler error after the merge. The
fix was to drop the divergent.go copy in the merge commit, leaving a single
implementation in remote.go.

This commit goes one step further: move that single implementation to a
new remotes.go file and export it as ListRemotes, so future features that
need the same helper have a clearly signposted canonical entry point
instead of being tempted to inline their own copy.

No behavior change. The two existing callers (GitHubURL in remote.go and
effectiveHead in diverged.go) now invoke ListRemotes directly.
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.

1 participant