jsmdcui 0.8.0 → 0.10.1
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/CHANGELOG.md +129 -0
- package/README.md +141 -1
- package/cdp-maze.js +141 -0
- package/demos/maze.md +6 -1
- package/llm-maze.txt +94 -0
- package/package.json +7 -5
- package/runmd.mjs +20 -11
- package/runtime/help/cdp.md +5 -0
- package/runtime/help/help.md +141 -1
- package/runtime/jsplugins/cdp/cdp-server.js +26 -2
- package/runtime/jsplugins/cdp/cdp.js +55 -49
- package/runtime/jsplugins/chapter/chapter.js +2 -1
- package/runtime/jsplugins/example/example.js +2 -0
- package/single-exe/README.md +268 -45
- package/single-exe/compiled.js +11 -6
- package/single-exe/entry.mjs +4 -3
- package/single-exe/packAssets.sh +1 -1
- package/src/cui/kitty-debug.mjs +1 -1
- package/src/index.js +208 -74
- package/src/lua/engine.js +1 -4
- package/src/plugins/js-bridge.js +43 -0
- package/tests/cat-markdown.test.js +59 -0
- package/tests/compiled-runtime.test.js +8 -0
- package/tests/demo.test.js +81 -2
- package/tests/kitty-demo.md +1 -1
- package/demo.resized.jpg +0 -0
- package/src/runtime/compiled.js +0 -25
package/runtime/help/help.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|

|
|
2
2
|
|
|
3
|
+
- Maze Game
|
|
4
|
+
* The TUI can be controlled through the Chrome DevTools Protocol (CDP). Codex successfully solved this maze using it.
|
|
5
|
+
|
|
6
|
+

