Decorations
What a language server or version control knows reaches the editor as decorations. Each setter replaces what was set before, and most decorations follow their text through edits until the host sets them again.
import { useCallback, useState } from 'react';
import type { Editor } from '@adecore/editor';
import { EditorFrame } from '../shared/editor-frame.tsx';
import { SAMPLE, useEditor } from '../shared/editor.ts';
const OPTIONS = { text: SAMPLE, language: 'typescript', theme: 'demo' } as const;
const range = (line: number, from: number, to: number) => ({ start: { line, character: from }, end: { line, character: to } });
/* What a language server and a version control system would hand the editor, set once by hand. */
function decorate(editor: Editor): void {
editor.setMarkers([
{ range: range(3, 34, 43), severity: 'error', message: "Cannot find name 'OrderLine'." },
{ range: range(6, 35, 43), severity: 'warning', deprecated: true, message: "'quantity' is deprecated." }
]);
editor.setInlayHints([
{ position: { line: 4, character: 13 }, label: ': number' },
{ position: { line: 12, character: 29 }, label: 'lines:' }
]);
editor.setHighlights([
{ range: range(4, 8, 13), kind: 'write' },
{ range: range(6, 8, 13), kind: 'write' },
{ range: range(8, 11, 16), kind: 'read' }
]);
editor.setChangeMarks([
{ kind: 'modified', startLine: 7, endLine: 7 },
{ kind: 'added', startLine: 12, endLine: 15 }
]);
editor.setGutterAction({ line: 3, label: 'Show fixes' });
}
export default function DecorationsDemo() {
const [pressed, setPressed] = useState<number | null>(null);
const setup = useCallback((editor: Editor) => {
decorate(editor);
return editor.onGutterAction(setPressed);
}, []);
const { host } = useEditor(OPTIONS, setup);
return (
<EditorFrame
host={host}
toolbar={
<span className="px-1 text-xs text-text-muted">
{pressed === null ? 'Press the button in the gutter of line 4.' : `The gutter action of line ${pressed + 1} was pressed.`}
</span>
}
/>
);
}Problems
setMarkers(markers) draws problems: a squiggle under the range and a tick in the scroll track, colored by severity (error, warning, info or hint). unnecessary: true fades the text and deprecated: true strikes it through. A message is what the tick says under the pointer, and a press on the tick goes to the problem.
editor.setMarkers([
{
range: { start: { line: 3, character: 34 }, end: { line: 3, character: 43 } },
severity: 'error',
message: "Cannot find name 'OrderLine'."
}
]);The editor draws no message card of its own. @adecore/editor-react shows one on hover.
Names and hints
setHighlights(highlights)marks the other uses of the name at the caret, each with akindoftext,readorwrite. The next edit clears them.setLink(range)underlines a range as a link under the pointer, such as a name while Mod is held, until the nextsetLinkor edit;nullremoves it.setInlayHints(hints)draws alabelas a soft pill between two characters, such as a parameter name or a type. It is not part of the text.
Semantic colors
setSemanticTokens(tokens) colors ranges by what a language server knows, over what the grammar made of them. Each EditorSemanticToken has a line, character, length and the TextMate scopes it stands for; the theme decides the color. That needs scopeColors on the engine, usually shikiScopeColors; without it the tokens are ignored. null removes them. See Theme and syntax.
Change marks
setChangeMarks(marks) draws how the text differs from the version the app compares against, in the gutter and in the scroll track. An EditorChangeMark has a kind of added, modified or deleted and one-based, inclusive startLine and endLine. A deleted mark sits above the line the removed lines were above, so its two lines are the same.
Gutter buttons
setGutterAction(action)puts one button in the gutter,{ line, label }, such as a lightbulb for code actions.onGutterActionreports a press with the zero-based line.nullremoves it.setGutterMarkers(markers, owner?)puts small buttons on lines,{ id, line, label }, such as the mark of a saved inline edit. Each owner has its own set anddefaultis the owner without one.onGutterMarkerreports a press with the id.
Lines, from one or from zero
The decorations that cover whole lines take one-based, inclusive lines: change marks, attribution marks and line highlights. Everything placed on a single line takes a zero-based line: widgets, line actions, code vision, gutter actions and gutter markers. Markers, highlights, links, inlay hints and remote cursors take EditorPositions.