Compare commits
4
Commits
b50e0c0224
...
36f41f00f0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
36f41f00f0 | ||
|
|
57dbdd5d02 | ||
|
|
9d3966772b | ||
|
|
7ab71fc843 |
+11
-11
@@ -14,13 +14,13 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@sveltejs/adapter-auto": "^7.0.1",
|
"@sveltejs/adapter-auto": "^7.0.1",
|
||||||
"@sveltejs/adapter-static": "^3.0.10",
|
"@sveltejs/adapter-static": "^3.0.10",
|
||||||
"@sveltejs/kit": "^2.70.1",
|
"@sveltejs/kit": "^2.70.3",
|
||||||
"@sveltejs/vite-plugin-svelte": "^6.2.4",
|
"@sveltejs/vite-plugin-svelte": "^6.2.4",
|
||||||
"@tailwindcss/forms": "^0.5.11",
|
"@tailwindcss/forms": "^0.5.11",
|
||||||
"@tailwindcss/typography": "^0.5.20",
|
"@tailwindcss/typography": "^0.5.20",
|
||||||
"@tailwindcss/vite": "^4.3.3",
|
"@tailwindcss/vite": "^4.3.3",
|
||||||
"svelte": "^5.56.7",
|
"svelte": "^5.57.0",
|
||||||
"svelte-check": "^4.7.3",
|
"svelte-check": "^4.7.6",
|
||||||
"tailwindcss": "^4.3.3",
|
"tailwindcss": "^4.3.3",
|
||||||
"typescript": "^5.9.3",
|
"typescript": "^5.9.3",
|
||||||
"vite": "^7.3.6",
|
"vite": "^7.3.6",
|
||||||
@@ -29,21 +29,21 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/autocomplete": "^6.20.3",
|
"@codemirror/autocomplete": "^6.20.3",
|
||||||
"@codemirror/commands": "^6.10.4",
|
"@codemirror/commands": "^6.11.0",
|
||||||
"@codemirror/lang-rust": "^6.0.2",
|
"@codemirror/lang-rust": "^6.0.2",
|
||||||
"@codemirror/lint": "^6.9.7",
|
"@codemirror/lint": "^6.9.7",
|
||||||
"@codemirror/lsp-client": "^6.2.5",
|
"@codemirror/lsp-client": "^6.2.5",
|
||||||
"@codemirror/legacy-modes": "^6.5.3",
|
"@codemirror/legacy-modes": "^6.5.4",
|
||||||
"@codemirror/language": "^6.12.4",
|
"@codemirror/language": "^6.12.4",
|
||||||
"@codemirror/state": "^6.7.1",
|
"@codemirror/state": "^6.7.4",
|
||||||
"@codemirror/view": "^6.43.6",
|
"@codemirror/view": "^6.43.11",
|
||||||
"@iconify/svelte": "^5.2.2",
|
"@iconify/svelte": "^5.2.2",
|
||||||
"chart.js": "^4.5.1",
|
"chart.js": "^4.5.1",
|
||||||
"codemirror": "^6.0.2",
|
"codemirror": "^6.0.2",
|
||||||
"codemirror-lang-typst": "^0.4.0",
|
"codemirror-lang-typst": "^0.4.0",
|
||||||
"highlight.js": "^11.11.1",
|
"highlight.js": "^11.12.0",
|
||||||
"y-codemirror.next": "^0.3.5",
|
"y-codemirror.next": "^0.3.6",
|
||||||
"y-websocket": "^3.0.0",
|
"y-websocket": "^3.1.0",
|
||||||
"yjs": "^13.6.31"
|
"yjs": "^13.6.32"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-4
@@ -726,8 +726,10 @@ pub async fn lsp_handler(
|
|||||||
.arg("--font-path")
|
.arg("--font-path")
|
||||||
.arg(temp_dir.path())
|
.arg(temp_dir.path())
|
||||||
.current_dir(temp_dir.path())
|
.current_dir(temp_dir.path())
|
||||||
|
.env("RUST_LOG", "warn")
|
||||||
.stdin(Stdio::piped())
|
.stdin(Stdio::piped())
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
|
.kill_on_drop(true)
|
||||||
.spawn()
|
.spawn()
|
||||||
.expect("Failed to start tinymist lsp");
|
.expect("Failed to start tinymist lsp");
|
||||||
|
|
||||||
@@ -745,7 +747,7 @@ pub async fn lsp_handler(
|
|||||||
use futures_util::SinkExt;
|
use futures_util::SinkExt;
|
||||||
let _ = ws_tx.send(axum::extract::ws::Message::Text(init_msg.to_string().into())).await;
|
let _ = ws_tx.send(axum::extract::ws::Message::Text(init_msg.to_string().into())).await;
|
||||||
|
|
||||||
let ws_to_lsp = tokio::spawn(async move {
|
let mut ws_to_lsp = tokio::spawn(async move {
|
||||||
while let Some(Ok(axum::extract::ws::Message::Text(msg))) = ws_rx.next().await {
|
while let Some(Ok(axum::extract::ws::Message::Text(msg))) = ws_rx.next().await {
|
||||||
let content_length = format!("Content-Length: {}\r\n\r\n", msg.len());
|
let content_length = format!("Content-Length: {}\r\n\r\n", msg.len());
|
||||||
if stdin.write_all(content_length.as_bytes()).await.is_err() {
|
if stdin.write_all(content_length.as_bytes()).await.is_err() {
|
||||||
@@ -757,7 +759,7 @@ pub async fn lsp_handler(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let lsp_to_ws = tokio::spawn(async move {
|
let mut lsp_to_ws = tokio::spawn(async move {
|
||||||
loop {
|
loop {
|
||||||
let mut content_length = 0;
|
let mut content_length = 0;
|
||||||
let mut header = String::new();
|
let mut header = String::new();
|
||||||
@@ -797,9 +799,13 @@ pub async fn lsp_handler(
|
|||||||
});
|
});
|
||||||
|
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
_ = ws_to_lsp => {}
|
_ = &mut ws_to_lsp => {}
|
||||||
_ = lsp_to_ws => {}
|
_ = &mut lsp_to_ws => {}
|
||||||
_ = child.wait() => {}
|
_ = child.wait() => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ws_to_lsp.abort();
|
||||||
|
lsp_to_ws.abort();
|
||||||
|
let _ = child.kill().await;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,8 +12,10 @@
|
|||||||
import { getThemeExtension } from '../ts/themes';
|
import { getThemeExtension } from '../ts/themes';
|
||||||
import { themeStore, darkModeStore, editorViewStore, editorErrors, triggerLspReconnect } from '../ts/store';
|
import { themeStore, darkModeStore, editorViewStore, editorErrors, triggerLspReconnect } from '../ts/store';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
import { LSPClient, languageServerExtensions } from "@codemirror/lsp-client";
|
import { LSPClient } from "@codemirror/lsp-client";
|
||||||
|
import { typstLspExtensions } from '../ts/editor-lsp';
|
||||||
import { setDiagnostics, lintGutter } from '@codemirror/lint';
|
import { setDiagnostics, lintGutter } from '@codemirror/lint';
|
||||||
|
import { bracketExtensions, typstBracketSettings } from '../ts/editor-brackets';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ytext = undefined,
|
ytext = undefined,
|
||||||
@@ -168,7 +170,7 @@
|
|||||||
);
|
);
|
||||||
|
|
||||||
const isToml = (filePath ?? '').toLowerCase().endsWith('.toml');
|
const isToml = (filePath ?? '').toLowerCase().endsWith('.toml');
|
||||||
const languageExtension = isToml ? StreamLanguage.define(toml) : myLang;
|
const languageExtension = isToml ? StreamLanguage.define(toml) : [myLang, typstBracketSettings(myLang)];
|
||||||
const completionExtensions = isToml ? [] : [autocompletion({ override: [typstCompletions] })];
|
const completionExtensions = isToml ? [] : [autocompletion({ override: [typstCompletions] })];
|
||||||
|
|
||||||
state = EditorState.create({
|
state = EditorState.create({
|
||||||
@@ -177,6 +179,7 @@
|
|||||||
lineNumbers(),
|
lineNumbers(),
|
||||||
lintGutter(),
|
lintGutter(),
|
||||||
history(),
|
history(),
|
||||||
|
...bracketExtensions,
|
||||||
keymap.of([...defaultKeymap, ...historyKeymap, indentWithTab] as any),
|
keymap.of([...defaultKeymap, ...historyKeymap, indentWithTab] as any),
|
||||||
languageExtension,
|
languageExtension,
|
||||||
yCollab(activeText, activeProvider.awareness),
|
yCollab(activeText, activeProvider.awareness),
|
||||||
@@ -200,6 +203,7 @@
|
|||||||
|
|
||||||
editorViewStore.set(view);
|
editorViewStore.set(view);
|
||||||
|
|
||||||
|
let lastCompilerDiagnostics = '';
|
||||||
unsubscribeErrors = editorErrors.subscribe((errors) => {
|
unsubscribeErrors = editorErrors.subscribe((errors) => {
|
||||||
if (view) {
|
if (view) {
|
||||||
const docLen = view.state.doc.length;
|
const docLen = view.state.doc.length;
|
||||||
@@ -216,6 +220,9 @@
|
|||||||
message: e.message
|
message: e.message
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
const snapshot = JSON.stringify(safeDiagnostics);
|
||||||
|
if (snapshot === lastCompilerDiagnostics) return;
|
||||||
|
lastCompilerDiagnostics = snapshot;
|
||||||
view.dispatch(setDiagnostics(view.state, safeDiagnostics));
|
view.dispatch(setDiagnostics(view.state, safeDiagnostics));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -244,6 +251,7 @@
|
|||||||
|
|
||||||
let lsHandlers: ((value: string) => void)[] = [];
|
let lsHandlers: ((value: string) => void)[] = [];
|
||||||
let lspInitialized = false;
|
let lspInitialized = false;
|
||||||
|
let lastServerDiagnostics = '';
|
||||||
|
|
||||||
const transport = {
|
const transport = {
|
||||||
send(message: string) { if (lsSocket?.readyState === WebSocket.OPEN) lsSocket.send(message); },
|
send(message: string) { if (lsSocket?.readyState === WebSocket.OPEN) lsSocket.send(message); },
|
||||||
@@ -259,6 +267,7 @@
|
|||||||
|
|
||||||
lspInitialized = false;
|
lspInitialized = false;
|
||||||
lsHandlers = [];
|
lsHandlers = [];
|
||||||
|
lastServerDiagnostics = '';
|
||||||
|
|
||||||
lsSocket = new WebSocket(`${protocol}//${host}/api/lsp/${docId}`);
|
lsSocket = new WebSocket(`${protocol}//${host}/api/lsp/${docId}`);
|
||||||
|
|
||||||
@@ -272,7 +281,7 @@
|
|||||||
client = new LSPClient({
|
client = new LSPClient({
|
||||||
rootUri: msg.rootUri,
|
rootUri: msg.rootUri,
|
||||||
timeout: 10000,
|
timeout: 10000,
|
||||||
extensions: languageServerExtensions()
|
extensions: typstLspExtensions()
|
||||||
}).connect(transport);
|
}).connect(transport);
|
||||||
|
|
||||||
view.dispatch({
|
view.dispatch({
|
||||||
@@ -290,6 +299,10 @@
|
|||||||
if (msg.method === 'textDocument/publishDiagnostics' && msg.params && msg.params.diagnostics) {
|
if (msg.method === 'textDocument/publishDiagnostics' && msg.params && msg.params.diagnostics) {
|
||||||
msg.params.diagnostics = msg.params.diagnostics.filter((d: any) => !d.message.toLowerCase().includes('unknown font family'));
|
msg.params.diagnostics = msg.params.diagnostics.filter((d: any) => !d.message.toLowerCase().includes('unknown font family'));
|
||||||
processedData = JSON.stringify(msg);
|
processedData = JSON.stringify(msg);
|
||||||
|
|
||||||
|
const snapshot = `${msg.params.uri}:${msg.params.version ?? ''}:${JSON.stringify(msg.params.diagnostics)}`;
|
||||||
|
if (snapshot === lastServerDiagnostics) return;
|
||||||
|
lastServerDiagnostics = snapshot;
|
||||||
}
|
}
|
||||||
} catch (err) {}
|
} catch (err) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { userStore } from '$lib/ts/auth';
|
import { userStore } from '$lib/ts/auth';
|
||||||
import Icon from '@iconify/svelte';
|
import Icon from '@iconify/svelte';
|
||||||
import ThemePicker from '$lib/components/ThemePicker.svelte';
|
|
||||||
|
|
||||||
async function logout() {
|
async function logout() {
|
||||||
await fetch('/api/auth/logout', { method: 'POST' });
|
await fetch('/api/auth/logout', { method: 'POST' });
|
||||||
@@ -43,8 +42,6 @@
|
|||||||
</a>
|
</a>
|
||||||
<div class="h-5 w-px bg-[var(--color-line)]"></div>
|
<div class="h-5 w-px bg-[var(--color-line)]"></div>
|
||||||
|
|
||||||
<ThemePicker />
|
|
||||||
|
|
||||||
<button onclick={() => goto('/settings')} class="text-sm font-medium text-[var(--color-ink-muted)] hover:text-[var(--color-ink)] transition-colors bg-[var(--color-surface-muted)] hover:bg-[var(--color-surface-sunken)] px-2 py-1.5 rounded-md flex items-center gap-2" title="Settings">
|
<button onclick={() => goto('/settings')} class="text-sm font-medium text-[var(--color-ink-muted)] hover:text-[var(--color-ink)] transition-colors bg-[var(--color-surface-muted)] hover:bg-[var(--color-surface-sunken)] px-2 py-1.5 rounded-md flex items-center gap-2" title="Settings">
|
||||||
<Icon icon="mdi:cog" class="text-lg" />
|
<Icon icon="mdi:cog" class="text-lg" />
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
import { closeBrackets, closeBracketsKeymap } from '@codemirror/autocomplete';
|
||||||
|
import { EditorView, keymap } from '@codemirror/view';
|
||||||
|
import { EditorSelection, Prec } from '@codemirror/state';
|
||||||
|
import type { Language } from '@codemirror/language';
|
||||||
|
|
||||||
|
const autoClosedDelimiters = ['(', '[', '{', '"', '$'];
|
||||||
|
|
||||||
|
const charactersAllowedAfterOpening = ')]}:;>,.$';
|
||||||
|
|
||||||
|
const markupDelimiters: Record<string, string> = {
|
||||||
|
'*': '*',
|
||||||
|
_: '_',
|
||||||
|
'`': '`',
|
||||||
|
'<': '>'
|
||||||
|
};
|
||||||
|
|
||||||
|
export function typstBracketSettings(language: Language) {
|
||||||
|
return language.data.of({
|
||||||
|
closeBrackets: {
|
||||||
|
brackets: autoClosedDelimiters,
|
||||||
|
before: charactersAllowedAfterOpening
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function surroundSelection(view: EditorView, typedText: string) {
|
||||||
|
const closingText = markupDelimiters[typedText];
|
||||||
|
if (!closingText) return false;
|
||||||
|
|
||||||
|
const state = view.state;
|
||||||
|
if (state.readOnly || state.selection.ranges.every((range) => range.empty)) return false;
|
||||||
|
|
||||||
|
const changes = state.changeByRange((range) => {
|
||||||
|
if (range.empty) return { range };
|
||||||
|
const shift = typedText.length;
|
||||||
|
return {
|
||||||
|
changes: [
|
||||||
|
{ from: range.from, insert: typedText },
|
||||||
|
{ from: range.to, insert: closingText }
|
||||||
|
],
|
||||||
|
range: EditorSelection.range(range.anchor + shift, range.head + shift)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
view.dispatch(state.update(changes, { scrollIntoView: true, userEvent: 'input.type' }));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const bracketExtensions = [
|
||||||
|
closeBrackets(),
|
||||||
|
Prec.high(
|
||||||
|
EditorView.inputHandler.of((view, _from, _to, typedText) => surroundSelection(view, typedText))
|
||||||
|
),
|
||||||
|
keymap.of(closeBracketsKeymap)
|
||||||
|
];
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import {
|
||||||
|
serverCompletion,
|
||||||
|
serverDiagnostics,
|
||||||
|
signatureHelp,
|
||||||
|
formatKeymap,
|
||||||
|
renameKeymap,
|
||||||
|
jumpToDefinitionKeymap,
|
||||||
|
findReferencesKeymap
|
||||||
|
} from '@codemirror/lsp-client';
|
||||||
|
import { keymap } from '@codemirror/view';
|
||||||
|
|
||||||
|
export function typstLspExtensions() {
|
||||||
|
return [
|
||||||
|
serverCompletion(),
|
||||||
|
signatureHelp(),
|
||||||
|
serverDiagnostics(),
|
||||||
|
keymap.of([...formatKeymap, ...renameKeymap, ...jumpToDefinitionKeymap, ...findReferencesKeymap])
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -2,9 +2,7 @@
|
|||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { userStore } from '$lib/ts/auth';
|
import { userStore } from '$lib/ts/auth';
|
||||||
import { themeStore, darkModeStore } from '$lib/ts/store';
|
|
||||||
import Icon from '@iconify/svelte';
|
import Icon from '@iconify/svelte';
|
||||||
import ThemePicker from '$lib/components/ThemePicker.svelte';
|
|
||||||
import Navbar from '$lib/components/dashboard/Navbar.svelte';
|
import Navbar from '$lib/components/dashboard/Navbar.svelte';
|
||||||
import FolderRow from '$lib/components/dashboard/FolderRow.svelte';
|
import FolderRow from '$lib/components/dashboard/FolderRow.svelte';
|
||||||
import DocCard from '$lib/components/dashboard/DocCard.svelte';
|
import DocCard from '$lib/components/dashboard/DocCard.svelte';
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
let svgs = $state<string[]>([]);
|
let svgs = $state<string[]>([]);
|
||||||
let errors = $state<Diagnostic[]>([]);
|
let errors = $state<Diagnostic[]>([]);
|
||||||
let timeoutId: number | undefined;
|
let timeoutId: number | undefined;
|
||||||
|
let lastCompiledContent: string | null = null;
|
||||||
let initialized = $state(false);
|
let initialized = $state(false);
|
||||||
let documentTitle = $state('Untitled Document');
|
let documentTitle = $state('Untitled Document');
|
||||||
let isViewer = $state(false);
|
let isViewer = $state(false);
|
||||||
@@ -54,6 +55,8 @@
|
|||||||
function triggerCompile() {
|
function triggerCompile() {
|
||||||
if (!text || !$previewOpenStore) return;
|
if (!text || !$previewOpenStore) return;
|
||||||
const content = text.toString();
|
const content = text.toString();
|
||||||
|
if (content === lastCompiledContent) return;
|
||||||
|
lastCompiledContent = content;
|
||||||
const docId = $page.params.id;
|
const docId = $page.params.id;
|
||||||
compileTypst(content, docId)
|
compileTypst(content, docId)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
@@ -71,6 +74,7 @@
|
|||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
console.error('Compilation fetch failed', e);
|
console.error('Compilation fetch failed', e);
|
||||||
|
lastCompiledContent = null;
|
||||||
errors = [{ message: 'Network or Server Error compiling document.', severity: 'error' }];
|
errors = [{ message: 'Network or Server Error compiling document.', severity: 'error' }];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -106,8 +110,6 @@
|
|||||||
timeoutId = window.setTimeout(triggerCompile, 500);
|
timeoutId = window.setTimeout(triggerCompile, 500);
|
||||||
});
|
});
|
||||||
|
|
||||||
triggerCompile();
|
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
if (timeoutId) clearTimeout(timeoutId);
|
if (timeoutId) clearTimeout(timeoutId);
|
||||||
cleanupYjs();
|
cleanupYjs();
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
let showPublish = $state(false);
|
let showPublish = $state(false);
|
||||||
let ready = $state(false);
|
let ready = $state(false);
|
||||||
let timeoutId: number | undefined;
|
let timeoutId: number | undefined;
|
||||||
|
let lastCompiledSources: string | null = null;
|
||||||
|
|
||||||
let contextMenu = $state({ show: false, x: 0, y: 0, text: '' });
|
let contextMenu = $state({ show: false, x: 0, y: 0, text: '' });
|
||||||
|
|
||||||
@@ -43,9 +44,18 @@
|
|||||||
timeoutId = window.setTimeout(triggerCompile, 500);
|
timeoutId = window.setTimeout(triggerCompile, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function recompileAfterFileChange() {
|
||||||
|
lastCompiledSources = null;
|
||||||
|
scheduleCompile();
|
||||||
|
}
|
||||||
|
|
||||||
function triggerCompile() {
|
function triggerCompile() {
|
||||||
if (!$previewOpenStore) return;
|
if (!$previewOpenStore) return;
|
||||||
compileProject(projectId, getAllText())
|
const sources = getAllText();
|
||||||
|
const fingerprint = JSON.stringify(sources);
|
||||||
|
if (fingerprint === lastCompiledSources) return;
|
||||||
|
lastCompiledSources = fingerprint;
|
||||||
|
compileProject(projectId, sources)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.stats) $documentStatsStore = res.stats;
|
if (res.stats) $documentStatsStore = res.stats;
|
||||||
if (res.svgs) {
|
if (res.svgs) {
|
||||||
@@ -58,6 +68,7 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
|
lastCompiledSources = null;
|
||||||
errors = [{ message: 'Network or server error compiling project.', severity: 'error' }];
|
errors = [{ message: 'Network or server error compiling project.', severity: 'error' }];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -106,7 +117,7 @@
|
|||||||
const res = await fetch(`/api/projects/${projectId}/files/upload`, { method: 'POST', body: form });
|
const res = await fetch(`/api/projects/${projectId}/files/upload`, { method: 'POST', body: form });
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
await loadFiles();
|
await loadFiles();
|
||||||
triggerCompile();
|
recompileAfterFileChange();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,7 +130,7 @@
|
|||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
files = files.map((f) => (f.id === file.id ? { ...f, path } : f));
|
files = files.map((f) => (f.id === file.id ? { ...f, path } : f));
|
||||||
renameOpenFile(file.id, path);
|
renameOpenFile(file.id, path);
|
||||||
scheduleCompile();
|
recompileAfterFileChange();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,7 +143,7 @@
|
|||||||
if (activeFileId === file.id) {
|
if (activeFileId === file.id) {
|
||||||
activeFileId = files.find((f) => f.kind === 'text')?.id ?? '';
|
activeFileId = files.find((f) => f.kind === 'text')?.id ?? '';
|
||||||
}
|
}
|
||||||
scheduleCompile();
|
recompileAfterFileChange();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +155,7 @@
|
|||||||
});
|
});
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
entrypoint = file.path;
|
entrypoint = file.path;
|
||||||
scheduleCompile();
|
recompileAfterFileChange();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user