Skip to content

Commit d4d03fd

Browse files
authored
Merge pull request #215 from Open-STEM/kq-dragdrop
implement dragdrop in the Folder tree component
2 parents 1824014 + 4061da7 commit d4d03fd

9 files changed

Lines changed: 290 additions & 97 deletions

File tree

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"homepage": "https://experientialrobotics.org/",
55
"license": "GPL-2.0-only",
66
"private": true,
7-
"version": "2.0.11",
7+
"version": "2.0.13",
88
"type": "module",
99
"scripts": {
1010
"dev": "vite",

src/components/MonacoEditor.tsx

Lines changed: 109 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,19 @@ import getKeybindingsServiceOverride from '@codingame/monaco-vscode-keybindings-
1010
import getConfigurationServiceOverride, {
1111
updateUserConfiguration,
1212
} from '@codingame/monaco-vscode-configuration-service-override';
13-
import { ExtensionHostKind, registerExtension } from 'vscode/extensions';
1413
// we need to import this so monaco-languageclient can use vscode-api
1514
import 'vscode/localExtensionHost';
15+
import { ExtensionHostKind, registerExtension } from '@codingame/monaco-vscode-api/extensions';
1616
import { initializedAndStartLanguageClient } from '@components/lsp-client';
1717
import AppMgr, { EventType, Themes } from '@/managers/appmgr';
1818
import { StorageKeys } from '@/utils/localstorage';
1919
import EditorMgr, { EditorSession } from '@/managers/editormgr';
2020
import { FontSize } from '@/utils/types';
2121
import { Constants } from '@/utils/constants';
2222
import { useTranslation } from 'react-i18next';
23+
import { whenReady } from '@codingame/monaco-vscode-python-default-extension';
2324

2425
const languageId = 'python';
25-
let isClientInitalized: boolean = false;
2626

2727
export type WorkerLoader = () => Worker;
2828
const workerLoaders: Partial<Record<string, WorkerLoader>> = {
@@ -48,55 +48,101 @@ window.MonacoEnvironment = {
4848
},
4949
};
5050

51-
await initialize({
52-
...getThemeServiceOverride(),
53-
...getTextMateServiceOverride(),
54-
...getConfigurationServiceOverride(),
55-
...getKeybindingsServiceOverride(),
56-
...getLanguagesServiceOverride(),
57-
});
51+
let initPromise: Promise<void> | null = null;
5852

59-
// extension configuration derived from:
60-
// https://github.com/microsoft/pyright/blob/main/packages/vscode-pyright/package.json
61-
// only a minimum is required to get pyright working
62-
const extension = {
63-
name: 'python-client',
64-
publisher: 'monaco-languageclient-project',
65-
version: '1.0.0',
66-
engines: {
67-
vscode: '^1.78.0',
68-
},
69-
contributes: {
70-
languages: [
71-
{
72-
id: languageId,
73-
aliases: ['Python'],
74-
extensions: ['.py', '.pyi'],
75-
},
76-
],
77-
commands: [
78-
{
79-
command: 'pyright.restartserver',
80-
title: 'Pyright: Restart Server',
81-
category: 'Pyright',
82-
},
83-
{
84-
command: 'pyright.organizeimports',
85-
title: 'Pyright: Organize Imports',
86-
category: 'Pyright',
53+
const ensureMonacoInitialized = () => {
54+
if (initPromise) {
55+
return initPromise;
56+
}
57+
58+
initPromise = (async () => {
59+
if (typeof window !== 'undefined') {
60+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
61+
const monacoInstance = (monaco as any).default ?? monaco;
62+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
63+
(window as any).monaco = monacoInstance;
64+
console.log('[MonacoEditor] window.monaco:', monacoInstance);
65+
if (!monacoInstance) {
66+
throw new Error('monaco instance is null or undefined');
67+
} else if (!monacoInstance.languages) {
68+
throw new Error('monaco.languages is undefined');
69+
}
70+
}
71+
try {
72+
console.log('[MonacoEditor] Calling initialize()');
73+
await initialize({
74+
...getTextMateServiceOverride(),
75+
...getThemeServiceOverride(),
76+
...getConfigurationServiceOverride(),
77+
...getKeybindingsServiceOverride(),
78+
...getLanguagesServiceOverride(),
79+
});
80+
console.log('[MonacoEditor] initialize() completed');
81+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
82+
} catch (err: any) {
83+
if (err?.message?.includes('already been initialized')) {
84+
console.warn('[MonacoEditor] Monaco services already initialized. Ignoring.');
85+
} else {
86+
console.error('[MonacoEditor] Error initializing monaco services:', err);
87+
throw err;
88+
}
89+
}
90+
91+
await whenReady();
92+
93+
// extension configuration derived from:
94+
// https://github.com/microsoft/pyright/blob/main/packages/vscode-pyright/package.json
95+
// only a minimum is required to get pyright working
96+
const extension = {
97+
name: 'python-client',
98+
publisher: 'monaco-languageclient-project',
99+
version: '1.0.0',
100+
engines: {
101+
vscode: '^1.78.0',
87102
},
88-
],
89-
keybindings: [
90-
{
91-
key: 'ctrl+k',
92-
command: 'pyright.organizeimports',
93-
when: 'editorTextFocus',
103+
contributes: {
104+
languages: [
105+
{
106+
id: languageId,
107+
aliases: ['Python'],
108+
extensions: ['.py', '.pyi'],
109+
},
110+
],
111+
commands: [
112+
{
113+
command: 'pyright.restartserver',
114+
title: 'Pyright: Restart Server',
115+
category: 'Pyright',
116+
},
117+
{
118+
command: 'pyright.organizeimports',
119+
title: 'Pyright: Organize Imports',
120+
category: 'Pyright',
121+
},
122+
],
123+
keybindings: [
124+
{
125+
key: 'ctrl+k',
126+
command: 'pyright.organizeimports',
127+
when: 'editorTextFocus',
128+
},
129+
],
94130
},
95-
],
96-
},
97-
};
131+
};
98132

99-
registerExtension(extension, ExtensionHostKind.LocalProcess);
133+
registerExtension(extension, ExtensionHostKind.LocalProcess);
134+
console.log('[MonacoEditor] Extension registered');
135+
136+
// start web socket lsp client to the Web Worker python server
137+
initializedAndStartLanguageClient();
138+
})().catch(err => {
139+
// Reset promise on error so we can retry
140+
initPromise = null;
141+
throw err;
142+
});
143+
144+
return initPromise;
145+
};
100146

101147
type MonacoEditorProps = {
102148
/**
@@ -146,6 +192,20 @@ const MonacoEditor = ({
146192
const [childHeight, setChildHeight] = useState(height);
147193
const [name, setName] = useState<string>(tabname);
148194
const nameRef = useRef(name);
195+
const [isReady, setIsReady] = useState(false);
196+
197+
useEffect(() => {
198+
let mounted = true;
199+
console.log('[MonacoEditor] useEffect mounting');
200+
201+
ensureMonacoInitialized().then(() => {
202+
console.log('[MonacoEditor] init() resolved');
203+
if (mounted) setIsReady(true);
204+
}).catch((err) => {
205+
console.error('[MonacoEditor] init failed', err);
206+
});
207+
return () => { mounted = false; };
208+
}, []);
149209

150210
useEffect(() => {
151211
nameRef.current = name;
@@ -246,7 +306,7 @@ const MonacoEditor = ({
246306
EditorMgr.getInstance().setSubscription(tabId);
247307
}
248308

249-
if (editorRef.current) {
309+
if (isReady && editorRef.current) {
250310
if (editor.current === null) {
251311
updateUserConfiguration(`{
252312
"editor.fontSize": ${Constants.DEFAULT_FONTSIZE},
@@ -296,15 +356,9 @@ const MonacoEditor = ({
296356
}
297357
},
298358
});
299-
300-
if (!isClientInitalized) {
301-
// start web socket lsp client to the Web Worker python server
302-
initializedAndStartLanguageClient();
303-
isClientInitalized = true;
304-
}
305359
}
306360
}
307-
}, [language, value, t, childWidth, childHeight, tabId]);
361+
}, [language, value, t, childWidth, childHeight, tabId, isReady]);
308362

309363
return (
310364
<>

0 commit comments

Comments
 (0)