Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Monaco] Add monaco.editor.registerEditorOpener method to be able to intercept editor open operations #177064

Merged
merged 3 commits into from
Apr 13, 2023

Conversation

spahnke
Copy link
Contributor

@spahnke spahnke commented Mar 14, 2023

Fixes microsoft/monaco-editor#2000

By default the "go to defintion" action in the Monaco editor does nothing if the definition is in another model, or opens a peek window when multiple definitions are found. This default is a good thing because just changing the underlying model would be very detrimental when embedding the editor. However, there are use-cases where you maybe want to control what happens when you go to a definition. For example, when we embed the Monaco editor we would like to open a new tab to the source code containing the definition for certain models but not all of them.

This PR adds a new function monaco.editor.registerEditorOpener that lets the embedder intercept such open operations and handle those themselves. By using a boolean return value the embedder can indicate if the resource was handled or the editor should fallback to the default. The function returns an IDisposable instance that can be used to unregister the handler again. This interception can be tested in the code below by e.g. Ctrl-clicking on the alert function. By intercepting the open operation you can also choose to change the underlying editor model yourself if that makes sense in your application (see linked issue).

Edit: I decided to remove a second commit because it didn't work properly in some cases. This reduces the PR to just the new method to intercept the editor open operation.

Monaco Playground Code:

const text = `function hello() {
	alert('Hello world!');
	Date.now();
}`;

// Hover on each property to see its docs!
const editor = monaco.editor.create(document.getElementById("container"), {
	value: text,
	language: "javascript",
	automaticLayout: true,
});

monaco.editor.registerEditorOpener({
	openCodeEditor(source, resource, selectionOrPosition) {
		console.log(source, resource, selectionOrPosition);
		if (resource.path === "/lib.dom.d.ts") {
			// simulate openening a new browser tab for our own type (open definition of alert)
			console.log(`Opened definition for ${resource}`);

			// alternatively set model directly in the editor if you have your own tab/navigation implementation
			// const model = monaco.editor.getModel(resource);
			// editor.setModel(model);
			// if (monaco.Range.isIRange(selectionOrPosition)) {
			// 	editor.revealRangeInCenterIfOutsideViewport(selectionOrPosition);
			// 	editor.setSelection(selectionOrPosition);
			// } else {
			// 	editor.revealPositionInCenterIfOutsideViewport(selectionOrPosition);
			// 	editor.setPosition(selectionOrPosition);
			// }

			return true;
		}
		return false;
	}
});

@spahnke
Copy link
Contributor Author

spahnke commented Apr 3, 2023

@hediet Could this be considered for one of the next Monaco versions? Thank you!

@hediet hediet assigned hediet and unassigned jrieken Apr 5, 2023
@@ -456,6 +459,36 @@ export function registerLinkOpener(opener: ILinkOpener): IDisposable {
});
}

export interface ICodeEditorOpener {
openCodeEditor(source: ICodeEditor, resource: URI, selectionOrPosition?: IRange | IPosition): boolean | Promise<boolean>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add some doc comments explaining when this method is called (copying the comment from the register call).

hediet
hediet previously approved these changes Apr 5, 2023
@hediet hediet added this to the April 2023 milestone Apr 5, 2023
@spahnke
Copy link
Contributor Author

spahnke commented Apr 5, 2023

Addressed review and rebased onto main.

@hediet
Copy link
Member

hediet commented Apr 5, 2023

Thanks!

Addressed review and rebased onto main.

Generally, please don't rebase in PRs, as that resets the review.
(we can also just squash the PR when merging)

@hediet hediet enabled auto-merge April 5, 2023 13:34
@spahnke
Copy link
Contributor Author

spahnke commented Apr 11, 2023

This seems stuck, do I need to do something?

@hediet hediet merged commit 663faf1 into microsoft:main Apr 13, 2023
@spahnke spahnke deleted the evident-ape branch April 13, 2023 17:59
@github-actions github-actions bot locked and limited conversation to collaborators May 28, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Goto definition (Ctrl + click) works only if definition is in same model
6 participants