Merge pull request #27123 from overleaf/ae-goto-scroll-select-text

Highlight double-clicked word when syncing position from PDF to code

GitOrigin-RevId: da120af9dec203346cb85c6aa7e403f4e585c748
This commit is contained in:
Alf Eaton
2025-07-28 10:53:29 +01:00
committed by Copybot
parent a689d03b41
commit 9958ffdf68
4 changed files with 29 additions and 13 deletions
@@ -268,7 +268,10 @@ function PdfJsViewer({ url, pdfFile }: PdfJsViewerProps) {
window.dispatchEvent(
new CustomEvent('synctex:sync-to-position', {
detail: clickPosition,
detail: {
position: clickPosition,
selectText: window.getSelection()?.toString(),
},
})
)
}
@@ -89,12 +89,13 @@ export default function useSynctex(): {
}, [dirname, getCurrentDocumentId, pathInFolder, rootDocId])
const goToCodeLine = useCallback(
(file?: string, line?: number) => {
(file?: string, line?: number, selectText?: string) => {
if (file) {
const doc = findEntityByPath(file)?.entity
if (doc) {
openDocWithId(doc._id, {
gotoLine: line,
selectText,
})
return
}
@@ -186,9 +187,11 @@ export default function useSynctex(): {
const _syncToCode = useCallback(
({
position = positionRef.current,
selectText,
visualOffset = 0,
}: {
position?: PdfScrollPosition
selectText?: string
visualOffset?: number
}) => {
if (!position) {
@@ -231,7 +234,7 @@ export default function useSynctex(): {
getJSON(`/project/${projectId}/sync/pdf?${params}`, { signal })
.then(data => {
const [{ file, line }] = data.code
goToCodeLine(file, line)
goToCodeLine(file, line, selectText)
if (data.downloadedFromCache) {
sendMB('synctex-downloaded-from-cache', {
projectId,
@@ -266,10 +269,7 @@ export default function useSynctex(): {
useEventListener(
'synctex:sync-to-position',
useCallback(
(event: CustomEvent) => syncToCode({ position: event.detail }),
[syncToCode]
)
useCallback((event: CustomEvent) => syncToCode(event.detail), [syncToCode])
)
const [hasSingleSelectedDoc, setHasSingleSelectedDoc] = useDetachState(
@@ -143,7 +143,7 @@ const dispatchSelectionAndScroll = (
export const setCursorLineAndScroll = (
view: EditorView,
lineNumber: number,
columnNumber = 0,
columnNumber?: number,
selectText?: string
) => {
// TODO: map the position through any changes since the previous compile?
@@ -153,10 +153,23 @@ export const setCursorLineAndScroll = (
const from = findValidPosition(doc, lineNumber, columnNumber)
if (selectText) {
const to = from + selectText.length
if (doc.sliceString(from, to) === selectText) {
dispatchSelectionAndScroll(view, from, to)
return
if (columnNumber === undefined) {
// somewhere on this line
const line = doc.lineAt(from)
const index = line.text.indexOf(selectText)
if (index > -1 && index === line.text.lastIndexOf(selectText)) {
const from = line.from + index
const to = from + selectText.length
dispatchSelectionAndScroll(view, from, to)
return
}
} else {
// at this exact position
const to = from + selectText.length
if (doc.sliceString(from, to) === selectText) {
dispatchSelectionAndScroll(view, from, to)
return
}
}
}
@@ -3,7 +3,7 @@ import { Text } from '@codemirror/state'
export const findValidPosition = (
doc: Text,
lineNumber: number, // 1-indexed
columnNumber: number // 0-indexed
columnNumber = 0 // 0-indexed
): number => {
const lines = doc.lines