diff --git a/dist/basic-setup.d.ts b/dist/basic-setup.d.ts index f1d40a3..158c634 100644 --- a/dist/basic-setup.d.ts +++ b/dist/basic-setup.d.ts @@ -1,21 +1,19 @@ -import { EditorState, EditorSelection, Compartment, SelectionRange, Facet, StateField, StateEffect, Transaction, Text, ChangeSet, combineConfig, Annotation } from "@codemirror/state"; -import { julia as julia_andrey } from "@plutojl/lang-julia"; -import { keymap, EditorView, highlightSpecialChars, drawSelection, placeholder, Decoration, ViewUpdate, ViewPlugin, WidgetType, lineNumbers, rectangularSelection, tooltips, showTooltip, Tooltip, MatchDecorator } from "@codemirror/view"; -import { defaultKeymap, indentMore, indentLess, moveLineUp, moveLineDown, historyKeymap, history } from "@codemirror/commands"; -import { indentOnInput, indentUnit, syntaxTree, syntaxTreeAvailable, bracketMatching, foldGutter, foldKeymap, HighlightStyle, defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language"; -import { tags } from "@lezer/highlight"; -import { closeBrackets, closeBracketsKeymap, completionKeymap } from "@codemirror/autocomplete"; -import * as autocomplete from "@codemirror/autocomplete"; -import { highlightSelectionMatches, searchKeymap, selectNextOccurrence } from "@codemirror/search"; -import { TreeCursor, NodeProp, parseMixed } from "@lezer/common"; -import { markdown, markdownLanguage } from "@codemirror/lang-markdown"; -import { parseCode } from "@lezer/markdown"; -import { html, htmlLanguage } from "@codemirror/lang-html"; -import { javascript, javascriptLanguage } from "@codemirror/lang-javascript"; -import { css, cssLanguage } from "@codemirror/lang-css"; -import { sql, PostgreSQL } from "@codemirror/lang-sql"; -import { python, pythonLanguage } from "@codemirror/lang-python"; -import { collab, receiveUpdates, sendableUpdates, getSyncedVersion, getClientID } from "@codemirror/collab"; -import { linter, setDiagnostics, Diagnostic } from "@codemirror/lint"; -export { css, cssLanguage }; -export { Facet, StateField, StateEffect, Transaction, ChangeSet, indentUnit, EditorState, EditorSelection, Compartment, EditorView, SelectionRange, placeholder, julia_andrey, keymap, history, historyKeymap, defaultKeymap, indentMore, indentLess, moveLineUp, moveLineDown, tags, HighlightStyle, syntaxHighlighting, syntaxTree, syntaxTreeAvailable, autocomplete, lineNumbers, highlightSpecialChars, foldGutter, drawSelection, indentOnInput, defaultHighlightStyle, bracketMatching, closeBrackets, rectangularSelection, highlightSelectionMatches, closeBracketsKeymap, searchKeymap, selectNextOccurrence, foldKeymap, completionKeymap, Decoration, ViewUpdate, ViewPlugin, WidgetType, TreeCursor, Text, Annotation, combineConfig, NodeProp, Tooltip, tooltips, showTooltip, MatchDecorator, markdown, markdownLanguage, parseCode, parseMixed, html, htmlLanguage, javascript, javascriptLanguage, sql, PostgreSQL, python, pythonLanguage, collab, receiveUpdates, sendableUpdates, getSyncedVersion, getClientID, linter, setDiagnostics, Diagnostic, }; +export { EditorState, EditorSelection, Compartment, SelectionRange, Facet, StateField, StateEffect, Transaction, Text, ChangeSet, combineConfig, Annotation, } from "@codemirror/state"; +export { keymap, EditorView, highlightSpecialChars, drawSelection, highlightActiveLine, placeholder, Decoration, ViewUpdate, ViewPlugin, WidgetType, lineNumbers, rectangularSelection, tooltips, showTooltip, Tooltip, MatchDecorator, } from "@codemirror/view"; +export { defaultKeymap, indentMore, indentLess, moveLineUp, moveLineDown, historyKeymap, history, } from "@codemirror/commands"; +export { indentOnInput, indentUnit, syntaxTree, syntaxTreeAvailable, bracketMatching, foldGutter, foldKeymap, HighlightStyle, defaultHighlightStyle, syntaxHighlighting, } from "@codemirror/language"; +export { closeBrackets, closeBracketsKeymap, completionKeymap } from "@codemirror/autocomplete"; +export * as autocomplete from "@codemirror/autocomplete"; +export { highlightSelectionMatches, searchKeymap, selectNextOccurrence, } from "@codemirror/search"; +export { collab, receiveUpdates, sendableUpdates, getSyncedVersion, getClientID } from "@codemirror/collab"; +export { linter, setDiagnostics, Diagnostic } from "@codemirror/lint"; +export { TreeCursor, Tree, NodeProp, parseMixed, NodeWeakMap } from "@lezer/common"; +export { tags } from "@lezer/highlight"; +export { julia } from "@plutojl/lang-julia"; +export { markdown, markdownLanguage } from "@codemirror/lang-markdown"; +export { parseCode } from "@lezer/markdown"; +export { html, htmlLanguage } from "@codemirror/lang-html"; +export { css, cssLanguage } from "@codemirror/lang-css"; +export { javascript, javascriptLanguage } from "@codemirror/lang-javascript"; +export { sql, PostgreSQL } from "@codemirror/lang-sql"; +export { python, pythonLanguage } from "@codemirror/lang-python"; diff --git a/dist/index.d.ts b/dist/index.d.ts index 7f39dd3..d86a63b 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -210,7 +210,7 @@ declare class ChangeDesc { Map this description, which should start with the same document as `other`, over another set of changes, so that it can be applied after it. When `before` is true, map as if the changes - in `other` happened before the ones in `this`. + in `this` happened before the ones in `other`. */ mapDesc(other: ChangeDesc, before?: boolean): ChangeDesc; /** @@ -1408,6 +1408,13 @@ interface RangeComparator { Notification for a changed (or inserted, or deleted) point range. */ comparePoint(from: number, to: number, pointA: T | null, pointB: T | null): void; + /** + Notification for a changed boundary between ranges. For example, + if the same span is covered by two partial ranges before and one + bigger range after, this is called at the point where the ranges + used to be split. + */ + boundChange?(pos: number): void; } /** Methods used when iterating over the spans created by a set of @@ -1580,3164 +1587,3309 @@ declare class RangeSet { static empty: RangeSet; } +declare class StyleModule { + constructor(spec: {[selector: string]: StyleSpec}, options?: { + finish?(sel: string): string + }) + getRules(): string + static mount( + root: Document | ShadowRoot | DocumentOrShadowRoot, + module: StyleModule | ReadonlyArray, + options?: {nonce?: string} + ): void + static newName(): string +} + +type StyleSpec = { + [propOrSelector: string]: string | number | StyleSpec | null +} + /** -The [`TreeFragment.applyChanges`](#common.TreeFragment^applyChanges) -method expects changed ranges in this format. +Used to indicate [text direction](https://codemirror.net/6/docs/ref/#view.EditorView.textDirection). */ -interface ChangedRange { - /** - The start of the change in the start document - */ - fromA: number; - /** - The end of the change in the start document - */ - toA: number; +declare enum Direction { /** - The start of the replacement in the new document + Left-to-right. */ - fromB: number; + LTR = 0, /** - The end of the replacement in the new document + Right-to-left. */ - toB: number; + RTL = 1 } /** -Tree fragments are used during [incremental -parsing](#common.Parser.startParse) to track parts of old trees -that can be reused in a new parse. An array of fragments is used -to track regions of an old tree whose nodes might be reused in new -parses. Use the static -[`applyChanges`](#common.TreeFragment^applyChanges) method to -update fragments for document changes. +Represents a contiguous range of text that has a single direction +(as in left-to-right or right-to-left). */ -declare class TreeFragment { +declare class BidiSpan { /** - The start of the unchanged range pointed to by this fragment. - This refers to an offset in the _updated_ document (as opposed - to the original tree). + The start of the span (relative to the start of the line). */ readonly from: number; /** - The end of the unchanged range. + The end of the span. */ readonly to: number; /** - The tree that this fragment is based on. + The ["bidi + level"](https://unicode.org/reports/tr9/#Basic_Display_Algorithm) + of the span (in this context, 0 means + left-to-right, 1 means right-to-left, 2 means left-to-right + number inside right-to-left text). */ - readonly tree: Tree; + readonly level: number; /** - The offset between the fragment's tree and the document that - this fragment can be used against. Add this when going from - document to tree positions, subtract it to go from tree to - document positions. + The direction of this span. */ - readonly offset: number; + get dir(): Direction; +} + +type Attrs = { + [name: string]: string; +}; + +/** +Basic rectangle type. +*/ +interface Rect { + readonly left: number; + readonly right: number; + readonly top: number; + readonly bottom: number; +} +type ScrollStrategy = "nearest" | "start" | "end" | "center"; + +interface MarkDecorationSpec { /** - Construct a tree fragment. You'll usually want to use - [`addTree`](#common.TreeFragment^addTree) and - [`applyChanges`](#common.TreeFragment^applyChanges) instead of - calling this directly. + Whether the mark covers its start and end position or not. This + influences whether content inserted at those positions becomes + part of the mark. Defaults to false. */ - constructor( + inclusive?: boolean; /** - The start of the unchanged range pointed to by this fragment. - This refers to an offset in the _updated_ document (as opposed - to the original tree). + Specify whether the start position of the marked range should be + inclusive. Overrides `inclusive`, when both are present. */ - from: number, + inclusiveStart?: boolean; /** - The end of the unchanged range. + Whether the end should be inclusive. */ - to: number, + inclusiveEnd?: boolean; /** - The tree that this fragment is based on. + Add attributes to the DOM elements that hold the text in the + marked range. */ - tree: Tree, + attributes?: { + [key: string]: string; + }; /** - The offset between the fragment's tree and the document that - this fragment can be used against. Add this when going from - document to tree positions, subtract it to go from tree to - document positions. + Shorthand for `{attributes: {class: value}}`. */ - offset: number, openStart?: boolean, openEnd?: boolean); + class?: string; /** - Whether the start of the fragment represents the start of a - parse, or the end of a change. (In the second case, it may not - be safe to reuse some nodes at the start, depending on the - parsing algorithm.) + Add a wrapping element around the text in the marked range. Note + that there will not necessarily be a single element covering the + entire range—other decorations with lower precedence might split + this one if they partially overlap it, and line breaks always + end decoration elements. */ - get openStart(): boolean; + tagName?: string; /** - Whether the end of the fragment represents the end of a - full-document parse, or the start of a change. + When using sets of decorations in + [`bidiIsolatedRanges`](https://codemirror.net/6/docs/ref/##view.EditorView^bidiIsolatedRanges), + this property provides the direction of the isolates. When null + or not given, it indicates the range has `dir=auto`, and its + direction should be derived from the first strong directional + character in it. */ - get openEnd(): boolean; + bidiIsolate?: Direction | null; /** - Create a set of fragments from a freshly parsed tree, or update - an existing set of fragments by replacing the ones that overlap - with a tree with content from the new tree. When `partial` is - true, the parse is treated as incomplete, and the resulting - fragment has [`openEnd`](#common.TreeFragment.openEnd) set to - true. + Decoration specs allow extra properties, which can be retrieved + through the decoration's [`spec`](https://codemirror.net/6/docs/ref/#view.Decoration.spec) + property. */ - static addTree(tree: Tree, fragments?: readonly TreeFragment[], partial?: boolean): readonly TreeFragment[]; + [other: string]: any; +} +interface WidgetDecorationSpec { /** - Apply a set of edits to an array of fragments, removing or - splitting fragments as necessary to remove edited ranges, and - adjusting offsets for fragments that moved. + The type of widget to draw here. */ - static applyChanges(fragments: readonly TreeFragment[], changes: readonly ChangedRange[], minGap?: number): readonly TreeFragment[]; -} -/** -Interface used to represent an in-progress parse, which can be -moved forward piece-by-piece. -*/ -interface PartialParse { + widget: WidgetType; /** - Advance the parse state by some amount. Will return the finished - syntax tree when the parse completes. + Which side of the given position the widget is on. When this is + positive, the widget will be drawn after the cursor if the + cursor is on the same position. Otherwise, it'll be drawn before + it. When multiple widgets sit at the same position, their `side` + values will determine their ordering—those with a lower value + come first. Defaults to 0. May not be more than 10000 or less + than -10000. */ - advance(): Tree | null; + side?: number; /** - The position up to which the document has been parsed. Note - that, in multi-pass parsers, this will stay back until the last - pass has moved past a given position. + By default, to avoid unintended mixing of block and inline + widgets, block widgets with a positive `side` are always drawn + after all inline widgets at that position, and those with a + non-positive side before inline widgets. Setting this option to + `true` for a block widget will turn this off and cause it to be + rendered between the inline widgets, ordered by `side`. */ - readonly parsedPos: number; + inlineOrder?: boolean; /** - Tell the parse to not advance beyond the given position. - `advance` will return a tree when the parse has reached the - position. Note that, depending on the parser algorithm and the - state of the parse when `stopAt` was called, that tree may - contain nodes beyond the position. It is an error to call - `stopAt` with a higher position than it's [current - value](#common.PartialParse.stoppedAt). + Determines whether this is a block widgets, which will be drawn + between lines, or an inline widget (the default) which is drawn + between the surrounding text. + + Note that block-level decorations should not have vertical + margins, and if you dynamically change their height, you should + make sure to call + [`requestMeasure`](https://codemirror.net/6/docs/ref/#view.EditorView.requestMeasure), so that the + editor can update its information about its vertical layout. */ - stopAt(pos: number): void; + block?: boolean; /** - Reports whether `stopAt` has been called on this parse. + Other properties are allowed. */ - readonly stoppedAt: number | null; + [other: string]: any; } -/** -A superclass that parsers should extend. -*/ -declare abstract class Parser { +interface ReplaceDecorationSpec { /** - Start a parse for a single tree. This is the method concrete - parser implementations must implement. Called by `startParse`, - with the optional arguments resolved. + An optional widget to drawn in the place of the replaced + content. */ - abstract createParse(input: Input, fragments: readonly TreeFragment[], ranges: readonly { - from: number; - to: number; - }[]): PartialParse; + widget?: WidgetType; /** - Start a parse, returning a [partial parse](#common.PartialParse) - object. [`fragments`](#common.TreeFragment) can be passed in to - make the parse incremental. - - By default, the entire input is parsed. You can pass `ranges`, - which should be a sorted array of non-empty, non-overlapping - ranges, to parse only those ranges. The tree returned in that - case will start at `ranges[0].from`. + Whether this range covers the positions on its sides. This + influences whether new content becomes part of the range and + whether the cursor can be drawn on its sides. Defaults to false + for inline replacements, and true for block replacements. */ - startParse(input: Input | string, fragments?: readonly TreeFragment[], ranges?: readonly { - from: number; - to: number; - }[]): PartialParse; + inclusive?: boolean; /** - Run a full parse, returning the resulting tree. + Set inclusivity at the start. */ - parse(input: Input | string, fragments?: readonly TreeFragment[], ranges?: readonly { - from: number; - to: number; - }[]): Tree; -} -/** -This is the interface parsers use to access the document. To run -Lezer directly on your own document data structure, you have to -write an implementation of it. -*/ -interface Input { - /** - The length of the document. - */ - readonly length: number; + inclusiveStart?: boolean; /** - Get the chunk after the given position. The returned string - should start at `from` and, if that isn't the end of the - document, may be of any length greater than zero. + Set inclusivity at the end. */ - chunk(from: number): string; + inclusiveEnd?: boolean; /** - Indicates whether the chunks already end at line breaks, so that - client code that wants to work by-line can avoid re-scanning - them for line breaks. When this is true, the result of `chunk()` - should either be a single line break, or the content between - `from` and the next line break. + Whether this is a block-level decoration. Defaults to false. */ - readonly lineChunks: boolean; + block?: boolean; /** - Read the part of the document between the given positions. + Other properties are allowed. */ - read(from: number, to: number): string; + [other: string]: any; } -/** -Parse wrapper functions are supported by some parsers to inject -additional parsing logic. -*/ -type ParseWrapper = (inner: PartialParse, input: Input, fragments: readonly TreeFragment[], ranges: readonly { - from: number; - to: number; -}[]) => PartialParse; -/** -Each [node type](#common.NodeType) or [individual tree](#common.Tree) -can have metadata associated with it in props. Instances of this -class represent prop names. -*/ -declare class NodeProp { +interface LineDecorationSpec { /** - Indicates whether this prop is stored per [node - type](#common.NodeType) or per [tree node](#common.Tree). + DOM attributes to add to the element wrapping the line. */ - perNode: boolean; + attributes?: { + [key: string]: string; + }; /** - A method that deserializes a value of this prop from a string. - Can be used to allow a prop to be directly written in a grammar - file. + Shorthand for `{attributes: {class: value}}`. */ - deserialize: (str: string) => T; + class?: string; /** - Create a new node prop type. + Other properties are allowed. */ - constructor(config?: { - /** - The [deserialize](#common.NodeProp.deserialize) function to - use for this prop, used for example when directly providing - the prop from a grammar file. Defaults to a function that - raises an error. - */ - deserialize?: (str: string) => T; - /** - By default, node props are stored in the [node - type](#common.NodeType). It can sometimes be useful to directly - store information (usually related to the parsing algorithm) - in [nodes](#common.Tree) themselves. Set this to true to enable - that for this prop. - */ - perNode?: boolean; - }); + [other: string]: any; +} +/** +Widgets added to the content are described by subclasses of this +class. Using a description object like that makes it possible to +delay creating of the DOM structure for a widget until it is +needed, and to avoid redrawing widgets even if the decorations +that define them are recreated. +*/ +declare abstract class WidgetType { /** - This is meant to be used with - [`NodeSet.extend`](#common.NodeSet.extend) or - [`LRParser.configure`](#lr.ParserConfig.props) to compute - prop values for each node type in the set. Takes a [match - object](#common.NodeType^match) or function that returns undefined - if the node type doesn't get this prop, and the prop's value if - it does. + Build the DOM structure for this widget instance. */ - add(match: { - [selector: string]: T; - } | ((type: NodeType) => T | undefined)): NodePropSource; + abstract toDOM(view: EditorView): HTMLElement; /** - Prop that is used to describe matching delimiters. For opening - delimiters, this holds an array of node names (written as a - space-separated string when declaring this prop in a grammar) - for the node types of closing delimiters that match it. + Compare this instance to another instance of the same type. + (TypeScript can't express this, but only instances of the same + specific class will be passed to this method.) This is used to + avoid redrawing widgets when they are replaced by a new + decoration of the same type. The default implementation just + returns `false`, which will cause new instances of the widget to + always be redrawn. */ - static closedBy: NodeProp; + eq(widget: WidgetType): boolean; /** - The inverse of [`closedBy`](#common.NodeProp^closedBy). This is - attached to closing delimiters, holding an array of node names - of types of matching opening delimiters. + Update a DOM element created by a widget of the same type (but + different, non-`eq` content) to reflect this widget. May return + true to indicate that it could update, false to indicate it + couldn't (in which case the widget will be redrawn). The default + implementation just returns false. */ - static openedBy: NodeProp; + updateDOM(dom: HTMLElement, view: EditorView): boolean; /** - Used to assign node types to groups (for example, all node - types that represent an expression could be tagged with an - `"Expression"` group). + The estimated height this widget will have, to be used when + estimating the height of content that hasn't been drawn. May + return -1 to indicate you don't know. The default implementation + returns -1. */ - static group: NodeProp; + get estimatedHeight(): number; /** - Attached to nodes to indicate these should be - [displayed](https://codemirror.net/docs/ref/#language.syntaxTree) - in a bidirectional text isolate, so that direction-neutral - characters on their sides don't incorrectly get associated with - surrounding text. You'll generally want to set this for nodes - that contain arbitrary text, like strings and comments, and for - nodes that appear _inside_ arbitrary text, like HTML tags. When - not given a value, in a grammar declaration, defaults to - `"auto"`. + For inline widgets that are displayed inline (as opposed to + `inline-block`) and introduce line breaks (through `
` tags + or textual newlines), this must indicate the amount of line + breaks they introduce. Defaults to 0. */ - static isolate: NodeProp<"rtl" | "ltr" | "auto">; + get lineBreaks(): number; /** - The hash of the [context](#lr.ContextTracker.constructor) - that the node was parsed in, if any. Used to limit reuse of - contextual nodes. + Can be used to configure which kinds of events inside the widget + should be ignored by the editor. The default is to ignore all + events. */ - static contextHash: NodeProp; + ignoreEvent(event: Event): boolean; /** - The distance beyond the end of the node that the tokenizer - looked ahead for any of the tokens inside the node. (The LR - parser only stores this when it is larger than 25, for - efficiency reasons.) + Override the way screen coordinates for positions at/in the + widget are found. `pos` will be the offset into the widget, and + `side` the side of the position that is being queried—less than + zero for before, greater than zero for after, and zero for + directly at that position. */ - static lookAhead: NodeProp; + coordsAt(dom: HTMLElement, pos: number, side: number): Rect | null; /** - This per-node prop is used to replace a given node, or part of a - node, with another tree. This is useful to include trees from - different languages in mixed-language parsers. + This is called when the an instance of the widget is removed + from the editor view. */ - static mounted: NodeProp; + destroy(dom: HTMLElement): void; } /** -A mounted tree, which can be [stored](#common.NodeProp^mounted) on -a tree node to indicate that parts of its content are -represented by another tree. +A decoration set represents a collection of decorated ranges, +organized for efficient access and mapping. See +[`RangeSet`](https://codemirror.net/6/docs/ref/#state.RangeSet) for its methods. */ -declare class MountedTree { - /** - The inner tree. - */ - readonly tree: Tree; - /** - If this is null, this tree replaces the entire node (it will - be included in the regular iteration instead of its host - node). If not, only the given ranges are considered to be - covered by this tree. This is used for trees that are mixed in - a way that isn't strictly hierarchical. Such mounted trees are - only entered by [`resolveInner`](#common.Tree.resolveInner) - and [`enter`](#common.SyntaxNode.enter). - */ - readonly overlay: readonly { - from: number; - to: number; - }[] | null; +type DecorationSet = RangeSet; +/** +The different types of blocks that can occur in an editor view. +*/ +declare enum BlockType { /** - The parser used to create this subtree. + A line of text. */ - readonly parser: Parser; - constructor( + Text = 0, /** - The inner tree. + A block widget associated with the position after it. */ - tree: Tree, + WidgetBefore = 1, /** - If this is null, this tree replaces the entire node (it will - be included in the regular iteration instead of its host - node). If not, only the given ranges are considered to be - covered by this tree. This is used for trees that are mixed in - a way that isn't strictly hierarchical. Such mounted trees are - only entered by [`resolveInner`](#common.Tree.resolveInner) - and [`enter`](#common.SyntaxNode.enter). + A block widget associated with the position before it. */ - overlay: readonly { - from: number; - to: number; - }[] | null, + WidgetAfter = 2, /** - The parser used to create this subtree. + A block widget [replacing](https://codemirror.net/6/docs/ref/#view.Decoration^replace) a range of content. */ - parser: Parser); + WidgetRange = 3 } /** -Type returned by [`NodeProp.add`](#common.NodeProp.add). Describes -whether a prop should be added to a given node type in a node set, -and what value it should have. -*/ -type NodePropSource = (type: NodeType) => null | [NodeProp, any]; -/** -Each node in a syntax tree has a node type associated with it. +A decoration provides information on how to draw or style a piece +of content. You'll usually use it wrapped in a +[`Range`](https://codemirror.net/6/docs/ref/#state.Range), which adds a start and end position. +@nonabstract */ -declare class NodeType { +declare abstract class Decoration extends RangeValue { /** - The name of the node type. Not necessarily unique, but if the - grammar was written properly, different node types with the - same name within a node set should play the same semantic - role. + The config object used to create this decoration. You can + include additional properties in there to store metadata about + your decoration. */ - readonly name: string; + readonly spec: any; + protected constructor( /** - The id of this node in its set. Corresponds to the term ids - used in the parser. + @internal */ - readonly id: number; + startSide: number, /** - Define a node type. + @internal */ - static define(spec: { - /** - The ID of the node type. When this type is used in a - [set](#common.NodeSet), the ID must correspond to its index in - the type array. - */ - id: number; - /** - The name of the node type. Leave empty to define an anonymous - node. - */ - name?: string; - /** - [Node props](#common.NodeProp) to assign to the type. The value - given for any given prop should correspond to the prop's type. - */ - props?: readonly ([NodeProp, any] | NodePropSource)[]; - /** - Whether this is a [top node](#common.NodeType.isTop). - */ - top?: boolean; - /** - Whether this node counts as an [error - node](#common.NodeType.isError). - */ - error?: boolean; - /** - Whether this node is a [skipped](#common.NodeType.isSkipped) - node. - */ - skipped?: boolean; - }): NodeType; + endSide: number, /** - Retrieves a node prop for this type. Will return `undefined` if - the prop isn't present on this node. + @internal */ - prop(prop: NodeProp): T | undefined; + widget: WidgetType | null, /** - True when this is the top node of a grammar. + The config object used to create this decoration. You can + include additional properties in there to store metadata about + your decoration. */ - get isTop(): boolean; + spec: any); + abstract eq(other: Decoration): boolean; /** - True when this node is produced by a skip rule. + Create a mark decoration, which influences the styling of the + content in its range. Nested mark decorations will cause nested + DOM elements to be created. Nesting order is determined by + precedence of the [facet](https://codemirror.net/6/docs/ref/#view.EditorView^decorations), with + the higher-precedence decorations creating the inner DOM nodes. + Such elements are split on line boundaries and on the boundaries + of lower-precedence decorations. */ - get isSkipped(): boolean; + static mark(spec: MarkDecorationSpec): Decoration; /** - Indicates whether this is an error node. + Create a widget decoration, which displays a DOM element at the + given position. */ - get isError(): boolean; + static widget(spec: WidgetDecorationSpec): Decoration; /** - When true, this node type doesn't correspond to a user-declared - named node, for example because it is used to cache repetition. + Create a replace decoration which replaces the given range with + a widget, or simply hides it. */ - get isAnonymous(): boolean; + static replace(spec: ReplaceDecorationSpec): Decoration; /** - Returns true when this node's name or one of its - [groups](#common.NodeProp^group) matches the given string. + Create a line decoration, which can add DOM attributes to the + line starting at the given position. */ - is(name: string | number): boolean; + static line(spec: LineDecorationSpec): Decoration; /** - An empty dummy node type to use when no actual type is available. + Build a [`DecorationSet`](https://codemirror.net/6/docs/ref/#view.DecorationSet) from the given + decorated range or ranges. If the ranges aren't already sorted, + pass `true` for `sort` to make the library sort them for you. */ - static none: NodeType; + static set(of: Range | readonly Range[], sort?: boolean): DecorationSet; /** - Create a function from node types to arbitrary values by - specifying an object whose property names are node or - [group](#common.NodeProp^group) names. Often useful with - [`NodeProp.add`](#common.NodeProp.add). You can put multiple - names, separated by spaces, in a single property name to map - multiple node names to a single value. + The empty set of decorations. */ - static match(map: { - [selector: string]: T; - }): (node: NodeType) => T | undefined; + static none: DecorationSet; } + /** -A node set holds a collection of node types. It is used to -compactly represent trees by storing their type ids, rather than a -full pointer to the type object, in a numeric array. Each parser -[has](#lr.LRParser.nodeSet) a node set, and [tree -buffers](#common.TreeBuffer) can only store collections of nodes -from the same set. A set can have a maximum of 2**16 (65536) node -types in it, so that the ids fit into 16-bit typed array slots. +Command functions are used in key bindings and other types of user +actions. Given an editor view, they check whether their effect can +apply to the editor, and if it can, perform it as a side effect +(which usually means [dispatching](https://codemirror.net/6/docs/ref/#view.EditorView.dispatch) a +transaction) and return `true`. */ -declare class NodeSet { - /** - The node types in this set, by id. - */ - readonly types: readonly NodeType[]; +type Command = (target: EditorView) => boolean; +declare class ScrollTarget { + readonly range: SelectionRange; + readonly y: ScrollStrategy; + readonly x: ScrollStrategy; + readonly yMargin: number; + readonly xMargin: number; + readonly isSnapshot: boolean; + constructor(range: SelectionRange, y?: ScrollStrategy, x?: ScrollStrategy, yMargin?: number, xMargin?: number, isSnapshot?: boolean); + map(changes: ChangeDesc): ScrollTarget; + clip(state: EditorState): ScrollTarget; +} +/** +This is the interface plugin objects conform to. +*/ +interface PluginValue extends Object { /** - Create a set with the given types. The `id` property of each - type should correspond to its position within the array. + Notifies the plugin of an update that happened in the view. This + is called _before_ the view updates its own DOM. It is + responsible for updating the plugin's internal state (including + any state that may be read by plugin fields) and _writing_ to + the DOM for the changes in the update. To avoid unnecessary + layout recomputations, it should _not_ read the DOM layout—use + [`requestMeasure`](https://codemirror.net/6/docs/ref/#view.EditorView.requestMeasure) to schedule + your code in a DOM reading phase if you need to. */ - constructor( + update?(update: ViewUpdate): void; /** - The node types in this set, by id. + Called when the document view is updated (due to content, + decoration, or viewport changes). Should not try to immediately + start another view update. Often useful for calling + [`requestMeasure`](https://codemirror.net/6/docs/ref/#view.EditorView.requestMeasure). */ - types: readonly NodeType[]); + docViewUpdate?(view: EditorView): void; /** - Create a copy of this set with some node properties added. The - arguments to this method can be created with - [`NodeProp.add`](#common.NodeProp.add). + Called when the plugin is no longer going to be used. Should + revert any changes the plugin made to the DOM. */ - extend(...props: NodePropSource[]): NodeSet; + destroy?(): void; } /** -Options that control iteration. Can be combined with the `|` -operator to enable multiple ones. +Provides additional information when defining a [view +plugin](https://codemirror.net/6/docs/ref/#view.ViewPlugin). */ -declare enum IterMode { +interface PluginSpec { /** - When enabled, iteration will only visit [`Tree`](#common.Tree) - objects, not nodes packed into - [`TreeBuffer`](#common.TreeBuffer)s. + Register the given [event + handlers](https://codemirror.net/6/docs/ref/#view.EditorView^domEventHandlers) for the plugin. + When called, these will have their `this` bound to the plugin + value. */ - ExcludeBuffers = 1, + eventHandlers?: DOMEventHandlers; /** - Enable this to make iteration include anonymous nodes (such as - the nodes that wrap repeated grammar constructs into a balanced - tree). + Registers [event observers](https://codemirror.net/6/docs/ref/#view.EditorView^domEventObservers) + for the plugin. Will, when called, have their `this` bound to + the plugin value. */ - IncludeAnonymous = 2, + eventObservers?: DOMEventHandlers; /** - By default, regular [mounted](#common.NodeProp^mounted) nodes - replace their base node in iteration. Enable this to ignore them - instead. + Specify that the plugin provides additional extensions when + added to an editor configuration. */ - IgnoreMounts = 4, + provide?: (plugin: ViewPlugin) => Extension; /** - This option only applies in - [`enter`](#common.SyntaxNode.enter)-style methods. It tells the - library to not enter mounted overlays if one covers the given - position. + Allow the plugin to provide decorations. When given, this should + be a function that take the plugin value and return a + [decoration set](https://codemirror.net/6/docs/ref/#view.DecorationSet). See also the caveat about + [layout-changing decorations](https://codemirror.net/6/docs/ref/#view.EditorView^decorations) that + depend on the view. */ - IgnoreOverlays = 8 + decorations?: (value: V) => DecorationSet; } /** -A piece of syntax tree. There are two ways to approach these -trees: the way they are actually stored in memory, and the -convenient way. - -Syntax trees are stored as a tree of `Tree` and `TreeBuffer` -objects. By packing detail information into `TreeBuffer` leaf -nodes, the representation is made a lot more memory-efficient. - -However, when you want to actually work with tree nodes, this -representation is very awkward, so most client code will want to -use the [`TreeCursor`](#common.TreeCursor) or -[`SyntaxNode`](#common.SyntaxNode) interface instead, which provides -a view on some part of this data structure, and can be used to -move around to adjacent nodes. +View plugins associate stateful values with a view. They can +influence the way the content is drawn, and are notified of things +that happen in the view. */ -declare class Tree { +declare class ViewPlugin { /** - The type of the top node. + Instances of this class act as extensions. */ - readonly type: NodeType; + extension: Extension; + private constructor(); /** - This node's child nodes. + Define a plugin from a constructor function that creates the + plugin's value, given an editor view. */ - readonly children: readonly (Tree | TreeBuffer)[]; + static define(create: (view: EditorView) => V, spec?: PluginSpec): ViewPlugin; /** - The positions (offsets relative to the start of this tree) of - the children. + Create a plugin for a class whose constructor takes a single + editor view as argument. */ - readonly positions: readonly number[]; + static fromClass(cls: { + new (view: EditorView): V; + }, spec?: PluginSpec): ViewPlugin; +} +interface MeasureRequest { /** - The total length of this tree + Called in a DOM read phase to gather information that requires + DOM layout. Should _not_ mutate the document. */ - readonly length: number; + read(view: EditorView): T; /** - Construct a new tree. See also [`Tree.build`](#common.Tree^build). + Called in a DOM write phase to update the document. Should _not_ + do anything that triggers DOM layout. */ - constructor( + write?(measure: T, view: EditorView): void; /** - The type of the top node. + When multiple requests with the same key are scheduled, only the + last one will actually be run. */ - type: NodeType, + key?: any; +} +type AttrSource = Attrs | ((view: EditorView) => Attrs | null); +/** +View [plugins](https://codemirror.net/6/docs/ref/#view.ViewPlugin) are given instances of this +class, which describe what happened, whenever the view is updated. +*/ +declare class ViewUpdate { /** - This node's child nodes. + The editor view that the update is associated with. */ - children: readonly (Tree | TreeBuffer)[], + readonly view: EditorView; /** - The positions (offsets relative to the start of this tree) of - the children. + The new editor state. */ - positions: readonly number[], - /** - The total length of this tree - */ - length: number, - /** - Per-node [node props](#common.NodeProp) to associate with this node. - */ - props?: readonly [NodeProp | number, any][]); + readonly state: EditorState; /** - The empty tree + The transactions involved in the update. May be empty. */ - static empty: Tree; + readonly transactions: readonly Transaction[]; /** - Get a [tree cursor](#common.TreeCursor) positioned at the top of - the tree. Mode can be used to [control](#common.IterMode) which - nodes the cursor visits. + The changes made to the document by this update. */ - cursor(mode?: IterMode): TreeCursor; + readonly changes: ChangeSet; /** - Get a [tree cursor](#common.TreeCursor) pointing into this tree - at the given position and side (see - [`moveTo`](#common.TreeCursor.moveTo). + The previous editor state. */ - cursorAt(pos: number, side?: -1 | 0 | 1, mode?: IterMode): TreeCursor; + readonly startState: EditorState; + private constructor(); /** - Get a [syntax node](#common.SyntaxNode) object for the top of the - tree. + Tells you whether the [viewport](https://codemirror.net/6/docs/ref/#view.EditorView.viewport) or + [visible ranges](https://codemirror.net/6/docs/ref/#view.EditorView.visibleRanges) changed in this + update. */ - get topNode(): SyntaxNode; + get viewportChanged(): boolean; /** - Get the [syntax node](#common.SyntaxNode) at the given position. - If `side` is -1, this will move into nodes that end at the - position. If 1, it'll move into nodes that start at the - position. With 0, it'll only enter nodes that cover the position - from both sides. - - Note that this will not enter - [overlays](#common.MountedTree.overlay), and you often want - [`resolveInner`](#common.Tree.resolveInner) instead. + Returns true when + [`viewportChanged`](https://codemirror.net/6/docs/ref/#view.ViewUpdate.viewportChanged) is true + and the viewport change is not just the result of mapping it in + response to document changes. */ - resolve(pos: number, side?: -1 | 0 | 1): SyntaxNode; + get viewportMoved(): boolean; /** - Like [`resolve`](#common.Tree.resolve), but will enter - [overlaid](#common.MountedTree.overlay) nodes, producing a syntax node - pointing into the innermost overlaid tree at the given position - (with parent links going through all parent structure, including - the host trees). + Indicates whether the height of a block element in the editor + changed in this update. */ - resolveInner(pos: number, side?: -1 | 0 | 1): SyntaxNode; + get heightChanged(): boolean; /** - In some situations, it can be useful to iterate through all - nodes around a position, including those in overlays that don't - directly cover the position. This method gives you an iterator - that will produce all nodes, from small to big, around the given - position. + Returns true when the document was modified or the size of the + editor, or elements within the editor, changed. */ - resolveStack(pos: number, side?: -1 | 0 | 1): NodeIterator; + get geometryChanged(): boolean; /** - Iterate over the tree and its children, calling `enter` for any - node that touches the `from`/`to` region (if given) before - running over such a node's children, and `leave` (if given) when - leaving the node. When `enter` returns `false`, that node will - not have its children iterated over (or `leave` called). + True when this update indicates a focus change. */ - iterate(spec: { - enter(node: SyntaxNodeRef): boolean | void; - leave?(node: SyntaxNodeRef): void; - from?: number; - to?: number; - mode?: IterMode; - }): void; + get focusChanged(): boolean; /** - Get the value of the given [node prop](#common.NodeProp) for this - node. Works with both per-node and per-type props. + Whether the document changed in this update. */ - prop(prop: NodeProp): T | undefined; + get docChanged(): boolean; /** - Returns the node's [per-node props](#common.NodeProp.perNode) in a - format that can be passed to the [`Tree`](#common.Tree) - constructor. + Whether the selection was explicitly set in this update. */ - get propValues(): readonly [NodeProp | number, any][]; + get selectionSet(): boolean; +} + +/** +Interface that objects registered with +[`EditorView.mouseSelectionStyle`](https://codemirror.net/6/docs/ref/#view.EditorView^mouseSelectionStyle) +must conform to. +*/ +interface MouseSelectionStyle { /** - Balance the direct children of this tree, producing a copy of - which may have children grouped into subtrees with type - [`NodeType.none`](#common.NodeType^none). + Return a new selection for the mouse gesture that starts with + the event that was originally given to the constructor, and ends + with the event passed here. In case of a plain click, those may + both be the `mousedown` event, in case of a drag gesture, the + latest `mousemove` event will be passed. + + When `extend` is true, that means the new selection should, if + possible, extend the start selection. If `multiple` is true, the + new selection should be added to the original selection. */ - balance(config?: { - /** - Function to create the newly balanced subtrees. - */ - makeTree?: (children: readonly (Tree | TreeBuffer)[], positions: readonly number[], length: number) => Tree; - }): Tree; + get: (curEvent: MouseEvent, extend: boolean, multiple: boolean) => EditorSelection; /** - Build a tree from a postfix-ordered buffer of node information, - or a cursor over such a buffer. + Called when the view is updated while the gesture is in + progress. When the document changes, it may be necessary to map + some data (like the original selection or start position) + through the changes. + + This may return `true` to indicate that the `get` method should + get queried again after the update, because something in the + update could change its result. Be wary of infinite loops when + using this (where `get` returns a new selection, which will + trigger `update`, which schedules another `get` in response). */ - static build(data: BuildData): Tree; + update: (update: ViewUpdate) => boolean | void; } +type MakeSelectionStyle = (view: EditorView, event: MouseEvent) => MouseSelectionStyle | null; + /** -Represents a sequence of nodes. +Record used to represent information about a block-level element +in the editor view. */ -type NodeIterator = { - node: SyntaxNode; - next: NodeIterator | null; -}; -type BuildData = { +declare class BlockInfo { /** - The buffer or buffer cursor to read the node data from. - - When this is an array, it should contain four values for every - node in the tree. - - - The first holds the node's type, as a node ID pointing into - the given `NodeSet`. - - The second holds the node's start offset. - - The third the end offset. - - The fourth the amount of space taken up in the array by this - node and its children. Since there's four values per node, - this is the total number of nodes inside this node (children - and transitive children) plus one for the node itself, times - four. - - Parent nodes should appear _after_ child nodes in the array. As - an example, a node of type 10 spanning positions 0 to 4, with - two children, of type 11 and 12, might look like this: - - [11, 0, 1, 4, 12, 2, 4, 4, 10, 0, 4, 12] + The start of the element in the document. */ - buffer: BufferCursor | readonly number[]; + readonly from: number; /** - The node types to use. + The length of the element. */ - nodeSet: NodeSet; + readonly length: number; /** - The id of the top node type. + The top position of the element (relative to the top of the + document). */ - topID: number; + readonly top: number; /** - The position the tree should start at. Defaults to 0. + Its height. */ - start?: number; + readonly height: number; /** - The position in the buffer where the function should stop - reading. Defaults to 0. + The type of element this is. When querying lines, this may be + an array of all the blocks that make up the line. */ - bufferStart?: number; + get type(): BlockType | readonly BlockInfo[]; /** - The length of the wrapping node. The end offset of the last - child is used when not provided. + The end of the element as a document position. */ - length?: number; + get to(): number; /** - The maximum buffer length to use. Defaults to - [`DefaultBufferLength`](#common.DefaultBufferLength). + The bottom position of the element. */ - maxBufferLength?: number; + get bottom(): number; /** - An optional array holding reused nodes that the buffer can refer - to. + If this is a widget block, this will return the widget + associated with it. */ - reused?: readonly Tree[]; + get widget(): WidgetType | null; /** - The first node type that indicates repeat constructs in this - grammar. + If this is a textblock, this holds the number of line breaks + that appear in widgets inside the block. */ - minRepeatType?: number; -}; + get widgetLineBreaks(): number; +} + /** -This is used by `Tree.build` as an abstraction for iterating over -a tree buffer. A cursor initially points at the very last element -in the buffer. Every time `next()` is called it moves on to the -previous one. +The type of object given to the [`EditorView`](https://codemirror.net/6/docs/ref/#view.EditorView) +constructor. */ -interface BufferCursor { +interface EditorViewConfig extends EditorStateConfig { /** - The current buffer position (four times the number of nodes - remaining). + The view's initial state. If not given, a new state is created + by passing this configuration object to + [`EditorState.create`](https://codemirror.net/6/docs/ref/#state.EditorState^create), using its + `doc`, `selection`, and `extensions` field (if provided). */ - pos: number; + state?: EditorState; /** - The node ID of the next node in the buffer. + When given, the editor is immediately appended to the given + element on creation. (Otherwise, you'll have to place the view's + [`dom`](https://codemirror.net/6/docs/ref/#view.EditorView.dom) element in the document yourself.) */ - id: number; + parent?: Element | DocumentFragment; /** - The start position of the next node in the buffer. + If the view is going to be mounted in a shadow root or document + other than the one held by the global variable `document` (the + default), you should pass it here. If you provide `parent`, but + not this option, the editor will automatically look up a root + from the parent. */ - start: number; + root?: Document | ShadowRoot; /** - The end position of the next node. + Pass an effect created with + [`EditorView.scrollIntoView`](https://codemirror.net/6/docs/ref/#view.EditorView^scrollIntoView) or + [`EditorView.scrollSnapshot`](https://codemirror.net/6/docs/ref/#view.EditorView.scrollSnapshot) + here to set an initial scroll position. */ - end: number; + scrollTo?: StateEffect; /** - The size of the next node (the number of nodes inside, counting - the node itself, times 4). + Override the way transactions are + [dispatched](https://codemirror.net/6/docs/ref/#view.EditorView.dispatch) for this editor view. + Your implementation, if provided, should probably call the + view's [`update` method](https://codemirror.net/6/docs/ref/#view.EditorView.update). */ - size: number; + dispatchTransactions?: (trs: readonly Transaction[], view: EditorView) => void; /** - Moves `this.pos` down by 4. + **Deprecated** single-transaction version of + `dispatchTransactions`. Will force transactions to be dispatched + one at a time when used. */ - next(): void; - /** - Create a copy of this cursor. - */ - fork(): BufferCursor; + dispatch?: (tr: Transaction, view: EditorView) => void; } /** -Tree buffers contain (type, start, end, endIndex) quads for each -node. In such a buffer, nodes are stored in prefix order (parents -before children, with the endIndex of the parent indicating which -children belong to it). +An editor view represents the editor's user interface. It holds +the editable DOM surface, and possibly other elements such as the +line number gutter. It handles events and dispatches state +transactions for editing actions. */ -declare class TreeBuffer { - /** - The buffer's content. - */ - readonly buffer: Uint16Array; +declare class EditorView { /** - The total length of the group of nodes in the buffer. + The current editor state. */ - readonly length: number; + get state(): EditorState; /** - The node set used in this buffer. + To be able to display large documents without consuming too much + memory or overloading the browser, CodeMirror only draws the + code that is visible (plus a margin around it) to the DOM. This + property tells you the extent of the current drawn viewport, in + document positions. */ - readonly set: NodeSet; + get viewport(): { + from: number; + to: number; + }; /** - Create a tree buffer. + When there are, for example, large collapsed ranges in the + viewport, its size can be a lot bigger than the actual visible + content. Thus, if you are doing something like styling the + content in the viewport, it is preferable to only do so for + these ranges, which are the subset of the viewport that is + actually drawn. */ - constructor( + get visibleRanges(): readonly { + from: number; + to: number; + }[]; /** - The buffer's content. + Returns false when the editor is entirely scrolled out of view + or otherwise hidden. */ - buffer: Uint16Array, + get inView(): boolean; /** - The total length of the group of nodes in the buffer. + Indicates whether the user is currently composing text via + [IME](https://en.wikipedia.org/wiki/Input_method), and at least + one change has been made in the current composition. */ - length: number, + get composing(): boolean; /** - The node set used in this buffer. + Indicates whether the user is currently in composing state. Note + that on some platforms, like Android, this will be the case a + lot, since just putting the cursor on a word starts a + composition there. */ - set: NodeSet); -} -/** -The set of properties provided by both [`SyntaxNode`](#common.SyntaxNode) -and [`TreeCursor`](#common.TreeCursor). Note that, if you need -an object that is guaranteed to stay stable in the future, you -need to use the [`node`](#common.SyntaxNodeRef.node) accessor. -*/ -interface SyntaxNodeRef { + get compositionStarted(): boolean; + private dispatchTransactions; + private _root; /** - The start position of the node. + The document or shadow root that the view lives in. */ - readonly from: number; + get root(): DocumentOrShadowRoot; /** - The end position of the node. + The DOM element that wraps the entire editor view. */ - readonly to: number; + readonly dom: HTMLElement; /** - The type of the node. + The DOM element that can be styled to scroll. (Note that it may + not have been, so you can't assume this is scrollable.) */ - readonly type: NodeType; + readonly scrollDOM: HTMLElement; /** - The name of the node (`.type.name`). + The editable DOM element holding the editor content. You should + not, usually, interact with this content directly though the + DOM, since the editor will immediately undo most of the changes + you make. Instead, [dispatch](https://codemirror.net/6/docs/ref/#view.EditorView.dispatch) + [transactions](https://codemirror.net/6/docs/ref/#state.Transaction) to modify content, and + [decorations](https://codemirror.net/6/docs/ref/#view.Decoration) to style it. */ - readonly name: string; + readonly contentDOM: HTMLElement; + private announceDOM; + private plugins; + private pluginMap; + private editorAttrs; + private contentAttrs; + private styleModules; + private bidiCache; + private destroyed; /** - Get the [tree](#common.Tree) that represents the current node, - if any. Will return null when the node is in a [tree - buffer](#common.TreeBuffer). + Construct a new view. You'll want to either provide a `parent` + option, or put `view.dom` into your document after creating a + view, so that the user can see the editor. */ - readonly tree: Tree | null; + constructor(config?: EditorViewConfig); /** - Retrieve a stable [syntax node](#common.SyntaxNode) at this - position. + All regular editor state updates should go through this. It + takes a transaction, array of transactions, or transaction spec + and updates the view to show the new state produced by that + transaction. Its implementation can be overridden with an + [option](https://codemirror.net/6/docs/ref/#view.EditorView.constructor^config.dispatchTransactions). + This function is bound to the view instance, so it does not have + to be called as a method. + + Note that when multiple `TransactionSpec` arguments are + provided, these define a single transaction (the specs will be + merged), not a sequence of transactions. */ - readonly node: SyntaxNode; + dispatch(tr: Transaction): void; + dispatch(trs: readonly Transaction[]): void; + dispatch(...specs: TransactionSpec[]): void; /** - Test whether the node matches a given context—a sequence of - direct parent nodes. Empty strings in the context array act as - wildcards, other strings must match the ancestor node's name. + Update the view for the given array of transactions. This will + update the visible document and selection to match the state + produced by the transactions, and notify view plugins of the + change. You should usually call + [`dispatch`](https://codemirror.net/6/docs/ref/#view.EditorView.dispatch) instead, which uses this + as a primitive. */ - matchContext(context: readonly string[]): boolean; -} -/** -A syntax node provides an immutable pointer to a given node in a -tree. When iterating over large amounts of nodes, you may want to -use a mutable [cursor](#common.TreeCursor) instead, which is more -efficient. -*/ -interface SyntaxNode extends SyntaxNodeRef { + update(transactions: readonly Transaction[]): void; /** - The node's parent node, if any. + Reset the view to the given state. (This will cause the entire + document to be redrawn and all view plugins to be reinitialized, + so you should probably only use it when the new state isn't + derived from the old state. Otherwise, use + [`dispatch`](https://codemirror.net/6/docs/ref/#view.EditorView.dispatch) instead.) */ - parent: SyntaxNode | null; + setState(newState: EditorState): void; + private updatePlugins; + private docViewUpdate; /** - The first child, if the node has children. + Get the CSS classes for the currently active editor themes. */ - firstChild: SyntaxNode | null; + get themeClasses(): string; + private updateAttrs; + private showAnnouncements; + private mountStyles; + private readMeasured; /** - The node's last child, if available. + Schedule a layout measurement, optionally providing callbacks to + do custom DOM measuring followed by a DOM write phase. Using + this is preferable reading DOM layout directly from, for + example, an event handler, because it'll make sure measuring and + drawing done by other components is synchronized, avoiding + unnecessary DOM layout computations. */ - lastChild: SyntaxNode | null; + requestMeasure(request?: MeasureRequest): void; /** - The first child that ends after `pos`. + Get the value of a specific plugin, if present. Note that + plugins that crash can be dropped from a view, so even when you + know you registered a given plugin, it is recommended to check + the return value of this method. */ - childAfter(pos: number): SyntaxNode | null; + plugin(plugin: ViewPlugin): T | null; /** - The last child that starts before `pos`. + The top position of the document, in screen coordinates. This + may be negative when the editor is scrolled down. Points + directly to the top of the first line, not above the padding. */ - childBefore(pos: number): SyntaxNode | null; + get documentTop(): number; /** - Enter the child at the given position. If side is -1 the child - may end at that position, when 1 it may start there. - - This will by default enter - [overlaid](#common.MountedTree.overlay) - [mounted](#common.NodeProp^mounted) trees. You can set - `overlays` to false to disable that. - - Similarly, when `buffers` is false this will not enter - [buffers](#common.TreeBuffer), only [nodes](#common.Tree) (which - is mostly useful when looking for props, which cannot exist on - buffer-allocated nodes). + Reports the padding above and below the document. */ - enter(pos: number, side: -1 | 0 | 1, mode?: IterMode): SyntaxNode | null; + get documentPadding(): { + top: number; + bottom: number; + }; /** - This node's next sibling, if any. + If the editor is transformed with CSS, this provides the scale + along the X axis. Otherwise, it will just be 1. Note that + transforms other than translation and scaling are not supported. */ - nextSibling: SyntaxNode | null; + get scaleX(): number; /** - This node's previous sibling. + Provide the CSS transformed scale along the Y axis. */ - prevSibling: SyntaxNode | null; + get scaleY(): number; /** - A [tree cursor](#common.TreeCursor) starting at this node. + Find the text line or block widget at the given vertical + position (which is interpreted as relative to the [top of the + document](https://codemirror.net/6/docs/ref/#view.EditorView.documentTop)). */ - cursor(mode?: IterMode): TreeCursor; + elementAtHeight(height: number): BlockInfo; /** - Find the node around, before (if `side` is -1), or after (`side` - is 1) the given position. Will look in parent nodes if the - position is outside this node. + Find the line block (see + [`lineBlockAt`](https://codemirror.net/6/docs/ref/#view.EditorView.lineBlockAt) at the given + height, again interpreted relative to the [top of the + document](https://codemirror.net/6/docs/ref/#view.EditorView.documentTop). */ - resolve(pos: number, side?: -1 | 0 | 1): SyntaxNode; + lineBlockAtHeight(height: number): BlockInfo; /** - Similar to `resolve`, but enter - [overlaid](#common.MountedTree.overlay) nodes. + Get the extent and vertical position of all [line + blocks](https://codemirror.net/6/docs/ref/#view.EditorView.lineBlockAt) in the viewport. Positions + are relative to the [top of the + document](https://codemirror.net/6/docs/ref/#view.EditorView.documentTop); */ - resolveInner(pos: number, side?: -1 | 0 | 1): SyntaxNode; + get viewportLineBlocks(): BlockInfo[]; /** - Move the position to the innermost node before `pos` that looks - like it is unfinished (meaning it ends in an error node or has a - child ending in an error node right at its end). + Find the line block around the given document position. A line + block is a range delimited on both sides by either a + non-[hidden](https://codemirror.net/6/docs/ref/#view.Decoration^replace) line break, or the + start/end of the document. It will usually just hold a line of + text, but may be broken into multiple textblocks by block + widgets. */ - enterUnfinishedNodesBefore(pos: number): SyntaxNode; + lineBlockAt(pos: number): BlockInfo; /** - Get a [tree](#common.Tree) for this node. Will allocate one if it - points into a buffer. + The editor's total content height. */ - toTree(): Tree; + get contentHeight(): number; /** - Get the first child of the given type (which may be a [node - name](#common.NodeType.name) or a [group - name](#common.NodeProp^group)). If `before` is non-null, only - return children that occur somewhere after a node with that name - or group. If `after` is non-null, only return children that - occur somewhere before a node with that name or group. + Move a cursor position by [grapheme + cluster](https://codemirror.net/6/docs/ref/#state.findClusterBreak). `forward` determines whether + the motion is away from the line start, or towards it. In + bidirectional text, the line is traversed in visual order, using + the editor's [text direction](https://codemirror.net/6/docs/ref/#view.EditorView.textDirection). + When the start position was the last one on the line, the + returned position will be across the line break. If there is no + further line, the original position is returned. + + By default, this method moves over a single cluster. The + optional `by` argument can be used to move across more. It will + be called with the first cluster as argument, and should return + a predicate that determines, for each subsequent cluster, + whether it should also be moved over. */ - getChild(type: string | number, before?: string | number | null, after?: string | number | null): SyntaxNode | null; + moveByChar(start: SelectionRange, forward: boolean, by?: (initial: string) => (next: string) => boolean): SelectionRange; /** - Like [`getChild`](#common.SyntaxNode.getChild), but return all - matching children, not just the first. + Move a cursor position across the next group of either + [letters](https://codemirror.net/6/docs/ref/#state.EditorState.charCategorizer) or non-letter + non-whitespace characters. */ - getChildren(type: string | number, before?: string | number | null, after?: string | number | null): SyntaxNode[]; -} -/** -A tree cursor object focuses on a given node in a syntax tree, and -allows you to move to adjacent nodes. -*/ -declare class TreeCursor implements SyntaxNodeRef { + moveByGroup(start: SelectionRange, forward: boolean): SelectionRange; /** - The node's type. + Get the cursor position visually at the start or end of a line. + Note that this may differ from the _logical_ position at its + start or end (which is simply at `line.from`/`line.to`) if text + at the start or end goes against the line's base text direction. */ - type: NodeType; + visualLineSide(line: Line$1, end: boolean): SelectionRange; /** - Shorthand for `.type.name`. + Move to the next line boundary in the given direction. If + `includeWrap` is true, line wrapping is on, and there is a + further wrap point on the current line, the wrap point will be + returned. Otherwise this function will return the start or end + of the line. */ - get name(): string; + moveToLineBoundary(start: SelectionRange, forward: boolean, includeWrap?: boolean): SelectionRange; /** - The start source offset of this node. + Move a cursor position vertically. When `distance` isn't given, + it defaults to moving to the next line (including wrapped + lines). Otherwise, `distance` should provide a positive distance + in pixels. + + When `start` has a + [`goalColumn`](https://codemirror.net/6/docs/ref/#state.SelectionRange.goalColumn), the vertical + motion will use that as a target horizontal position. Otherwise, + the cursor's own horizontal position is used. The returned + cursor will have its goal column set to whichever column was + used. */ - from: number; + moveVertically(start: SelectionRange, forward: boolean, distance?: number): SelectionRange; /** - The end source offset. + Find the DOM parent node and offset (child offset if `node` is + an element, character offset when it is a text node) at the + given document position. + + Note that for positions that aren't currently in + `visibleRanges`, the resulting DOM position isn't necessarily + meaningful (it may just point before or after a placeholder + element). */ - to: number; - private stack; - private bufferNode; - private yieldNode; - private yieldBuf; + domAtPos(pos: number): { + node: Node; + offset: number; + }; /** - Move the cursor to this node's first child. When this returns - false, the node has no child, and the cursor has not been moved. + Find the document position at the given DOM node. Can be useful + for associating positions with DOM events. Will raise an error + when `node` isn't part of the editor content. */ - firstChild(): boolean; + posAtDOM(node: Node, offset?: number): number; /** - Move the cursor to this node's last child. + Get the document position at the given screen coordinates. For + positions not covered by the visible viewport's DOM structure, + this will return null, unless `false` is passed as second + argument, in which case it'll return an estimated position that + would be near the coordinates if it were rendered. */ - lastChild(): boolean; + posAtCoords(coords: { + x: number; + y: number; + }, precise: false): number; + posAtCoords(coords: { + x: number; + y: number; + }): number | null; /** - Move the cursor to the first child that ends after `pos`. + Get the screen coordinates at the given document position. + `side` determines whether the coordinates are based on the + element before (-1) or after (1) the position (if no element is + available on the given side, the method will transparently use + another strategy to get reasonable coordinates). */ - childAfter(pos: number): boolean; + coordsAtPos(pos: number, side?: -1 | 1): Rect | null; /** - Move to the last child that starts before `pos`. + Return the rectangle around a given character. If `pos` does not + point in front of a character that is in the viewport and + rendered (i.e. not replaced, not a line break), this will return + null. For space characters that are a line wrap point, this will + return the position before the line break. */ - childBefore(pos: number): boolean; + coordsForChar(pos: number): Rect | null; /** - Move the cursor to the child around `pos`. If side is -1 the - child may end at that position, when 1 it may start there. This - will also enter [overlaid](#common.MountedTree.overlay) - [mounted](#common.NodeProp^mounted) trees unless `overlays` is - set to false. + The default width of a character in the editor. May not + accurately reflect the width of all characters (given variable + width fonts or styling of invididual ranges). */ - enter(pos: number, side: -1 | 0 | 1, mode?: IterMode): boolean; + get defaultCharacterWidth(): number; /** - Move to the node's parent node, if this isn't the top node. + The default height of a line in the editor. May not be accurate + for all lines. */ - parent(): boolean; + get defaultLineHeight(): number; /** - Move to this node's next sibling, if any. + The text direction + ([`direction`](https://developer.mozilla.org/en-US/docs/Web/CSS/direction) + CSS property) of the editor's content element. */ - nextSibling(): boolean; + get textDirection(): Direction; /** - Move to this node's previous sibling, if any. + Find the text direction of the block at the given position, as + assigned by CSS. If + [`perLineTextDirection`](https://codemirror.net/6/docs/ref/#view.EditorView^perLineTextDirection) + isn't enabled, or the given position is outside of the viewport, + this will always return the same as + [`textDirection`](https://codemirror.net/6/docs/ref/#view.EditorView.textDirection). Note that + this may trigger a DOM layout. */ - prevSibling(): boolean; - private atLastNode; - private move; + textDirectionAt(pos: number): Direction; /** - Move to the next node in a - [pre-order](https://en.wikipedia.org/wiki/Tree_traversal#Pre-order,_NLR) - traversal, going from a node to its first child or, if the - current node is empty or `enter` is false, its next sibling or - the next sibling of the first parent node that has one. + Whether this editor [wraps lines](https://codemirror.net/6/docs/ref/#view.EditorView.lineWrapping) + (as determined by the + [`white-space`](https://developer.mozilla.org/en-US/docs/Web/CSS/white-space) + CSS property of its content element). */ - next(enter?: boolean): boolean; + get lineWrapping(): boolean; /** - Move to the next node in a last-to-first pre-order traveral. A - node is followed by its last child or, if it has none, its - previous sibling or the previous sibling of the first parent - node that has one. + Returns the bidirectional text structure of the given line + (which should be in the current document) as an array of span + objects. The order of these spans matches the [text + direction](https://codemirror.net/6/docs/ref/#view.EditorView.textDirection)—if that is + left-to-right, the leftmost spans come first, otherwise the + rightmost spans come first. */ - prev(enter?: boolean): boolean; + bidiSpans(line: Line$1): readonly BidiSpan[]; /** - Move the cursor to the innermost node that covers `pos`. If - `side` is -1, it will enter nodes that end at `pos`. If it is 1, - it will enter nodes that start at `pos`. + Check whether the editor has focus. */ - moveTo(pos: number, side?: -1 | 0 | 1): this; + get hasFocus(): boolean; /** - Get a [syntax node](#common.SyntaxNode) at the cursor's current - position. + Put focus on the editor. */ - get node(): SyntaxNode; + focus(): void; /** - Get the [tree](#common.Tree) that represents the current node, if - any. Will return null when the node is in a [tree - buffer](#common.TreeBuffer). + Update the [root](https://codemirror.net/6/docs/ref/##view.EditorViewConfig.root) in which the editor lives. This is only + necessary when moving the editor's existing DOM to a new window or shadow root. */ - get tree(): Tree | null; + setRoot(root: Document | ShadowRoot): void; /** - Iterate over the current node and all its descendants, calling - `enter` when entering a node and `leave`, if given, when leaving - one. When `enter` returns `false`, any children of that node are - skipped, and `leave` isn't called for it. + Clean up this editor view, removing its element from the + document, unregistering event handlers, and notifying + plugins. The view instance can no longer be used after + calling this. */ - iterate(enter: (node: SyntaxNodeRef) => boolean | void, leave?: (node: SyntaxNodeRef) => void): void; + destroy(): void; /** - Test whether the current node matches a given context—a sequence - of direct parent node names. Empty strings in the context array - are treated as wildcards. + Returns an effect that can be + [added](https://codemirror.net/6/docs/ref/#state.TransactionSpec.effects) to a transaction to + cause it to scroll the given position or range into view. */ - matchContext(context: readonly string[]): boolean; -} - -/** -Objects returned by the function passed to -[`parseMixed`](#common.parseMixed) should conform to this -interface. -*/ -interface NestedParse { + static scrollIntoView(pos: number | SelectionRange, options?: { + /** + By default (`"nearest"`) the position will be vertically + scrolled only the minimal amount required to move the given + position into view. You can set this to `"start"` to move it + to the top of the view, `"end"` to move it to the bottom, or + `"center"` to move it to the center. + */ + y?: ScrollStrategy; + /** + Effect similar to + [`y`](https://codemirror.net/6/docs/ref/#view.EditorView^scrollIntoView^options.y), but for the + horizontal scroll position. + */ + x?: ScrollStrategy; + /** + Extra vertical distance to add when moving something into + view. Not used with the `"center"` strategy. Defaults to 5. + Must be less than the height of the editor. + */ + yMargin?: number; + /** + Extra horizontal distance to add. Not used with the `"center"` + strategy. Defaults to 5. Must be less than the width of the + editor. + */ + xMargin?: number; + }): StateEffect; /** - The parser to use for the inner region. + Return an effect that resets the editor to its current (at the + time this method was called) scroll position. Note that this + only affects the editor's own scrollable element, not parents. + See also + [`EditorViewConfig.scrollTo`](https://codemirror.net/6/docs/ref/#view.EditorViewConfig.scrollTo). + + The effect should be used with a document identical to the one + it was created for. Failing to do so is not an error, but may + not scroll to the expected position. You can + [map](https://codemirror.net/6/docs/ref/#state.StateEffect.map) the effect to account for changes. */ - parser: Parser; + scrollSnapshot(): StateEffect; /** - When this property is not given, the entire node is parsed with - this parser, and it is [mounted](#common.NodeProp^mounted) as a - non-overlay node, replacing its host node in tree iteration. - - When an array of ranges is given, only those ranges are parsed, - and the tree is mounted as an - [overlay](#common.MountedTree.overlay). + Enable or disable tab-focus mode, which disables key bindings + for Tab and Shift-Tab, letting the browser's default + focus-changing behavior go through instead. This is useful to + prevent trapping keyboard users in your editor. - When a function is given, that function will be called for - descendant nodes of the target node, not including child nodes - that are covered by another nested parse, to determine the - overlay ranges. When it returns true, the entire descendant is - included, otherwise just the range given. The mixed parser will - optimize range-finding in reused nodes, which means it's a good - idea to use a function here when the target node is expected to - have a large, deep structure. + Without argument, this toggles the mode. With a boolean, it + enables (true) or disables it (false). Given a number, it + temporarily enables the mode until that number of milliseconds + have passed or another non-Tab key is pressed. */ - overlay?: readonly { - from: number; - to: number; - }[] | ((node: SyntaxNodeRef) => { - from: number; - to: number; - } | boolean); -} -/** -Create a parse wrapper that, after the inner parse completes, -scans its tree for mixed language regions with the `nest` -function, runs the resulting [inner parses](#common.NestedParse), -and then [mounts](#common.NodeProp^mounted) their results onto the -tree. -*/ -declare function parseMixed(nest: (node: SyntaxNodeRef, input: Input) => NestedParse | null): ParseWrapper; - -/** -A parse stack. These are used internally by the parser to track -parsing progress. They also provide some properties and methods -that external code such as a tokenizer can use to get information -about the parse state. -*/ -declare class Stack { + setTabFocusMode(to?: boolean | number): void; /** - The input position up to which this stack has parsed. + Facet to add a [style + module](https://github.com/marijnh/style-mod#documentation) to + an editor view. The view will ensure that the module is + mounted in its [document + root](https://codemirror.net/6/docs/ref/#view.EditorView.constructor^config.root). */ - pos: number; + static styleModule: Facet; /** - The stack's current [context](#lr.ContextTracker) value, if - any. Its type will depend on the context tracker's type - parameter, or it will be `null` if there is no context - tracker. + Returns an extension that can be used to add DOM event handlers. + The value should be an object mapping event names to handler + functions. For any given event, such functions are ordered by + extension precedence, and the first handler to return true will + be assumed to have handled that event, and no other handlers or + built-in behavior will be activated for it. These are registered + on the [content element](https://codemirror.net/6/docs/ref/#view.EditorView.contentDOM), except + for `scroll` handlers, which will be called any time the + editor's [scroll element](https://codemirror.net/6/docs/ref/#view.EditorView.scrollDOM) or one of + its parent nodes is scrolled. */ - get context(): any; + static domEventHandlers(handlers: DOMEventHandlers): Extension; /** - Check if the given term would be able to be shifted (optionally - after some reductions) on this stack. This can be useful for - external tokenizers that want to make sure they only provide a - given token when it applies. + Create an extension that registers DOM event observers. Contrary + to event [handlers](https://codemirror.net/6/docs/ref/#view.EditorView^domEventHandlers), + observers can't be prevented from running by a higher-precedence + handler returning true. They also don't prevent other handlers + and observers from running when they return true, and should not + call `preventDefault`. */ - canShift(term: number): boolean; + static domEventObservers(observers: DOMEventHandlers): Extension; /** - Get the parser used by this stack. + An input handler can override the way changes to the editable + DOM content are handled. Handlers are passed the document + positions between which the change was found, and the new + content. When one returns true, no further input handlers are + called and the default behavior is prevented. + + The `insert` argument can be used to get the default transaction + that would be applied for this input. This can be useful when + dispatching the custom behavior as a separate transaction. */ - get parser(): LRParser; + static inputHandler: Facet<(view: EditorView, from: number, to: number, text: string, insert: () => Transaction) => boolean, readonly ((view: EditorView, from: number, to: number, text: string, insert: () => Transaction) => boolean)[]>; /** - Test whether a given dialect (by numeric ID, as exported from - the terms file) is enabled. + Functions provided in this facet will be used to transform text + pasted or dropped into the editor. */ - dialectEnabled(dialectID: number): boolean; - private shiftContext; - private reduceContext; - private updateContext; -} - -/** -[Tokenizers](#lr.ExternalTokenizer) interact with the input -through this interface. It presents the input as a stream of -characters, tracking lookahead and hiding the complexity of -[ranges](#common.Parser.parse^ranges) from tokenizer code. -*/ -declare class InputStream { + static clipboardInputFilter: Facet<(text: string, state: EditorState) => string, readonly ((text: string, state: EditorState) => string)[]>; /** - Backup chunk + Transform text copied or dragged from the editor. */ - private chunk2; - private chunk2Pos; + static clipboardOutputFilter: Facet<(text: string, state: EditorState) => string, readonly ((text: string, state: EditorState) => string)[]>; /** - The character code of the next code unit in the input, or -1 - when the stream is at the end of the input. + Scroll handlers can override how things are scrolled into view. + If they return `true`, no further handling happens for the + scrolling. If they return false, the default scroll behavior is + applied. Scroll handlers should never initiate editor updates. */ - next: number; + static scrollHandler: Facet<(view: EditorView, range: SelectionRange, options: { + x: ScrollStrategy; + y: ScrollStrategy; + xMargin: number; + yMargin: number; + }) => boolean, readonly ((view: EditorView, range: SelectionRange, options: { + x: ScrollStrategy; + y: ScrollStrategy; + xMargin: number; + yMargin: number; + }) => boolean)[]>; /** - The current position of the stream. Note that, due to parses - being able to cover non-contiguous - [ranges](#common.Parser.startParse), advancing the stream does - not always mean its position moves a single unit. + This facet can be used to provide functions that create effects + to be dispatched when the editor's focus state changes. */ - pos: number; - private rangeIndex; - private range; + static focusChangeEffect: Facet<(state: EditorState, focusing: boolean) => StateEffect | null, readonly ((state: EditorState, focusing: boolean) => StateEffect | null)[]>; /** - Look at a code unit near the stream position. `.peek(0)` equals - `.next`, `.peek(-1)` gives you the previous character, and so - on. - - Note that looking around during tokenizing creates dependencies - on potentially far-away content, which may reduce the - effectiveness incremental parsing—when looking forward—or even - cause invalid reparses when looking backward more than 25 code - units, since the library does not track lookbehind. + By default, the editor assumes all its content has the same + [text direction](https://codemirror.net/6/docs/ref/#view.Direction). Configure this with a `true` + value to make it read the text direction of every (rendered) + line separately. */ - peek(offset: number): number; + static perLineTextDirection: Facet; /** - Accept a token. By default, the end of the token is set to the - current stream position, but you can pass an offset (relative to - the stream position) to change that. + Allows you to provide a function that should be called when the + library catches an exception from an extension (mostly from view + plugins, but may be used by other extensions to route exceptions + from user-code-provided callbacks). This is mostly useful for + debugging and logging. See [`logException`](https://codemirror.net/6/docs/ref/#view.logException). */ - acceptToken(token: number, endOffset?: number): void; - private getChunk; - private readNext; + static exceptionSink: Facet<(exception: any) => void, readonly ((exception: any) => void)[]>; /** - Move the stream forward N (defaults to 1) code units. Returns - the new value of [`next`](#lr.InputStream.next). + A facet that can be used to register a function to be called + every time the view updates. */ - advance(n?: number): number; - private setDone; -} -interface ExternalOptions { + static updateListener: Facet<(update: ViewUpdate) => void, readonly ((update: ViewUpdate) => void)[]>; /** - When set to true, mark this tokenizer as depending on the - current parse stack, which prevents its result from being cached - between parser actions at the same positions. + Facet that controls whether the editor content DOM is editable. + When its highest-precedence value is `false`, the element will + not have its `contenteditable` attribute set. (Note that this + doesn't affect API calls that change the editor content, even + when those are bound to keys or buttons. See the + [`readOnly`](https://codemirror.net/6/docs/ref/#state.EditorState.readOnly) facet for that.) */ - contextual?: boolean; + static editable: Facet; /** - By defaults, when a tokenizer returns a token, that prevents - tokenizers with lower precedence from even running. When - `fallback` is true, the tokenizer is allowed to run when a - previous tokenizer returned a token that didn't match any of the - current state's actions. + Allows you to influence the way mouse selection happens. The + functions in this facet will be called for a `mousedown` event + on the editor, and can return an object that overrides the way a + selection is computed from that mouse click or drag. */ - fallback?: boolean; + static mouseSelectionStyle: Facet; /** - When set to true, tokenizing will not stop after this tokenizer - has produced a token. (But it will still fail to reach this one - if a higher-precedence tokenizer produced a token.) + Facet used to configure whether a given selection drag event + should move or copy the selection. The given predicate will be + called with the `mousedown` event, and can return `true` when + the drag should move the content. */ - extend?: boolean; -} -/** -`@external tokens` declarations in the grammar should resolve to -an instance of this class. -*/ -declare class ExternalTokenizer { + static dragMovesSelection: Facet<(event: MouseEvent) => boolean, readonly ((event: MouseEvent) => boolean)[]>; /** - Create a tokenizer. The first argument is the function that, - given an input stream, scans for the types of tokens it - recognizes at the stream's position, and calls - [`acceptToken`](#lr.InputStream.acceptToken) when it finds - one. + Facet used to configure whether a given selecting click adds a + new range to the existing selection or replaces it entirely. The + default behavior is to check `event.metaKey` on macOS, and + `event.ctrlKey` elsewhere. */ - constructor( + static clickAddsSelectionRange: Facet<(event: MouseEvent) => boolean, readonly ((event: MouseEvent) => boolean)[]>; /** - @internal + A facet that determines which [decorations](https://codemirror.net/6/docs/ref/#view.Decoration) + are shown in the view. Decorations can be provided in two + ways—directly, or via a function that takes an editor view. + + Only decoration sets provided directly are allowed to influence + the editor's vertical layout structure. The ones provided as + functions are called _after_ the new viewport has been computed, + and thus **must not** introduce block widgets or replacing + decorations that cover line breaks. + + If you want decorated ranges to behave like atomic units for + cursor motion and deletion purposes, also provide the range set + containing the decorations to + [`EditorView.atomicRanges`](https://codemirror.net/6/docs/ref/#view.EditorView^atomicRanges). */ - token: (input: InputStream, stack: Stack) => void, options?: ExternalOptions); -} - -/** -Context trackers are used to track stateful context (such as -indentation in the Python grammar, or parent elements in the XML -grammar) needed by external tokenizers. You declare them in a -grammar file as `@context exportName from "module"`. - -Context values should be immutable, and can be updated (replaced) -on shift or reduce actions. - -The export used in a `@context` declaration should be of this -type. -*/ -declare class ContextTracker { + static decorations: Facet DecorationSet), readonly (DecorationSet | ((view: EditorView) => DecorationSet))[]>; /** - Define a context tracker. - */ - constructor(spec: { - /** - The initial value of the context at the start of the parse. - */ - start: T; - /** - Update the context when the parser executes a - [shift](https://en.wikipedia.org/wiki/LR_parser#Shift_and_reduce_actions) - action. - */ - shift?(context: T, term: number, stack: Stack, input: InputStream): T; - /** - Update the context when the parser executes a reduce action. - */ - reduce?(context: T, term: number, stack: Stack, input: InputStream): T; - /** - Update the context when the parser reuses a node from a tree - fragment. - */ - reuse?(context: T, node: Tree, stack: Stack, input: InputStream): T; - /** - Reduce a context value to a number (for cheap storage and - comparison). Only needed for strict contexts. - */ - hash?(context: T): number; - /** - By default, nodes can only be reused during incremental - parsing if they were created in the same context as the one in - which they are reused. Set this to false to disable that - check (and the overhead of storing the hashes). - */ - strict?: boolean; - }); -} -/** -Configuration options when -[reconfiguring](#lr.LRParser.configure) a parser. -*/ -interface ParserConfig { + Facet that works much like + [`decorations`](https://codemirror.net/6/docs/ref/#view.EditorView^decorations), but puts its + inputs at the very bottom of the precedence stack, meaning mark + decorations provided here will only be split by other, partially + overlapping \`outerDecorations\` ranges, and wrap around all + regular decorations. Use this for mark elements that should, as + much as possible, remain in one piece. + */ + static outerDecorations: Facet DecorationSet), readonly (DecorationSet | ((view: EditorView) => DecorationSet))[]>; /** - Node prop values to add to the parser's node set. + Used to provide ranges that should be treated as atoms as far as + cursor motion is concerned. This causes methods like + [`moveByChar`](https://codemirror.net/6/docs/ref/#view.EditorView.moveByChar) and + [`moveVertically`](https://codemirror.net/6/docs/ref/#view.EditorView.moveVertically) (and the + commands built on top of them) to skip across such regions when + a selection endpoint would enter them. This does _not_ prevent + direct programmatic [selection + updates](https://codemirror.net/6/docs/ref/#state.TransactionSpec.selection) from moving into such + regions. */ - props?: readonly NodePropSource[]; + static atomicRanges: Facet<(view: EditorView) => RangeSet, readonly ((view: EditorView) => RangeSet)[]>; /** - The name of the `@top` declaration to parse from. If not - specified, the first top rule declaration in the grammar is - used. + When range decorations add a `unicode-bidi: isolate` style, they + should also include a + [`bidiIsolate`](https://codemirror.net/6/docs/ref/#view.MarkDecorationSpec.bidiIsolate) property + in their decoration spec, and be exposed through this facet, so + that the editor can compute the proper text order. (Other values + for `unicode-bidi`, except of course `normal`, are not + supported.) */ - top?: string; + static bidiIsolatedRanges: Facet DecorationSet), readonly (DecorationSet | ((view: EditorView) => DecorationSet))[]>; /** - A space-separated string of dialects to enable. + Facet that allows extensions to provide additional scroll + margins (space around the sides of the scrolling element that + should be considered invisible). This can be useful when the + plugin introduces elements that cover part of that element (for + example a horizontally fixed gutter). */ - dialect?: string; + static scrollMargins: Facet<(view: EditorView) => Partial | null, readonly ((view: EditorView) => Partial | null)[]>; /** - Replace the given external tokenizers with new ones. + Create a theme extension. The first argument can be a + [`style-mod`](https://github.com/marijnh/style-mod#documentation) + style spec providing the styles for the theme. These will be + prefixed with a generated class for the style. + + Because the selectors will be prefixed with a scope class, rule + that directly match the editor's [wrapper + element](https://codemirror.net/6/docs/ref/#view.EditorView.dom)—to which the scope class will be + added—need to be explicitly differentiated by adding an `&` to + the selector for that element—for example + `&.cm-focused`. + + When `dark` is set to true, the theme will be marked as dark, + which will cause the `&dark` rules from [base + themes](https://codemirror.net/6/docs/ref/#view.EditorView^baseTheme) to be used (as opposed to + `&light` when a light theme is active). */ - tokenizers?: { - from: ExternalTokenizer; - to: ExternalTokenizer; - }[]; + static theme(spec: { + [selector: string]: StyleSpec; + }, options?: { + dark?: boolean; + }): Extension; /** - Replace external specializers with new ones. + This facet records whether a dark theme is active. The extension + returned by [`theme`](https://codemirror.net/6/docs/ref/#view.EditorView^theme) automatically + includes an instance of this when the `dark` option is set to + true. */ - specializers?: { - from: (value: string, stack: Stack) => number; - to: (value: string, stack: Stack) => number; - }[]; + static darkTheme: Facet; /** - Replace the context tracker with a new one. + Create an extension that adds styles to the base theme. Like + with [`theme`](https://codemirror.net/6/docs/ref/#view.EditorView^theme), use `&` to indicate the + place of the editor wrapper element when directly targeting + that. You can also use `&dark` or `&light` instead to only + target editors with a dark or light theme. */ - contextTracker?: ContextTracker; + static baseTheme(spec: { + [selector: string]: StyleSpec; + }): Extension; /** - When true, the parser will raise an exception, rather than run - its error-recovery strategies, when the input doesn't match the - grammar. + Provides a Content Security Policy nonce to use when creating + the style sheets for the editor. Holds the empty string when no + nonce has been provided. */ - strict?: boolean; + static cspNonce: Facet; /** - Add a wrapper, which can extend parses created by this parser - with additional logic (usually used to add - [mixed-language](#common.parseMixed) parsing). + Facet that provides additional DOM attributes for the editor's + editable DOM element. */ - wrap?: ParseWrapper; + static contentAttributes: Facet; /** - The maximum length of the TreeBuffers generated in the output - tree. Defaults to 1024. + Facet that provides DOM attributes for the editor's outer + element. */ - bufferLength?: number; + static editorAttributes: Facet; + /** + An extension that enables line wrapping in the editor (by + setting CSS `white-space` to `pre-wrap` in the content). + */ + static lineWrapping: Extension; + /** + State effect used to include screen reader announcements in a + transaction. These will be added to the DOM in a visually hidden + element with `aria-live="polite"` set, and should be used to + describe effects that are visually obvious but may not be + noticed by screen reader users (such as moving to the next + search match). + */ + static announce: StateEffectType; + /** + Retrieve an editor view instance from the view's DOM + representation. + */ + static findFromDOM(dom: HTMLElement): EditorView | null; } /** -Holds the parse tables for a given grammar, as generated by -`lezer-generator`, and provides [methods](#common.Parser) to parse -content with. +Helper type that maps event names to event object types, or the +`any` type for unknown events. */ -declare class LRParser extends Parser { +interface DOMEventMap extends HTMLElementEventMap { + [other: string]: any; +} +/** +Event handlers are specified with objects like this. For event +types known by TypeScript, this will infer the event argument type +to hold the appropriate event object type. For unknown events, it +is inferred to `any`, and should be explicitly set if you want type +checking. +*/ +type DOMEventHandlers = { + [event in keyof DOMEventMap]?: (this: This, event: DOMEventMap[event], view: EditorView) => boolean | void; +}; + +/** +Key bindings associate key names with +[command](https://codemirror.net/6/docs/ref/#view.Command)-style functions. + +Key names may be strings like `"Shift-Ctrl-Enter"`—a key identifier +prefixed with zero or more modifiers. Key identifiers are based on +the strings that can appear in +[`KeyEvent.key`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key). +Use lowercase letters to refer to letter keys (or uppercase letters +if you want shift to be held). You may use `"Space"` as an alias +for the `" "` name. + +Modifiers can be given in any order. `Shift-` (or `s-`), `Alt-` (or +`a-`), `Ctrl-` (or `c-` or `Control-`) and `Cmd-` (or `m-` or +`Meta-`) are recognized. + +When a key binding contains multiple key names separated by +spaces, it represents a multi-stroke binding, which will fire when +the user presses the given keys after each other. + +You can use `Mod-` as a shorthand for `Cmd-` on Mac and `Ctrl-` on +other platforms. So `Mod-b` is `Ctrl-b` on Linux but `Cmd-b` on +macOS. +*/ +interface KeyBinding { /** - The nodes used in the trees emitted by this parser. + The key name to use for this binding. If the platform-specific + property (`mac`, `win`, or `linux`) for the current platform is + used as well in the binding, that one takes precedence. If `key` + isn't defined and the platform-specific binding isn't either, + a binding is ignored. */ - readonly nodeSet: NodeSet; - createParse(input: Input, fragments: readonly TreeFragment[], ranges: readonly { - from: number; - to: number; - }[]): PartialParse; + key?: string; /** - Configure the parser. Returns a new parser instance that has the - given settings modified. Settings not provided in `config` are - kept from the original parser. + Key to use specifically on macOS. */ - configure(config: ParserConfig): LRParser; + mac?: string; /** - Tells you whether any [parse wrappers](#lr.ParserConfig.wrap) - are registered for this parser. + Key to use specifically on Windows. */ - hasWrappers(): boolean; + win?: string; /** - Returns the name associated with a given term. This will only - work for all terms when the parser was generated with the - `--names` option. By default, only the names of tagged terms are - stored. + Key to use specifically on Linux. */ - getName(term: number): string; + linux?: string; /** - The type of top node produced by the parser. + The command to execute when this binding is triggered. When the + command function returns `false`, further bindings will be tried + for the key. */ - get topNode(): NodeType; + run?: Command; /** - Used by the output of the parser generator. Not available to - user code. @hide + When given, this defines a second binding, using the (possibly + platform-specific) key name prefixed with `Shift-` to activate + this command. */ - static deserialize(spec: any): LRParser; -} - -declare class StyleModule { - constructor(spec: {[selector: string]: StyleSpec}, options?: { - finish?(sel: string): string - }) - getRules(): string - static mount( - root: Document | ShadowRoot | DocumentOrShadowRoot, - module: StyleModule | ReadonlyArray, - options?: {nonce?: string} - ): void - static newName(): string + shift?: Command; + /** + When this property is present, the function is called for every + key that is not a multi-stroke prefix. + */ + any?: (view: EditorView, event: KeyboardEvent) => boolean; + /** + By default, key bindings apply when focus is on the editor + content (the `"editor"` scope). Some extensions, mostly those + that define their own panels, might want to allow you to + register bindings local to that panel. Such bindings should use + a custom scope name. You may also assign multiple scope names to + a binding, separating them by spaces. + */ + scope?: string; + /** + When set to true (the default is false), this will always + prevent the further handling for the bound key, even if the + command(s) return false. This can be useful for cases where the + native behavior of the key is annoying or irrelevant but the + command doesn't always apply (such as, Mod-u for undo selection, + which would cause the browser to view source instead when no + selection can be undone). + */ + preventDefault?: boolean; + /** + When set to true, `stopPropagation` will be called on keyboard + events that have their `preventDefault` called in response to + this key binding (see also + [`preventDefault`](https://codemirror.net/6/docs/ref/#view.KeyBinding.preventDefault)). + */ + stopPropagation?: boolean; } +/** +Facet used for registering keymaps. -type StyleSpec = { - [propOrSelector: string]: string | number | StyleSpec | null -} +You can add multiple keymaps to an editor. Their priorities +determine their precedence (the ones specified early or with high +priority get checked first). When a handler has returned `true` +for a given key, no further handlers are called. +*/ +declare const keymap: Facet; +type SelectionConfig = { + /** + The length of a full cursor blink cycle, in milliseconds. + Defaults to 1200. Can be set to 0 to disable blinking. + */ + cursorBlinkRate?: number; + /** + Whether to show a cursor for non-empty ranges. Defaults to + true. + */ + drawRangeCursor?: boolean; +}; /** -Used to indicate [text direction](https://codemirror.net/6/docs/ref/#view.EditorView.textDirection). +Returns an extension that hides the browser's native selection and +cursor, replacing the selection with a background behind the text +(with the `cm-selectionBackground` class), and the +cursors with elements overlaid over the code (using +`cm-cursor-primary` and `cm-cursor-secondary`). + +This allows the editor to display secondary selection ranges, and +tends to produce a type of selection more in line with that users +expect in a text editor (the native selection styling will often +leave gaps between lines and won't fill the horizontal space after +a line when the selection continues past it). + +It does have a performance cost, in that it requires an extra DOM +layout cycle for many updates (the selection is drawn based on DOM +layout information that's only available after laying out the +content). */ -declare enum Direction { +declare function drawSelection(config?: SelectionConfig): Extension; + +interface SpecialCharConfig { /** - Left-to-right. + An optional function that renders the placeholder elements. + + The `description` argument will be text that clarifies what the + character is, which should be provided to screen readers (for + example with the + [`aria-label`](https://www.w3.org/TR/wai-aria/#aria-label) + attribute) and optionally shown to the user in other ways (such + as the + [`title`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/title) + attribute). + + The given placeholder string is a suggestion for how to display + the character visually. */ - LTR = 0, + render?: ((code: number, description: string | null, placeholder: string) => HTMLElement) | null; /** - Right-to-left. + Regular expression that matches the special characters to + highlight. Must have its 'g'/global flag set. */ - RTL = 1 + specialChars?: RegExp; + /** + Regular expression that can be used to add characters to the + default set of characters to highlight. + */ + addSpecialChars?: RegExp | null; } /** -Represents a contiguous range of text that has a single direction -(as in left-to-right or right-to-left). +Returns an extension that installs highlighting of special +characters. */ -declare class BidiSpan { - /** - The start of the span (relative to the start of the line). - */ - readonly from: number; +declare function highlightSpecialChars( +/** +Configuration options. +*/ +config?: SpecialCharConfig): Extension; + +/** +Mark lines that have a cursor on them with the `"cm-activeLine"` +DOM class. +*/ +declare function highlightActiveLine(): Extension; + +/** +Extension that enables a placeholder—a piece of example content +to show when the editor is empty. +*/ +declare function placeholder(content: string | HTMLElement | ((view: EditorView) => HTMLElement)): Extension; + +/** +Helper class used to make it easier to maintain decorations on +visible code that matches a given regular expression. To be used +in a [view plugin](https://codemirror.net/6/docs/ref/#view.ViewPlugin). Instances of this object +represent a matching configuration. +*/ +declare class MatchDecorator { + private regexp; + private addMatch; + private boundary; + private maxLength; /** - The end of the span. + Create a decorator. */ - readonly to: number; + constructor(config: { + /** + The regular expression to match against the content. Will only + be matched inside lines (not across them). Should have its 'g' + flag set. + */ + regexp: RegExp; + /** + The decoration to apply to matches, either directly or as a + function of the match. + */ + decoration?: Decoration | ((match: RegExpExecArray, view: EditorView, pos: number) => Decoration | null); + /** + Customize the way decorations are added for matches. This + function, when given, will be called for matches and should + call `add` to create decorations for them. Note that the + decorations should appear *in* the given range, and the + function should have no side effects beyond calling `add`. + + The `decoration` option is ignored when `decorate` is + provided. + */ + decorate?: (add: (from: number, to: number, decoration: Decoration) => void, from: number, to: number, match: RegExpExecArray, view: EditorView) => void; + /** + By default, changed lines are re-matched entirely. You can + provide a boundary expression, which should match single + character strings that can never occur in `regexp`, to reduce + the amount of re-matching. + */ + boundary?: RegExp; + /** + Matching happens by line, by default, but when lines are + folded or very long lines are only partially drawn, the + decorator may avoid matching part of them for speed. This + controls how much additional invisible content it should + include in its matches. Defaults to 1000. + */ + maxLength?: number; + }); /** - The ["bidi - level"](https://unicode.org/reports/tr9/#Basic_Display_Algorithm) - of the span (in this context, 0 means - left-to-right, 1 means right-to-left, 2 means left-to-right - number inside right-to-left text). + Compute the full set of decorations for matches in the given + view's viewport. You'll want to call this when initializing your + plugin. */ - readonly level: number; + createDeco(view: EditorView): RangeSet; /** - The direction of this span. + Update a set of decorations for a view update. `deco` _must_ be + the set of decorations produced by _this_ `MatchDecorator` for + the view state before the update. */ - get dir(): Direction; + updateDeco(update: ViewUpdate, deco: DecorationSet): DecorationSet; + private updateRange; } -type Attrs = { - [name: string]: string; -}; - /** -Basic rectangle type. +Create an extension that enables rectangular selections. By +default, it will react to left mouse drag with the Alt key held +down. When such a selection occurs, the text within the rectangle +that was dragged over will be selected, as one selection +[range](https://codemirror.net/6/docs/ref/#state.SelectionRange) per line. */ -interface Rect { - readonly left: number; - readonly right: number; - readonly top: number; - readonly bottom: number; -} -type ScrollStrategy = "nearest" | "start" | "end" | "center"; - -interface MarkDecorationSpec { - /** - Whether the mark covers its start and end position or not. This - influences whether content inserted at those positions becomes - part of the mark. Defaults to false. - */ - inclusive?: boolean; - /** - Specify whether the start position of the marked range should be - inclusive. Overrides `inclusive`, when both are present. - */ - inclusiveStart?: boolean; - /** - Whether the end should be inclusive. - */ - inclusiveEnd?: boolean; - /** - Add attributes to the DOM elements that hold the text in the - marked range. - */ - attributes?: { - [key: string]: string; - }; - /** - Shorthand for `{attributes: {class: value}}`. - */ - class?: string; - /** - Add a wrapping element around the text in the marked range. Note - that there will not necessarily be a single element covering the - entire range—other decorations with lower precedence might split - this one if they partially overlap it, and line breaks always - end decoration elements. - */ - tagName?: string; - /** - When using sets of decorations in - [`bidiIsolatedRanges`](https://codemirror.net/6/docs/ref/##view.EditorView^bidiIsolatedRanges), - this property provides the direction of the isolates. When null - or not given, it indicates the range has `dir=auto`, and its - direction should be derived from the first strong directional - character in it. - */ - bidiIsolate?: Direction | null; - /** - Decoration specs allow extra properties, which can be retrieved - through the decoration's [`spec`](https://codemirror.net/6/docs/ref/#view.Decoration.spec) - property. - */ - [other: string]: any; -} -interface WidgetDecorationSpec { - /** - The type of widget to draw here. - */ - widget: WidgetType; - /** - Which side of the given position the widget is on. When this is - positive, the widget will be drawn after the cursor if the - cursor is on the same position. Otherwise, it'll be drawn before - it. When multiple widgets sit at the same position, their `side` - values will determine their ordering—those with a lower value - come first. Defaults to 0. May not be more than 10000 or less - than -10000. - */ - side?: number; +declare function rectangularSelection(options?: { /** - By default, to avoid unintended mixing of block and inline - widgets, block widgets with a positive `side` are always drawn - after all inline widgets at that position, and those with a - non-positive side before inline widgets. Setting this option to - `true` for a block widget will turn this off and cause it to be - rendered between the inline widgets, ordered by `side`. + A custom predicate function, which takes a `mousedown` event and + returns true if it should be used for rectangular selection. */ - inlineOrder?: boolean; + eventFilter?: (event: MouseEvent) => boolean; +}): Extension; + +/** +Creates an extension that configures tooltip behavior. +*/ +declare function tooltips(config?: { /** - Determines whether this is a block widgets, which will be drawn - between lines, or an inline widget (the default) which is drawn - between the surrounding text. + By default, tooltips use `"fixed"` + [positioning](https://developer.mozilla.org/en-US/docs/Web/CSS/position), + which has the advantage that tooltips don't get cut off by + scrollable parent elements. However, CSS rules like `contain: + layout` can break fixed positioning in child nodes, which can be + worked about by using `"absolute"` here. - Note that block-level decorations should not have vertical - margins, and if you dynamically change their height, you should - make sure to call - [`requestMeasure`](https://codemirror.net/6/docs/ref/#view.EditorView.requestMeasure), so that the - editor can update its information about its vertical layout. - */ - block?: boolean; - /** - Other properties are allowed. + On iOS, which at the time of writing still doesn't properly + support fixed positioning, the library always uses absolute + positioning. + + If the tooltip parent element sits in a transformed element, the + library also falls back to absolute positioning. */ - [other: string]: any; -} -interface ReplaceDecorationSpec { + position?: "fixed" | "absolute"; /** - An optional widget to drawn in the place of the replaced - content. + The element to put the tooltips into. By default, they are put + in the editor (`cm-editor`) element, and that is usually what + you want. But in some layouts that can lead to positioning + issues, and you need to use a different parent to work around + those. */ - widget?: WidgetType; + parent?: HTMLElement; /** - Whether this range covers the positions on its sides. This - influences whether new content becomes part of the range and - whether the cursor can be drawn on its sides. Defaults to false - for inline replacements, and true for block replacements. + By default, when figuring out whether there is room for a + tooltip at a given position, the extension considers the entire + space between 0,0 and `innerWidth`,`innerHeight` to be available + for showing tooltips. You can provide a function here that + returns an alternative rectangle. */ - inclusive?: boolean; + tooltipSpace?: (view: EditorView) => Rect; +}): Extension; +/** +Describes a tooltip. Values of this type, when provided through +the [`showTooltip`](https://codemirror.net/6/docs/ref/#view.showTooltip) facet, control the +individual tooltips on the editor. +*/ +interface Tooltip { /** - Set inclusivity at the start. + The document position at which to show the tooltip. */ - inclusiveStart?: boolean; + pos: number; /** - Set inclusivity at the end. + The end of the range annotated by this tooltip, if different + from `pos`. */ - inclusiveEnd?: boolean; + end?: number; /** - Whether this is a block-level decoration. Defaults to false. + A constructor function that creates the tooltip's [DOM + representation](https://codemirror.net/6/docs/ref/#view.TooltipView). */ - block?: boolean; + create(view: EditorView): TooltipView; /** - Other properties are allowed. + Whether the tooltip should be shown above or below the target + position. Not guaranteed to be respected for hover tooltips + since all hover tooltips for the same range are always + positioned together. Defaults to false. */ - [other: string]: any; -} -interface LineDecorationSpec { + above?: boolean; /** - DOM attributes to add to the element wrapping the line. + Whether the `above` option should be honored when there isn't + enough space on that side to show the tooltip inside the + viewport. Defaults to false. */ - attributes?: { - [key: string]: string; - }; + strictSide?: boolean; /** - Shorthand for `{attributes: {class: value}}`. + When set to true, show a triangle connecting the tooltip element + to position `pos`. */ - class?: string; + arrow?: boolean; /** - Other properties are allowed. + By default, tooltips are hidden when their position is outside + of the visible editor content. Set this to false to turn that + off. */ - [other: string]: any; + clip?: boolean; } /** -Widgets added to the content are described by subclasses of this -class. Using a description object like that makes it possible to -delay creating of the DOM structure for a widget until it is -needed, and to avoid redrawing widgets even if the decorations -that define them are recreated. +Describes the way a tooltip is displayed. */ -declare abstract class WidgetType { +interface TooltipView { /** - Build the DOM structure for this widget instance. + The DOM element to position over the editor. */ - abstract toDOM(view: EditorView): HTMLElement; + dom: HTMLElement; /** - Compare this instance to another instance of the same type. - (TypeScript can't express this, but only instances of the same - specific class will be passed to this method.) This is used to - avoid redrawing widgets when they are replaced by a new - decoration of the same type. The default implementation just - returns `false`, which will cause new instances of the widget to - always be redrawn. + Adjust the position of the tooltip relative to its anchor + position. A positive `x` value will move the tooltip + horizontally along with the text direction (so right in + left-to-right context, left in right-to-left). A positive `y` + will move the tooltip up when it is above its anchor, and down + otherwise. */ - eq(widget: WidgetType): boolean; + offset?: { + x: number; + y: number; + }; /** - Update a DOM element created by a widget of the same type (but - different, non-`eq` content) to reflect this widget. May return - true to indicate that it could update, false to indicate it - couldn't (in which case the widget will be redrawn). The default - implementation just returns false. + By default, a tooltip's screen position will be based on the + text position of its `pos` property. This method can be provided + to make the tooltip view itself responsible for finding its + screen position. + */ + getCoords?: (pos: number) => Rect; + /** + By default, tooltips are moved when they overlap with other + tooltips. Set this to `true` to disable that behavior for this + tooltip. */ - updateDOM(dom: HTMLElement, view: EditorView): boolean; + overlap?: boolean; /** - The estimated height this widget will have, to be used when - estimating the height of content that hasn't been drawn. May - return -1 to indicate you don't know. The default implementation - returns -1. + Called after the tooltip is added to the DOM for the first time. */ - get estimatedHeight(): number; + mount?(view: EditorView): void; /** - For inline widgets that are displayed inline (as opposed to - `inline-block`) and introduce line breaks (through `
` tags - or textual newlines), this must indicate the amount of line - breaks they introduce. Defaults to 0. + Update the DOM element for a change in the view's state. */ - get lineBreaks(): number; + update?(update: ViewUpdate): void; /** - Can be used to configure which kinds of events inside the widget - should be ignored by the editor. The default is to ignore all - events. + Called when the tooltip is removed from the editor or the editor + is destroyed. */ - ignoreEvent(event: Event): boolean; + destroy?(): void; /** - Override the way screen coordinates for positions at/in the - widget are found. `pos` will be the offset into the widget, and - `side` the side of the position that is being queried—less than - zero for before, greater than zero for after, and zero for - directly at that position. + Called when the tooltip has been (re)positioned. The argument is + the [space](https://codemirror.net/6/docs/ref/#view.tooltips^config.tooltipSpace) available to the + tooltip. */ - coordsAt(dom: HTMLElement, pos: number, side: number): Rect | null; + positioned?(space: Rect): void; /** - This is called when the an instance of the widget is removed - from the editor view. + By default, the library will restrict the size of tooltips so + that they don't stick out of the available space. Set this to + false to disable that. */ - destroy(dom: HTMLElement): void; + resize?: boolean; } /** -A decoration set represents a collection of decorated ranges, -organized for efficient access and mapping. See -[`RangeSet`](https://codemirror.net/6/docs/ref/#state.RangeSet) for its methods. -*/ -type DecorationSet = RangeSet; -/** -The different types of blocks that can occur in an editor view. +Facet to which an extension can add a value to show a tooltip. */ -declare enum BlockType { +declare const showTooltip: Facet; +type Handlers$1 = { + [event: string]: (view: EditorView, line: BlockInfo, event: Event) => boolean; +}; +interface LineNumberConfig { /** - A line of text. + How to display line numbers. Defaults to simply converting them + to string. */ - Text = 0, + formatNumber?: (lineNo: number, state: EditorState) => string; /** - A block widget associated with the position after it. + Supply event handlers for DOM events on this gutter. */ - WidgetBefore = 1, + domEventHandlers?: Handlers$1; +} +/** +Create a line number gutter extension. +*/ +declare function lineNumbers(config?: LineNumberConfig): Extension; + +interface HistoryConfig { /** - A block widget associated with the position before it. + The minimum depth (amount of events) to store. Defaults to 100. */ - WidgetAfter = 2, + minDepth?: number; /** - A block widget [replacing](https://codemirror.net/6/docs/ref/#view.Decoration^replace) a range of content. + The maximum time (in milliseconds) that adjacent events can be + apart and still be grouped together. Defaults to 500. */ - WidgetRange = 3 + newGroupDelay?: number; + /** + By default, when close enough together in time, changes are + joined into an existing undo event if they touch any of the + changed ranges from that event. You can pass a custom predicate + here to influence that logic. + */ + joinToEvent?: (tr: Transaction, isAdjacent: boolean) => boolean; } /** -A decoration provides information on how to draw or style a piece -of content. You'll usually use it wrapped in a -[`Range`](https://codemirror.net/6/docs/ref/#state.Range), which adds a start and end position. -@nonabstract +Create a history extension with the given configuration. */ -declare abstract class Decoration extends RangeValue { - /** - The config object used to create this decoration. You can - include additional properties in there to store metadata about - your decoration. - */ - readonly spec: any; - protected constructor( +declare function history(config?: HistoryConfig): Extension; +/** +Default key bindings for the undo history. + +- Mod-z: [`undo`](https://codemirror.net/6/docs/ref/#commands.undo). +- Mod-y (Mod-Shift-z on macOS) + Ctrl-Shift-z on Linux: [`redo`](https://codemirror.net/6/docs/ref/#commands.redo). +- Mod-u: [`undoSelection`](https://codemirror.net/6/docs/ref/#commands.undoSelection). +- Alt-u (Mod-Shift-u on macOS): [`redoSelection`](https://codemirror.net/6/docs/ref/#commands.redoSelection). +*/ +declare const historyKeymap: readonly KeyBinding[]; +/** +Move the selected lines up one line. +*/ +declare const moveLineUp: StateCommand; +/** +Move the selected lines down one line. +*/ +declare const moveLineDown: StateCommand; +/** +Add a [unit](https://codemirror.net/6/docs/ref/#language.indentUnit) of indentation to all selected +lines. +*/ +declare const indentMore: StateCommand; +/** +Remove a [unit](https://codemirror.net/6/docs/ref/#language.indentUnit) of indentation from all +selected lines. +*/ +declare const indentLess: StateCommand; +/** +The default keymap. Includes all bindings from +[`standardKeymap`](https://codemirror.net/6/docs/ref/#commands.standardKeymap) plus the following: + +- Alt-ArrowLeft (Ctrl-ArrowLeft on macOS): [`cursorSyntaxLeft`](https://codemirror.net/6/docs/ref/#commands.cursorSyntaxLeft) ([`selectSyntaxLeft`](https://codemirror.net/6/docs/ref/#commands.selectSyntaxLeft) with Shift) +- Alt-ArrowRight (Ctrl-ArrowRight on macOS): [`cursorSyntaxRight`](https://codemirror.net/6/docs/ref/#commands.cursorSyntaxRight) ([`selectSyntaxRight`](https://codemirror.net/6/docs/ref/#commands.selectSyntaxRight) with Shift) +- Alt-ArrowUp: [`moveLineUp`](https://codemirror.net/6/docs/ref/#commands.moveLineUp) +- Alt-ArrowDown: [`moveLineDown`](https://codemirror.net/6/docs/ref/#commands.moveLineDown) +- Shift-Alt-ArrowUp: [`copyLineUp`](https://codemirror.net/6/docs/ref/#commands.copyLineUp) +- Shift-Alt-ArrowDown: [`copyLineDown`](https://codemirror.net/6/docs/ref/#commands.copyLineDown) +- Escape: [`simplifySelection`](https://codemirror.net/6/docs/ref/#commands.simplifySelection) +- Ctrl-Enter (Cmd-Enter on macOS): [`insertBlankLine`](https://codemirror.net/6/docs/ref/#commands.insertBlankLine) +- Alt-l (Ctrl-l on macOS): [`selectLine`](https://codemirror.net/6/docs/ref/#commands.selectLine) +- Ctrl-i (Cmd-i on macOS): [`selectParentSyntax`](https://codemirror.net/6/docs/ref/#commands.selectParentSyntax) +- Ctrl-[ (Cmd-[ on macOS): [`indentLess`](https://codemirror.net/6/docs/ref/#commands.indentLess) +- Ctrl-] (Cmd-] on macOS): [`indentMore`](https://codemirror.net/6/docs/ref/#commands.indentMore) +- Ctrl-Alt-\\ (Cmd-Alt-\\ on macOS): [`indentSelection`](https://codemirror.net/6/docs/ref/#commands.indentSelection) +- Shift-Ctrl-k (Shift-Cmd-k on macOS): [`deleteLine`](https://codemirror.net/6/docs/ref/#commands.deleteLine) +- Shift-Ctrl-\\ (Shift-Cmd-\\ on macOS): [`cursorMatchingBracket`](https://codemirror.net/6/docs/ref/#commands.cursorMatchingBracket) +- Ctrl-/ (Cmd-/ on macOS): [`toggleComment`](https://codemirror.net/6/docs/ref/#commands.toggleComment). +- Shift-Alt-a: [`toggleBlockComment`](https://codemirror.net/6/docs/ref/#commands.toggleBlockComment). +- Ctrl-m (Alt-Shift-m on macOS): [`toggleTabFocusMode`](https://codemirror.net/6/docs/ref/#commands.toggleTabFocusMode). +*/ +declare const defaultKeymap: readonly KeyBinding[]; + +/** +The [`TreeFragment.applyChanges`](#common.TreeFragment^applyChanges) +method expects changed ranges in this format. +*/ +interface ChangedRange { /** - @internal + The start of the change in the start document */ - startSide: number, + fromA: number; /** - @internal + The end of the change in the start document */ - endSide: number, + toA: number; /** - @internal + The start of the replacement in the new document */ - widget: WidgetType | null, + fromB: number; /** - The config object used to create this decoration. You can - include additional properties in there to store metadata about - your decoration. + The end of the replacement in the new document */ - spec: any); - abstract eq(other: Decoration): boolean; + toB: number; +} +/** +Tree fragments are used during [incremental +parsing](#common.Parser.startParse) to track parts of old trees +that can be reused in a new parse. An array of fragments is used +to track regions of an old tree whose nodes might be reused in new +parses. Use the static +[`applyChanges`](#common.TreeFragment^applyChanges) method to +update fragments for document changes. +*/ +declare class TreeFragment { /** - Create a mark decoration, which influences the styling of the - content in its range. Nested mark decorations will cause nested - DOM elements to be created. Nesting order is determined by - precedence of the [facet](https://codemirror.net/6/docs/ref/#view.EditorView^decorations), with - the higher-precedence decorations creating the inner DOM nodes. - Such elements are split on line boundaries and on the boundaries - of lower-precedence decorations. + The start of the unchanged range pointed to by this fragment. + This refers to an offset in the _updated_ document (as opposed + to the original tree). */ - static mark(spec: MarkDecorationSpec): Decoration; + readonly from: number; /** - Create a widget decoration, which displays a DOM element at the - given position. + The end of the unchanged range. */ - static widget(spec: WidgetDecorationSpec): Decoration; + readonly to: number; /** - Create a replace decoration which replaces the given range with - a widget, or simply hides it. + The tree that this fragment is based on. */ - static replace(spec: ReplaceDecorationSpec): Decoration; + readonly tree: Tree; /** - Create a line decoration, which can add DOM attributes to the - line starting at the given position. + The offset between the fragment's tree and the document that + this fragment can be used against. Add this when going from + document to tree positions, subtract it to go from tree to + document positions. */ - static line(spec: LineDecorationSpec): Decoration; + readonly offset: number; /** - Build a [`DecorationSet`](https://codemirror.net/6/docs/ref/#view.DecorationSet) from the given - decorated range or ranges. If the ranges aren't already sorted, - pass `true` for `sort` to make the library sort them for you. + Construct a tree fragment. You'll usually want to use + [`addTree`](#common.TreeFragment^addTree) and + [`applyChanges`](#common.TreeFragment^applyChanges) instead of + calling this directly. */ - static set(of: Range | readonly Range[], sort?: boolean): DecorationSet; + constructor( /** - The empty set of decorations. + The start of the unchanged range pointed to by this fragment. + This refers to an offset in the _updated_ document (as opposed + to the original tree). */ - static none: DecorationSet; -} - -/** -Command functions are used in key bindings and other types of user -actions. Given an editor view, they check whether their effect can -apply to the editor, and if it can, perform it as a side effect -(which usually means [dispatching](https://codemirror.net/6/docs/ref/#view.EditorView.dispatch) a -transaction) and return `true`. -*/ -type Command = (target: EditorView) => boolean; -declare class ScrollTarget { - readonly range: SelectionRange; - readonly y: ScrollStrategy; - readonly x: ScrollStrategy; - readonly yMargin: number; - readonly xMargin: number; - readonly isSnapshot: boolean; - constructor(range: SelectionRange, y?: ScrollStrategy, x?: ScrollStrategy, yMargin?: number, xMargin?: number, isSnapshot?: boolean); - map(changes: ChangeDesc): ScrollTarget; - clip(state: EditorState): ScrollTarget; -} -/** -This is the interface plugin objects conform to. -*/ -interface PluginValue extends Object { + from: number, /** - Notifies the plugin of an update that happened in the view. This - is called _before_ the view updates its own DOM. It is - responsible for updating the plugin's internal state (including - any state that may be read by plugin fields) and _writing_ to - the DOM for the changes in the update. To avoid unnecessary - layout recomputations, it should _not_ read the DOM layout—use - [`requestMeasure`](https://codemirror.net/6/docs/ref/#view.EditorView.requestMeasure) to schedule - your code in a DOM reading phase if you need to. + The end of the unchanged range. */ - update?(update: ViewUpdate): void; + to: number, /** - Called when the document view is updated (due to content, - decoration, or viewport changes). Should not try to immediately - start another view update. Often useful for calling - [`requestMeasure`](https://codemirror.net/6/docs/ref/#view.EditorView.requestMeasure). + The tree that this fragment is based on. */ - docViewUpdate?(view: EditorView): void; + tree: Tree, /** - Called when the plugin is no longer going to be used. Should - revert any changes the plugin made to the DOM. + The offset between the fragment's tree and the document that + this fragment can be used against. Add this when going from + document to tree positions, subtract it to go from tree to + document positions. */ - destroy?(): void; -} -/** -Provides additional information when defining a [view -plugin](https://codemirror.net/6/docs/ref/#view.ViewPlugin). -*/ -interface PluginSpec { + offset: number, openStart?: boolean, openEnd?: boolean); /** - Register the given [event - handlers](https://codemirror.net/6/docs/ref/#view.EditorView^domEventHandlers) for the plugin. - When called, these will have their `this` bound to the plugin - value. + Whether the start of the fragment represents the start of a + parse, or the end of a change. (In the second case, it may not + be safe to reuse some nodes at the start, depending on the + parsing algorithm.) */ - eventHandlers?: DOMEventHandlers; + get openStart(): boolean; /** - Registers [event observers](https://codemirror.net/6/docs/ref/#view.EditorView^domEventObservers) - for the plugin. Will, when called, have their `this` bound to - the plugin value. + Whether the end of the fragment represents the end of a + full-document parse, or the start of a change. */ - eventObservers?: DOMEventHandlers; + get openEnd(): boolean; /** - Specify that the plugin provides additional extensions when - added to an editor configuration. + Create a set of fragments from a freshly parsed tree, or update + an existing set of fragments by replacing the ones that overlap + with a tree with content from the new tree. When `partial` is + true, the parse is treated as incomplete, and the resulting + fragment has [`openEnd`](#common.TreeFragment.openEnd) set to + true. */ - provide?: (plugin: ViewPlugin) => Extension; + static addTree(tree: Tree, fragments?: readonly TreeFragment[], partial?: boolean): readonly TreeFragment[]; /** - Allow the plugin to provide decorations. When given, this should - be a function that take the plugin value and return a - [decoration set](https://codemirror.net/6/docs/ref/#view.DecorationSet). See also the caveat about - [layout-changing decorations](https://codemirror.net/6/docs/ref/#view.EditorView^decorations) that - depend on the view. + Apply a set of edits to an array of fragments, removing or + splitting fragments as necessary to remove edited ranges, and + adjusting offsets for fragments that moved. */ - decorations?: (value: V) => DecorationSet; + static applyChanges(fragments: readonly TreeFragment[], changes: readonly ChangedRange[], minGap?: number): readonly TreeFragment[]; } /** -View plugins associate stateful values with a view. They can -influence the way the content is drawn, and are notified of things -that happen in the view. +Interface used to represent an in-progress parse, which can be +moved forward piece-by-piece. */ -declare class ViewPlugin { +interface PartialParse { /** - Instances of this class act as extensions. + Advance the parse state by some amount. Will return the finished + syntax tree when the parse completes. */ - extension: Extension; - private constructor(); + advance(): Tree | null; /** - Define a plugin from a constructor function that creates the - plugin's value, given an editor view. + The position up to which the document has been parsed. Note + that, in multi-pass parsers, this will stay back until the last + pass has moved past a given position. */ - static define(create: (view: EditorView) => V, spec?: PluginSpec): ViewPlugin; + readonly parsedPos: number; /** - Create a plugin for a class whose constructor takes a single - editor view as argument. + Tell the parse to not advance beyond the given position. + `advance` will return a tree when the parse has reached the + position. Note that, depending on the parser algorithm and the + state of the parse when `stopAt` was called, that tree may + contain nodes beyond the position. It is an error to call + `stopAt` with a higher position than it's [current + value](#common.PartialParse.stoppedAt). */ - static fromClass(cls: { - new (view: EditorView): V; - }, spec?: PluginSpec): ViewPlugin; + stopAt(pos: number): void; + /** + Reports whether `stopAt` has been called on this parse. + */ + readonly stoppedAt: number | null; } -interface MeasureRequest { +/** +A superclass that parsers should extend. +*/ +declare abstract class Parser { /** - Called in a DOM read phase to gather information that requires - DOM layout. Should _not_ mutate the document. + Start a parse for a single tree. This is the method concrete + parser implementations must implement. Called by `startParse`, + with the optional arguments resolved. */ - read(view: EditorView): T; + abstract createParse(input: Input, fragments: readonly TreeFragment[], ranges: readonly { + from: number; + to: number; + }[]): PartialParse; /** - Called in a DOM write phase to update the document. Should _not_ - do anything that triggers DOM layout. + Start a parse, returning a [partial parse](#common.PartialParse) + object. [`fragments`](#common.TreeFragment) can be passed in to + make the parse incremental. + + By default, the entire input is parsed. You can pass `ranges`, + which should be a sorted array of non-empty, non-overlapping + ranges, to parse only those ranges. The tree returned in that + case will start at `ranges[0].from`. */ - write?(measure: T, view: EditorView): void; + startParse(input: Input | string, fragments?: readonly TreeFragment[], ranges?: readonly { + from: number; + to: number; + }[]): PartialParse; /** - When multiple requests with the same key are scheduled, only the - last one will actually be run. + Run a full parse, returning the resulting tree. */ - key?: any; + parse(input: Input | string, fragments?: readonly TreeFragment[], ranges?: readonly { + from: number; + to: number; + }[]): Tree; } -type AttrSource = Attrs | ((view: EditorView) => Attrs | null); /** -View [plugins](https://codemirror.net/6/docs/ref/#view.ViewPlugin) are given instances of this -class, which describe what happened, whenever the view is updated. +This is the interface parsers use to access the document. To run +Lezer directly on your own document data structure, you have to +write an implementation of it. */ -declare class ViewUpdate { +interface Input { /** - The editor view that the update is associated with. + The length of the document. */ - readonly view: EditorView; + readonly length: number; /** - The new editor state. + Get the chunk after the given position. The returned string + should start at `from` and, if that isn't the end of the + document, may be of any length greater than zero. */ - readonly state: EditorState; + chunk(from: number): string; /** - The transactions involved in the update. May be empty. + Indicates whether the chunks already end at line breaks, so that + client code that wants to work by-line can avoid re-scanning + them for line breaks. When this is true, the result of `chunk()` + should either be a single line break, or the content between + `from` and the next line break. */ - readonly transactions: readonly Transaction[]; + readonly lineChunks: boolean; /** - The changes made to the document by this update. + Read the part of the document between the given positions. */ - readonly changes: ChangeSet; + read(from: number, to: number): string; +} +/** +Parse wrapper functions are supported by some parsers to inject +additional parsing logic. +*/ +type ParseWrapper = (inner: PartialParse, input: Input, fragments: readonly TreeFragment[], ranges: readonly { + from: number; + to: number; +}[]) => PartialParse; +/** +Each [node type](#common.NodeType) or [individual tree](#common.Tree) +can have metadata associated with it in props. Instances of this +class represent prop names. +*/ +declare class NodeProp { /** - The previous editor state. + Indicates whether this prop is stored per [node + type](#common.NodeType) or per [tree node](#common.Tree). */ - readonly startState: EditorState; - private constructor(); + perNode: boolean; /** - Tells you whether the [viewport](https://codemirror.net/6/docs/ref/#view.EditorView.viewport) or - [visible ranges](https://codemirror.net/6/docs/ref/#view.EditorView.visibleRanges) changed in this - update. + A method that deserializes a value of this prop from a string. + Can be used to allow a prop to be directly written in a grammar + file. */ - get viewportChanged(): boolean; + deserialize: (str: string) => T; /** - Indicates whether the height of a block element in the editor - changed in this update. + Create a new node prop type. */ - get heightChanged(): boolean; + constructor(config?: { + /** + The [deserialize](#common.NodeProp.deserialize) function to + use for this prop, used for example when directly providing + the prop from a grammar file. Defaults to a function that + raises an error. + */ + deserialize?: (str: string) => T; + /** + By default, node props are stored in the [node + type](#common.NodeType). It can sometimes be useful to directly + store information (usually related to the parsing algorithm) + in [nodes](#common.Tree) themselves. Set this to true to enable + that for this prop. + */ + perNode?: boolean; + }); /** - Returns true when the document was modified or the size of the - editor, or elements within the editor, changed. + This is meant to be used with + [`NodeSet.extend`](#common.NodeSet.extend) or + [`LRParser.configure`](#lr.ParserConfig.props) to compute + prop values for each node type in the set. Takes a [match + object](#common.NodeType^match) or function that returns undefined + if the node type doesn't get this prop, and the prop's value if + it does. */ - get geometryChanged(): boolean; + add(match: { + [selector: string]: T; + } | ((type: NodeType) => T | undefined)): NodePropSource; /** - True when this update indicates a focus change. + Prop that is used to describe matching delimiters. For opening + delimiters, this holds an array of node names (written as a + space-separated string when declaring this prop in a grammar) + for the node types of closing delimiters that match it. */ - get focusChanged(): boolean; + static closedBy: NodeProp; + /** + The inverse of [`closedBy`](#common.NodeProp^closedBy). This is + attached to closing delimiters, holding an array of node names + of types of matching opening delimiters. + */ + static openedBy: NodeProp; + /** + Used to assign node types to groups (for example, all node + types that represent an expression could be tagged with an + `"Expression"` group). + */ + static group: NodeProp; /** - Whether the document changed in this update. + Attached to nodes to indicate these should be + [displayed](https://codemirror.net/docs/ref/#language.syntaxTree) + in a bidirectional text isolate, so that direction-neutral + characters on their sides don't incorrectly get associated with + surrounding text. You'll generally want to set this for nodes + that contain arbitrary text, like strings and comments, and for + nodes that appear _inside_ arbitrary text, like HTML tags. When + not given a value, in a grammar declaration, defaults to + `"auto"`. */ - get docChanged(): boolean; + static isolate: NodeProp<"rtl" | "ltr" | "auto">; /** - Whether the selection was explicitly set in this update. + The hash of the [context](#lr.ContextTracker.constructor) + that the node was parsed in, if any. Used to limit reuse of + contextual nodes. */ - get selectionSet(): boolean; -} - -/** -Interface that objects registered with -[`EditorView.mouseSelectionStyle`](https://codemirror.net/6/docs/ref/#view.EditorView^mouseSelectionStyle) -must conform to. -*/ -interface MouseSelectionStyle { + static contextHash: NodeProp; /** - Return a new selection for the mouse gesture that starts with - the event that was originally given to the constructor, and ends - with the event passed here. In case of a plain click, those may - both be the `mousedown` event, in case of a drag gesture, the - latest `mousemove` event will be passed. - - When `extend` is true, that means the new selection should, if - possible, extend the start selection. If `multiple` is true, the - new selection should be added to the original selection. + The distance beyond the end of the node that the tokenizer + looked ahead for any of the tokens inside the node. (The LR + parser only stores this when it is larger than 25, for + efficiency reasons.) */ - get: (curEvent: MouseEvent, extend: boolean, multiple: boolean) => EditorSelection; + static lookAhead: NodeProp; /** - Called when the view is updated while the gesture is in - progress. When the document changes, it may be necessary to map - some data (like the original selection or start position) - through the changes. - - This may return `true` to indicate that the `get` method should - get queried again after the update, because something in the - update could change its result. Be wary of infinite loops when - using this (where `get` returns a new selection, which will - trigger `update`, which schedules another `get` in response). + This per-node prop is used to replace a given node, or part of a + node, with another tree. This is useful to include trees from + different languages in mixed-language parsers. */ - update: (update: ViewUpdate) => boolean | void; + static mounted: NodeProp; } -type MakeSelectionStyle = (view: EditorView, event: MouseEvent) => MouseSelectionStyle | null; - /** -Record used to represent information about a block-level element -in the editor view. +A mounted tree, which can be [stored](#common.NodeProp^mounted) on +a tree node to indicate that parts of its content are +represented by another tree. */ -declare class BlockInfo { - /** - The start of the element in the document. - */ - readonly from: number; +declare class MountedTree { /** - The length of the element. + The inner tree. */ - readonly length: number; + readonly tree: Tree; /** - The top position of the element (relative to the top of the - document). + If this is null, this tree replaces the entire node (it will + be included in the regular iteration instead of its host + node). If not, only the given ranges are considered to be + covered by this tree. This is used for trees that are mixed in + a way that isn't strictly hierarchical. Such mounted trees are + only entered by [`resolveInner`](#common.Tree.resolveInner) + and [`enter`](#common.SyntaxNode.enter). */ - readonly top: number; + readonly overlay: readonly { + from: number; + to: number; + }[] | null; /** - Its height. + The parser used to create this subtree. */ - readonly height: number; + readonly parser: Parser; + constructor( /** - The type of element this is. When querying lines, this may be - an array of all the blocks that make up the line. + The inner tree. */ - get type(): BlockType | readonly BlockInfo[]; + tree: Tree, /** - The end of the element as a document position. + If this is null, this tree replaces the entire node (it will + be included in the regular iteration instead of its host + node). If not, only the given ranges are considered to be + covered by this tree. This is used for trees that are mixed in + a way that isn't strictly hierarchical. Such mounted trees are + only entered by [`resolveInner`](#common.Tree.resolveInner) + and [`enter`](#common.SyntaxNode.enter). */ - get to(): number; + overlay: readonly { + from: number; + to: number; + }[] | null, /** - The bottom position of the element. + The parser used to create this subtree. */ - get bottom(): number; + parser: Parser); +} +/** +Type returned by [`NodeProp.add`](#common.NodeProp.add). Describes +whether a prop should be added to a given node type in a node set, +and what value it should have. +*/ +type NodePropSource = (type: NodeType) => null | [NodeProp, any]; +/** +Each node in a syntax tree has a node type associated with it. +*/ +declare class NodeType { /** - If this is a widget block, this will return the widget - associated with it. + The name of the node type. Not necessarily unique, but if the + grammar was written properly, different node types with the + same name within a node set should play the same semantic + role. */ - get widget(): WidgetType | null; + readonly name: string; /** - If this is a textblock, this holds the number of line breaks - that appear in widgets inside the block. + The id of this node in its set. Corresponds to the term ids + used in the parser. */ - get widgetLineBreaks(): number; -} - -/** -The type of object given to the [`EditorView`](https://codemirror.net/6/docs/ref/#view.EditorView) -constructor. -*/ -interface EditorViewConfig extends EditorStateConfig { + readonly id: number; /** - The view's initial state. If not given, a new state is created - by passing this configuration object to - [`EditorState.create`](https://codemirror.net/6/docs/ref/#state.EditorState^create), using its - `doc`, `selection`, and `extensions` field (if provided). + Define a node type. */ - state?: EditorState; + static define(spec: { + /** + The ID of the node type. When this type is used in a + [set](#common.NodeSet), the ID must correspond to its index in + the type array. + */ + id: number; + /** + The name of the node type. Leave empty to define an anonymous + node. + */ + name?: string; + /** + [Node props](#common.NodeProp) to assign to the type. The value + given for any given prop should correspond to the prop's type. + */ + props?: readonly ([NodeProp, any] | NodePropSource)[]; + /** + Whether this is a [top node](#common.NodeType.isTop). + */ + top?: boolean; + /** + Whether this node counts as an [error + node](#common.NodeType.isError). + */ + error?: boolean; + /** + Whether this node is a [skipped](#common.NodeType.isSkipped) + node. + */ + skipped?: boolean; + }): NodeType; /** - When given, the editor is immediately appended to the given - element on creation. (Otherwise, you'll have to place the view's - [`dom`](https://codemirror.net/6/docs/ref/#view.EditorView.dom) element in the document yourself.) + Retrieves a node prop for this type. Will return `undefined` if + the prop isn't present on this node. */ - parent?: Element | DocumentFragment; + prop(prop: NodeProp): T | undefined; /** - If the view is going to be mounted in a shadow root or document - other than the one held by the global variable `document` (the - default), you should pass it here. If you provide `parent`, but - not this option, the editor will automatically look up a root - from the parent. + True when this is the top node of a grammar. */ - root?: Document | ShadowRoot; + get isTop(): boolean; /** - Pass an effect created with - [`EditorView.scrollIntoView`](https://codemirror.net/6/docs/ref/#view.EditorView^scrollIntoView) or - [`EditorView.scrollSnapshot`](https://codemirror.net/6/docs/ref/#view.EditorView.scrollSnapshot) - here to set an initial scroll position. + True when this node is produced by a skip rule. */ - scrollTo?: StateEffect; + get isSkipped(): boolean; /** - Override the way transactions are - [dispatched](https://codemirror.net/6/docs/ref/#view.EditorView.dispatch) for this editor view. - Your implementation, if provided, should probably call the - view's [`update` method](https://codemirror.net/6/docs/ref/#view.EditorView.update). + Indicates whether this is an error node. */ - dispatchTransactions?: (trs: readonly Transaction[], view: EditorView) => void; + get isError(): boolean; /** - **Deprecated** single-transaction version of - `dispatchTransactions`. Will force transactions to be dispatched - one at a time when used. + When true, this node type doesn't correspond to a user-declared + named node, for example because it is used to cache repetition. */ - dispatch?: (tr: Transaction, view: EditorView) => void; -} -/** -An editor view represents the editor's user interface. It holds -the editable DOM surface, and possibly other elements such as the -line number gutter. It handles events and dispatches state -transactions for editing actions. -*/ -declare class EditorView { + get isAnonymous(): boolean; /** - The current editor state. + Returns true when this node's name or one of its + [groups](#common.NodeProp^group) matches the given string. */ - get state(): EditorState; + is(name: string | number): boolean; /** - To be able to display large documents without consuming too much - memory or overloading the browser, CodeMirror only draws the - code that is visible (plus a margin around it) to the DOM. This - property tells you the extent of the current drawn viewport, in - document positions. + An empty dummy node type to use when no actual type is available. */ - get viewport(): { - from: number; - to: number; - }; + static none: NodeType; /** - When there are, for example, large collapsed ranges in the - viewport, its size can be a lot bigger than the actual visible - content. Thus, if you are doing something like styling the - content in the viewport, it is preferable to only do so for - these ranges, which are the subset of the viewport that is - actually drawn. + Create a function from node types to arbitrary values by + specifying an object whose property names are node or + [group](#common.NodeProp^group) names. Often useful with + [`NodeProp.add`](#common.NodeProp.add). You can put multiple + names, separated by spaces, in a single property name to map + multiple node names to a single value. */ - get visibleRanges(): readonly { - from: number; - to: number; - }[]; + static match(map: { + [selector: string]: T; + }): (node: NodeType) => T | undefined; +} +/** +A node set holds a collection of node types. It is used to +compactly represent trees by storing their type ids, rather than a +full pointer to the type object, in a numeric array. Each parser +[has](#lr.LRParser.nodeSet) a node set, and [tree +buffers](#common.TreeBuffer) can only store collections of nodes +from the same set. A set can have a maximum of 2**16 (65536) node +types in it, so that the ids fit into 16-bit typed array slots. +*/ +declare class NodeSet { /** - Returns false when the editor is entirely scrolled out of view - or otherwise hidden. + The node types in this set, by id. */ - get inView(): boolean; + readonly types: readonly NodeType[]; /** - Indicates whether the user is currently composing text via - [IME](https://en.wikipedia.org/wiki/Input_method), and at least - one change has been made in the current composition. + Create a set with the given types. The `id` property of each + type should correspond to its position within the array. */ - get composing(): boolean; + constructor( /** - Indicates whether the user is currently in composing state. Note - that on some platforms, like Android, this will be the case a - lot, since just putting the cursor on a word starts a - composition there. + The node types in this set, by id. */ - get compositionStarted(): boolean; - private dispatchTransactions; - private _root; + types: readonly NodeType[]); /** - The document or shadow root that the view lives in. + Create a copy of this set with some node properties added. The + arguments to this method can be created with + [`NodeProp.add`](#common.NodeProp.add). */ - get root(): DocumentOrShadowRoot; + extend(...props: NodePropSource[]): NodeSet; +} +/** +Options that control iteration. Can be combined with the `|` +operator to enable multiple ones. +*/ +declare enum IterMode { /** - The DOM element that wraps the entire editor view. + When enabled, iteration will only visit [`Tree`](#common.Tree) + objects, not nodes packed into + [`TreeBuffer`](#common.TreeBuffer)s. */ - readonly dom: HTMLElement; + ExcludeBuffers = 1, /** - The DOM element that can be styled to scroll. (Note that it may - not have been, so you can't assume this is scrollable.) + Enable this to make iteration include anonymous nodes (such as + the nodes that wrap repeated grammar constructs into a balanced + tree). */ - readonly scrollDOM: HTMLElement; + IncludeAnonymous = 2, /** - The editable DOM element holding the editor content. You should - not, usually, interact with this content directly though the - DOM, since the editor will immediately undo most of the changes - you make. Instead, [dispatch](https://codemirror.net/6/docs/ref/#view.EditorView.dispatch) - [transactions](https://codemirror.net/6/docs/ref/#state.Transaction) to modify content, and - [decorations](https://codemirror.net/6/docs/ref/#view.Decoration) to style it. + By default, regular [mounted](#common.NodeProp^mounted) nodes + replace their base node in iteration. Enable this to ignore them + instead. */ - readonly contentDOM: HTMLElement; - private announceDOM; - private plugins; - private pluginMap; - private editorAttrs; - private contentAttrs; - private styleModules; - private bidiCache; - private destroyed; + IgnoreMounts = 4, /** - Construct a new view. You'll want to either provide a `parent` - option, or put `view.dom` into your document after creating a - view, so that the user can see the editor. + This option only applies in + [`enter`](#common.SyntaxNode.enter)-style methods. It tells the + library to not enter mounted overlays if one covers the given + position. */ - constructor(config?: EditorViewConfig); + IgnoreOverlays = 8 +} +/** +A piece of syntax tree. There are two ways to approach these +trees: the way they are actually stored in memory, and the +convenient way. + +Syntax trees are stored as a tree of `Tree` and `TreeBuffer` +objects. By packing detail information into `TreeBuffer` leaf +nodes, the representation is made a lot more memory-efficient. + +However, when you want to actually work with tree nodes, this +representation is very awkward, so most client code will want to +use the [`TreeCursor`](#common.TreeCursor) or +[`SyntaxNode`](#common.SyntaxNode) interface instead, which provides +a view on some part of this data structure, and can be used to +move around to adjacent nodes. +*/ +declare class Tree { /** - All regular editor state updates should go through this. It - takes a transaction, array of transactions, or transaction spec - and updates the view to show the new state produced by that - transaction. Its implementation can be overridden with an - [option](https://codemirror.net/6/docs/ref/#view.EditorView.constructor^config.dispatchTransactions). - This function is bound to the view instance, so it does not have - to be called as a method. - - Note that when multiple `TransactionSpec` arguments are - provided, these define a single transaction (the specs will be - merged), not a sequence of transactions. + The type of the top node. */ - dispatch(tr: Transaction): void; - dispatch(trs: readonly Transaction[]): void; - dispatch(...specs: TransactionSpec[]): void; + readonly type: NodeType; /** - Update the view for the given array of transactions. This will - update the visible document and selection to match the state - produced by the transactions, and notify view plugins of the - change. You should usually call - [`dispatch`](https://codemirror.net/6/docs/ref/#view.EditorView.dispatch) instead, which uses this - as a primitive. + This node's child nodes. */ - update(transactions: readonly Transaction[]): void; + readonly children: readonly (Tree | TreeBuffer)[]; /** - Reset the view to the given state. (This will cause the entire - document to be redrawn and all view plugins to be reinitialized, - so you should probably only use it when the new state isn't - derived from the old state. Otherwise, use - [`dispatch`](https://codemirror.net/6/docs/ref/#view.EditorView.dispatch) instead.) + The positions (offsets relative to the start of this tree) of + the children. */ - setState(newState: EditorState): void; - private updatePlugins; - private docViewUpdate; + readonly positions: readonly number[]; /** - Get the CSS classes for the currently active editor themes. + The total length of this tree */ - get themeClasses(): string; - private updateAttrs; - private showAnnouncements; - private mountStyles; - private readMeasured; + readonly length: number; /** - Schedule a layout measurement, optionally providing callbacks to - do custom DOM measuring followed by a DOM write phase. Using - this is preferable reading DOM layout directly from, for - example, an event handler, because it'll make sure measuring and - drawing done by other components is synchronized, avoiding - unnecessary DOM layout computations. + Construct a new tree. See also [`Tree.build`](#common.Tree^build). */ - requestMeasure(request?: MeasureRequest): void; + constructor( /** - Get the value of a specific plugin, if present. Note that - plugins that crash can be dropped from a view, so even when you - know you registered a given plugin, it is recommended to check - the return value of this method. + The type of the top node. */ - plugin(plugin: ViewPlugin): T | null; + type: NodeType, /** - The top position of the document, in screen coordinates. This - may be negative when the editor is scrolled down. Points - directly to the top of the first line, not above the padding. + This node's child nodes. */ - get documentTop(): number; + children: readonly (Tree | TreeBuffer)[], /** - Reports the padding above and below the document. + The positions (offsets relative to the start of this tree) of + the children. */ - get documentPadding(): { - top: number; - bottom: number; - }; + positions: readonly number[], /** - If the editor is transformed with CSS, this provides the scale - along the X axis. Otherwise, it will just be 1. Note that - transforms other than translation and scaling are not supported. + The total length of this tree */ - get scaleX(): number; + length: number, /** - Provide the CSS transformed scale along the Y axis. + Per-node [node props](#common.NodeProp) to associate with this node. */ - get scaleY(): number; + props?: readonly [NodeProp | number, any][]); /** - Find the text line or block widget at the given vertical - position (which is interpreted as relative to the [top of the - document](https://codemirror.net/6/docs/ref/#view.EditorView.documentTop)). + The empty tree */ - elementAtHeight(height: number): BlockInfo; + static empty: Tree; /** - Find the line block (see - [`lineBlockAt`](https://codemirror.net/6/docs/ref/#view.EditorView.lineBlockAt) at the given - height, again interpreted relative to the [top of the - document](https://codemirror.net/6/docs/ref/#view.EditorView.documentTop). + Get a [tree cursor](#common.TreeCursor) positioned at the top of + the tree. Mode can be used to [control](#common.IterMode) which + nodes the cursor visits. */ - lineBlockAtHeight(height: number): BlockInfo; + cursor(mode?: IterMode): TreeCursor; /** - Get the extent and vertical position of all [line - blocks](https://codemirror.net/6/docs/ref/#view.EditorView.lineBlockAt) in the viewport. Positions - are relative to the [top of the - document](https://codemirror.net/6/docs/ref/#view.EditorView.documentTop); + Get a [tree cursor](#common.TreeCursor) pointing into this tree + at the given position and side (see + [`moveTo`](#common.TreeCursor.moveTo). */ - get viewportLineBlocks(): BlockInfo[]; + cursorAt(pos: number, side?: -1 | 0 | 1, mode?: IterMode): TreeCursor; /** - Find the line block around the given document position. A line - block is a range delimited on both sides by either a - non-[hidden](https://codemirror.net/6/docs/ref/#view.Decoration^replace) line breaks, or the - start/end of the document. It will usually just hold a line of - text, but may be broken into multiple textblocks by block - widgets. + Get a [syntax node](#common.SyntaxNode) object for the top of the + tree. */ - lineBlockAt(pos: number): BlockInfo; + get topNode(): SyntaxNode; /** - The editor's total content height. + Get the [syntax node](#common.SyntaxNode) at the given position. + If `side` is -1, this will move into nodes that end at the + position. If 1, it'll move into nodes that start at the + position. With 0, it'll only enter nodes that cover the position + from both sides. + + Note that this will not enter + [overlays](#common.MountedTree.overlay), and you often want + [`resolveInner`](#common.Tree.resolveInner) instead. */ - get contentHeight(): number; + resolve(pos: number, side?: -1 | 0 | 1): SyntaxNode; /** - Move a cursor position by [grapheme - cluster](https://codemirror.net/6/docs/ref/#state.findClusterBreak). `forward` determines whether - the motion is away from the line start, or towards it. In - bidirectional text, the line is traversed in visual order, using - the editor's [text direction](https://codemirror.net/6/docs/ref/#view.EditorView.textDirection). - When the start position was the last one on the line, the - returned position will be across the line break. If there is no - further line, the original position is returned. - - By default, this method moves over a single cluster. The - optional `by` argument can be used to move across more. It will - be called with the first cluster as argument, and should return - a predicate that determines, for each subsequent cluster, - whether it should also be moved over. + Like [`resolve`](#common.Tree.resolve), but will enter + [overlaid](#common.MountedTree.overlay) nodes, producing a syntax node + pointing into the innermost overlaid tree at the given position + (with parent links going through all parent structure, including + the host trees). */ - moveByChar(start: SelectionRange, forward: boolean, by?: (initial: string) => (next: string) => boolean): SelectionRange; + resolveInner(pos: number, side?: -1 | 0 | 1): SyntaxNode; /** - Move a cursor position across the next group of either - [letters](https://codemirror.net/6/docs/ref/#state.EditorState.charCategorizer) or non-letter - non-whitespace characters. + In some situations, it can be useful to iterate through all + nodes around a position, including those in overlays that don't + directly cover the position. This method gives you an iterator + that will produce all nodes, from small to big, around the given + position. */ - moveByGroup(start: SelectionRange, forward: boolean): SelectionRange; + resolveStack(pos: number, side?: -1 | 0 | 1): NodeIterator; /** - Get the cursor position visually at the start or end of a line. - Note that this may differ from the _logical_ position at its - start or end (which is simply at `line.from`/`line.to`) if text - at the start or end goes against the line's base text direction. + Iterate over the tree and its children, calling `enter` for any + node that touches the `from`/`to` region (if given) before + running over such a node's children, and `leave` (if given) when + leaving the node. When `enter` returns `false`, that node will + not have its children iterated over (or `leave` called). */ - visualLineSide(line: Line$1, end: boolean): SelectionRange; + iterate(spec: { + enter(node: SyntaxNodeRef): boolean | void; + leave?(node: SyntaxNodeRef): void; + from?: number; + to?: number; + mode?: IterMode; + }): void; /** - Move to the next line boundary in the given direction. If - `includeWrap` is true, line wrapping is on, and there is a - further wrap point on the current line, the wrap point will be - returned. Otherwise this function will return the start or end - of the line. + Get the value of the given [node prop](#common.NodeProp) for this + node. Works with both per-node and per-type props. */ - moveToLineBoundary(start: SelectionRange, forward: boolean, includeWrap?: boolean): SelectionRange; + prop(prop: NodeProp): T | undefined; /** - Move a cursor position vertically. When `distance` isn't given, - it defaults to moving to the next line (including wrapped - lines). Otherwise, `distance` should provide a positive distance - in pixels. - - When `start` has a - [`goalColumn`](https://codemirror.net/6/docs/ref/#state.SelectionRange.goalColumn), the vertical - motion will use that as a target horizontal position. Otherwise, - the cursor's own horizontal position is used. The returned - cursor will have its goal column set to whichever column was - used. + Returns the node's [per-node props](#common.NodeProp.perNode) in a + format that can be passed to the [`Tree`](#common.Tree) + constructor. */ - moveVertically(start: SelectionRange, forward: boolean, distance?: number): SelectionRange; + get propValues(): readonly [NodeProp | number, any][]; /** - Find the DOM parent node and offset (child offset if `node` is - an element, character offset when it is a text node) at the - given document position. - - Note that for positions that aren't currently in - `visibleRanges`, the resulting DOM position isn't necessarily - meaningful (it may just point before or after a placeholder - element). + Balance the direct children of this tree, producing a copy of + which may have children grouped into subtrees with type + [`NodeType.none`](#common.NodeType^none). */ - domAtPos(pos: number): { - node: Node; - offset: number; - }; + balance(config?: { + /** + Function to create the newly balanced subtrees. + */ + makeTree?: (children: readonly (Tree | TreeBuffer)[], positions: readonly number[], length: number) => Tree; + }): Tree; /** - Find the document position at the given DOM node. Can be useful - for associating positions with DOM events. Will raise an error - when `node` isn't part of the editor content. + Build a tree from a postfix-ordered buffer of node information, + or a cursor over such a buffer. */ - posAtDOM(node: Node, offset?: number): number; + static build(data: BuildData): Tree; +} +/** +Represents a sequence of nodes. +*/ +type NodeIterator = { + node: SyntaxNode; + next: NodeIterator | null; +}; +type BuildData = { /** - Get the document position at the given screen coordinates. For - positions not covered by the visible viewport's DOM structure, - this will return null, unless `false` is passed as second - argument, in which case it'll return an estimated position that - would be near the coordinates if it were rendered. + The buffer or buffer cursor to read the node data from. + + When this is an array, it should contain four values for every + node in the tree. + + - The first holds the node's type, as a node ID pointing into + the given `NodeSet`. + - The second holds the node's start offset. + - The third the end offset. + - The fourth the amount of space taken up in the array by this + node and its children. Since there's four values per node, + this is the total number of nodes inside this node (children + and transitive children) plus one for the node itself, times + four. + + Parent nodes should appear _after_ child nodes in the array. As + an example, a node of type 10 spanning positions 0 to 4, with + two children, of type 11 and 12, might look like this: + + [11, 0, 1, 4, 12, 2, 4, 4, 10, 0, 4, 12] */ - posAtCoords(coords: { - x: number; - y: number; - }, precise: false): number; - posAtCoords(coords: { - x: number; - y: number; - }): number | null; + buffer: BufferCursor | readonly number[]; /** - Get the screen coordinates at the given document position. - `side` determines whether the coordinates are based on the - element before (-1) or after (1) the position (if no element is - available on the given side, the method will transparently use - another strategy to get reasonable coordinates). + The node types to use. */ - coordsAtPos(pos: number, side?: -1 | 1): Rect | null; + nodeSet: NodeSet; /** - Return the rectangle around a given character. If `pos` does not - point in front of a character that is in the viewport and - rendered (i.e. not replaced, not a line break), this will return - null. For space characters that are a line wrap point, this will - return the position before the line break. + The id of the top node type. */ - coordsForChar(pos: number): Rect | null; + topID: number; /** - The default width of a character in the editor. May not - accurately reflect the width of all characters (given variable - width fonts or styling of invididual ranges). + The position the tree should start at. Defaults to 0. */ - get defaultCharacterWidth(): number; + start?: number; /** - The default height of a line in the editor. May not be accurate - for all lines. + The position in the buffer where the function should stop + reading. Defaults to 0. */ - get defaultLineHeight(): number; + bufferStart?: number; /** - The text direction - ([`direction`](https://developer.mozilla.org/en-US/docs/Web/CSS/direction) - CSS property) of the editor's content element. + The length of the wrapping node. The end offset of the last + child is used when not provided. */ - get textDirection(): Direction; + length?: number; /** - Find the text direction of the block at the given position, as - assigned by CSS. If - [`perLineTextDirection`](https://codemirror.net/6/docs/ref/#view.EditorView^perLineTextDirection) - isn't enabled, or the given position is outside of the viewport, - this will always return the same as - [`textDirection`](https://codemirror.net/6/docs/ref/#view.EditorView.textDirection). Note that - this may trigger a DOM layout. + The maximum buffer length to use. Defaults to + [`DefaultBufferLength`](#common.DefaultBufferLength). */ - textDirectionAt(pos: number): Direction; + maxBufferLength?: number; /** - Whether this editor [wraps lines](https://codemirror.net/6/docs/ref/#view.EditorView.lineWrapping) - (as determined by the - [`white-space`](https://developer.mozilla.org/en-US/docs/Web/CSS/white-space) - CSS property of its content element). + An optional array holding reused nodes that the buffer can refer + to. */ - get lineWrapping(): boolean; + reused?: readonly Tree[]; /** - Returns the bidirectional text structure of the given line - (which should be in the current document) as an array of span - objects. The order of these spans matches the [text - direction](https://codemirror.net/6/docs/ref/#view.EditorView.textDirection)—if that is - left-to-right, the leftmost spans come first, otherwise the - rightmost spans come first. + The first node type that indicates repeat constructs in this + grammar. */ - bidiSpans(line: Line$1): readonly BidiSpan[]; + minRepeatType?: number; +}; +/** +This is used by `Tree.build` as an abstraction for iterating over +a tree buffer. A cursor initially points at the very last element +in the buffer. Every time `next()` is called it moves on to the +previous one. +*/ +interface BufferCursor { /** - Check whether the editor has focus. + The current buffer position (four times the number of nodes + remaining). */ - get hasFocus(): boolean; + pos: number; /** - Put focus on the editor. + The node ID of the next node in the buffer. */ - focus(): void; + id: number; /** - Update the [root](https://codemirror.net/6/docs/ref/##view.EditorViewConfig.root) in which the editor lives. This is only - necessary when moving the editor's existing DOM to a new window or shadow root. + The start position of the next node in the buffer. */ - setRoot(root: Document | ShadowRoot): void; + start: number; /** - Clean up this editor view, removing its element from the - document, unregistering event handlers, and notifying - plugins. The view instance can no longer be used after - calling this. + The end position of the next node. */ - destroy(): void; + end: number; /** - Returns an effect that can be - [added](https://codemirror.net/6/docs/ref/#state.TransactionSpec.effects) to a transaction to - cause it to scroll the given position or range into view. + The size of the next node (the number of nodes inside, counting + the node itself, times 4). */ - static scrollIntoView(pos: number | SelectionRange, options?: { - /** - By default (`"nearest"`) the position will be vertically - scrolled only the minimal amount required to move the given - position into view. You can set this to `"start"` to move it - to the top of the view, `"end"` to move it to the bottom, or - `"center"` to move it to the center. - */ - y?: ScrollStrategy; - /** - Effect similar to - [`y`](https://codemirror.net/6/docs/ref/#view.EditorView^scrollIntoView^options.y), but for the - horizontal scroll position. - */ - x?: ScrollStrategy; - /** - Extra vertical distance to add when moving something into - view. Not used with the `"center"` strategy. Defaults to 5. - Must be less than the height of the editor. - */ - yMargin?: number; - /** - Extra horizontal distance to add. Not used with the `"center"` - strategy. Defaults to 5. Must be less than the width of the - editor. - */ - xMargin?: number; - }): StateEffect; + size: number; + /** + Moves `this.pos` down by 4. + */ + next(): void; /** - Return an effect that resets the editor to its current (at the - time this method was called) scroll position. Note that this - only affects the editor's own scrollable element, not parents. - See also - [`EditorViewConfig.scrollTo`](https://codemirror.net/6/docs/ref/#view.EditorViewConfig.scrollTo). - - The effect should be used with a document identical to the one - it was created for. Failing to do so is not an error, but may - not scroll to the expected position. You can - [map](https://codemirror.net/6/docs/ref/#state.StateEffect.map) the effect to account for changes. + Create a copy of this cursor. */ - scrollSnapshot(): StateEffect; + fork(): BufferCursor; +} +/** +Tree buffers contain (type, start, end, endIndex) quads for each +node. In such a buffer, nodes are stored in prefix order (parents +before children, with the endIndex of the parent indicating which +children belong to it). +*/ +declare class TreeBuffer { /** - Facet to add a [style - module](https://github.com/marijnh/style-mod#documentation) to - an editor view. The view will ensure that the module is - mounted in its [document - root](https://codemirror.net/6/docs/ref/#view.EditorView.constructor^config.root). + The buffer's content. */ - static styleModule: Facet; + readonly buffer: Uint16Array; /** - Returns an extension that can be used to add DOM event handlers. - The value should be an object mapping event names to handler - functions. For any given event, such functions are ordered by - extension precedence, and the first handler to return true will - be assumed to have handled that event, and no other handlers or - built-in behavior will be activated for it. These are registered - on the [content element](https://codemirror.net/6/docs/ref/#view.EditorView.contentDOM), except - for `scroll` handlers, which will be called any time the - editor's [scroll element](https://codemirror.net/6/docs/ref/#view.EditorView.scrollDOM) or one of - its parent nodes is scrolled. + The total length of the group of nodes in the buffer. */ - static domEventHandlers(handlers: DOMEventHandlers): Extension; + readonly length: number; /** - Create an extension that registers DOM event observers. Contrary - to event [handlers](https://codemirror.net/6/docs/ref/#view.EditorView^domEventHandlers), - observers can't be prevented from running by a higher-precedence - handler returning true. They also don't prevent other handlers - and observers from running when they return true, and should not - call `preventDefault`. + The node set used in this buffer. */ - static domEventObservers(observers: DOMEventHandlers): Extension; + readonly set: NodeSet; /** - An input handler can override the way changes to the editable - DOM content are handled. Handlers are passed the document - positions between which the change was found, and the new - content. When one returns true, no further input handlers are - called and the default behavior is prevented. - - The `insert` argument can be used to get the default transaction - that would be applied for this input. This can be useful when - dispatching the custom behavior as a separate transaction. + Create a tree buffer. */ - static inputHandler: Facet<(view: EditorView, from: number, to: number, text: string, insert: () => Transaction) => boolean, readonly ((view: EditorView, from: number, to: number, text: string, insert: () => Transaction) => boolean)[]>; + constructor( /** - Scroll handlers can override how things are scrolled into view. - If they return `true`, no further handling happens for the - scrolling. If they return false, the default scroll behavior is - applied. Scroll handlers should never initiate editor updates. + The buffer's content. */ - static scrollHandler: Facet<(view: EditorView, range: SelectionRange, options: { - x: ScrollStrategy; - y: ScrollStrategy; - xMargin: number; - yMargin: number; - }) => boolean, readonly ((view: EditorView, range: SelectionRange, options: { - x: ScrollStrategy; - y: ScrollStrategy; - xMargin: number; - yMargin: number; - }) => boolean)[]>; + buffer: Uint16Array, /** - This facet can be used to provide functions that create effects - to be dispatched when the editor's focus state changes. + The total length of the group of nodes in the buffer. */ - static focusChangeEffect: Facet<(state: EditorState, focusing: boolean) => StateEffect | null, readonly ((state: EditorState, focusing: boolean) => StateEffect | null)[]>; + length: number, /** - By default, the editor assumes all its content has the same - [text direction](https://codemirror.net/6/docs/ref/#view.Direction). Configure this with a `true` - value to make it read the text direction of every (rendered) - line separately. + The node set used in this buffer. */ - static perLineTextDirection: Facet; + set: NodeSet); +} +/** +The set of properties provided by both [`SyntaxNode`](#common.SyntaxNode) +and [`TreeCursor`](#common.TreeCursor). Note that, if you need +an object that is guaranteed to stay stable in the future, you +need to use the [`node`](#common.SyntaxNodeRef.node) accessor. +*/ +interface SyntaxNodeRef { /** - Allows you to provide a function that should be called when the - library catches an exception from an extension (mostly from view - plugins, but may be used by other extensions to route exceptions - from user-code-provided callbacks). This is mostly useful for - debugging and logging. See [`logException`](https://codemirror.net/6/docs/ref/#view.logException). + The start position of the node. */ - static exceptionSink: Facet<(exception: any) => void, readonly ((exception: any) => void)[]>; + readonly from: number; /** - A facet that can be used to register a function to be called - every time the view updates. + The end position of the node. */ - static updateListener: Facet<(update: ViewUpdate) => void, readonly ((update: ViewUpdate) => void)[]>; + readonly to: number; /** - Facet that controls whether the editor content DOM is editable. - When its highest-precedence value is `false`, the element will - not have its `contenteditable` attribute set. (Note that this - doesn't affect API calls that change the editor content, even - when those are bound to keys or buttons. See the - [`readOnly`](https://codemirror.net/6/docs/ref/#state.EditorState.readOnly) facet for that.) + The type of the node. */ - static editable: Facet; + readonly type: NodeType; /** - Allows you to influence the way mouse selection happens. The - functions in this facet will be called for a `mousedown` event - on the editor, and can return an object that overrides the way a - selection is computed from that mouse click or drag. + The name of the node (`.type.name`). */ - static mouseSelectionStyle: Facet; + readonly name: string; /** - Facet used to configure whether a given selection drag event - should move or copy the selection. The given predicate will be - called with the `mousedown` event, and can return `true` when - the drag should move the content. + Get the [tree](#common.Tree) that represents the current node, + if any. Will return null when the node is in a [tree + buffer](#common.TreeBuffer). */ - static dragMovesSelection: Facet<(event: MouseEvent) => boolean, readonly ((event: MouseEvent) => boolean)[]>; + readonly tree: Tree | null; /** - Facet used to configure whether a given selecting click adds a - new range to the existing selection or replaces it entirely. The - default behavior is to check `event.metaKey` on macOS, and - `event.ctrlKey` elsewhere. + Retrieve a stable [syntax node](#common.SyntaxNode) at this + position. */ - static clickAddsSelectionRange: Facet<(event: MouseEvent) => boolean, readonly ((event: MouseEvent) => boolean)[]>; + readonly node: SyntaxNode; /** - A facet that determines which [decorations](https://codemirror.net/6/docs/ref/#view.Decoration) - are shown in the view. Decorations can be provided in two - ways—directly, or via a function that takes an editor view. - - Only decoration sets provided directly are allowed to influence - the editor's vertical layout structure. The ones provided as - functions are called _after_ the new viewport has been computed, - and thus **must not** introduce block widgets or replacing - decorations that cover line breaks. - - If you want decorated ranges to behave like atomic units for - cursor motion and deletion purposes, also provide the range set - containing the decorations to - [`EditorView.atomicRanges`](https://codemirror.net/6/docs/ref/#view.EditorView^atomicRanges). + Test whether the node matches a given context—a sequence of + direct parent nodes. Empty strings in the context array act as + wildcards, other strings must match the ancestor node's name. */ - static decorations: Facet DecorationSet), readonly (DecorationSet | ((view: EditorView) => DecorationSet))[]>; + matchContext(context: readonly string[]): boolean; +} +/** +A syntax node provides an immutable pointer to a given node in a +tree. When iterating over large amounts of nodes, you may want to +use a mutable [cursor](#common.TreeCursor) instead, which is more +efficient. +*/ +interface SyntaxNode extends SyntaxNodeRef { /** - Facet that works much like - [`decorations`](https://codemirror.net/6/docs/ref/#view.EditorView^decorations), but puts its - inputs at the very bottom of the precedence stack, meaning mark - decorations provided here will only be split by other, partially - overlapping \`outerDecorations\` ranges, and wrap around all - regular decorations. Use this for mark elements that should, as - much as possible, remain in one piece. + The node's parent node, if any. */ - static outerDecorations: Facet DecorationSet), readonly (DecorationSet | ((view: EditorView) => DecorationSet))[]>; + parent: SyntaxNode | null; /** - Used to provide ranges that should be treated as atoms as far as - cursor motion is concerned. This causes methods like - [`moveByChar`](https://codemirror.net/6/docs/ref/#view.EditorView.moveByChar) and - [`moveVertically`](https://codemirror.net/6/docs/ref/#view.EditorView.moveVertically) (and the - commands built on top of them) to skip across such regions when - a selection endpoint would enter them. This does _not_ prevent - direct programmatic [selection - updates](https://codemirror.net/6/docs/ref/#state.TransactionSpec.selection) from moving into such - regions. + The first child, if the node has children. */ - static atomicRanges: Facet<(view: EditorView) => RangeSet, readonly ((view: EditorView) => RangeSet)[]>; + firstChild: SyntaxNode | null; /** - When range decorations add a `unicode-bidi: isolate` style, they - should also include a - [`bidiIsolate`](https://codemirror.net/6/docs/ref/#view.MarkDecorationSpec.bidiIsolate) property - in their decoration spec, and be exposed through this facet, so - that the editor can compute the proper text order. (Other values - for `unicode-bidi`, except of course `normal`, are not - supported.) + The node's last child, if available. */ - static bidiIsolatedRanges: Facet DecorationSet), readonly (DecorationSet | ((view: EditorView) => DecorationSet))[]>; + lastChild: SyntaxNode | null; /** - Facet that allows extensions to provide additional scroll - margins (space around the sides of the scrolling element that - should be considered invisible). This can be useful when the - plugin introduces elements that cover part of that element (for - example a horizontally fixed gutter). + The first child that ends after `pos`. */ - static scrollMargins: Facet<(view: EditorView) => Partial | null, readonly ((view: EditorView) => Partial | null)[]>; + childAfter(pos: number): SyntaxNode | null; /** - Create a theme extension. The first argument can be a - [`style-mod`](https://github.com/marijnh/style-mod#documentation) - style spec providing the styles for the theme. These will be - prefixed with a generated class for the style. + The last child that starts before `pos`. + */ + childBefore(pos: number): SyntaxNode | null; + /** + Enter the child at the given position. If side is -1 the child + may end at that position, when 1 it may start there. - Because the selectors will be prefixed with a scope class, rule - that directly match the editor's [wrapper - element](https://codemirror.net/6/docs/ref/#view.EditorView.dom)—to which the scope class will be - added—need to be explicitly differentiated by adding an `&` to - the selector for that element—for example - `&.cm-focused`. + This will by default enter + [overlaid](#common.MountedTree.overlay) + [mounted](#common.NodeProp^mounted) trees. You can set + `overlays` to false to disable that. - When `dark` is set to true, the theme will be marked as dark, - which will cause the `&dark` rules from [base - themes](https://codemirror.net/6/docs/ref/#view.EditorView^baseTheme) to be used (as opposed to - `&light` when a light theme is active). + Similarly, when `buffers` is false this will not enter + [buffers](#common.TreeBuffer), only [nodes](#common.Tree) (which + is mostly useful when looking for props, which cannot exist on + buffer-allocated nodes). */ - static theme(spec: { - [selector: string]: StyleSpec; - }, options?: { - dark?: boolean; - }): Extension; + enter(pos: number, side: -1 | 0 | 1, mode?: IterMode): SyntaxNode | null; /** - This facet records whether a dark theme is active. The extension - returned by [`theme`](https://codemirror.net/6/docs/ref/#view.EditorView^theme) automatically - includes an instance of this when the `dark` option is set to - true. + This node's next sibling, if any. + */ + nextSibling: SyntaxNode | null; + /** + This node's previous sibling. */ - static darkTheme: Facet; + prevSibling: SyntaxNode | null; /** - Create an extension that adds styles to the base theme. Like - with [`theme`](https://codemirror.net/6/docs/ref/#view.EditorView^theme), use `&` to indicate the - place of the editor wrapper element when directly targeting - that. You can also use `&dark` or `&light` instead to only - target editors with a dark or light theme. + A [tree cursor](#common.TreeCursor) starting at this node. */ - static baseTheme(spec: { - [selector: string]: StyleSpec; - }): Extension; + cursor(mode?: IterMode): TreeCursor; /** - Provides a Content Security Policy nonce to use when creating - the style sheets for the editor. Holds the empty string when no - nonce has been provided. + Find the node around, before (if `side` is -1), or after (`side` + is 1) the given position. Will look in parent nodes if the + position is outside this node. */ - static cspNonce: Facet; + resolve(pos: number, side?: -1 | 0 | 1): SyntaxNode; /** - Facet that provides additional DOM attributes for the editor's - editable DOM element. + Similar to `resolve`, but enter + [overlaid](#common.MountedTree.overlay) nodes. */ - static contentAttributes: Facet; + resolveInner(pos: number, side?: -1 | 0 | 1): SyntaxNode; /** - Facet that provides DOM attributes for the editor's outer - element. + Move the position to the innermost node before `pos` that looks + like it is unfinished (meaning it ends in an error node or has a + child ending in an error node right at its end). */ - static editorAttributes: Facet; + enterUnfinishedNodesBefore(pos: number): SyntaxNode; /** - An extension that enables line wrapping in the editor (by - setting CSS `white-space` to `pre-wrap` in the content). + Get a [tree](#common.Tree) for this node. Will allocate one if it + points into a buffer. */ - static lineWrapping: Extension; + toTree(): Tree; /** - State effect used to include screen reader announcements in a - transaction. These will be added to the DOM in a visually hidden - element with `aria-live="polite"` set, and should be used to - describe effects that are visually obvious but may not be - noticed by screen reader users (such as moving to the next - search match). + Get the first child of the given type (which may be a [node + name](#common.NodeType.name) or a [group + name](#common.NodeProp^group)). If `before` is non-null, only + return children that occur somewhere after a node with that name + or group. If `after` is non-null, only return children that + occur somewhere before a node with that name or group. */ - static announce: StateEffectType; + getChild(type: string | number, before?: string | number | null, after?: string | number | null): SyntaxNode | null; /** - Retrieve an editor view instance from the view's DOM - representation. + Like [`getChild`](#common.SyntaxNode.getChild), but return all + matching children, not just the first. */ - static findFromDOM(dom: HTMLElement): EditorView | null; -} -/** -Helper type that maps event names to event object types, or the -`any` type for unknown events. -*/ -interface DOMEventMap extends HTMLElementEventMap { - [other: string]: any; + getChildren(type: string | number, before?: string | number | null, after?: string | number | null): SyntaxNode[]; } /** -Event handlers are specified with objects like this. For event -types known by TypeScript, this will infer the event argument type -to hold the appropriate event object type. For unknown events, it -is inferred to `any`, and should be explicitly set if you want type -checking. -*/ -type DOMEventHandlers = { - [event in keyof DOMEventMap]?: (this: This, event: DOMEventMap[event], view: EditorView) => boolean | void; -}; - -/** -Key bindings associate key names with -[command](https://codemirror.net/6/docs/ref/#view.Command)-style functions. - -Key names may be strings like `"Shift-Ctrl-Enter"`—a key identifier -prefixed with zero or more modifiers. Key identifiers are based on -the strings that can appear in -[`KeyEvent.key`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key). -Use lowercase letters to refer to letter keys (or uppercase letters -if you want shift to be held). You may use `"Space"` as an alias -for the `" "` name. - -Modifiers can be given in any order. `Shift-` (or `s-`), `Alt-` (or -`a-`), `Ctrl-` (or `c-` or `Control-`) and `Cmd-` (or `m-` or -`Meta-`) are recognized. - -When a key binding contains multiple key names separated by -spaces, it represents a multi-stroke binding, which will fire when -the user presses the given keys after each other. - -You can use `Mod-` as a shorthand for `Cmd-` on Mac and `Ctrl-` on -other platforms. So `Mod-b` is `Ctrl-b` on Linux but `Cmd-b` on -macOS. +A tree cursor object focuses on a given node in a syntax tree, and +allows you to move to adjacent nodes. */ -interface KeyBinding { +declare class TreeCursor implements SyntaxNodeRef { /** - The key name to use for this binding. If the platform-specific - property (`mac`, `win`, or `linux`) for the current platform is - used as well in the binding, that one takes precedence. If `key` - isn't defined and the platform-specific binding isn't either, - a binding is ignored. + The node's type. */ - key?: string; + type: NodeType; /** - Key to use specifically on macOS. + Shorthand for `.type.name`. */ - mac?: string; + get name(): string; /** - Key to use specifically on Windows. + The start source offset of this node. */ - win?: string; + from: number; /** - Key to use specifically on Linux. + The end source offset. */ - linux?: string; + to: number; + private stack; + private bufferNode; + private yieldNode; + private yieldBuf; /** - The command to execute when this binding is triggered. When the - command function returns `false`, further bindings will be tried - for the key. + Move the cursor to this node's first child. When this returns + false, the node has no child, and the cursor has not been moved. */ - run?: Command; + firstChild(): boolean; /** - When given, this defines a second binding, using the (possibly - platform-specific) key name prefixed with `Shift-` to activate - this command. + Move the cursor to this node's last child. */ - shift?: Command; + lastChild(): boolean; /** - When this property is present, the function is called for every - key that is not a multi-stroke prefix. + Move the cursor to the first child that ends after `pos`. */ - any?: (view: EditorView, event: KeyboardEvent) => boolean; + childAfter(pos: number): boolean; /** - By default, key bindings apply when focus is on the editor - content (the `"editor"` scope). Some extensions, mostly those - that define their own panels, might want to allow you to - register bindings local to that panel. Such bindings should use - a custom scope name. You may also assign multiple scope names to - a binding, separating them by spaces. + Move to the last child that starts before `pos`. */ - scope?: string; + childBefore(pos: number): boolean; /** - When set to true (the default is false), this will always - prevent the further handling for the bound key, even if the - command(s) return false. This can be useful for cases where the - native behavior of the key is annoying or irrelevant but the - command doesn't always apply (such as, Mod-u for undo selection, - which would cause the browser to view source instead when no - selection can be undone). + Move the cursor to the child around `pos`. If side is -1 the + child may end at that position, when 1 it may start there. This + will also enter [overlaid](#common.MountedTree.overlay) + [mounted](#common.NodeProp^mounted) trees unless `overlays` is + set to false. */ - preventDefault?: boolean; + enter(pos: number, side: -1 | 0 | 1, mode?: IterMode): boolean; /** - When set to true, `stopPropagation` will be called on keyboard - events that have their `preventDefault` called in response to - this key binding (see also - [`preventDefault`](https://codemirror.net/6/docs/ref/#view.KeyBinding.preventDefault)). + Move to the node's parent node, if this isn't the top node. */ - stopPropagation?: boolean; -} -/** -Facet used for registering keymaps. - -You can add multiple keymaps to an editor. Their priorities -determine their precedence (the ones specified early or with high -priority get checked first). When a handler has returned `true` -for a given key, no further handlers are called. -*/ -declare const keymap: Facet; - -type SelectionConfig = { + parent(): boolean; /** - The length of a full cursor blink cycle, in milliseconds. - Defaults to 1200. Can be set to 0 to disable blinking. + Move to this node's next sibling, if any. */ - cursorBlinkRate?: number; + nextSibling(): boolean; /** - Whether to show a cursor for non-empty ranges. Defaults to - true. + Move to this node's previous sibling, if any. */ - drawRangeCursor?: boolean; -}; -/** -Returns an extension that hides the browser's native selection and -cursor, replacing the selection with a background behind the text -(with the `cm-selectionBackground` class), and the -cursors with elements overlaid over the code (using -`cm-cursor-primary` and `cm-cursor-secondary`). - -This allows the editor to display secondary selection ranges, and -tends to produce a type of selection more in line with that users -expect in a text editor (the native selection styling will often -leave gaps between lines and won't fill the horizontal space after -a line when the selection continues past it). - -It does have a performance cost, in that it requires an extra DOM -layout cycle for many updates (the selection is drawn based on DOM -layout information that's only available after laying out the -content). -*/ -declare function drawSelection(config?: SelectionConfig): Extension; - -interface SpecialCharConfig { + prevSibling(): boolean; + private atLastNode; + private move; /** - An optional function that renders the placeholder elements. - - The `description` argument will be text that clarifies what the - character is, which should be provided to screen readers (for - example with the - [`aria-label`](https://www.w3.org/TR/wai-aria/#aria-label) - attribute) and optionally shown to the user in other ways (such - as the - [`title`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/title) - attribute). - - The given placeholder string is a suggestion for how to display - the character visually. + Move to the next node in a + [pre-order](https://en.wikipedia.org/wiki/Tree_traversal#Pre-order,_NLR) + traversal, going from a node to its first child or, if the + current node is empty or `enter` is false, its next sibling or + the next sibling of the first parent node that has one. + */ + next(enter?: boolean): boolean; + /** + Move to the next node in a last-to-first pre-order traversal. A + node is followed by its last child or, if it has none, its + previous sibling or the previous sibling of the first parent + node that has one. + */ + prev(enter?: boolean): boolean; + /** + Move the cursor to the innermost node that covers `pos`. If + `side` is -1, it will enter nodes that end at `pos`. If it is 1, + it will enter nodes that start at `pos`. + */ + moveTo(pos: number, side?: -1 | 0 | 1): this; + /** + Get a [syntax node](#common.SyntaxNode) at the cursor's current + position. */ - render?: ((code: number, description: string | null, placeholder: string) => HTMLElement) | null; + get node(): SyntaxNode; /** - Regular expression that matches the special characters to - highlight. Must have its 'g'/global flag set. + Get the [tree](#common.Tree) that represents the current node, if + any. Will return null when the node is in a [tree + buffer](#common.TreeBuffer). */ - specialChars?: RegExp; + get tree(): Tree | null; /** - Regular expression that can be used to add characters to the - default set of characters to highlight. + Iterate over the current node and all its descendants, calling + `enter` when entering a node and `leave`, if given, when leaving + one. When `enter` returns `false`, any children of that node are + skipped, and `leave` isn't called for it. */ - addSpecialChars?: RegExp | null; + iterate(enter: (node: SyntaxNodeRef) => boolean | void, leave?: (node: SyntaxNodeRef) => void): void; + /** + Test whether the current node matches a given context—a sequence + of direct parent node names. Empty strings in the context array + are treated as wildcards. + */ + matchContext(context: readonly string[]): boolean; } /** -Returns an extension that installs highlighting of special -characters. +Provides a way to associate values with pieces of trees. As long +as that part of the tree is reused, the associated values can be +retrieved from an updated tree. */ -declare function highlightSpecialChars( +declare class NodeWeakMap { + private map; + private setBuffer; + private getBuffer; + /** + Set the value for this syntax node. + */ + set(node: SyntaxNode, value: T): void; + /** + Retrieve value for this syntax node, if it exists in the map. + */ + get(node: SyntaxNode): T | undefined; + /** + Set the value for the node that a cursor currently points to. + */ + cursorSet(cursor: TreeCursor, value: T): void; + /** + Retrieve the value for the node that a cursor currently points + to. + */ + cursorGet(cursor: TreeCursor): T | undefined; +} + /** -Configuration options. +Objects returned by the function passed to +[`parseMixed`](#common.parseMixed) should conform to this +interface. */ -config?: SpecialCharConfig): Extension; - +interface NestedParse { + /** + The parser to use for the inner region. + */ + parser: Parser; + /** + When this property is not given, the entire node is parsed with + this parser, and it is [mounted](#common.NodeProp^mounted) as a + non-overlay node, replacing its host node in tree iteration. + + When an array of ranges is given, only those ranges are parsed, + and the tree is mounted as an + [overlay](#common.MountedTree.overlay). + + When a function is given, that function will be called for + descendant nodes of the target node, not including child nodes + that are covered by another nested parse, to determine the + overlay ranges. When it returns true, the entire descendant is + included, otherwise just the range given. The mixed parser will + optimize range-finding in reused nodes, which means it's a good + idea to use a function here when the target node is expected to + have a large, deep structure. + */ + overlay?: readonly { + from: number; + to: number; + }[] | ((node: SyntaxNodeRef) => { + from: number; + to: number; + } | boolean); +} /** -Extension that enables a placeholder—a piece of example content -to show when the editor is empty. +Create a parse wrapper that, after the inner parse completes, +scans its tree for mixed language regions with the `nest` +function, runs the resulting [inner parses](#common.NestedParse), +and then [mounts](#common.NodeProp^mounted) their results onto the +tree. */ -declare function placeholder(content: string | HTMLElement): Extension; +declare function parseMixed(nest: (node: SyntaxNodeRef, input: Input) => NestedParse | null): ParseWrapper; /** -Helper class used to make it easier to maintain decorations on -visible code that matches a given regular expression. To be used -in a [view plugin](https://codemirror.net/6/docs/ref/#view.ViewPlugin). Instances of this object -represent a matching configuration. +A parse stack. These are used internally by the parser to track +parsing progress. They also provide some properties and methods +that external code such as a tokenizer can use to get information +about the parse state. */ -declare class MatchDecorator { - private regexp; - private addMatch; - private boundary; - private maxLength; +declare class Stack { /** - Create a decorator. + The input position up to which this stack has parsed. */ - constructor(config: { - /** - The regular expression to match against the content. Will only - be matched inside lines (not across them). Should have its 'g' - flag set. - */ - regexp: RegExp; - /** - The decoration to apply to matches, either directly or as a - function of the match. - */ - decoration?: Decoration | ((match: RegExpExecArray, view: EditorView, pos: number) => Decoration | null); - /** - Customize the way decorations are added for matches. This - function, when given, will be called for matches and should - call `add` to create decorations for them. Note that the - decorations should appear *in* the given range, and the - function should have no side effects beyond calling `add`. - - The `decoration` option is ignored when `decorate` is - provided. - */ - decorate?: (add: (from: number, to: number, decoration: Decoration) => void, from: number, to: number, match: RegExpExecArray, view: EditorView) => void; - /** - By default, changed lines are re-matched entirely. You can - provide a boundary expression, which should match single - character strings that can never occur in `regexp`, to reduce - the amount of re-matching. - */ - boundary?: RegExp; - /** - Matching happens by line, by default, but when lines are - folded or very long lines are only partially drawn, the - decorator may avoid matching part of them for speed. This - controls how much additional invisible content it should - include in its matches. Defaults to 1000. - */ - maxLength?: number; - }); + pos: number; /** - Compute the full set of decorations for matches in the given - view's viewport. You'll want to call this when initializing your - plugin. + The stack's current [context](#lr.ContextTracker) value, if + any. Its type will depend on the context tracker's type + parameter, or it will be `null` if there is no context + tracker. */ - createDeco(view: EditorView): RangeSet; + get context(): any; /** - Update a set of decorations for a view update. `deco` _must_ be - the set of decorations produced by _this_ `MatchDecorator` for - the view state before the update. + Check if the given term would be able to be shifted (optionally + after some reductions) on this stack. This can be useful for + external tokenizers that want to make sure they only provide a + given token when it applies. */ - updateDeco(update: ViewUpdate, deco: DecorationSet): DecorationSet; - private updateRange; + canShift(term: number): boolean; + /** + Get the parser used by this stack. + */ + get parser(): LRParser; + /** + Test whether a given dialect (by numeric ID, as exported from + the terms file) is enabled. + */ + dialectEnabled(dialectID: number): boolean; + private shiftContext; + private reduceContext; + private updateContext; } /** -Create an extension that enables rectangular selections. By -default, it will react to left mouse drag with the Alt key held -down. When such a selection occurs, the text within the rectangle -that was dragged over will be selected, as one selection -[range](https://codemirror.net/6/docs/ref/#state.SelectionRange) per line. +[Tokenizers](#lr.ExternalTokenizer) interact with the input +through this interface. It presents the input as a stream of +characters, tracking lookahead and hiding the complexity of +[ranges](#common.Parser.parse^ranges) from tokenizer code. */ -declare function rectangularSelection(options?: { +declare class InputStream { /** - A custom predicate function, which takes a `mousedown` event and - returns true if it should be used for rectangular selection. + Backup chunk */ - eventFilter?: (event: MouseEvent) => boolean; -}): Extension; - -/** -Creates an extension that configures tooltip behavior. -*/ -declare function tooltips(config?: { + private chunk2; + private chunk2Pos; /** - By default, tooltips use `"fixed"` - [positioning](https://developer.mozilla.org/en-US/docs/Web/CSS/position), - which has the advantage that tooltips don't get cut off by - scrollable parent elements. However, CSS rules like `contain: - layout` can break fixed positioning in child nodes, which can be - worked about by using `"absolute"` here. - - On iOS, which at the time of writing still doesn't properly - support fixed positioning, the library always uses absolute - positioning. + The character code of the next code unit in the input, or -1 + when the stream is at the end of the input. + */ + next: number; + /** + The current position of the stream. Note that, due to parses + being able to cover non-contiguous + [ranges](#common.Parser.startParse), advancing the stream does + not always mean its position moves a single unit. + */ + pos: number; + private rangeIndex; + private range; + /** + Look at a code unit near the stream position. `.peek(0)` equals + `.next`, `.peek(-1)` gives you the previous character, and so + on. - If the tooltip parent element sits in a transformed element, the - library also falls back to absolute positioning. + Note that looking around during tokenizing creates dependencies + on potentially far-away content, which may reduce the + effectiveness incremental parsing—when looking forward—or even + cause invalid reparses when looking backward more than 25 code + units, since the library does not track lookbehind. */ - position?: "fixed" | "absolute"; + peek(offset: number): number; /** - The element to put the tooltips into. By default, they are put - in the editor (`cm-editor`) element, and that is usually what - you want. But in some layouts that can lead to positioning - issues, and you need to use a different parent to work around - those. + Accept a token. By default, the end of the token is set to the + current stream position, but you can pass an offset (relative to + the stream position) to change that. */ - parent?: HTMLElement; + acceptToken(token: number, endOffset?: number): void; /** - By default, when figuring out whether there is room for a - tooltip at a given position, the extension considers the entire - space between 0,0 and `innerWidth`,`innerHeight` to be available - for showing tooltips. You can provide a function here that - returns an alternative rectangle. + Accept a token ending at a specific given position. */ - tooltipSpace?: (view: EditorView) => Rect; -}): Extension; -/** -Describes a tooltip. Values of this type, when provided through -the [`showTooltip`](https://codemirror.net/6/docs/ref/#view.showTooltip) facet, control the -individual tooltips on the editor. -*/ -interface Tooltip { + acceptTokenTo(token: number, endPos: number): void; + private getChunk; + private readNext; /** - The document position at which to show the tooltip. + Move the stream forward N (defaults to 1) code units. Returns + the new value of [`next`](#lr.InputStream.next). */ - pos: number; + advance(n?: number): number; + private setDone; +} +interface ExternalOptions { /** - The end of the range annotated by this tooltip, if different - from `pos`. + When set to true, mark this tokenizer as depending on the + current parse stack, which prevents its result from being cached + between parser actions at the same positions. */ - end?: number; + contextual?: boolean; /** - A constructor function that creates the tooltip's [DOM - representation](https://codemirror.net/6/docs/ref/#view.TooltipView). + By defaults, when a tokenizer returns a token, that prevents + tokenizers with lower precedence from even running. When + `fallback` is true, the tokenizer is allowed to run when a + previous tokenizer returned a token that didn't match any of the + current state's actions. */ - create(view: EditorView): TooltipView; + fallback?: boolean; /** - Whether the tooltip should be shown above or below the target - position. Not guaranteed to be respected for hover tooltips - since all hover tooltips for the same range are always - positioned together. Defaults to false. + When set to true, tokenizing will not stop after this tokenizer + has produced a token. (But it will still fail to reach this one + if a higher-precedence tokenizer produced a token.) */ - above?: boolean; + extend?: boolean; +} +/** +`@external tokens` declarations in the grammar should resolve to +an instance of this class. +*/ +declare class ExternalTokenizer { /** - Whether the `above` option should be honored when there isn't - enough space on that side to show the tooltip inside the - viewport. Defaults to false. + Create a tokenizer. The first argument is the function that, + given an input stream, scans for the types of tokens it + recognizes at the stream's position, and calls + [`acceptToken`](#lr.InputStream.acceptToken) when it finds + one. */ - strictSide?: boolean; + constructor( /** - When set to true, show a triangle connecting the tooltip element - to position `pos`. + @internal */ - arrow?: boolean; + token: (input: InputStream, stack: Stack) => void, options?: ExternalOptions); } + /** -Describes the way a tooltip is displayed. +Context trackers are used to track stateful context (such as +indentation in the Python grammar, or parent elements in the XML +grammar) needed by external tokenizers. You declare them in a +grammar file as `@context exportName from "module"`. + +Context values should be immutable, and can be updated (replaced) +on shift or reduce actions. + +The export used in a `@context` declaration should be of this +type. */ -interface TooltipView { +declare class ContextTracker { /** - The DOM element to position over the editor. + Define a context tracker. */ - dom: HTMLElement; + constructor(spec: { + /** + The initial value of the context at the start of the parse. + */ + start: T; + /** + Update the context when the parser executes a + [shift](https://en.wikipedia.org/wiki/LR_parser#Shift_and_reduce_actions) + action. + */ + shift?(context: T, term: number, stack: Stack, input: InputStream): T; + /** + Update the context when the parser executes a reduce action. + */ + reduce?(context: T, term: number, stack: Stack, input: InputStream): T; + /** + Update the context when the parser reuses a node from a tree + fragment. + */ + reuse?(context: T, node: Tree, stack: Stack, input: InputStream): T; + /** + Reduce a context value to a number (for cheap storage and + comparison). Only needed for strict contexts. + */ + hash?(context: T): number; + /** + By default, nodes can only be reused during incremental + parsing if they were created in the same context as the one in + which they are reused. Set this to false to disable that + check (and the overhead of storing the hashes). + */ + strict?: boolean; + }); +} +/** +Configuration options when +[reconfiguring](#lr.LRParser.configure) a parser. +*/ +interface ParserConfig { /** - Adjust the position of the tooltip relative to its anchor - position. A positive `x` value will move the tooltip - horizontally along with the text direction (so right in - left-to-right context, left in right-to-left). A positive `y` - will move the tooltip up when it is above its anchor, and down - otherwise. + Node prop values to add to the parser's node set. */ - offset?: { - x: number; - y: number; - }; + props?: readonly NodePropSource[]; /** - By default, a tooltip's screen position will be based on the - text position of its `pos` property. This method can be provided - to make the tooltip view itself responsible for finding its - screen position. + The name of the `@top` declaration to parse from. If not + specified, the first top rule declaration in the grammar is + used. */ - getCoords?: (pos: number) => Rect; + top?: string; /** - By default, tooltips are moved when they overlap with other - tooltips. Set this to `true` to disable that behavior for this - tooltip. + A space-separated string of dialects to enable. */ - overlap?: boolean; + dialect?: string; /** - Called after the tooltip is added to the DOM for the first time. + Replace the given external tokenizers with new ones. */ - mount?(view: EditorView): void; + tokenizers?: { + from: ExternalTokenizer; + to: ExternalTokenizer; + }[]; /** - Update the DOM element for a change in the view's state. + Replace external specializers with new ones. */ - update?(update: ViewUpdate): void; + specializers?: { + from: (value: string, stack: Stack) => number; + to: (value: string, stack: Stack) => number; + }[]; /** - Called when the tooltip is removed from the editor or the editor - is destroyed. + Replace the context tracker with a new one. */ - destroy?(): void; + contextTracker?: ContextTracker; /** - Called when the tooltip has been (re)positioned. The argument is - the [space](https://codemirror.net/6/docs/ref/#view.tooltips^config.tooltipSpace) available to the - tooltip. + When true, the parser will raise an exception, rather than run + its error-recovery strategies, when the input doesn't match the + grammar. */ - positioned?(space: Rect): void; + strict?: boolean; /** - By default, the library will restrict the size of tooltips so - that they don't stick out of the available space. Set this to - false to disable that. + Add a wrapper, which can extend parses created by this parser + with additional logic (usually used to add + [mixed-language](#common.parseMixed) parsing). */ - resize?: boolean; + wrap?: ParseWrapper; + /** + The maximum length of the TreeBuffers generated in the output + tree. Defaults to 1024. + */ + bufferLength?: number; } /** -Facet to which an extension can add a value to show a tooltip. +Holds the parse tables for a given grammar, as generated by +`lezer-generator`, and provides [methods](#common.Parser) to parse +content with. */ -declare const showTooltip: Facet; -type Handlers$1 = { - [event: string]: (view: EditorView, line: BlockInfo, event: Event) => boolean; -}; -interface LineNumberConfig { +declare class LRParser extends Parser { /** - How to display line numbers. Defaults to simply converting them - to string. + The nodes used in the trees emitted by this parser. */ - formatNumber?: (lineNo: number, state: EditorState) => string; + readonly nodeSet: NodeSet; + createParse(input: Input, fragments: readonly TreeFragment[], ranges: readonly { + from: number; + to: number; + }[]): PartialParse; /** - Supply event handlers for DOM events on this gutter. + Configure the parser. Returns a new parser instance that has the + given settings modified. Settings not provided in `config` are + kept from the original parser. */ - domEventHandlers?: Handlers$1; + configure(config: ParserConfig): LRParser; + /** + Tells you whether any [parse wrappers](#lr.ParserConfig.wrap) + are registered for this parser. + */ + hasWrappers(): boolean; + /** + Returns the name associated with a given term. This will only + work for all terms when the parser was generated with the + `--names` option. By default, only the names of tagged terms are + stored. + */ + getName(term: number): string; + /** + The type of top node produced by the parser. + */ + get topNode(): NodeType; + /** + Used by the output of the parser generator. Not available to + user code. @hide + */ + static deserialize(spec: any): LRParser; } -/** -Create a line number gutter extension. -*/ -declare function lineNumbers(config?: LineNumberConfig): Extension; /** Highlighting tags are markers that denote a highlighting category. @@ -4764,6 +4916,7 @@ declare class Tag { this one itself and sorted in order of decreasing specificity. */ readonly set: Tag[]; + toString(): string; /** Define a new tag. If `parent` is given, the tag is treated as a sub-tag of that parent, and @@ -4771,6 +4924,7 @@ declare class Tag { this tag will try to fall back to the parent tag (or grandparent tag, etc). */ + static define(name?: string, parent?: Tag): Tag; static define(parent?: Tag): Tag; /** Define a tag _modifier_, which is a function that, given a tag, @@ -4784,7 +4938,7 @@ declare class Tag { example `m1(m2(m3(t1)))` is a subtype of `m1(m2(t1))`, `m1(m3(t1)`, and so on. */ - static defineModifier(): (tag: Tag) => Tag; + static defineModifier(name?: string): (tag: Tag) => Tag; } /** A highlighter defines a mapping from highlighting tags and @@ -5085,7 +5239,7 @@ declare const tags: { */ heading6: Tag; /** - A prose separator (such as a horizontal rule). + A prose [content](#highlight.tags.content) separator (such as a horizontal rule). */ contentSeparator: Tag; /** @@ -5526,7 +5680,7 @@ declare class HighlightStyle implements Highlighter { */ readonly module: StyleModule | null; readonly style: (tags: readonly Tag[]) => string | null; - readonly scope: ((type: NodeType) => boolean) | undefined; + readonly scope?: (type: NodeType) => boolean; private constructor(); /** Create a highlighter style that associates the given styles to @@ -5651,101 +5805,22 @@ interface MatchResult { The extent of the bracket token found. */ start: { - from: number; - to: number; - }; - /** - The extent of the matched token, if any was found. - */ - end?: { - from: number; - to: number; - }; - /** - Whether the tokens match. This can be false even when `end` has - a value, if that token doesn't match the opening token. - */ - matched: boolean; -} - -type JuliaLanguageConfig = { - /** Enable keyword completion */ - enableKeywordCompletion?: boolean; -}; -declare function julia(config?: JuliaLanguageConfig): LanguageSupport; - -interface HistoryConfig { - /** - The minimum depth (amount of events) to store. Defaults to 100. - */ - minDepth?: number; + from: number; + to: number; + }; /** - The maximum time (in milliseconds) that adjacent events can be - apart and still be grouped together. Defaults to 500. + The extent of the matched token, if any was found. */ - newGroupDelay?: number; + end?: { + from: number; + to: number; + }; /** - By default, when close enough together in time, changes are - joined into an existing undo event if they touch any of the - changed ranges from that event. You can pass a custom predicate - here to influence that logic. + Whether the tokens match. This can be false even when `end` has + a value, if that token doesn't match the opening token. */ - joinToEvent?: (tr: Transaction, isAdjacent: boolean) => boolean; + matched: boolean; } -/** -Create a history extension with the given configuration. -*/ -declare function history(config?: HistoryConfig): Extension; -/** -Default key bindings for the undo history. - -- Mod-z: [`undo`](https://codemirror.net/6/docs/ref/#commands.undo). -- Mod-y (Mod-Shift-z on macOS) + Ctrl-Shift-z on Linux: [`redo`](https://codemirror.net/6/docs/ref/#commands.redo). -- Mod-u: [`undoSelection`](https://codemirror.net/6/docs/ref/#commands.undoSelection). -- Alt-u (Mod-Shift-u on macOS): [`redoSelection`](https://codemirror.net/6/docs/ref/#commands.redoSelection). -*/ -declare const historyKeymap: readonly KeyBinding[]; -/** -Move the selected lines up one line. -*/ -declare const moveLineUp: StateCommand; -/** -Move the selected lines down one line. -*/ -declare const moveLineDown: StateCommand; -/** -Add a [unit](https://codemirror.net/6/docs/ref/#language.indentUnit) of indentation to all selected -lines. -*/ -declare const indentMore: StateCommand; -/** -Remove a [unit](https://codemirror.net/6/docs/ref/#language.indentUnit) of indentation from all -selected lines. -*/ -declare const indentLess: StateCommand; -/** -The default keymap. Includes all bindings from -[`standardKeymap`](https://codemirror.net/6/docs/ref/#commands.standardKeymap) plus the following: - -- Alt-ArrowLeft (Ctrl-ArrowLeft on macOS): [`cursorSyntaxLeft`](https://codemirror.net/6/docs/ref/#commands.cursorSyntaxLeft) ([`selectSyntaxLeft`](https://codemirror.net/6/docs/ref/#commands.selectSyntaxLeft) with Shift) -- Alt-ArrowRight (Ctrl-ArrowRight on macOS): [`cursorSyntaxRight`](https://codemirror.net/6/docs/ref/#commands.cursorSyntaxRight) ([`selectSyntaxRight`](https://codemirror.net/6/docs/ref/#commands.selectSyntaxRight) with Shift) -- Alt-ArrowUp: [`moveLineUp`](https://codemirror.net/6/docs/ref/#commands.moveLineUp) -- Alt-ArrowDown: [`moveLineDown`](https://codemirror.net/6/docs/ref/#commands.moveLineDown) -- Shift-Alt-ArrowUp: [`copyLineUp`](https://codemirror.net/6/docs/ref/#commands.copyLineUp) -- Shift-Alt-ArrowDown: [`copyLineDown`](https://codemirror.net/6/docs/ref/#commands.copyLineDown) -- Escape: [`simplifySelection`](https://codemirror.net/6/docs/ref/#commands.simplifySelection) -- Ctrl-Enter (Cmd-Enter on macOS): [`insertBlankLine`](https://codemirror.net/6/docs/ref/#commands.insertBlankLine) -- Alt-l (Ctrl-l on macOS): [`selectLine`](https://codemirror.net/6/docs/ref/#commands.selectLine) -- Ctrl-i (Cmd-i on macOS): [`selectParentSyntax`](https://codemirror.net/6/docs/ref/#commands.selectParentSyntax) -- Ctrl-[ (Cmd-[ on macOS): [`indentLess`](https://codemirror.net/6/docs/ref/#commands.indentLess) -- Ctrl-] (Cmd-] on macOS): [`indentMore`](https://codemirror.net/6/docs/ref/#commands.indentMore) -- Ctrl-Alt-\\ (Cmd-Alt-\\ on macOS): [`indentSelection`](https://codemirror.net/6/docs/ref/#commands.indentSelection) -- Shift-Ctrl-k (Shift-Cmd-k on macOS): [`deleteLine`](https://codemirror.net/6/docs/ref/#commands.deleteLine) -- Shift-Ctrl-\\ (Shift-Cmd-\\ on macOS): [`cursorMatchingBracket`](https://codemirror.net/6/docs/ref/#commands.cursorMatchingBracket) -- Ctrl-/ (Cmd-/ on macOS): [`toggleComment`](https://codemirror.net/6/docs/ref/#commands.toggleComment). -- Shift-Alt-a: [`toggleBlockComment`](https://codemirror.net/6/docs/ref/#commands.toggleBlockComment). -*/ -declare const defaultKeymap: readonly KeyBinding[]; /** Objects type used to represent individual completions. @@ -5873,6 +5948,14 @@ declare class CompletionContext { */ readonly explicit: boolean; /** + The editor view. May be undefined if the context was created + in a situation where there is no such view available, such as + in synchronous updates via + [`CompletionResult.update`](https://codemirror.net/6/docs/ref/#autocomplete.CompletionResult.update) + or when called by test code. + */ + readonly view?: EditorView | undefined; + /** Create a new completion context. (Mostly useful for testing completion sources—in the editor, the extension will create these for you.) @@ -5892,7 +5975,15 @@ declare class CompletionContext { only return completions when either there is part of a completable entity before the cursor, or `explicit` is true. */ - explicit: boolean); + explicit: boolean, + /** + The editor view. May be undefined if the context was created + in a situation where there is no such view available, such as + in synchronous updates via + [`CompletionResult.update`](https://codemirror.net/6/docs/ref/#autocomplete.CompletionResult.update) + or when called by test code. + */ + view?: EditorView | undefined); /** Get the extent, content, and (if there is a token) type of the token before `this.pos`. @@ -5921,8 +6012,18 @@ declare class CompletionContext { Allows you to register abort handlers, which will be called when the query is [aborted](https://codemirror.net/6/docs/ref/#autocomplete.CompletionContext.aborted). - */ - addEventListener(type: "abort", listener: () => void): void; + + By default, running queries will not be aborted for regular + typing or backspacing, on the assumption that they are likely to + return a result with a + [`validFor`](https://codemirror.net/6/docs/ref/#autocomplete.CompletionResult.validFor) field that + allows the result to be used after all. Passing `onDocChange: + true` will cause this query to be aborted for any document + change. + */ + addEventListener(type: "abort", listener: () => void, options?: { + onDocChange: boolean; + }): void; } /** Given a a fixed array of options, return an autocompleter that @@ -6038,6 +6139,11 @@ interface CompletionConfig { */ activateOnTyping?: boolean; /** + When given, if a completion that matches the predicate is + picked, reactivate completion again as if it was typed normally. + */ + activateOnCompletion?: (completion: Completion) => boolean; + /** The amount of time to wait for further typing before querying completion sources via [`activateOnTyping`](https://codemirror.net/6/docs/ref/#autocomplete.autocompletion^config.activateOnTyping). @@ -6261,7 +6367,7 @@ interface CloseBracketConfig { /** The opening brackets to close. Defaults to `["(", "[", "{", "'", '"']`. Brackets may be single characters or a triple of quotes - (as in `"''''"`). + (as in `"'''"`). */ brackets?: string[]; /** @@ -6314,7 +6420,7 @@ declare function autocompletion(config?: CompletionConfig): Extension; /** Basic keybindings for autocompletion. - - Ctrl-Space: [`startCompletion`](https://codemirror.net/6/docs/ref/#autocomplete.startCompletion) + - Ctrl-Space (and Alt-\` on macOS): [`startCompletion`](https://codemirror.net/6/docs/ref/#autocomplete.startCompletion) - Escape: [`closeCompletion`](https://codemirror.net/6/docs/ref/#autocomplete.closeCompletion) - ArrowDown: [`moveCompletionSelection`](https://codemirror.net/6/docs/ref/#autocomplete.moveCompletionSelection)`(true)` - ArrowUp: [`moveCompletionSelection`](https://codemirror.net/6/docs/ref/#autocomplete.moveCompletionSelection)`(false)` @@ -6429,47 +6535,241 @@ declare namespace index_d { type HighlightOptions = { /** - Determines whether, when nothing is selected, the word around - the cursor is matched instead. Defaults to false. + Determines whether, when nothing is selected, the word around + the cursor is matched instead. Defaults to false. + */ + highlightWordAroundCursor?: boolean; + /** + The minimum length of the selection before it is highlighted. + Defaults to 1 (always highlight non-cursor selections). + */ + minSelectionLength?: number; + /** + The amount of matches (in the viewport) at which to disable + highlighting. Defaults to 100. + */ + maxMatches?: number; + /** + Whether to only highlight whole words. + */ + wholeWords?: boolean; +}; +/** +This extension highlights text that matches the selection. It uses +the `"cm-selectionMatch"` class for the highlighting. When +`highlightWordAroundCursor` is enabled, the word at the cursor +itself will be highlighted with `"cm-selectionMatch-main"`. +*/ +declare function highlightSelectionMatches(options?: HighlightOptions): Extension; +/** +Select next occurrence of the current selection. Expand selection +to the surrounding word when the selection is empty. +*/ +declare const selectNextOccurrence: StateCommand; +/** +Default search-related key bindings. + + - Mod-f: [`openSearchPanel`](https://codemirror.net/6/docs/ref/#search.openSearchPanel) + - F3, Mod-g: [`findNext`](https://codemirror.net/6/docs/ref/#search.findNext) + - Shift-F3, Shift-Mod-g: [`findPrevious`](https://codemirror.net/6/docs/ref/#search.findPrevious) + - Mod-Alt-g: [`gotoLine`](https://codemirror.net/6/docs/ref/#search.gotoLine) + - Mod-d: [`selectNextOccurrence`](https://codemirror.net/6/docs/ref/#search.selectNextOccurrence) +*/ +declare const searchKeymap: readonly KeyBinding[]; + +/** +An update is a set of changes and effects. +*/ +interface Update { + /** + The changes made by this update. + */ + changes: ChangeSet; + /** + The effects in this update. There'll only ever be effects here + when you configure your collab extension with a + [`sharedEffects`](https://codemirror.net/6/docs/ref/#collab.collab^config.sharedEffects) option. + */ + effects?: readonly StateEffect[]; + /** + The [ID](https://codemirror.net/6/docs/ref/#collab.collab^config.clientID) of the client who + created this update. + */ + clientID: string; +} +type CollabConfig = { + /** + The starting document version. Defaults to 0. + */ + startVersion?: number; + /** + This client's identifying [ID](https://codemirror.net/6/docs/ref/#collab.getClientID). Will be a + randomly generated string if not provided. + */ + clientID?: string; + /** + It is possible to share information other than document changes + through this extension. If you provide this option, your + function will be called on each transaction, and the effects it + returns will be sent to the server, much like changes are. Such + effects are automatically remapped when conflicting remote + changes come in. + */ + sharedEffects?: (tr: Transaction) => readonly StateEffect[]; +}; +/** +Create an instance of the collaborative editing plugin. +*/ +declare function collab(config?: CollabConfig): Extension; +/** +Create a transaction that represents a set of new updates received +from the authority. Applying this transaction moves the state +forward to adjust to the authority's view of the document. +*/ +declare function receiveUpdates(state: EditorState, updates: readonly Update[]): Transaction; +/** +Returns the set of locally made updates that still have to be sent +to the authority. The returned objects will also have an `origin` +property that points at the transaction that created them. This +may be useful if you want to send along metadata like timestamps. +(But note that the updates may have been mapped in the meantime, +whereas the transaction is just the original transaction that +created them.) +*/ +declare function sendableUpdates(state: EditorState): readonly (Update & { + origin: Transaction; +})[]; +/** +Get the version up to which the collab plugin has synced with the +central authority. +*/ +declare function getSyncedVersion(state: EditorState): number; +/** +Get this editor's collaborative editing client ID. +*/ +declare function getClientID(state: EditorState): string; + +type Severity = "hint" | "info" | "warning" | "error"; +/** +Describes a problem or hint for a piece of code. +*/ +interface Diagnostic { + /** + The start position of the relevant text. + */ + from: number; + /** + The end position. May be equal to `from`, though actually + covering text is preferable. + */ + to: number; + /** + The severity of the problem. This will influence how it is + displayed. + */ + severity: Severity; + /** + When given, add an extra CSS class to parts of the code that + this diagnostic applies to. + */ + markClass?: string; + /** + An optional source string indicating where the diagnostic is + coming from. You can put the name of your linter here, if + applicable. + */ + source?: string; + /** + The message associated with this diagnostic. + */ + message: string; + /** + An optional custom rendering function that displays the message + as a DOM node. + */ + renderMessage?: (view: EditorView) => Node; + /** + An optional array of actions that can be taken on this + diagnostic. + */ + actions?: readonly Action[]; +} +/** +An action associated with a diagnostic. +*/ +interface Action { + /** + The label to show to the user. Should be relatively short. + */ + name: string; + /** + The function to call when the user activates this action. Is + given the diagnostic's _current_ position, which may have + changed since the creation of the diagnostic, due to editing. + */ + apply: (view: EditorView, from: number, to: number) => void; +} +type DiagnosticFilter = (diagnostics: readonly Diagnostic[], state: EditorState) => Diagnostic[]; +interface LintConfig { + /** + Time to wait (in milliseconds) after a change before running + the linter. Defaults to 750ms. */ - highlightWordAroundCursor?: boolean; + delay?: number; /** - The minimum length of the selection before it is highlighted. - Defaults to 1 (always highlight non-cursor selections). + Optional predicate that can be used to indicate when diagnostics + need to be recomputed. Linting is always re-done on document + changes. */ - minSelectionLength?: number; + needsRefresh?: null | ((update: ViewUpdate) => boolean); /** - The amount of matches (in the viewport) at which to disable - highlighting. Defaults to 100. + Optional filter to determine which diagnostics produce markers + in the content. */ - maxMatches?: number; + markerFilter?: null | DiagnosticFilter; /** - Whether to only highlight whole words. + Filter applied to a set of diagnostics shown in a tooltip. No + tooltip will appear if the empty set is returned. */ - wholeWords?: boolean; -}; + tooltipFilter?: null | DiagnosticFilter; + /** + Can be used to control what kind of transactions cause lint + hover tooltips associated with the given document range to be + hidden. By default any transactions that changes the line + around the range will hide it. Returning null falls back to this + behavior. + */ + hideOn?: (tr: Transaction, from: number, to: number) => boolean | null; + /** + When enabled (defaults to off), this will cause the lint panel + to automatically open when diagnostics are found, and close when + all diagnostics are resolved or removed. + */ + autoPanel?: boolean; +} /** -This extension highlights text that matches the selection. It uses -the `"cm-selectionMatch"` class for the highlighting. When -`highlightWordAroundCursor` is enabled, the word at the cursor -itself will be highlighted with `"cm-selectionMatch-main"`. +Returns a transaction spec which updates the current set of +diagnostics, and enables the lint extension if if wasn't already +active. */ -declare function highlightSelectionMatches(options?: HighlightOptions): Extension; +declare function setDiagnostics(state: EditorState, diagnostics: readonly Diagnostic[]): TransactionSpec; /** -Select next occurrence of the current selection. Expand selection -to the surrounding word when the selection is empty. +The type of a function that produces diagnostics. */ -declare const selectNextOccurrence: StateCommand; +type LintSource = (view: EditorView) => readonly Diagnostic[] | Promise; /** -Default search-related key bindings. - - - Mod-f: [`openSearchPanel`](https://codemirror.net/6/docs/ref/#search.openSearchPanel) - - F3, Mod-g: [`findNext`](https://codemirror.net/6/docs/ref/#search.findNext) - - Shift-F3, Shift-Mod-g: [`findPrevious`](https://codemirror.net/6/docs/ref/#search.findPrevious) - - Mod-Alt-g: [`gotoLine`](https://codemirror.net/6/docs/ref/#search.gotoLine) - - Mod-d: [`selectNextOccurrence`](https://codemirror.net/6/docs/ref/#search.selectNextOccurrence) +Given a diagnostic source, this function returns an extension that +enables linting with that source. It will be called whenever the +editor is idle (after its content changed). If `null` is given as +source, this only configures the lint extension. */ -declare const searchKeymap: readonly KeyBinding[]; +declare function linter(source: LintSource | null, config?: LintConfig): Extension; + +type JuliaLanguageConfig = { + /** Enable keyword completion */ + enableKeywordCompletion?: boolean; +}; +declare function julia(config?: JuliaLanguageConfig): LanguageSupport; declare class LeafBlock { readonly start: number; @@ -6578,6 +6878,7 @@ declare class InlineContext { get end(): number; slice(from: number, to: number): string; addDelimiter(type: DelimiterType, from: number, to: number, open: boolean, close: boolean): number; + get hasOpenLink(): boolean; addElement(elt: Element$1): number; findOpeningDelimiter(type: DelimiterType): number; takeContent(startIndex: number): any[]; @@ -6636,6 +6937,13 @@ declare function markdown(config?: { disable this. */ completeHTMLTags?: boolean; + /** + By default, HTML tags in the document are handled by the [HTML + language](https://github.com/codemirror/lang-html) package with + tag matching turned off. You can pass in an alternative language + configuration here if you want. + */ + htmlTagLanguage?: LanguageSupport; }): LanguageSupport; /** @@ -6718,107 +7026,16 @@ declare function html(config?: { nestedAttributes?: NestedAttr[]; }): LanguageSupport; -type Severity = "hint" | "info" | "warning" | "error"; -/** -Describes a problem or hint for a piece of code. -*/ -interface Diagnostic { - /** - The start position of the relevant text. - */ - from: number; - /** - The end position. May be equal to `from`, though actually - covering text is preferable. - */ - to: number; - /** - The severity of the problem. This will influence how it is - displayed. - */ - severity: Severity; - /** - When given, add an extra CSS class to parts of the code that - this diagnostic applies to. - */ - markClass?: string; - /** - An optional source string indicating where the diagnostic is - coming from. You can put the name of your linter here, if - applicable. - */ - source?: string; - /** - The message associated with this diagnostic. - */ - message: string; - /** - An optional custom rendering function that displays the message - as a DOM node. - */ - renderMessage?: () => Node; - /** - An optional array of actions that can be taken on this - diagnostic. - */ - actions?: readonly Action[]; -} -/** -An action associated with a diagnostic. -*/ -interface Action { - /** - The label to show to the user. Should be relatively short. - */ - name: string; - /** - The function to call when the user activates this action. Is - given the diagnostic's _current_ position, which may have - changed since the creation of the diagnostic, due to editing. - */ - apply: (view: EditorView, from: number, to: number) => void; -} -type DiagnosticFilter = (diagnostics: readonly Diagnostic[], state: EditorState) => Diagnostic[]; -interface LintConfig { - /** - Time to wait (in milliseconds) after a change before running - the linter. Defaults to 750ms. - */ - delay?: number; - /** - Optional predicate that can be used to indicate when diagnostics - need to be recomputed. Linting is always re-done on document - changes. - */ - needsRefresh?: null | ((update: ViewUpdate) => boolean); - /** - Optional filter to determine which diagnostics produce markers - in the content. - */ - markerFilter?: null | DiagnosticFilter; - /** - Filter applied to a set of diagnostics shown in a tooltip. No - tooltip will appear if the empty set is returned. - */ - tooltipFilter?: null | DiagnosticFilter; -} -/** -Returns a transaction spec which updates the current set of -diagnostics, and enables the lint extension if if wasn't already -active. -*/ -declare function setDiagnostics(state: EditorState, diagnostics: readonly Diagnostic[]): TransactionSpec; /** -The type of a function that produces diagnostics. +A language provider based on the [Lezer CSS +parser](https://github.com/lezer-parser/css), extended with +highlighting and indentation information. */ -type LintSource = (view: EditorView) => readonly Diagnostic[] | Promise; +declare const cssLanguage: LRLanguage; /** -Given a diagnostic source, this function returns an extension that -enables linting with that source. It will be called whenever the -editor is idle (after its content changed). If `null` is given as -source, this only configures the lint extension. +Language support for CSS. */ -declare function linter(source: LintSource | null, config?: LintConfig): Extension; +declare function css(): LanguageSupport; /** A language provider based on the [Lezer JavaScript @@ -6835,17 +7052,6 @@ declare function javascript(config?: { typescript?: boolean; }): LanguageSupport; -/** -A language provider based on the [Lezer CSS -parser](https://github.com/lezer-parser/css), extended with -highlighting and indentation information. -*/ -declare const cssLanguage: LRLanguage; -/** -Language support for CSS. -*/ -declare function css(): LanguageSupport; - /** Configuration for an [SQL Dialect](https://codemirror.net/6/docs/ref/#lang-sql.SQLDialect). */ @@ -6914,6 +7120,12 @@ type SQLDialectSpec = { */ identifierQuotes?: string; /** + Controls whether identifiers are case-insensitive. Identifiers + with upper-case letters are quoted when set to false (which is + the default). + */ + caseInsensitiveIdentifiers?: boolean; + /** Controls whether bit values can be defined as 0b1010. Defaults to false. */ @@ -6996,6 +7208,10 @@ interface SQLConfig { When set to true, keyword completions will be upper-case. */ upperCaseKeywords?: boolean; + /** + Can be used to customize the completions generated for keywords. + */ + keywordCompletion?: (label: string, type: string) => Completion; } /** SQL language support for the given SQL dialect, with keyword @@ -7019,76 +7235,4 @@ Python language support. */ declare function python(): LanguageSupport; -/** -An update is a set of changes and effects. -*/ -interface Update { - /** - The changes made by this update. - */ - changes: ChangeSet; - /** - The effects in this update. There'll only ever be effects here - when you configure your collab extension with a - [`sharedEffects`](https://codemirror.net/6/docs/ref/#collab.collab^config.sharedEffects) option. - */ - effects?: readonly StateEffect[]; - /** - The [ID](https://codemirror.net/6/docs/ref/#collab.collab^config.clientID) of the client who - created this update. - */ - clientID: string; -} -type CollabConfig = { - /** - The starting document version. Defaults to 0. - */ - startVersion?: number; - /** - This client's identifying [ID](https://codemirror.net/6/docs/ref/#collab.getClientID). Will be a - randomly generated string if not provided. - */ - clientID?: string; - /** - It is possible to share information other than document changes - through this extension. If you provide this option, your - function will be called on each transaction, and the effects it - returns will be sent to the server, much like changes are. Such - effects are automatically remapped when conflicting remote - changes come in. - */ - sharedEffects?: (tr: Transaction) => readonly StateEffect[]; -}; -/** -Create an instance of the collaborative editing plugin. -*/ -declare function collab(config?: CollabConfig): Extension; -/** -Create a transaction that represents a set of new updates received -from the authority. Applying this transaction moves the state -forward to adjust to the authority's view of the document. -*/ -declare function receiveUpdates(state: EditorState, updates: readonly Update[]): Transaction; -/** -Returns the set of locally made updates that still have to be sent -to the authority. The returned objects will also have an `origin` -property that points at the transaction that created them. This -may be useful if you want to send along metadata like timestamps. -(But note that the updates may have been mapped in the meantime, -whereas the transaction is just the original transaction that -created them.) -*/ -declare function sendableUpdates(state: EditorState): readonly (Update & { - origin: Transaction; -})[]; -/** -Get the version up to which the collab plugin has synced with the -central authority. -*/ -declare function getSyncedVersion(state: EditorState): number; -/** -Get this editor's collaborative editing client ID. -*/ -declare function getClientID(state: EditorState): string; - -export { Annotation, ChangeSet, Compartment, Decoration, Diagnostic, EditorSelection, EditorState, EditorView, Facet, HighlightStyle, MatchDecorator, NodeProp, PostgreSQL, SelectionRange, StateEffect, StateField, Text, Tooltip, Transaction, TreeCursor, ViewPlugin, ViewUpdate, WidgetType, index_d as autocomplete, bracketMatching, closeBrackets, closeBracketsKeymap, collab, combineConfig, completionKeymap, css, cssLanguage, defaultHighlightStyle, defaultKeymap, drawSelection, foldGutter, foldKeymap, getClientID, getSyncedVersion, highlightSelectionMatches, highlightSpecialChars, history, historyKeymap, html, htmlLanguage, indentLess, indentMore, indentOnInput, indentUnit, javascript, javascriptLanguage, julia as julia_andrey, keymap, lineNumbers, linter, markdown, markdownLanguage, moveLineDown, moveLineUp, parseCode, parseMixed, placeholder, python, pythonLanguage, receiveUpdates, rectangularSelection, searchKeymap, selectNextOccurrence, sendableUpdates, setDiagnostics, showTooltip, sql, syntaxHighlighting, syntaxTree, syntaxTreeAvailable, tags, tooltips }; +export { Annotation, ChangeSet, Compartment, Decoration, Diagnostic, EditorSelection, EditorState, EditorView, Facet, HighlightStyle, MatchDecorator, NodeProp, NodeWeakMap, PostgreSQL, SelectionRange, StateEffect, StateField, Text, Tooltip, Transaction, Tree, TreeCursor, ViewPlugin, ViewUpdate, WidgetType, index_d as autocomplete, bracketMatching, closeBrackets, closeBracketsKeymap, collab, combineConfig, completionKeymap, css, cssLanguage, defaultHighlightStyle, defaultKeymap, drawSelection, foldGutter, foldKeymap, getClientID, getSyncedVersion, highlightActiveLine, highlightSelectionMatches, highlightSpecialChars, history, historyKeymap, html, htmlLanguage, indentLess, indentMore, indentOnInput, indentUnit, javascript, javascriptLanguage, julia, keymap, lineNumbers, linter, markdown, markdownLanguage, moveLineDown, moveLineUp, parseCode, parseMixed, placeholder, python, pythonLanguage, receiveUpdates, rectangularSelection, searchKeymap, selectNextOccurrence, sendableUpdates, setDiagnostics, showTooltip, sql, syntaxHighlighting, syntaxTree, syntaxTreeAvailable, tags, tooltips }; diff --git a/dist/index.es.js b/dist/index.es.js index 97b281e..96e4575 100644 --- a/dist/index.es.js +++ b/dist/index.es.js @@ -1,3 +1,84 @@ +// These are filled with ranges (rangeFrom[i] up to but not including +// rangeTo[i]) of code points that count as extending characters. +let rangeFrom = [], rangeTo = [] + +;(() => { + // Compressed representation of the Grapheme_Cluster_Break=Extend + // information from + // http://www.unicode.org/Public/16.0.0/ucd/auxiliary/GraphemeBreakProperty.txt. + // Each pair of elements represents a range, as an offet from the + // previous range and a length. Numbers are in base-36, with the empty + // string being a shorthand for 1. + let numbers = "lc,34,7n,7,7b,19,,,,2,,2,,,20,b,1c,l,g,,2t,7,2,6,2,2,,4,z,,u,r,2j,b,1m,9,9,,o,4,,9,,3,,5,17,3,3b,f,,w,1j,,,,4,8,4,,3,7,a,2,t,,1m,,,,2,4,8,,9,,a,2,q,,2,2,1l,,4,2,4,2,2,3,3,,u,2,3,,b,2,1l,,4,5,,2,4,,k,2,m,6,,,1m,,,2,,4,8,,7,3,a,2,u,,1n,,,,c,,9,,14,,3,,1l,3,5,3,,4,7,2,b,2,t,,1m,,2,,2,,3,,5,2,7,2,b,2,s,2,1l,2,,,2,4,8,,9,,a,2,t,,20,,4,,2,3,,,8,,29,,2,7,c,8,2q,,2,9,b,6,22,2,r,,,,,,1j,e,,5,,2,5,b,,10,9,,2u,4,,6,,2,2,2,p,2,4,3,g,4,d,,2,2,6,,f,,jj,3,qa,3,t,3,t,2,u,2,1s,2,,7,8,,2,b,9,,19,3,3b,2,y,,3a,3,4,2,9,,6,3,63,2,2,,1m,,,7,,,,,2,8,6,a,2,,1c,h,1r,4,1c,7,,,5,,14,9,c,2,w,4,2,2,,3,1k,,,2,3,,,3,1m,8,2,2,48,3,,d,,7,4,,6,,3,2,5i,1m,,5,ek,,5f,x,2da,3,3x,,2o,w,fe,6,2x,2,n9w,4,,a,w,2,28,2,7k,,3,,4,,p,2,5,,47,2,q,i,d,,12,8,p,b,1a,3,1c,,2,4,2,2,13,,1v,6,2,2,2,2,c,,8,,1b,,1f,,,3,2,2,5,2,,,16,2,8,,6m,,2,,4,,fn4,,kh,g,g,g,a6,2,gt,,6a,,45,5,1ae,3,,2,5,4,14,3,4,,4l,2,fx,4,ar,2,49,b,4w,,1i,f,1k,3,1d,4,2,2,1x,3,10,5,,8,1q,,c,2,1g,9,a,4,2,,2n,3,2,,,2,6,,4g,,3,8,l,2,1l,2,,,,,m,,e,7,3,5,5f,8,2,3,,,n,,29,,2,6,,,2,,,2,,2,6j,,2,4,6,2,,2,r,2,2d,8,2,,,2,2y,,,,2,6,,,2t,3,2,4,,5,77,9,,2,6t,,a,2,,,4,,40,4,2,2,4,,w,a,14,6,2,4,8,,9,6,2,3,1a,d,,2,ba,7,,6,,,2a,m,2,7,,2,,2,3e,6,3,,,2,,7,,,20,2,3,,,,9n,2,f0b,5,1n,7,t4,,1r,4,29,,f5k,2,43q,,,3,4,5,8,8,2,7,u,4,44,3,1iz,1j,4,1e,8,,e,,m,5,,f,11s,7,,h,2,7,,2,,5,79,7,c5,4,15s,7,31,7,240,5,gx7k,2o,3k,6o".split(",").map(s => s ? parseInt(s, 36) : 1); + for (let i = 0, n = 0; i < numbers.length; i++) + (i % 2 ? rangeTo : rangeFrom).push(n = n + numbers[i]); +})(); + +function isExtendingChar(code) { + if (code < 768) return false + for (let from = 0, to = rangeFrom.length;;) { + let mid = (from + to) >> 1; + if (code < rangeFrom[mid]) to = mid; + else if (code >= rangeTo[mid]) from = mid + 1; + else return true + if (from == to) return false + } +} + +function isRegionalIndicator(code) { + return code >= 0x1F1E6 && code <= 0x1F1FF +} + +const ZWJ = 0x200d; + +function findClusterBreak$1(str, pos, forward = true, includeExtending = true) { + return (forward ? nextClusterBreak : prevClusterBreak)(str, pos, includeExtending) +} + +function nextClusterBreak(str, pos, includeExtending) { + if (pos == str.length) return pos + // If pos is in the middle of a surrogate pair, move to its start + if (pos && surrogateLow$1(str.charCodeAt(pos)) && surrogateHigh$1(str.charCodeAt(pos - 1))) pos--; + let prev = codePointAt$1(str, pos); + pos += codePointSize$1(prev); + while (pos < str.length) { + let next = codePointAt$1(str, pos); + if (prev == ZWJ || next == ZWJ || includeExtending && isExtendingChar(next)) { + pos += codePointSize$1(next); + prev = next; + } else if (isRegionalIndicator(next)) { + let countBefore = 0, i = pos - 2; + while (i >= 0 && isRegionalIndicator(codePointAt$1(str, i))) { countBefore++; i -= 2; } + if (countBefore % 2 == 0) break + else pos += 2; + } else { + break + } + } + return pos +} + +function prevClusterBreak(str, pos, includeExtending) { + while (pos > 0) { + let found = nextClusterBreak(str, pos - 2, includeExtending); + if (found < pos) return found + pos--; + } + return 0 +} + +function codePointAt$1(str, pos) { + let code0 = str.charCodeAt(pos); + if (!surrogateHigh$1(code0) || pos + 1 == str.length) return code0 + let code1 = str.charCodeAt(pos + 1); + if (!surrogateLow$1(code1)) return code0 + return ((code0 - 0xd800) << 10) + (code1 - 0xdc00) + 0x10000 +} + +function surrogateLow$1(ch) { return ch >= 0xDC00 && ch < 0xE000 } +function surrogateHigh$1(ch) { return ch >= 0xD800 && ch < 0xDC00 } +function codePointSize$1(code) { return code < 0x10000 ? 1 : 2 } + /** The data structure for documents. @nonabstract */ @@ -560,26 +641,6 @@ function clip(text, from, to) { return [from, Math.max(from, Math.min(text.length, to))]; } -// Compressed representation of the Grapheme_Cluster_Break=Extend -// information from -// http://www.unicode.org/Public/13.0.0/ucd/auxiliary/GraphemeBreakProperty.txt. -// Each pair of elements represents a range, as an offet from the -// previous range and a length. Numbers are in base-36, with the empty -// string being a shorthand for 1. -let extend = /*@__PURE__*/"lc,34,7n,7,7b,19,,,,2,,2,,,20,b,1c,l,g,,2t,7,2,6,2,2,,4,z,,u,r,2j,b,1m,9,9,,o,4,,9,,3,,5,17,3,3b,f,,w,1j,,,,4,8,4,,3,7,a,2,t,,1m,,,,2,4,8,,9,,a,2,q,,2,2,1l,,4,2,4,2,2,3,3,,u,2,3,,b,2,1l,,4,5,,2,4,,k,2,m,6,,,1m,,,2,,4,8,,7,3,a,2,u,,1n,,,,c,,9,,14,,3,,1l,3,5,3,,4,7,2,b,2,t,,1m,,2,,2,,3,,5,2,7,2,b,2,s,2,1l,2,,,2,4,8,,9,,a,2,t,,20,,4,,2,3,,,8,,29,,2,7,c,8,2q,,2,9,b,6,22,2,r,,,,,,1j,e,,5,,2,5,b,,10,9,,2u,4,,6,,2,2,2,p,2,4,3,g,4,d,,2,2,6,,f,,jj,3,qa,3,t,3,t,2,u,2,1s,2,,7,8,,2,b,9,,19,3,3b,2,y,,3a,3,4,2,9,,6,3,63,2,2,,1m,,,7,,,,,2,8,6,a,2,,1c,h,1r,4,1c,7,,,5,,14,9,c,2,w,4,2,2,,3,1k,,,2,3,,,3,1m,8,2,2,48,3,,d,,7,4,,6,,3,2,5i,1m,,5,ek,,5f,x,2da,3,3x,,2o,w,fe,6,2x,2,n9w,4,,a,w,2,28,2,7k,,3,,4,,p,2,5,,47,2,q,i,d,,12,8,p,b,1a,3,1c,,2,4,2,2,13,,1v,6,2,2,2,2,c,,8,,1b,,1f,,,3,2,2,5,2,,,16,2,8,,6m,,2,,4,,fn4,,kh,g,g,g,a6,2,gt,,6a,,45,5,1ae,3,,2,5,4,14,3,4,,4l,2,fx,4,ar,2,49,b,4w,,1i,f,1k,3,1d,4,2,2,1x,3,10,5,,8,1q,,c,2,1g,9,a,4,2,,2n,3,2,,,2,6,,4g,,3,8,l,2,1l,2,,,,,m,,e,7,3,5,5f,8,2,3,,,n,,29,,2,6,,,2,,,2,,2,6j,,2,4,6,2,,2,r,2,2d,8,2,,,2,2y,,,,2,6,,,2t,3,2,4,,5,77,9,,2,6t,,a,2,,,4,,40,4,2,2,4,,w,a,14,6,2,4,8,,9,6,2,3,1a,d,,2,ba,7,,6,,,2a,m,2,7,,2,,2,3e,6,3,,,2,,7,,,20,2,3,,,,9n,2,f0b,5,1n,7,t4,,1r,4,29,,f5k,2,43q,,,3,4,5,8,8,2,7,u,4,44,3,1iz,1j,4,1e,8,,e,,m,5,,f,11s,7,,h,2,7,,2,,5,79,7,c5,4,15s,7,31,7,240,5,gx7k,2o,3k,6o".split(",").map(s => s ? parseInt(s, 36) : 1); -// Convert offsets into absolute values -for (let i = 1; i < extend.length; i++) - extend[i] += extend[i - 1]; -function isExtendingChar(code) { - for (let i = 1; i < extend.length; i += 2) - if (extend[i] > code) - return extend[i - 1] <= code; - return false; -} -function isRegionalIndicator(code) { - return code >= 0x1F1E6 && code <= 0x1F1FF; -} -const ZWJ = 0x200d; /** Returns a next grapheme cluster break _after_ (not equal to) `pos`, if `forward` is true, or before otherwise. Returns `pos` @@ -589,47 +650,7 @@ Moves across surrogate pairs, extending characters (when joiners, and flag emoji. */ function findClusterBreak(str, pos, forward = true, includeExtending = true) { - return (forward ? nextClusterBreak : prevClusterBreak)(str, pos, includeExtending); -} -function nextClusterBreak(str, pos, includeExtending) { - if (pos == str.length) - return pos; - // If pos is in the middle of a surrogate pair, move to its start - if (pos && surrogateLow(str.charCodeAt(pos)) && surrogateHigh(str.charCodeAt(pos - 1))) - pos--; - let prev = codePointAt(str, pos); - pos += codePointSize(prev); - while (pos < str.length) { - let next = codePointAt(str, pos); - if (prev == ZWJ || next == ZWJ || includeExtending && isExtendingChar(next)) { - pos += codePointSize(next); - prev = next; - } - else if (isRegionalIndicator(next)) { - let countBefore = 0, i = pos - 2; - while (i >= 0 && isRegionalIndicator(codePointAt(str, i))) { - countBefore++; - i -= 2; - } - if (countBefore % 2 == 0) - break; - else - pos += 2; - } - else { - break; - } - } - return pos; -} -function prevClusterBreak(str, pos, includeExtending) { - while (pos > 0) { - let found = nextClusterBreak(str, pos - 2, includeExtending); - if (found < pos) - return found; - pos--; - } - return 0; + return findClusterBreak$1(str, pos, forward, includeExtending); } function surrogateLow(ch) { return ch >= 0xDC00 && ch < 0xE000; } function surrogateHigh(ch) { return ch >= 0xD800 && ch < 0xDC00; } @@ -659,7 +680,7 @@ function fromCodePoint(code) { return String.fromCharCode((code >> 10) + 0xd800, (code & 1023) + 0xdc00); } /** -The amount of positions a character takes up a JavaScript string. +The amount of positions a character takes up in a JavaScript string. */ function codePointSize(code) { return code < 0x10000 ? 1 : 2; } @@ -788,7 +809,7 @@ class ChangeDesc { Map this description, which should start with the same document as `other`, over another set of changes, so that it can be applied after it. When `before` is true, map as if the changes - in `other` happened before the ones in `this`. + in `this` happened before the ones in `other`. */ mapDesc(other, before = false) { return other.empty ? this : mapSet(this, other, before); } mapPos(pos, assoc = -1, mode = MapMode.Simple) { @@ -1091,7 +1112,7 @@ function addSection(sections, len, ins, forceJoin = false) { let last = sections.length - 2; if (last >= 0 && ins <= 0 && ins == sections[last + 1]) sections[last] += len; - else if (len == 0 && sections[last] == 0) + else if (last >= 0 && len == 0 && sections[last] == 0) sections[last + 1] += ins; else if (forceJoin) { sections[last] += len; @@ -1149,7 +1170,10 @@ function mapSet(setA, setB, before, mkSet = false) { // content has been inserted already, and refers to the section // index. for (let inserted = -1;;) { - if (a.ins == -1 && b.ins == -1) { + if (a.done && b.len || b.done && a.len) { + throw new Error("Mismatched change set lengths"); + } + else if (a.ins == -1 && b.ins == -1) { // Move across ranges skipped by both sets. let len = Math.min(a.len, b.len); addSection(sections, len, -1); @@ -3841,7 +3865,7 @@ function compare(a, startA, b, startB, length, comparator) { let endB = startB + length; let pos = startB, dPos = startB - startA; for (;;) { - let diff = (a.to + dPos) - b.to || a.endSide - b.endSide; + let dEnd = (a.to + dPos) - b.to, diff = dEnd || a.endSide - b.endSide; let end = diff < 0 ? a.to + dPos : b.to, clipEnd = Math.min(end, endB); if (a.point || b.point) { if (!(a.point && b.point && (a.point == b.point || a.point.eq(b.point)) && @@ -3854,6 +3878,8 @@ function compare(a, startA, b, startB, length, comparator) { } if (end > endB) break; + if ((dEnd || a.openEnd != b.openEnd) && comparator.boundChange) + comparator.boundChange(end); pos = end; if (diff <= 0) a.next(); @@ -3926,21598 +3952,19669 @@ function findColumn(string, col, tabSize, strict) { return strict === true ? -1 : string.length; } -/** -The default maximum length of a `TreeBuffer` node. -*/ -const DefaultBufferLength = 1024; -let nextPropID = 0; -class Range { - constructor(from, to) { - this.from = from; - this.to = to; +const C = "\u037c"; +const COUNT = typeof Symbol == "undefined" ? "__" + C : Symbol.for(C); +const SET = typeof Symbol == "undefined" ? "__styleSet" + Math.floor(Math.random() * 1e8) : Symbol("styleSet"); +const top = typeof globalThis != "undefined" ? globalThis : typeof window != "undefined" ? window : {}; + +// :: - Style modules encapsulate a set of CSS rules defined from +// JavaScript. Their definitions are only available in a given DOM +// root after it has been _mounted_ there with `StyleModule.mount`. +// +// Style modules should be created once and stored somewhere, as +// opposed to re-creating them every time you need them. The amount of +// CSS rules generated for a given DOM root is bounded by the amount +// of style modules that were used. So to avoid leaking rules, don't +// create these dynamically, but treat them as one-time allocations. +class StyleModule { + // :: (Object