Open chat file links at the referenced line (#2309)

* fix(app): open chat file links at referenced lines

Pass chat file locations through the editable CodeMirror path so opening a reference selects and scrolls to its requested line. Cover the real assistant-link flow with a browser regression.

* fix(app): repeat chat file navigation

Track file navigation separately from stable tab identity so reopening the same path and line recenters both editable and read-only panes. Extend the browser regression to cover moving away and clicking the same link again.

* test(app): stabilize repeated file link navigation
This commit is contained in:
Mohamed Boudra
2026-07-21 21:34:20 +02:00
committed by GitHub
parent 7d10791bad
commit cb6d2f1459
8 changed files with 131 additions and 3 deletions
@@ -1,11 +1,14 @@
import { Text, View } from "react-native";
import { StyleSheet } from "react-native-unistyles";
import type { HighlightStyle } from "@getpaseo/highlight";
import type { WorkspaceFileLocation } from "@/workspace/file-open";
import type { FileEditorModel } from "./model";
export function FileEditorView(_props: {
model: FileEditorModel;
filename: string;
location: WorkspaceFileLocation;
navigationRevision: number;
vimEnabled: boolean;
theme: {
background: string;
@@ -3,12 +3,15 @@ import { Annotation, Compartment, EditorState, Transaction } from "@codemirror/s
import { EditorView } from "@codemirror/view";
import { getLanguageForFile } from "@getpaseo/highlight";
import { getCM, vim } from "@replit/codemirror-vim";
import type { WorkspaceFileLocation } from "@/workspace/file-open";
import type { FileEditorModel } from "./model";
import { editorBaseExtensions, editorTheme, type EditorVisualTheme } from "./extensions.web";
interface FileEditorViewProps {
model: FileEditorModel;
filename: string;
location: WorkspaceFileLocation;
navigationRevision: number;
vimEnabled: boolean;
theme: EditorVisualTheme;
onCursorChange(position: { line: number; column: number }): void;
@@ -22,6 +25,8 @@ const vimCompartment = new Compartment();
export function FileEditorView({
model,
filename,
location,
navigationRevision,
vimEnabled,
theme,
onCursorChange,
@@ -81,6 +86,19 @@ export function FileEditorView({
});
}, [snapshot.content]);
useEffect(() => {
const view = viewRef.current;
if (!view || !location.lineStart) return;
const lineStart = Math.min(location.lineStart, view.state.doc.lines);
const lineEnd = Math.min(location.lineEnd ?? lineStart, view.state.doc.lines);
const from = view.state.doc.line(lineStart).from;
const to = view.state.doc.line(Math.max(lineStart, lineEnd)).to;
view.dispatch({
selection: { anchor: from, head: lineEnd > lineStart ? to : from },
effects: EditorView.scrollIntoView(from, { y: "center" }),
});
}, [location.lineEnd, location.lineStart, navigationRevision]);
useEffect(() => {
viewRef.current?.dispatch({
effects: languageCompartment.reconfigure(getLanguageForFile(filename)?.extension ?? []),