feat(preview): line numbers, quotePath handling, synthetic untracked diff - #42
Merged
Conversation
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
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Iteration on the text file preview feature landed in #XX, adding three pieces of functionality called out by code review:
preview.html: single-row flex containers (.code-line) replace the original two-column<pre>layout, eliminating baseline drift between line-number and code gutters.splitHighlightedLinestracks unclosed<span>across lines so multi-line tokens (block comments, raw strings) keep their colour.core.quotePathhandling inapp.go: every git invocation now passes-c core.quotePath=false, withunquoteGitPathas a defense-in-depth safety net for non-ASCII paths (e.g. Chinese filenames in Safari bug reports).git diffreturns empty,handleWorktreeFileDiffreads the file and constructs a standard unified diff (incl.\ No newline at end of filemarker), withos.Statpre-check + post-build re-check honouring the 500KB cap.Test plan
go test ./...passes (16 packages, no failures)go vet ./...cleango build ./...cleanTestUnquoteGitPath— 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\nTestHandleWorktreeFileDiffSyntheticNoNewline— verifies\ No newline at end of filefor files without trailing newlineTestHandleWorktreeFileDiffSyntheticTooLarge— pins the silent-skip behaviour when file >500KB/previewagainst an untracked file and verify Diff tab shows full content as additions/previewagainst a file with Chinese path and verify title bar shows the decoded pathDocs
docs/API.md: documents both new endpoints (/api/worktree/file/diff,/api/worktree/file/content), including the synthetic diff contract for untracked filesdocs/plans/text-file-preview/FEASIBILITY.md: adds "实际实现偏差" table covering layout, line numbers, diff colouring, code highlighting, tab style, synthetic diff, Chinese-path handling, size guarddocs/plans/text-file-preview/TASK.md: adds Phase 6 "审阅回顾与补充改动" summarising the iterationOut of scope
No changes to the XSS surface (
cd.innerHTMLstill trusts hljs output, consistent with existing architecture). No CSP changes (project has no CSP today).