Skip to content

Commit e153ffe

Browse files
committed
pybricksMicropython: fix import completion for user module
The pybricks_jedi package was filtering on only pybricks modules but now has a feature to amend the filter to include user modules. Fixes: pybricks/support#759
1 parent a981bcb commit e153ffe

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
- Fixed clipping of code completion popup by terminal.
1212
- Fixed code completion for builtin types.
1313
- Fixed code completion for names starting with `_`.
14+
- Fixed code completion for `from ...` for user modules ([support#759]).
15+
16+
[support#759]: https://github.com/pybricks/support/issues/759
1417

1518
## [2.1.0-beta.2] - 2022-12-26
1619

src/pybricksMicropython/python-worker.ts

+20
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,25 @@ function fixUpError(err: unknown): Error {
4343
return error;
4444
}
4545

46+
/**
47+
* Naively converts a file system path to a python module name.
48+
*
49+
* Assumes `.py` file extension and no invalid characters.
50+
*
51+
* @param path The path.
52+
*/
53+
function pathToModule(path: string): string {
54+
return path.slice(0, path.length - 3).replaceAll('/', '.');
55+
}
56+
4657
const setUpPythonEnvironment = `
4758
import jedi
4859
import pybricks_jedi
4960
5061
print('preloading pybricks_jedi...')
5162
pybricks_jedi.initialize()
63+
# TODO: this could be moved to pybricks_jedi.initialize()
64+
pybricks_jedi.complete("from ", 1, 6)
5265
print('preloading done.')
5366
`;
5467

@@ -68,16 +81,20 @@ async function init(): Promise<void> {
6881
pyodide.FS.mkdir(mountDir);
6982
pyodide.FS.mount(pyodide.FS.filesystems.MEMFS, { root: '.' }, mountDir);
7083

84+
const userModules = new Set<string>();
85+
7186
self.addEventListener('message', async (e) => {
7287
if (pythonMessageWriteUserFile.matches(e.data)) {
7388
pyodide.FS.writeFile(`${mountDir}/${e.data.path}`, e.data.contents);
7489
console.debug('copied', e.data.path, 'to emscripten fs');
90+
userModules.add(pathToModule(e.data.path));
7591
return;
7692
}
7793

7894
if (pythonMessageDeleteUserFile.matches(e.data)) {
7995
pyodide.FS.unlink(`${mountDir}/${e.data.path}`);
8096
console.debug('removed', e.data.path, ' from emscripten fs');
97+
userModules.delete(pathToModule(e.data.path));
8198
return;
8299
}
83100
});
@@ -103,6 +120,7 @@ async function init(): Promise<void> {
103120

104121
const complete = pyodide.runPython('pybricks_jedi.complete');
105122
const getSignatures = pyodide.runPython('pybricks_jedi.get_signatures');
123+
const updateUserModules = pyodide.runPython('pybricks_jedi.update_user_modules');
106124

107125
self.addEventListener('message', async (e) => {
108126
if (pythonMessageSetInterruptBuffer.matches(e.data)) {
@@ -113,6 +131,7 @@ async function init(): Promise<void> {
113131
if (pythonMessageComplete.matches(e.data)) {
114132
console.debug('worker received complete message');
115133
try {
134+
updateUserModules(userModules);
116135
const { code, lineNumber, column } = e.data;
117136
const list = complete(code, lineNumber, column);
118137
self.postMessage(pythonMessageDidComplete(list));
@@ -125,6 +144,7 @@ async function init(): Promise<void> {
125144
if (pythonMessageGetSignature.matches(e.data)) {
126145
console.debug('worker received getSignatures message');
127146
try {
147+
updateUserModules(userModules);
128148
const { code, lineNumber, column } = e.data;
129149
const list = getSignatures(code, lineNumber, column);
130150
self.postMessage(pythonMessageDidGetSignature(list));

0 commit comments

Comments
 (0)