@adecore/editor-core 0.17.0-beta.1 → 0.17.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +26 -40
- package/package.json +1 -1
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,54 +1,40 @@
|
|
|
1
1
|
# @adecore/editor-core
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@adecore/editor-core)
|
|
4
|
+
[](https://adecore.dev/editor-core/)
|
|
4
5
|
|
|
5
|
-
The document model
|
|
6
|
+
The document model of a code editor, with no DOM and no dependencies. `DocumentModel` holds the text, the selections, an undo history and the editing commands: typing with bracket pairing, smart Enter, comment toggles, line moves, multiple carets, search and folding. It runs in a browser, Bun and Node. [`@adecore/editor`](https://adecore.dev/editor/) draws it on screen.
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
## Install
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
```sh
|
|
11
|
+
bun add @adecore/editor-core
|
|
12
|
+
```
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
## Use
|
|
12
15
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
- `applyEdits` takes `expectedRevision` and refuses the batch if the text moved on. A revision only goes up.
|
|
16
|
-
- `typeText` is one keystroke on every caret. It pairs brackets and quotes (each with its own option, and not in plain text), pairs a bracket only when the text after it has no closer for it, pairs a quote only when no identifier character follows, types over a closer, wraps a selection in a bracket, `<` or quote and swaps the quotes of a string when one of them is selected, sends a closing bracket alone on its line back to the indentation of its opener, leaves a Python docstring opener at three quotes and moves a `;` to the end of a call. It reads the language id (`typescript`, `php`, `python`, and so on) to tell code from comments and strings.
|
|
17
|
-
- `paste` writes the document's own line breaks, takes one line for each caret when the counts match, puts text copied from a bare caret (`wholeLines`) above the line of each bare caret, and moves a pasted block to the indentation of the line it lands on, only when it lands in code and not in a string, a template literal, a comment or a heredoc.
|
|
18
|
-
- `execute` runs an `EditorCommand`: word and camel-hump movement, smart Home and End, backspace, Enter and its variants (start a line below or above, split a line), Tab, join lines, toggle case, auto-indent, line duplicate, delete and move, line and block comment toggles, indent, multiple carets (add above and below, which takes them back when pressed the other way, and one per selected line), selection expansion and the occurrence commands (next, unselect and all).
|
|
19
|
-
- A word move stops at the end of a word, then at the start of the next line, and on an empty line, going back at the start of a word and then the end of the line above; deleting by word stops at both edges of a word. Camel humps are off unless `camelCase` is true. Home and End take `visualLine`, so a wrapped row is an edge of its own, and Home inside the indentation goes to the start of the line.
|
|
20
|
-
- `lineSpan` in the command options names the lines that stand on one row of the screen, which a host with folds fills in: a collapsed fold is then one line to delete, duplicate, comment and move (it swaps with the whole row it passes, and `onLinesMoved` tells the host where each line went), one word stop that never lands inside it, and its lines are skipped by add caret above and below.
|
|
21
|
-
- Select next occurrence selects the word at the caret, then whole words with the same case; from a selection it finds the text inside other words too. The end of the text is said (`occurrencesExhausted`) and the press after it starts again.
|
|
22
|
-
- `getFoldingRanges` also reads, with a language, runs of import lines, runs of line comments and `region` markers (`lexicalFolds`), and the whole-line blocks of Markdown (front matter, code fences, tables, the section under a heading) and PHP (heredocs and nowdocs, `<?php ... ?>` blocks between markup) in `blockFolds`.
|
|
23
|
-
- A range may carry a `role`, which is what the settings fold by when a file opens: the file header, a documentation comment, imports, a region, an object or array literal in a script and a PHP attribute list are read off the text (`fold-roles.ts`). The body of a function, a method or a class, and the tag a server's range starts with, come from `hints` in the options, which a host fills from a language server's symbols and folding ranges as offsets. A symbol names the bracket pair that closes where it ends, or the indented block that does; a range the text has no fold for becomes a `server` fold, one per line it starts on.
|
|
24
|
-
- `replace` and `replaceAll` can give the replacement the case of the match (`preserveCase`).
|
|
25
|
-
- Enter works from the lexer's state at the caret. It continues a line comment when text follows the caret (with the marker the comment starts with, so a PHP `#` and a Python `##` go on as they are), closes and continues `/*` and `/**` comments with the stars lined up under the opener's first star (a `/** text */` that closes on its line gives the closer a line of its own), splits a string literal with the language's concatenation (not in the value of a JSX attribute or the path of an import, `require` or `export ... from`, where it breaks the line as it is), closes a brace nothing closes, indents after an opener, `def f():` (the code before a trailing comment decides, as if the comment were not there), a YAML `key:`, a `case` label, an open tag and a statement left unfinished, and replaces the whitespace after the caret by the indentation it computes.
|
|
26
|
-
- Comment toggles use a table of markers per language (`commentSyntax`), with the region of a Vue file picked by the caret's line. Line comments go in at the smallest indentation of the lines, and a lone caret moves down a line. A language with block comments only wraps each line.
|
|
27
|
-
- Backspace at the start of a line also takes the whitespace that trails the line above. Tab inserts up to the next tab stop, which for several carets on a line counts what the carets before it added, or steps over a closer the editor added.
|
|
28
|
-
- `scanBrackets` pairs brackets lexically, for code that does not parse yet.
|
|
29
|
-
- `changedSpan` is the one stretch that differs between two texts and `changedSpans` the stretches of a bounded line diff (Myers on interned lines, then trimmed to the characters), which `applyEdits` takes as one batch. A diff past 4 million steps of work, 1,000 edited lines or 16 MiB between the first and last change is the one span. On 100,000 lines (6 MB) with three changes it takes about 20 ms.
|
|
30
|
-
- `findMatches` and `replacementText` are the search the model uses.
|
|
31
|
-
- `isWordBoundary`, `isHumpBoundary` and `wordBoundary` are the word predicates and the navigation on top of them.
|
|
32
|
-
- Types for selections, edits, changes, snapshots, commands and options.
|
|
16
|
+
```ts
|
|
17
|
+
import { DocumentModel } from '@adecore/editor-core';
|
|
33
18
|
|
|
34
|
-
|
|
19
|
+
const document = new DocumentModel('const greeting = "hello";\n');
|
|
35
20
|
|
|
36
|
-
|
|
21
|
+
document.setSelections([{ anchor: 26, head: 26 }]);
|
|
22
|
+
document.typeText('(', { language: 'typescript' }); // the closer comes along
|
|
23
|
+
document.undo();
|
|
24
|
+
```
|
|
37
25
|
|
|
38
|
-
|
|
26
|
+
Offsets are UTF-16 code units, lines and columns zero-based. A batch of edits is simultaneous, in the coordinates of the text before it.
|
|
39
27
|
|
|
40
|
-
|
|
28
|
+
## Documentation
|
|
41
29
|
|
|
42
|
-
|
|
30
|
+
| Page | What it covers |
|
|
31
|
+
|---|---|
|
|
32
|
+
| [Overview](https://adecore.dev/editor-core/) | Coordinates, limits and provenance |
|
|
33
|
+
| [Documents and edits](https://adecore.dev/editor-core/documents) | Text, selections, edit batches, revisions, history and change events |
|
|
34
|
+
| [Typing and commands](https://adecore.dev/editor-core/commands) | `typeText`, `paste`, `execute` and their options |
|
|
35
|
+
| [Search and folding](https://adecore.dev/editor-core/search-folding) | Find and replace, folding ranges and roles |
|
|
36
|
+
| [API reference](https://adecore.dev/editor-core/api) | The helpers and types next to the model |
|
|
43
37
|
|
|
44
|
-
|
|
45
|
-
- Language is a string id (the Shiki ones) with positive lists for the lexer: which languages have `//`, `#` (anywhere, or only at the start of a word in shell, YAML and Dockerfile), `--`, `/* */` and `<!-- -->` comments, which have braces, and a table of comment markers. An unknown id has no comments and no braces, so nothing in it reads as a comment. Indentation is worked out from brackets, keywords and the end of the previous line, not by a formatter, so Auto-indent Lines leaves languages without braces alone. It also leaves markup alone: only lines the lexer calls code are re-indented, never the lines of JSX elements (a scanner finds them, `markup-regions.ts`), a Vue template or anything outside its script and style blocks, the markup and heredocs of a PHP file, and the bodies of template literals, multi-line strings and comments.
|
|
46
|
-
- Smart semicolons only cross a trailing chain of `)` and `]`, and only in TypeScript, JavaScript and PHP.
|
|
47
|
-
- Search, folding and selection expansion read the whole document on request, synchronously. A regex has no timeout, so run untrusted patterns in a worker.
|
|
48
|
-
- Word navigation reads what it crosses: a single 4 MiB word takes well over half a second. History keeps the last 200 steps. The rope has no size cap and was measured up to 25 MiB (`bun run benchmark`).
|
|
49
|
-
- Backspace and delete by grapheme need `Intl.Segmenter`.
|
|
50
|
-
- Columns are UTF-16, not graphemes or visual columns, and tab stops only matter for indentation commands and indentation folds.
|
|
38
|
+
## License
|
|
51
39
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
This unpublished package is private at version `0.0.0`. Its sources retain FSL-1.1-MIT except the explicitly attributed Apache-2.0 word predicates; `LICENSE`, `NOTICE` and `LICENSE.apache-2.0.txt` are included in the package. Source consumers enable `source` in their bundler and TypeScript `customConditions`. Default exports use compiled JavaScript and declarations. Run `bun run build`, `bun run typecheck`, `bun run test`, or the separate `bun run benchmark` from the package after workspace installation.
|
|
40
|
+
FSL-1.1-MIT, except the word-boundary predicates in `src/words.ts`, which are adapted from the IntelliJ Platform (`EditorActionUtil.java` of JetBrains/intellij-community at `7184b03af6c5370e79a01ded0df68cf56d7669da`, lines 934 through 982) under Apache 2.0. `NOTICE` and `LICENSE.apache-2.0.txt` ship with the package.
|