You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
SyncTeX forward search (source line → PDF position)
Important
Problem — When a researcher edits a .tex file and previews the compiled PDF, the PDF opens at page 1. There is no way to jump to the section corresponding to the code being edited.
Approach — Parse the .synctex.gz file that latexmk generates by default and implement forward search: given a source file and cursor line, scroll the PDF viewer to the corresponding page and position. This is a trailing additive slice — it depends on both the CodeMirror editor (slice 4) for cursor position and the TeX compilation pipeline (slice 5) for the .synctex.gz artifact.
Scope — in: SyncTeX .synctex.gz parser, forward search (source line → PDF page + position), PDF viewer scroll-to-position API. out: inverse search (PDF click → source line), SyncTeX file generation (handled by latexmk), custom SyncTeX configuration.
Risk — This is the highest-risk slice. The SyncTeX binary format is non-trivial and existing JS parsers (synctex-js) are minimally maintained. If the parser proves unreliable, this slice may be dropped without affecting the rest of the feature.
Acceptance Criteria
When the cursor moves in a .tex file being edited in CodeMirror, and a compiled PDF with a .synctex.gz file exists, the PDF viewer scrolls to the corresponding page and vertical position
Forward search triggers on cursor line change (not every keystroke — debounced or on explicit action)
When no .synctex.gz file exists (compilation not run, or latexmk configured without SyncTeX), forward search is silently disabled — no error, no UI element
The .synctex.gz file is read from the build output directory (same location as the compiled PDF)
Forward search accuracy: correct page and approximate vertical position (within ~100px at default zoom)
Testing Decisions
Unit test the SyncTeX parser with a fixture .synctex.gz file — verify page and position extraction for known source lines
Unit test the debounce logic for cursor-line-change triggers
Integration test: compile a fixture .tex file, verify forward search scrolls to the correct page (gated on which latexmk)
Key Decisions
Forward search only. Inverse search (click PDF → jump to source) is out of scope. Forward search is the higher-value feature (the researcher knows where they are in source and wants to see the output).
Debounced cursor tracking. Forward search triggers when the cursor line changes, not on every keystroke. A 500ms debounce prevents the PDF from jumping while the user is typing.
Best-effort parser. If the SyncTeX format proves too fragile to parse reliably in JS, this slice is dropped. The rest of #721 does not depend on it.
Constraints & Invariants
SyncTeX is purely additive — its absence never degrades the core experience
The parser never blocks the main thread (parse in a web worker or async chunks)
Forward search never fires without a valid .synctex.gz file
Prior Art
synctex-js — minimally maintained JS SyncTeX parser (evaluate before building custom)
@anthropic-ai/claude-code SyncTeX reference — not applicable (different architecture)
Source
harmoniqs/opencode — new SyncTeX parser module + PDF viewer scroll API extension in packages/app/src/components/
SyncTeX forward search (source line → PDF position)
Important
Problem — When a researcher edits a
.texfile and previews the compiled PDF, the PDF opens at page 1. There is no way to jump to the section corresponding to the code being edited.Approach — Parse the
.synctex.gzfile thatlatexmkgenerates by default and implement forward search: given a source file and cursor line, scroll the PDF viewer to the corresponding page and position. This is a trailing additive slice — it depends on both the CodeMirror editor (slice 4) for cursor position and the TeX compilation pipeline (slice 5) for the.synctex.gzartifact.Scope — in: SyncTeX
.synctex.gzparser, forward search (source line → PDF page + position), PDF viewer scroll-to-position API. out: inverse search (PDF click → source line), SyncTeX file generation (handled bylatexmk), custom SyncTeX configuration.Risk — This is the highest-risk slice. The SyncTeX binary format is non-trivial and existing JS parsers (
synctex-js) are minimally maintained. If the parser proves unreliable, this slice may be dropped without affecting the rest of the feature.Acceptance Criteria
.texfile being edited in CodeMirror, and a compiled PDF with a.synctex.gzfile exists, the PDF viewer scrolls to the corresponding page and vertical position.synctex.gzfile exists (compilation not run, orlatexmkconfigured without SyncTeX), forward search is silently disabled — no error, no UI element.synctex.gzfile is read from the build output directory (same location as the compiled PDF)Testing Decisions
.synctex.gzfile — verify page and position extraction for known source lines.texfile, verify forward search scrolls to the correct page (gated onwhich latexmk)Key Decisions
Forward search only. Inverse search (click PDF → jump to source) is out of scope. Forward search is the higher-value feature (the researcher knows where they are in source and wants to see the output).
Debounced cursor tracking. Forward search triggers when the cursor line changes, not on every keystroke. A 500ms debounce prevents the PDF from jumping while the user is typing.
Best-effort parser. If the SyncTeX format proves too fragile to parse reliably in JS, this slice is dropped. The rest of #721 does not depend on it.
Constraints & Invariants
.synctex.gzfilePrior Art
synctex-js— minimally maintained JS SyncTeX parser (evaluate before building custom)@anthropic-ai/claude-codeSyncTeX reference — not applicable (different architecture)Source
harmoniqs/opencode— new SyncTeX parser module + PDF viewer scroll API extension inpackages/app/src/components/