Filtering the default @codemirror/lang-python completion result

I’m currently creating an editor that uses the lang-python completion. But, it has a lot of keywords or syntaxes that I want to remove/filter. I can fork and manually modify the github but it’s hard to maintain it if ever there are some changes that needs to be made in the future.

I know there’s a way to override the autocompletion but this would result to overriding the entire python autocomplete (which I don’t want).

I’ve been trying to figure this out and I can’t seem to find an issue, article, or tutorial to do this.

To be more clear, here’s the high level on what I want to achieve:

CodeMirror gathers suggestions using lang-python ↓ I will filter the CompletionResult from lang-python and remove the syntaxes I don’t want (e.g., “annotations”, “builtins”, “debug”, etc.) ↓ I will add some dynamic additional suggestions to the CompletionResult ↓ Return the filtered and additional CompletionResult

To be more clear, the reason why I want to filter the CompletionResult from lang-python is the editor i’m creating is for an ERP web ide that does not use SOME python syntaxes. This is also the reason why I want to add other suggestions that the ERP exposes.

Thanks in advance!

The @codemirror/lang-python package exports its completion sources. If, instead of using the default Python support extensions, you wrap these functions and provide them as your own completion sources, with the wrapper doing the filtering you want, that should give you the setup you’re looking for without duplicating code from the package.

1 Like

I get what you’re suggesting and very thankful for it. But, I can’t seem to make it work right now, I’m 90% sure i’m doing it wrong but can’t figure out where. Here’s my current progress:

function filterOptions(options: readonly Completion[]) {
	return options.filter((opt) => !UNWANTED_SYNTAX.has(opt.label));
}

async function customCompletionSource(pythonSource: CompletionSource) {
	console.log(pythonSource);
	return async (
		context: CompletionContext,
	): Promise<CompletionResult | null> => {
		const result = await pythonSource(context);
		console.log(result);
		if (!result) return null;

		return {
			...result,
			options: filterOptions(result.options),
		};
	};
}

export function App() {
	const refContainer = useRef<T>(null);
	const [editor, setEditor] = useState<EditorView | null>(null);

	useEffect(() => {
		if (!refContainer) return;

		const editorState = EditorState.create({
			doc: `print("Hello World")`,
			extensions: [
				basicSetup,
				pythonLanguage.data.of({
					autocompletion: customCompletionSource(globalCompletion),
				}),
				autocompletion(),
			],
		});
		if (!editorState) {
			console.warn("No EditorState created.");
			return;
		}

		const view = new EditorView({
			state: editorState,
			parent: refContainer.current,
		});
		setEditor(view);
	}, [refContainer]);

	return <div ref={refContainer}></div>;
}

The editor is showing, but the whole python autocomplete and highlighting is gone.

Apologies and thank you in advance.

Looks like you’re not including the Python language in your configuration, only autocompletion that’s marked as applying to the Python language. Including pythonLanguage itself in the array of extensions should help.

1 Like

The highlighting works now. Thanks!

But, currently the autocomplete seems to not work? There’s no suggestion/intellisense

Use autocomplete: instead of autocompletion: in the language data, and make sure your customCompletionSource function isn’t async.

1 Like

yeah, I also noticed from this gist.

Everything works now. Thank you so much Marjin! :smiling_face: