@profullstack/readm3 0.2.0 → 0.3.0
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/README.md +100 -12
- package/dist/cli.d.ts +5 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +45 -5
- package/dist/cli.js.map +1 -1
- package/dist/editor.d.ts +77 -0
- package/dist/editor.d.ts.map +1 -0
- package/dist/editor.js +308 -0
- package/dist/editor.js.map +1 -0
- package/dist/emoji.d.ts +12 -0
- package/dist/emoji.d.ts.map +1 -0
- package/dist/emoji.js +73 -0
- package/dist/emoji.js.map +1 -0
- package/dist/flavors.d.ts +68 -0
- package/dist/flavors.d.ts.map +1 -0
- package/dist/flavors.js +223 -0
- package/dist/flavors.js.map +1 -0
- package/dist/index.d.ts +10 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -4
- package/dist/index.js.map +1 -1
- package/dist/markdown.d.ts +12 -3
- package/dist/markdown.d.ts.map +1 -1
- package/dist/markdown.js +424 -379
- package/dist/markdown.js.map +1 -1
- package/dist/print.d.ts +3 -3
- package/dist/print.d.ts.map +1 -1
- package/dist/print.js +8 -3
- package/dist/print.js.map +1 -1
- package/dist/roles.d.ts.map +1 -1
- package/dist/roles.js +17 -0
- package/dist/roles.js.map +1 -1
- package/dist/viewer.d.ts +5 -0
- package/dist/viewer.d.ts.map +1 -1
- package/dist/viewer.js +375 -60
- package/dist/viewer.js.map +1 -1
- package/package.json +9 -3
package/README.md
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
# readm3
|
|
2
2
|
|
|
3
|
-
A terminal markdown reader. File browser on the left, the rendered
|
|
4
|
-
the right, and nothing else in the way.
|
|
3
|
+
A terminal markdown reader and editor. File browser on the left, the rendered
|
|
4
|
+
document on the right, and nothing else in the way. Press `e` to edit the file
|
|
5
|
+
you are looking at, `esc` to see it rendered again.
|
|
6
|
+
|
|
7
|
+
CommonMark and GitHub Flavored Markdown, plus the extras each dialect added on
|
|
8
|
+
top: GitHub alerts, footnotes and `:emoji:`, and Reddit spoilers, superscript
|
|
9
|
+
and `r/` `u/` links.
|
|
5
10
|
|
|
6
11
|
Built on [HQTUI](https://github.com/profullstack/hqtui) — truecolor, mouse, and
|
|
7
12
|
a terminal that gets restored no matter how the process dies.
|
|
@@ -76,22 +81,73 @@ pruned, `node_modules` and friends are never walked, and README sorts first.
|
|
|
76
81
|
| `enter` | open the file | `esc` | clear the filter |
|
|
77
82
|
| `space` `b` | page down / up | `r` | rescan and reload |
|
|
78
83
|
| `g` `G` | top / bottom | `[` `]` | sidebar width |
|
|
79
|
-
|
|
|
84
|
+
| `e` `i` | edit this file | `s` | reveal spoilers |
|
|
85
|
+
| `ctrl+s` | save | `?` | help |
|
|
86
|
+
| | | `q` `ctrl+c` | quit |
|
|
80
87
|
|
|
81
88
|
The mouse works too: the wheel scrolls whichever pane it is over, and a click
|
|
82
89
|
opens a file.
|
|
83
90
|
|
|
91
|
+
### Editing
|
|
92
|
+
|
|
93
|
+
`e` puts the caret in the file. `esc` takes it out, and the preview re-renders
|
|
94
|
+
what you just typed — there is no separate preview pane to keep in step,
|
|
95
|
+
because both modes read the same buffer.
|
|
96
|
+
|
|
97
|
+
| | | | |
|
|
98
|
+
|---|---|---|---|
|
|
99
|
+
| `esc` | back to the preview | `ctrl+s` | save |
|
|
100
|
+
| `ctrl+z` `ctrl+y` | undo / redo | `ctrl+g` | keys |
|
|
101
|
+
| `ctrl+a` `ctrl+e` | line start / end | `ctrl+k` | kill to end of line |
|
|
102
|
+
| `ctrl+←` `ctrl+→` | move by word | `ctrl+u` | kill to start of line |
|
|
103
|
+
| `ctrl+home` `ctrl+end` | top / bottom | `tab` | indent two spaces |
|
|
104
|
+
|
|
105
|
+
`enter` continues the list you are in — the same bullet, the next number, an
|
|
106
|
+
unchecked box for a task — and ends it when you press it on an empty item.
|
|
107
|
+
Quitting or switching files with unsaved changes asks first. `--read-only`
|
|
108
|
+
turns editing off entirely, for use as a pager.
|
|
109
|
+
|
|
110
|
+
There is no selection, and so no cut and paste: this is a place to fix a typo
|
|
111
|
+
and add a paragraph, not a replacement for your editor. `$EDITOR` is still
|
|
112
|
+
`$EDITOR`.
|
|
113
|
+
|
|
84
114
|
## What it renders
|
|
85
115
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
116
|
+
Parsing is [marked](https://github.com/markedjs/marked) — CommonMark and GFM,
|
|
117
|
+
zero dependencies of its own — so readm3 has two dependencies in total.
|
|
118
|
+
|
|
119
|
+
Headings, **bold**, *italic*, `inline code`, links, reference links, bare URLs,
|
|
120
|
+
fenced and indented code blocks with a language label, ordered and unordered
|
|
121
|
+
lists, nested lists, task lists, blockquotes, tables with per-column alignment,
|
|
122
|
+
strikethrough, hard line breaks, horizontal rules, images as labelled
|
|
123
|
+
placeholders, and YAML front matter — shown rather than hidden, because it is
|
|
124
|
+
usually what you opened the file for.
|
|
91
125
|
|
|
92
126
|
The HTML that real READMEs are full of is folded back into markdown rather than
|
|
93
|
-
printed as tags, and
|
|
94
|
-
|
|
127
|
+
printed as tags, and code is held out of that, so `Array<string>` survives.
|
|
128
|
+
|
|
129
|
+
### Flavors
|
|
130
|
+
|
|
131
|
+
`--flavor` picks which dialect's extras are honored. The default is `github`.
|
|
132
|
+
|
|
133
|
+
| flavor | adds |
|
|
134
|
+
|---|---|
|
|
135
|
+
| `commonmark` | nothing beyond CommonMark |
|
|
136
|
+
| `github` | GFM, alerts (`> [!WARNING]`), footnotes (`[^1]`), `:emoji:` |
|
|
137
|
+
| `reddit` | GFM, spoilers (`>!hidden!<`), superscript (`^(text)`), `r/` and `u/` links |
|
|
138
|
+
| `all` | both dialects at once |
|
|
139
|
+
|
|
140
|
+
It matters which one you pick. `2^32` is a number in a README and a superscript
|
|
141
|
+
on Reddit, and `>!spoiler!<` is a blockquote everywhere except Reddit — so the
|
|
142
|
+
flavor decides, rather than every document getting every rule.
|
|
143
|
+
|
|
144
|
+
Alerts get a gutter colored by severity. Footnotes are numbered in order of
|
|
145
|
+
first reference and collected under a rule at the foot of the document.
|
|
146
|
+
Superscript uses real Unicode glyphs when every character has one (`mc^2`
|
|
147
|
+
becomes mc²) and keeps its caret when they do not, because there is no
|
|
148
|
+
superscript `q`. Spoilers are blocked out with `█` rather than colored out, so
|
|
149
|
+
they stay hidden in a pipe and with `--color never`; `s` reveals them in the
|
|
150
|
+
reader, `--spoilers` in `--print`.
|
|
95
151
|
|
|
96
152
|
## Options
|
|
97
153
|
|
|
@@ -103,6 +159,9 @@ survives.
|
|
|
103
159
|
monochrome, high-contrast, light
|
|
104
160
|
-w, --width <n> sidebar width in columns, or the render width with --print
|
|
105
161
|
(default: 28% of the terminal, its full width printing)
|
|
162
|
+
-f, --flavor <name> commonmark, github (default), reddit, or all
|
|
163
|
+
--spoilers reveal spoiler text instead of blocking it out
|
|
164
|
+
-R, --read-only refuse to edit, for use as a pager
|
|
106
165
|
-a, --all include dot-directories and dotfiles
|
|
107
166
|
-M, --no-mouse disable mouse tracking
|
|
108
167
|
-v, --version
|
|
@@ -111,8 +170,8 @@ survives.
|
|
|
111
170
|
|
|
112
171
|
## As a library
|
|
113
172
|
|
|
114
|
-
The renderer
|
|
115
|
-
reused on their own:
|
|
173
|
+
The renderer, the file tree and the edit buffer are pure and need no terminal,
|
|
174
|
+
so they can be reused on their own:
|
|
116
175
|
|
|
117
176
|
```ts
|
|
118
177
|
import { renderMarkdown, toText, renderAnsi, scan, files } from "@profullstack/readm3";
|
|
@@ -121,9 +180,26 @@ const lines = renderMarkdown("# Hello\n\nSome **text**.", 60);
|
|
|
121
180
|
console.log(toText(lines));
|
|
122
181
|
// [ 'Hello', '━━━…', '', 'Some text.' ]
|
|
123
182
|
|
|
183
|
+
// A flavor, and spoilers revealed.
|
|
184
|
+
renderMarkdown(post, 60, { flavor: "reddit", spoilers: true });
|
|
185
|
+
|
|
124
186
|
for (const file of files(scan("./docs"))) console.log(file.path);
|
|
125
187
|
```
|
|
126
188
|
|
|
189
|
+
The edit buffer is a plain object with functions over it, so the editing rules
|
|
190
|
+
can be tested without a screen:
|
|
191
|
+
|
|
192
|
+
```ts
|
|
193
|
+
import { createEditor, insert, newline, undo, text } from "@profullstack/readm3";
|
|
194
|
+
|
|
195
|
+
const ed = createEditor("- first");
|
|
196
|
+
ed.col = 7;
|
|
197
|
+
newline(ed); // continues the list
|
|
198
|
+
insert(ed, "second");
|
|
199
|
+
console.log(text(ed)); // "- first\n- second"
|
|
200
|
+
undo(ed);
|
|
201
|
+
```
|
|
202
|
+
|
|
127
203
|
`renderMarkdown` returns lines of spans carrying a semantic `role` — `h1`,
|
|
128
204
|
`code`, `link`, `quote` and so on — rather than colors, so the same document can
|
|
129
205
|
be re-themed without re-parsing. `renderAnsi(source, width, theme, depth)` is
|
|
@@ -145,6 +221,18 @@ bun run typecheck
|
|
|
145
221
|
bun run build
|
|
146
222
|
```
|
|
147
223
|
|
|
224
|
+
## The website
|
|
225
|
+
|
|
226
|
+
[readm3.com](https://readm3.com) is built from this repository by `site/build.ts`,
|
|
227
|
+
which renders every document on the page through `renderMarkdown` and takes every
|
|
228
|
+
color from a real HQTUI theme. There is no second implementation to keep in sync:
|
|
229
|
+
change the parser and the site changes with it.
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
bun run site:build # writes site/dist
|
|
233
|
+
bun run site:start # serves it on $PORT, default 3000
|
|
234
|
+
```
|
|
235
|
+
|
|
148
236
|
## License
|
|
149
237
|
|
|
150
238
|
MIT.
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { type ColorMode } from "./print.ts";
|
|
2
2
|
import { type ViewerOptions } from "./viewer.ts";
|
|
3
|
-
export declare const VERSION = "0.
|
|
3
|
+
export declare const VERSION = "0.3.0";
|
|
4
|
+
/** The help text, exported so a test can hold it to the flags it documents. */
|
|
5
|
+
export declare const USAGE: string;
|
|
4
6
|
export interface ParsedArgs extends ViewerOptions {
|
|
5
7
|
help: boolean;
|
|
6
8
|
version: boolean;
|
|
7
9
|
/** Render to stdout instead of opening the reader. */
|
|
8
10
|
print: boolean;
|
|
9
11
|
color: ColorMode;
|
|
12
|
+
/** Reveal spoiler text rather than blocking it out. */
|
|
13
|
+
spoilers: boolean;
|
|
10
14
|
}
|
|
11
15
|
export declare function parseArgs(argv: string[]): ParsedArgs;
|
|
12
16
|
export declare function main(argv?: string[]): Promise<void>;
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAQA,OAAO,EAA8B,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AACxE,OAAO,EAAO,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAEtD,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B,+EAA+E;AAC/E,eAAO,MAAM,KAAK,QA0CjB,CAAC;AAEF,MAAM,WAAW,UAAW,SAAQ,aAAa;IAC/C,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,sDAAsD;IACtD,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,SAAS,CAAC;IACjB,uDAAuD;IACvD,QAAQ,EAAE,OAAO,CAAC;CACnB;AAID,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CA6GpD;AAED,wBAAsB,IAAI,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAwChF"}
|
package/dist/cli.js
CHANGED
|
@@ -5,10 +5,12 @@ import { statSync } from "node:fs";
|
|
|
5
5
|
import { dirname, resolve } from "node:path";
|
|
6
6
|
import { pathToFileURL } from "node:url";
|
|
7
7
|
import { themeList } from "@profullstack/hqtui";
|
|
8
|
+
import { FLAVORS, isFlavor } from "./flavors.js";
|
|
8
9
|
import { printDocument, COLOR_MODES } from "./print.js";
|
|
9
10
|
import { run } from "./viewer.js";
|
|
10
|
-
export const VERSION = "0.
|
|
11
|
-
|
|
11
|
+
export const VERSION = "0.3.0";
|
|
12
|
+
/** The help text, exported so a test can hold it to the flags it documents. */
|
|
13
|
+
export const USAGE = `readm3 — a terminal markdown reader and editor
|
|
12
14
|
|
|
13
15
|
Usage
|
|
14
16
|
readm3 [path] [options]
|
|
@@ -25,6 +27,11 @@ Options
|
|
|
25
27
|
-w, --width <n> Sidebar width in columns, or the render width with
|
|
26
28
|
--print. Default: 28% of the terminal, and its full
|
|
27
29
|
width when printing
|
|
30
|
+
-f, --flavor <name> Markdown dialect. One of: ${FLAVORS.join(", ")}.
|
|
31
|
+
Default: github (GFM, alerts, footnotes, :emoji:).
|
|
32
|
+
reddit adds spoilers, superscript and r/ u/ links
|
|
33
|
+
--spoilers Reveal spoiler text instead of blocking it out
|
|
34
|
+
-R, --read-only Refuse to edit, for use as a pager
|
|
28
35
|
-a, --all Include dot-directories and dotfiles
|
|
29
36
|
-M, --no-mouse Disable mouse tracking
|
|
30
37
|
-v, --version Print the version
|
|
@@ -35,8 +42,16 @@ Keys
|
|
|
35
42
|
right/left l h expand or collapse / filter files
|
|
36
43
|
enter open the file r rescan and reload
|
|
37
44
|
space / b page down / up [ ] sidebar width
|
|
38
|
-
g / G top / bottom
|
|
39
|
-
|
|
45
|
+
g / G top / bottom s reveal spoilers
|
|
46
|
+
e / i edit this file ? help
|
|
47
|
+
ctrl+s save q quit
|
|
48
|
+
|
|
49
|
+
Editing
|
|
50
|
+
esc back to the preview, which re-renders as you left it
|
|
51
|
+
ctrl+z ctrl+y undo / redo ctrl+k kill to end of line
|
|
52
|
+
ctrl+a ctrl+e line start / end ctrl+u kill to start of line
|
|
53
|
+
ctrl+arrow move by word enter split, continuing a list
|
|
54
|
+
ctrl+g keys for editing tab indent two spaces
|
|
40
55
|
`;
|
|
41
56
|
class UsageError extends Error {
|
|
42
57
|
}
|
|
@@ -47,8 +62,10 @@ export function parseArgs(argv) {
|
|
|
47
62
|
version: false,
|
|
48
63
|
print: false,
|
|
49
64
|
color: "auto",
|
|
65
|
+
spoilers: false,
|
|
50
66
|
mouse: true,
|
|
51
67
|
all: false,
|
|
68
|
+
readOnly: false,
|
|
52
69
|
};
|
|
53
70
|
let target;
|
|
54
71
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -92,6 +109,22 @@ export function parseArgs(argv) {
|
|
|
92
109
|
parsed.color = value;
|
|
93
110
|
break;
|
|
94
111
|
}
|
|
112
|
+
case "-f":
|
|
113
|
+
case "--flavor": {
|
|
114
|
+
const value = next();
|
|
115
|
+
if (!isFlavor(value)) {
|
|
116
|
+
throw new UsageError(`--flavor must be one of: ${FLAVORS.join(", ")}`);
|
|
117
|
+
}
|
|
118
|
+
parsed.flavor = value;
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
case "--spoilers":
|
|
122
|
+
parsed.spoilers = true;
|
|
123
|
+
break;
|
|
124
|
+
case "-R":
|
|
125
|
+
case "--read-only":
|
|
126
|
+
parsed.readOnly = true;
|
|
127
|
+
break;
|
|
95
128
|
case "-a":
|
|
96
129
|
case "--all":
|
|
97
130
|
parsed.all = true;
|
|
@@ -157,7 +190,14 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
157
190
|
return;
|
|
158
191
|
}
|
|
159
192
|
if (args.print) {
|
|
160
|
-
printDocument({
|
|
193
|
+
printDocument({
|
|
194
|
+
path: args.open,
|
|
195
|
+
width: args.sidebar,
|
|
196
|
+
theme: args.theme,
|
|
197
|
+
color: args.color,
|
|
198
|
+
flavor: args.flavor,
|
|
199
|
+
spoilers: args.spoilers,
|
|
200
|
+
});
|
|
161
201
|
return;
|
|
162
202
|
}
|
|
163
203
|
if (!process.stdout.isTTY) {
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAkB,MAAM,YAAY,CAAC;AACxE,OAAO,EAAE,GAAG,EAAsB,MAAM,aAAa,CAAC;AAEtD,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,MAAM,KAAK,GAAG;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/editor.d.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The edit buffer: lines, a caret, and undo.
|
|
3
|
+
*
|
|
4
|
+
* Nothing here touches a terminal. The viewer owns the keys and the drawing;
|
|
5
|
+
* this owns what the text is, which is the part worth testing — the same split
|
|
6
|
+
* `markdown.ts` makes between parsing and painting.
|
|
7
|
+
*
|
|
8
|
+
* Functions mutate the state they are given and return it. A buffer is a few
|
|
9
|
+
* thousand lines at most, but copying the array on every keystroke to look
|
|
10
|
+
* functional would buy nothing a snapshot in `undo` does not already give.
|
|
11
|
+
*/
|
|
12
|
+
/** What the last edit was, so a run of typing collapses into one undo step. */
|
|
13
|
+
export type EditKind = "none" | "insert" | "delete" | "newline" | "other";
|
|
14
|
+
export interface Snapshot {
|
|
15
|
+
lines: string[];
|
|
16
|
+
row: number;
|
|
17
|
+
col: number;
|
|
18
|
+
}
|
|
19
|
+
export interface Editor {
|
|
20
|
+
lines: string[];
|
|
21
|
+
row: number;
|
|
22
|
+
col: number;
|
|
23
|
+
/** Column to aim for on vertical motion, so crossing a short line keeps place. */
|
|
24
|
+
goal: number;
|
|
25
|
+
dirty: boolean;
|
|
26
|
+
undo: Snapshot[];
|
|
27
|
+
redo: Snapshot[];
|
|
28
|
+
last: EditKind;
|
|
29
|
+
}
|
|
30
|
+
export declare function createEditor(source: string): Editor;
|
|
31
|
+
/** The buffer as one string. Round-trips whatever `createEditor` was given. */
|
|
32
|
+
export declare function text(ed: Editor): string;
|
|
33
|
+
export declare function lineAt(ed: Editor, row: number): string;
|
|
34
|
+
/** Break the current undo run, so the next edit starts a new step. */
|
|
35
|
+
export declare function breakRun(ed: Editor): Editor;
|
|
36
|
+
export declare function undo(ed: Editor): Editor;
|
|
37
|
+
export declare function redo(ed: Editor): Editor;
|
|
38
|
+
export declare function moveLeft(ed: Editor): Editor;
|
|
39
|
+
export declare function moveRight(ed: Editor): Editor;
|
|
40
|
+
/** Vertical motion aims at `goal`, so a short line in the way is passed over. */
|
|
41
|
+
export declare function moveVertical(ed: Editor, delta: number): Editor;
|
|
42
|
+
export declare const moveUp: (ed: Editor) => Editor;
|
|
43
|
+
export declare const moveDown: (ed: Editor) => Editor;
|
|
44
|
+
/** Home, but to the first non-blank first — the second press goes to column 0. */
|
|
45
|
+
export declare function moveHome(ed: Editor): Editor;
|
|
46
|
+
export declare function moveEnd(ed: Editor): Editor;
|
|
47
|
+
export declare function moveDocStart(ed: Editor): Editor;
|
|
48
|
+
export declare function moveDocEnd(ed: Editor): Editor;
|
|
49
|
+
export declare function moveWordLeft(ed: Editor): Editor;
|
|
50
|
+
export declare function moveWordRight(ed: Editor): Editor;
|
|
51
|
+
/** Insert text at the caret. Newlines in it split lines, so paste works. */
|
|
52
|
+
export declare function insert(ed: Editor, str: string): Editor;
|
|
53
|
+
/**
|
|
54
|
+
* The prefix a new line should inherit: the indent, and the list marker when
|
|
55
|
+
* the caret is leaving one.
|
|
56
|
+
*
|
|
57
|
+
* Returns `null` for an item that has no content, which is the signal to clear
|
|
58
|
+
* it instead — pressing enter twice is how a list ends.
|
|
59
|
+
*/
|
|
60
|
+
export declare function continuation(line: string): {
|
|
61
|
+
prefix: string;
|
|
62
|
+
clear: boolean;
|
|
63
|
+
};
|
|
64
|
+
/** Split the line at the caret, carrying indentation and list markers over. */
|
|
65
|
+
export declare function newline(ed: Editor): Editor;
|
|
66
|
+
export declare function backspace(ed: Editor): Editor;
|
|
67
|
+
/** Delete forward. Joins the next line when the caret is at the end. */
|
|
68
|
+
export declare function del(ed: Editor): Editor;
|
|
69
|
+
/** Delete to the end of the line, or join the next when already there. */
|
|
70
|
+
export declare function killToLineEnd(ed: Editor): Editor;
|
|
71
|
+
/** Delete from the caret back to the start of the line's text. */
|
|
72
|
+
export declare function killToLineStart(ed: Editor): Editor;
|
|
73
|
+
/** Two spaces, the indent the renderer reads back as one list level. */
|
|
74
|
+
export declare function indent(ed: Editor): Editor;
|
|
75
|
+
/** Mark the buffer as matching what is on disk. */
|
|
76
|
+
export declare function markSaved(ed: Editor): Editor;
|
|
77
|
+
//# sourceMappingURL=editor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../src/editor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,+EAA+E;AAC/E,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;AAE1E,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB,IAAI,EAAE,QAAQ,CAAC;CAChB;AAOD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAWnD;AAED,+EAA+E;AAC/E,wBAAgB,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAEvC;AAED,wBAAgB,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEtD;AAoCD,sEAAsE;AACtE,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAG3C;AAED,wBAAgB,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAUvC;AAED,wBAAgB,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAUvC;AAID,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAQ3C;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAQ5C;AAED,iFAAiF;AACjF,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAK9D;AAED,eAAO,MAAM,MAAM,GAAI,IAAI,MAAM,KAAG,MAA8B,CAAC;AACnE,eAAO,MAAM,QAAQ,GAAI,IAAI,MAAM,KAAG,MAA6B,CAAC;AAEpE,kFAAkF;AAClF,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAK3C;AAED,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAI1C;AAED,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAK/C;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAK7C;AAID,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAS/C;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAShD;AAID,4EAA4E;AAC5E,wBAAgB,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAqBtD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAkB7E;AAED,+EAA+E;AAC/E,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAqB1C;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAkB5C;AAED,wEAAwE;AACxE,wBAAgB,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAUtC;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAMhD;AAED,kEAAkE;AAClE,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAMlD;AAED,wEAAwE;AACxE,wBAAgB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAEzC;AAED,mDAAmD;AACnD,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAI5C"}
|