mirror of
https://github.com/pybricks/pybricks-code.git
synced 2026-09-14 18:46:17 +00:00
pybricksMicropython: add support for peer file code completion
This allows importing user-created files and getting code completion for those imports. This is done by mirroring the dexie-based file system used by the editor to the emscripten based file system used by pyodide. In the future, ideally we would have some sort of shared file system, but this works for now. Note: completing `from ` doesn't list user files/modules because of filters in the pybricks-jedi python package but completing `from my_file import ` does work as expected.
This commit is contained in:
@@ -99,3 +99,20 @@ export const pythonMessageDidFailToGetSignature = createAction((error: Error) =>
|
||||
type: 'python.message.didFailToGetSignature',
|
||||
error,
|
||||
}));
|
||||
|
||||
export const pythonMessageWriteUserFile = createAction(
|
||||
(path: string, contents: string) => ({
|
||||
type: 'python.message.writeUserFile',
|
||||
path,
|
||||
contents,
|
||||
}),
|
||||
);
|
||||
|
||||
export const pythonMessageDeleteUserFile = createAction((path: string) => ({
|
||||
type: 'python.message.deleteUserFile',
|
||||
path,
|
||||
}));
|
||||
|
||||
export const pythonMessageDidMountUserFileSystem = createAction(() => ({
|
||||
type: 'python.message.didMountUserFileSystem',
|
||||
}));
|
||||
|
||||
@@ -11,15 +11,18 @@ import pyodidePackage from 'pyodide/package.json';
|
||||
import { ensureError } from '../utils';
|
||||
import {
|
||||
pythonMessageComplete,
|
||||
pythonMessageDeleteUserFile,
|
||||
pythonMessageDidComplete,
|
||||
pythonMessageDidFailToComplete,
|
||||
pythonMessageDidFailToGetSignature,
|
||||
pythonMessageDidFailToInit,
|
||||
pythonMessageDidGetSignature,
|
||||
pythonMessageDidInit,
|
||||
pythonMessageDidMountUserFileSystem,
|
||||
pythonMessageGetSignature,
|
||||
pythonMessageInit,
|
||||
pythonMessageSetInterruptBuffer,
|
||||
pythonMessageWriteUserFile,
|
||||
} from './python-message';
|
||||
|
||||
/**
|
||||
@@ -61,6 +64,34 @@ async function init(): Promise<void> {
|
||||
lockFileURL: new URL('pyodide/repodata.json', import.meta.url).toString(),
|
||||
});
|
||||
|
||||
// REVISIT: it would be nice if we could make a custom driver to mount
|
||||
// the custom Pybricks Code Dexie-based file system directly instead of
|
||||
// mirroring it
|
||||
const mountDir = '/user';
|
||||
pyodide.FS.mkdir(mountDir);
|
||||
pyodide.FS.mount(pyodide.FS.filesystems.MEMFS, { root: '.' }, mountDir);
|
||||
|
||||
self.addEventListener('message', async (e) => {
|
||||
if (pythonMessageWriteUserFile.matches(e.data)) {
|
||||
pyodide.FS.writeFile(`${mountDir}/${e.data.path}`, e.data.contents);
|
||||
console.debug('copied', e.data.path, 'to emscripten fs');
|
||||
return;
|
||||
}
|
||||
|
||||
if (pythonMessageDeleteUserFile.matches(e.data)) {
|
||||
pyodide.FS.unlink(`${mountDir}/${e.data.path}`);
|
||||
console.debug('removed', e.data.path, ' from emscripten fs');
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
// separate message for file system ready since it takes a long time for
|
||||
// the rest of the init
|
||||
self.postMessage(pythonMessageDidMountUserFileSystem());
|
||||
|
||||
// add user directory to sys.path for code completion
|
||||
await pyodide.runPythonAsync(`import sys; sys.path.append("${mountDir}")`);
|
||||
|
||||
// NB: using URL+import.meta.url for webpack magic - don't try to optimize it
|
||||
await pyodide.loadPackage(
|
||||
new URL('@pybricks/jedi/docstring-parser.whl', import.meta.url).toString(),
|
||||
|
||||
Reference in New Issue
Block a user