livebook/assets/js/cell/live_editor/monaco.js
Jonatan Kłosko e2490c0f7f
Implement signature intellisense (#640)
* Remove Code.Fragment backport

* Fix tests compatibility with Elixir 1.13

* Implement signature intellisense

* Don't show signatures on module attributes

* Add tests for calls with do-end block

* Unify spec formatting

* Insert parentheses when completing a function call

* Send all text until cursor in signature request

* Add configuration for completion/signature popups (#693)

* Add editor settings form

* Add configuration for intellisense defaults

* Read fresh settings when editor mounts

* Scope attribute names

* Fix disabled button styling

* Simplify signature box and enable by default

* Split settings into system and user sections

* Update lib/livebook_web/live/settings_live.ex

Co-authored-by: José Valim <jose.valim@dashbit.co>

* Update lib/livebook_web/live/settings_live.ex

Co-authored-by: José Valim <jose.valim@dashbit.co>

Co-authored-by: José Valim <jose.valim@dashbit.co>

* Fix spacing in documentation tests

Co-authored-by: José Valim <jose.valim@dashbit.co>
2021-12-03 21:57:21 +01:00

114 lines
3.4 KiB
JavaScript

import * as monaco from "monaco-editor/esm/vs/editor/editor.api";
import { CommandsRegistry } from "monaco-editor/esm/vs/platform/commands/common/commands";
import ElixirOnTypeFormattingEditProvider from "./elixir/on_type_formatting_edit_provider";
import theme from "./theme";
monaco.languages.registerOnTypeFormattingEditProvider(
"elixir",
ElixirOnTypeFormattingEditProvider
);
// Define custom theme
monaco.editor.defineTheme("custom", theme);
// See https://github.com/microsoft/monaco-editor/issues/648#issuecomment-564978560
// Without this selecting text with whitespace shrinks the whitespace.
document.fonts.addEventListener("loadingdone", (event) => {
const jetBrainsMonoLoaded = event.fontfaces.some(
// font-family may be either "JetBrains Mono" or "\"JetBrains Mono\""
(fontFace) => fontFace.family.includes("JetBrains Mono")
);
if (jetBrainsMonoLoaded) {
// We use JetBrains Mono in all instances of the editor,
// so we wait until it loads and then tell Monaco to remeasure
// fonts and updates its cache.
monaco.editor.remeasureFonts();
}
});
/**
* Define custom providers for various editor features.
*
* In our case, each cell has its own editor and behaviour
* of requests like completion and hover are cell dependent.
* For this reason we delegate the implementation to the
* specific cell by using its text model object.
*
* See cell/live_editor.js for more details.
*/
monaco.languages.registerCompletionItemProvider("elixir", {
provideCompletionItems: (model, position, context, token) => {
if (model.__getCompletionItems) {
return model.__getCompletionItems(model, position);
} else {
return null;
}
},
});
monaco.languages.registerHoverProvider("elixir", {
provideHover: (model, position, token) => {
if (model.__getHover) {
return model.__getHover(model, position);
} else {
return null;
}
},
});
monaco.languages.registerSignatureHelpProvider("elixir", {
signatureHelpTriggerCharacters: ["(", ","],
provideSignatureHelp: (model, position, token, context) => {
if (model.__getSignatureHelp) {
return model.__getSignatureHelp(model, position);
} else {
return null;
}
},
});
monaco.languages.registerDocumentFormattingEditProvider("elixir", {
provideDocumentFormattingEdits: (model, options, token) => {
if (model.__getDocumentFormattingEdits) {
return model.__getDocumentFormattingEdits(model);
} else {
return null;
}
},
});
export default monaco;
/**
* Highlights the given code using the same rules as in the editor.
*
* Returns a promise resolving to HTML that renders as the highlighted code.
*/
export function highlight(code, language) {
return monaco.editor.colorize(code, language).then((result) => {
// `colorize` always adds additional newline, so we remove it
return result.replace(/<br\/>$/, "");
});
}
/**
* Updates keybinding for the given editor command.
*
* This uses an internal API, since there is no clean support
* for customizing keybindings.
* See https://github.com/microsoft/monaco-editor/issues/102#issuecomment-822981429
*/
export function addKeybinding(editor, id, newKeybinding) {
const { handler, when } = CommandsRegistry.getCommand(id) ?? {};
if (handler) {
editor._standaloneKeybindingService.addDynamicKeybinding(
id,
newKeybinding,
handler,
when
);
}
}