|
|
7
|
+
|
|
3
8
|
# Demo App
|
|
4
9
|
## My app
|
|
5
10
|
|
|
@@ -36,7 +41,8 @@ npx jsmdcui@latest README.md
|
|
|
36
41
|
|
|
37
42
|
## Quick start
|
|
38
43
|
|
|
39
|
-
jsmdcui requires [Bun](https://bun.com).
|
|
44
|
+
jsmdcui requires [Bun ≥ 1.3.12](https://bun.com).
|
|
45
|
+
On Android, install it in Termux:
|
|
40
46
|
|
|
41
47
|
```sh
|
|
42
48
|
npm install -g bun
|
|
@@ -94,6 +100,13 @@ npx jsmdcui --demo-imgtool-zh
|
|
|
94
100
|
npx jsmdcui --demo-maze
|
|
95
101
|
```
|
|
96
102
|
|
|
103
|
+
To watch jsmdcui start the maze with a local CDP server and solve it
|
|
104
|
+
automatically after three seconds, run:
|
|
105
|
+
|
|
106
|
+
```sh
|
|
107
|
+
npx jsmdcui --cdp-maze
|
|
108
|
+
```
|
|
109
|
+
|
|
97
110
|
```sh
|
|
98
111
|
# WUI(Web User Interface) Demo
|
|
99
112
|
npx jsmdcui --wui
|
|
@@ -147,14 +160,19 @@ bun src/index.js --wui testapp.md
|
|
|
147
160
|
| `bun src/index.js --cat app.md` | Render the terminal version to stdout, write five generated files beside it, and exit. |
|
|
148
161
|
| `bun src/index.js --testapp.md` | Write the bundled `testapp.md` source to stdout and exit. |
|
|
149
162
|
| `bun src/index.js --export-readme` | Write or overwrite `./README.md` with the bundled README source and exit. |
|
|
163
|
+
| `bun src/index.js --export-cdp-maze` | Write or overwrite `./cdp-maze.js` with the bundled CDP maze solver and exit. |
|
|
150
164
|
| `bun src/index.js --demo-list` | List `testapp.md` and every bundled `demos/*.md` example with its command-line option, then exit. |
|
|
151
165
|
| `bun src/index.js --demo` | Use local `testapp.md` when present, otherwise write the bundled demo; open it in the terminal UI and write five generated files beside it. |
|
|
166
|
+
| `bun src/index.js --overwrite-demo --demo` | Replace an existing local `testapp.md` with the bundled copy before opening it. `--overwrite-demo` can modify any `--demo-*` option. |
|
|
152
167
|
| `bun src/index.js --demo-<filename>` | Load `demos/<filename>.md`; preserve an existing local copy or write the bundled copy, then open it and generate its five companion files. New files added under `demos/` work automatically. |
|
|
153
168
|
| `bun src/index.js --demo-imgtool` | Compatibility alias for `--demo-image-processor`. |
|
|
154
169
|
| `bun src/index.js --demo-imgtool-zh` | Compatibility alias for `--demo-image-processor.zh-TW`. |
|
|
170
|
+
| `bun src/index.js --cdp-maze` | Load the maze demo, start CDP on `127.0.0.1:9222`, and run the bundled solver after three seconds. |
|
|
155
171
|
| `bun src/index.js --allow-url URL.md` | Download HTTP(S) Markdown to the current directory and, with Kitty mode enabled, download its HTTP(S) images; write 5 generated files and allow embedded code to run. Only use trusted URLs. |
|
|
156
172
|
| `bun src/index.js --wui` | Use local `testapp.md` when present, otherwise write the bundled demo; write five generated files in the current directory, then print and serve a random URL. |
|
|
157
173
|
| `bun src/index.js --wui app.md` | Write five generated files beside `app.md`, then print and serve a random URL. |
|
|
174
|
+
| `bun src/index.js --wui --demo-<filename>` | Load the selected bundled demo and serve it as a Web UI. |
|
|
175
|
+
| `bun src/index.js --wui --print-ui app.md` | Also print the generated TUI, raw ANSI, and HTML before starting the WUI server. |
|
|
158
176
|
| `PORT=8080 bun src/index.js --wui app.md` | Start the browser UI on another port. |
|
|
159
177
|
| `bun src/index.js` | Open the normal terminal editor with an empty buffer. |
|
|
160
178
|
|
|
@@ -537,6 +555,10 @@ selection, search, and copy remain available.
|
|
|
537
555
|
| `Alt-G` | Show or hide the shortcut bar. |
|
|
538
556
|
| `Ctrl-Q` or `Alt-Q` | Close the current UI. |
|
|
539
557
|
|
|
558
|
+
To preview another color theme, press `Ctrl-E` or click on `€`, type `theme `, then use `Tab`
|
|
559
|
+
and the arrow keys to browse the available themes. Press `Enter` to switch to
|
|
560
|
+
the selected theme, or `Esc` to cancel and restore the previous one.
|
|
561
|
+
|
|
540
562
|
The terminal automatically reflows the Markdown when its width changes.
|
|
541
563
|
Only `javascript:` links execute in the TUI; ordinary web links behave as
|
|
542
564
|
normal links in the browser.
|
|
@@ -554,6 +576,63 @@ supported HTTP(S) images with Kitty graphics, combine the options:
|
|
|
554
576
|
bun src/index.js --kitty --allow-url https://example.com/app.md
|
|
555
577
|
```
|
|
556
578
|
|
|
579
|
+
### CDP control for TUI automation
|
|
580
|
+
|
|
581
|
+
The terminal UI can expose a Chrome DevTools Protocol (CDP) server, so another
|
|
582
|
+
Bun process can inspect the terminal buffer, click buffer coordinates, and send
|
|
583
|
+
real keyboard events to the running TUI.
|
|
584
|
+
|
|
585
|
+
Start CDP from the command line when launching jsmdcui:
|
|
586
|
+
|
|
587
|
+
```sh
|
|
588
|
+
bun src/index.js --remote-debugging-port=9222 demos/maze.md
|
|
589
|
+
bun src/index.js --remote-debugging-port=9222 --remote-debugging-address=127.0.0.1 demos/maze.md
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
Or start it from inside the TUI editor command prompt(Ctrl-E or €):
|
|
593
|
+
|
|
594
|
+
```text
|
|
595
|
+
Ctrl-E cdp
|
|
596
|
+
Ctrl-E cdp 9000
|
|
597
|
+
Ctrl-E cdp --address=127.0.0.1
|
|
598
|
+
Ctrl-E cdp 9000 --public
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
The default bind address is `127.0.0.1` and the default port is `9222`.
|
|
602
|
+
Use `--public` or `--address=0.0.0.0` only on a trusted network.
|
|
603
|
+
|
|
604
|
+
Once CDP is running, control the TUI with `Bun.WebView`. For more info, enter
|
|
605
|
+
jsmdcui and use `Ctrl-E` or `€` → `help cdp`.
|
|
606
|
+
|
|
607
|
+
The cli flag `--cdp-maze` is a combination of
|
|
608
|
+
1. Start the demos/maze.md
|
|
609
|
+
2. Start a local CDP server
|
|
610
|
+
3. Wait three seconds
|
|
611
|
+
4. Run the solver cdp-maze.js automatically
|
|
612
|
+
|
|
613
|
+
The solver was
|
|
614
|
+
generated from the `llm-maze.txt` instructions; it focuses the maze controls,
|
|
615
|
+
resets the game, reads the maze from the TUI, solves it with breadth-first
|
|
616
|
+
search, and sends arrow-key input until the maze is escaped:
|
|
617
|
+
|
|
618
|
+
```sh
|
|
619
|
+
npx jsmdcui@latest --cdp-maze
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
From the source tree, run:
|
|
623
|
+
|
|
624
|
+
```sh
|
|
625
|
+
bun src/index.js --cdp-maze
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
Useful automation methods used by `cdp-maze.js`:
|
|
629
|
+
|
|
630
|
+
- `view.evaluate(js)`
|
|
631
|
+
- `view.evaluate("micro.getAllText()")`
|
|
632
|
+
- `view.evaluate("micro.getAllAnsiText()")`
|
|
633
|
+
- `view.click(column, line)`
|
|
634
|
+
- `view.press(key, options)`
|
|
635
|
+
|
|
557
636
|
## Browser interaction
|
|
558
637
|
|
|
559
638
|
The WUI uses normal browser mouse and keyboard behavior. Clicking a
|
|
@@ -666,6 +745,67 @@ or serve Markdown UI files that you trust.
|
|
|
666
745
|
calls, but it does not protect the backend module from trusted local code and
|
|
667
746
|
is not a substitute for authentication.
|
|
668
747
|
|
|
748
|
+
## Distribution
|
|
749
|
+
|
|
750
|
+
### Text editor distribution
|
|
751
|
+
|
|
752
|
+
Distributions intended primarily as text editors can include an empty
|
|
753
|
+
`src/MDCUI_DEFAULT_EDIT` file. When this marker exists, opening a `.md` file uses the
|
|
754
|
+
normal editable UTF-8 view instead of automatically entering `mdcui` mode.
|
|
755
|
+
Markdown UI support remains available explicitly with `--mdcui` or `--tui`;
|
|
756
|
+
both are equivalent to `-encoding mdcui`.
|
|
757
|
+
|
|
758
|
+
### Build-time distribution constants
|
|
759
|
+
|
|
760
|
+
Single-file distributions can define one of these default modes:
|
|
761
|
+
|
|
762
|
+
- `MDCUI_DEFAULT_EDIT`: open files as editable text by default.
|
|
763
|
+
- `MDCUI_DEFAULT_DEMO`: add `--demo` when launched without arguments.
|
|
764
|
+
- `MDCUI_DEFAULT_DEMO_WUI`: add `--wui` when launched without arguments.
|
|
765
|
+
|
|
766
|
+
Choose only one of the three default-mode constants for a distribution.
|
|
767
|
+
`MDCUI_OVERWRITE_DEMO` is an optional modifier for the demo or WUI mode.
|
|
768
|
+
These are presence-based constants, so their build values do not require
|
|
769
|
+
shell-quoted strings:
|
|
770
|
+
|
|
771
|
+
```sh
|
|
772
|
+
bun src/index.js --build-exe --define MDCUI_DEFAULT_EDIT=true
|
|
773
|
+
```
|
|
774
|
+
|
|
775
|
+
### Ship `testapp.md` as a standalone application
|
|
776
|
+
|
|
777
|
+
To turn your finished Markdown UI into a standalone executable, save it as the
|
|
778
|
+
repository-root `testapp.md`, then build with both demo constants:
|
|
779
|
+
|
|
780
|
+
```sh
|
|
781
|
+
bun src/index.js --build-exe \
|
|
782
|
+
--define MDCUI_DEFAULT_DEMO=true \
|
|
783
|
+
--define MDCUI_OVERWRITE_DEMO=true
|
|
784
|
+
```
|
|
785
|
+
|
|
786
|
+
The build first packs `testapp.md` into the executable and writes the resulting
|
|
787
|
+
`mdcui` binary in the current directory. In that binary,
|
|
788
|
+
`MDCUI_DEFAULT_DEMO` adds `--demo` when the user launches it without arguments,
|
|
789
|
+
and `MDCUI_OVERWRITE_DEMO` adds `--overwrite-demo`. Consequently, running
|
|
790
|
+
`./mdcui` writes the bundled application to `./testapp.md`, replacing an older
|
|
791
|
+
copy, and starts it as the terminal UI.
|
|
792
|
+
|
|
793
|
+
To make a no-argument launch start the browser UI instead, build with
|
|
794
|
+
`MDCUI_DEFAULT_DEMO_WUI`:
|
|
795
|
+
|
|
796
|
+
```sh
|
|
797
|
+
bun src/index.js --build-exe \
|
|
798
|
+
--define MDCUI_DEFAULT_DEMO_WUI=true \
|
|
799
|
+
--define MDCUI_OVERWRITE_DEMO=true
|
|
800
|
+
```
|
|
801
|
+
|
|
802
|
+
This adds `--wui` when the executable is launched without arguments.
|
|
803
|
+
|
|
804
|
+
You can rename and distribute the resulting binary. It contains the Bun
|
|
805
|
+
runtime, jsmdcui, the packed runtime assets, and your `testapp.md`; the target
|
|
806
|
+
directory must remain writable because launching the application creates
|
|
807
|
+
`testapp.md` and its generated companion files there.
|
|
808
|
+
|
|
669
809
|
## Development
|
|
670
810
|
|
|
671
811
|
```sh
|
|
@@ -554,8 +554,30 @@ async function dispatch(ctx, state, method, params, sessionId, emit) {
|
|
|
554
554
|
return {};
|
|
555
555
|
}
|
|
556
556
|
case "Input.dispatchKeyEvent": {
|
|
557
|
-
|
|
558
|
-
|
|
557
|
+
const target = getSessionTarget(state, sessionId);
|
|
558
|
+
const key = params.key ?? params.text ?? "";
|
|
559
|
+
const signature = `${params.code ?? key}:${params.modifiers ?? 0}`;
|
|
560
|
+
if (params.type === "rawKeyDown" || params.type === "keyDown") {
|
|
561
|
+
if (target.cdpKeyDown !== signature || params.autoRepeat) {
|
|
562
|
+
await ctx.press?.(key, {
|
|
563
|
+
modifiers: params.modifiers ?? 0,
|
|
564
|
+
text: params.text ?? "",
|
|
565
|
+
code: params.code ?? "",
|
|
566
|
+
repeat: !!params.autoRepeat,
|
|
567
|
+
});
|
|
568
|
+
target.cdpKeyDown = signature;
|
|
569
|
+
}
|
|
570
|
+
} else if (params.type === "char") {
|
|
571
|
+
if (!target.cdpKeyDown) {
|
|
572
|
+
await ctx.press?.(key, {
|
|
573
|
+
modifiers: params.modifiers ?? 0,
|
|
574
|
+
text: params.text ?? "",
|
|
575
|
+
code: params.code ?? "",
|
|
576
|
+
repeat: !!params.autoRepeat,
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
} else if (params.type === "keyUp") {
|
|
580
|
+
target.cdpKeyDown = null;
|
|
559
581
|
}
|
|
560
582
|
return {};
|
|
561
583
|
}
|
|
@@ -695,6 +717,8 @@ function navigateTarget(state, target, url, emit, options = {}) {
|
|
|
695
717
|
}
|
|
696
718
|
|
|
697
719
|
function getSessionTarget(state, sessionId) {
|
|
720
|
+
if (!sessionId) return getImplicitTarget(state);
|
|
721
|
+
|
|
698
722
|
const targetId = state.sessions.get(sessionId);
|
|
699
723
|
const target = state.targets.get(targetId);
|
|
700
724
|
if (!target) throw new Error(`No target for session: ${sessionId}`);
|
|
@@ -34,6 +34,8 @@ Flat buffer helpers (all 1-based line numbers, omit → cursor line):
|
|
|
34
34
|
micro.getLine(n?) micro.putLine(text, n?) micro.delLine(n?)
|
|
35
35
|
micro.getLines(from?, to?) micro.getLinesCount()
|
|
36
36
|
micro.getAllText() — entire buffer as one string (lines joined by "\n")
|
|
37
|
+
micro.getAllAnsiText() — rendered ANSI document, or plain text when unavailable
|
|
38
|
+
micro.clickBufferCell(x, y) — activate a 1-based MDCUI cell, or goto in other buffers
|
|
37
39
|
micro.putAllText(text) — replace entire buffer content; pushes undo
|
|
38
40
|
micro.getSelection() micro.putSelection(text)
|
|
39
41
|
|
|
@@ -82,7 +84,7 @@ micro.on("init", () => {
|
|
|
82
84
|
},
|
|
83
85
|
async click(x,y,opt){
|
|
84
86
|
x=x||1 ; y=y||1 ;
|
|
85
|
-
await micro.
|
|
87
|
+
await micro.clickBufferCell(x, y);
|
|
86
88
|
},
|
|
87
89
|
async scroll(dx,dy){
|
|
88
90
|
const pane = micro.CurPane();
|
|
@@ -111,54 +113,8 @@ micro.on("init", () => {
|
|
|
111
113
|
bp.Insert(text);
|
|
112
114
|
},
|
|
113
115
|
async press(key, options){
|
|
114
|
-
const
|
|
115
|
-
if (
|
|
116
|
-
|
|
117
|
-
// modifiers bitmask: Alt=1, Ctrl=2, Meta=4, Shift=8
|
|
118
|
-
const mod = options?.modifiers ?? 0;
|
|
119
|
-
const ctrl = !!(mod & 2);
|
|
120
|
-
const shift = !!(mod & 8);
|
|
121
|
-
|
|
122
|
-
if (ctrl) {
|
|
123
|
-
const ctrlMap = {
|
|
124
|
-
a: () => micro.action.SelectAll(),
|
|
125
|
-
c: () => micro.action.Copy(),
|
|
126
|
-
x: () => micro.action.Cut(),
|
|
127
|
-
v: () => micro.action.Paste(),
|
|
128
|
-
z: () => micro.action.Undo(),
|
|
129
|
-
y: () => micro.action.Redo(),
|
|
130
|
-
s: () => micro.action.Save(),
|
|
131
|
-
};
|
|
132
|
-
const h = ctrlMap[key.toLowerCase()];
|
|
133
|
-
if (h) await h();
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const arrowAction = shift
|
|
138
|
-
? { ArrowUp: 'SelectUp', ArrowDown: 'SelectDown', ArrowLeft: 'SelectLeft', ArrowRight: 'SelectRight' }
|
|
139
|
-
: { ArrowUp: 'CursorUp', ArrowDown: 'CursorDown', ArrowLeft: 'CursorLeft', ArrowRight: 'CursorRight' };
|
|
140
|
-
|
|
141
|
-
const keyMap = {
|
|
142
|
-
...arrowAction,
|
|
143
|
-
Enter: () => micro.action.InsertNewline(),
|
|
144
|
-
Backspace: () => micro.action.Backspace(),
|
|
145
|
-
Delete: () => micro.action.Delete(),
|
|
146
|
-
Tab: () => micro.action.InsertTab(),
|
|
147
|
-
Escape: () => micro.action.Escape(),
|
|
148
|
-
Home: () => shift ? micro.action.SelectToStartOfLine() : micro.action.StartOfLine(),
|
|
149
|
-
End: () => shift ? micro.action.SelectToEndOfLine() : micro.action.EndOfLine(),
|
|
150
|
-
PageUp: () => shift ? micro.action.SelectPageUp() : micro.action.CursorPageUp(),
|
|
151
|
-
PageDown: () => shift ? micro.action.SelectPageDown() : micro.action.CursorPageDown(),
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
const entry = keyMap[key];
|
|
155
|
-
if (typeof entry === 'string') {
|
|
156
|
-
await micro.action[entry]();
|
|
157
|
-
} else if (typeof entry === 'function') {
|
|
158
|
-
await entry();
|
|
159
|
-
} else if (key.length === 1) {
|
|
160
|
-
bp.Insert(key);
|
|
161
|
-
}
|
|
116
|
+
const raw = cdpKeyToTerminalInput(key, options);
|
|
117
|
+
if (raw) await micro._dispatchRawInput(raw);
|
|
162
118
|
},
|
|
163
119
|
}
|
|
164
120
|
|
|
@@ -193,3 +149,53 @@ function toInteger(value) {
|
|
|
193
149
|
const number = Number(value);
|
|
194
150
|
return Number.isFinite(number) ? Math.trunc(number) : 0;
|
|
195
151
|
}
|
|
152
|
+
|
|
153
|
+
function cdpKeyToTerminalInput(key, options = {}) {
|
|
154
|
+
const modifiers = Number(options.modifiers) || 0;
|
|
155
|
+
const alt = !!(modifiers & 1);
|
|
156
|
+
const ctrl = !!(modifiers & 2);
|
|
157
|
+
const meta = !!(modifiers & 4);
|
|
158
|
+
const shift = !!(modifiers & 8);
|
|
159
|
+
const modifierCode = 1 + (shift ? 1 : 0) + (alt || meta ? 2 : 0) + (ctrl ? 4 : 0);
|
|
160
|
+
const value = String(key ?? options.text ?? "");
|
|
161
|
+
|
|
162
|
+
const cursorFinal = {
|
|
163
|
+
ArrowUp: "A",
|
|
164
|
+
ArrowDown: "B",
|
|
165
|
+
ArrowRight: "C",
|
|
166
|
+
ArrowLeft: "D",
|
|
167
|
+
Home: "H",
|
|
168
|
+
End: "F",
|
|
169
|
+
}[value];
|
|
170
|
+
if (cursorFinal) {
|
|
171
|
+
return modifierCode === 1
|
|
172
|
+
? `\x1b[${cursorFinal}`
|
|
173
|
+
: `\x1b[1;${modifierCode}${cursorFinal}`;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (value === "PageUp" || value === "PageDown" || value === "Delete") {
|
|
177
|
+
const number = value === "PageUp" ? 5 : value === "PageDown" ? 6 : 3;
|
|
178
|
+
return modifierCode === 1
|
|
179
|
+
? `\x1b[${number}~`
|
|
180
|
+
: `\x1b[${number};${modifierCode}~`;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (value === "Tab") return shift ? "\x1b[Z" : "\t";
|
|
184
|
+
if (value === "Enter") return alt || meta ? "\x1b\r" : "\r";
|
|
185
|
+
if (value === "Backspace") return "\x7f";
|
|
186
|
+
if (value === "Escape") return "\x1b";
|
|
187
|
+
|
|
188
|
+
let text = typeof options.text === "string" && options.text
|
|
189
|
+
? options.text
|
|
190
|
+
: value === "Space" ? " " : value;
|
|
191
|
+
if ([...text].length !== 1) return "";
|
|
192
|
+
|
|
193
|
+
if (ctrl) {
|
|
194
|
+
const code = text.toUpperCase().charCodeAt(0);
|
|
195
|
+
if (code >= 64 && code <= 95) text = String.fromCharCode(code & 31);
|
|
196
|
+
} else if (shift && /^[a-z]$/.test(text)) {
|
|
197
|
+
text = text.toUpperCase();
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return alt || meta ? `\x1b${text}` : text;
|
|
201
|
+
}
|
|
@@ -35,6 +35,8 @@ Flat buffer helpers (all 1-based line numbers, omit → cursor line):
|
|
|
35
35
|
micro.getLine(n?) micro.putLine(text, n?) micro.delLine(n?)
|
|
36
36
|
micro.getLines(from?, to?) micro.getLinesCount()
|
|
37
37
|
micro.getAllText() — entire buffer as one string (lines joined by "\n")
|
|
38
|
+
micro.getAllAnsiText() — rendered ANSI document, or plain text when unavailable
|
|
39
|
+
micro.clickBufferCell(x, y) — activate a 1-based MDCUI cell, or goto in other buffers
|
|
38
40
|
micro.putAllText(text) — replace entire buffer content; pushes undo
|
|
39
41
|
micro.getSelection() micro.putSelection(text)
|
|
40
42
|
|
|
@@ -107,4 +109,3 @@ micro.on("init", () => {
|
|
|
107
109
|
});
|
|
108
110
|
|
|
109
111
|
});
|
|
110
|
-
|
|
@@ -35,6 +35,8 @@ Flat buffer helpers (all 1-based line numbers, omit → cursor line):
|
|
|
35
35
|
micro.getLine(n?) micro.putLine(text, n?) micro.delLine(n?)
|
|
36
36
|
micro.getLines(from?, to?) micro.getLinesCount()
|
|
37
37
|
micro.getAllText() — entire buffer as one string (lines joined by "\n")
|
|
38
|
+
micro.getAllAnsiText() — rendered ANSI document, or plain text when unavailable
|
|
39
|
+
micro.clickBufferCell(x, y) — activate a 1-based MDCUI cell, or goto in other buffers
|
|
38
40
|
micro.putAllText(text) — replace entire buffer content; pushes undo
|
|
39
41
|
micro.getSelection() micro.putSelection(text)
|
|
40
42
|
|