restty 0.1.25 → 0.1.26
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 +70 -1
- package/dist/{chunk-pab3ge3d.js → chunk-y290zh3e.js} +59 -32
- package/dist/internal.js +1 -1
- package/dist/restty.js +1 -1
- package/dist/runtime/create-runtime.d.ts +1 -1
- package/dist/xterm.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -173,10 +173,23 @@ const metricsPlugin: ResttyPlugin = {
|
|
|
173
173
|
const lifecycle = ctx.addLifecycleHook(({ phase, action }) => {
|
|
174
174
|
console.log("lifecycle", phase, action);
|
|
175
175
|
});
|
|
176
|
+
const stage = ctx.addRenderStage({
|
|
177
|
+
id: "metrics/tint",
|
|
178
|
+
mode: "after-main",
|
|
179
|
+
uniforms: [0.12],
|
|
180
|
+
shader: {
|
|
181
|
+
wgsl: `
|
|
182
|
+
fn resttyStage(color: vec4f, uv: vec2f, time: f32, params0: vec4f, params1: vec4f) -> vec4f {
|
|
183
|
+
return vec4f(min(vec3f(1.0), color.rgb + vec3f(params0.x, 0.0, 0.0)), color.a);
|
|
184
|
+
}
|
|
185
|
+
`,
|
|
186
|
+
},
|
|
187
|
+
});
|
|
176
188
|
return () => {
|
|
177
189
|
paneCreated.dispose();
|
|
178
190
|
outgoing.dispose();
|
|
179
191
|
lifecycle.dispose();
|
|
192
|
+
stage.dispose();
|
|
180
193
|
};
|
|
181
194
|
},
|
|
182
195
|
};
|
|
@@ -199,6 +212,50 @@ await restty.loadPlugins(
|
|
|
199
212
|
|
|
200
213
|
See `docs/plugins.md` for full plugin authoring details.
|
|
201
214
|
|
|
215
|
+
### Shader stages
|
|
216
|
+
|
|
217
|
+
Shader stages let you extend the final frame pipeline with WGSL/GLSL passes.
|
|
218
|
+
|
|
219
|
+
Global stages:
|
|
220
|
+
|
|
221
|
+
```ts
|
|
222
|
+
restty.setShaderStages([
|
|
223
|
+
{
|
|
224
|
+
id: "app/crt-lite",
|
|
225
|
+
mode: "after-main",
|
|
226
|
+
backend: "both",
|
|
227
|
+
uniforms: [0.24, 0.12],
|
|
228
|
+
shader: {
|
|
229
|
+
wgsl: `
|
|
230
|
+
fn resttyStage(color: vec4f, uv: vec2f, time: f32, params0: vec4f, params1: vec4f) -> vec4f {
|
|
231
|
+
let v = clamp(params0.x, 0.0, 0.8);
|
|
232
|
+
let centered = (uv - vec2f(0.5, 0.5)) * 2.0;
|
|
233
|
+
let vignette = max(0.0, 1.0 - v * dot(centered, centered));
|
|
234
|
+
return vec4f(color.rgb * vignette, color.a);
|
|
235
|
+
}
|
|
236
|
+
`,
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
]);
|
|
240
|
+
|
|
241
|
+
const stage = restty.addShaderStage({
|
|
242
|
+
id: "app/mono",
|
|
243
|
+
mode: "after-main",
|
|
244
|
+
uniforms: [1.0],
|
|
245
|
+
shader: {
|
|
246
|
+
wgsl: `
|
|
247
|
+
fn resttyStage(color: vec4f, uv: vec2f, time: f32, params0: vec4f, params1: vec4f) -> vec4f {
|
|
248
|
+
let l = dot(color.rgb, vec3f(0.2126, 0.7152, 0.0722));
|
|
249
|
+
return vec4f(l * 0.12, l * 0.95, l * 0.35, color.a);
|
|
250
|
+
}
|
|
251
|
+
`,
|
|
252
|
+
},
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
stage.setEnabled(false);
|
|
256
|
+
restty.removeShaderStage("app/mono");
|
|
257
|
+
```
|
|
258
|
+
|
|
202
259
|
### xterm compatibility layer
|
|
203
260
|
|
|
204
261
|
For migration from xterm.js-style app code, use `restty/xterm`:
|
|
@@ -260,7 +317,12 @@ Active-pane convenience:
|
|
|
260
317
|
Plugin host:
|
|
261
318
|
|
|
262
319
|
- `use(plugin, options?)` / `loadPlugins(manifest, registry)` / `unuse(pluginId)` / `plugins()` / `pluginInfo(pluginId?)`
|
|
263
|
-
- plugin context supports `on(...)`, `addInputInterceptor(...)`, `addOutputInterceptor(...)`, `addLifecycleHook(...)`, `addRenderHook(...)`
|
|
320
|
+
- plugin context supports `on(...)`, `addInputInterceptor(...)`, `addOutputInterceptor(...)`, `addLifecycleHook(...)`, `addRenderHook(...)`, `addRenderStage(...)`
|
|
321
|
+
|
|
322
|
+
Shader stages:
|
|
323
|
+
|
|
324
|
+
- `setShaderStages(stages)` / `getShaderStages()`
|
|
325
|
+
- `addShaderStage(stage)` / `removeShaderStage(id)`
|
|
264
326
|
|
|
265
327
|
## Advanced / Internal Modules
|
|
266
328
|
|
|
@@ -281,6 +343,13 @@ bun run playground
|
|
|
281
343
|
|
|
282
344
|
Open `http://localhost:5173`.
|
|
283
345
|
|
|
346
|
+
## Code Layout
|
|
347
|
+
|
|
348
|
+
- `src/surface/`: public API (`Restty`), pane manager orchestration, plugin host, xterm shim.
|
|
349
|
+
- `src/runtime/`: terminal runtime/render loop implementation.
|
|
350
|
+
- `src/renderer/`, `src/input/`, `src/pty/`, `src/fonts/`, `src/theme/`, `src/wasm/`, `src/selection/`: subsystem modules.
|
|
351
|
+
- `src/app/`: compatibility re-export layer while internals are refactored.
|
|
352
|
+
|
|
284
353
|
## Repository Commands
|
|
285
354
|
|
|
286
355
|
```bash
|
|
@@ -7922,12 +7922,14 @@ function encodeBeforeInputEvent(event) {
|
|
|
7922
7922
|
const type = event.inputType;
|
|
7923
7923
|
if (type === "insertText")
|
|
7924
7924
|
return event.data || "";
|
|
7925
|
-
if (type === "insertLineBreak")
|
|
7925
|
+
if (type === "insertLineBreak" || type === "insertParagraph")
|
|
7926
7926
|
return sequences.enter;
|
|
7927
|
-
if (type === "deleteContentBackward")
|
|
7927
|
+
if (type === "deleteContentBackward" || type === "deleteWordBackward" || type === "deleteSoftLineBackward" || type === "deleteHardLineBackward" || type === "deleteEntireSoftLine") {
|
|
7928
7928
|
return sequences.backspace;
|
|
7929
|
-
|
|
7929
|
+
}
|
|
7930
|
+
if (type === "deleteContentForward" || type === "deleteWordForward" || type === "deleteSoftLineForward" || type === "deleteHardLineForward") {
|
|
7930
7931
|
return sequences.delete;
|
|
7932
|
+
}
|
|
7931
7933
|
if (type === "insertFromPaste") {
|
|
7932
7934
|
return event.dataTransfer?.getData("text/plain") || "";
|
|
7933
7935
|
}
|
|
@@ -8303,10 +8305,20 @@ function encodeKittyKeyEvent(event, kittyFlags) {
|
|
|
8303
8305
|
}
|
|
8304
8306
|
|
|
8305
8307
|
// src/input/keymap/pty-map.ts
|
|
8308
|
+
function parseKittyEventType(body) {
|
|
8309
|
+
const [, modifiersPart = ""] = body.split(";");
|
|
8310
|
+
if (!modifiersPart)
|
|
8311
|
+
return 0;
|
|
8312
|
+
const [, eventTypePart = ""] = modifiersPart.split(":");
|
|
8313
|
+
const parsed = Number(eventTypePart);
|
|
8314
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
8315
|
+
}
|
|
8306
8316
|
function mapKeySequenceForPty(seq) {
|
|
8307
8317
|
const csi = "\x1B[";
|
|
8308
8318
|
if (seq.startsWith(csi) && seq.endsWith("u")) {
|
|
8309
8319
|
const body = seq.slice(csi.length, -1);
|
|
8320
|
+
if (parseKittyEventType(body) === 3)
|
|
8321
|
+
return seq;
|
|
8310
8322
|
const [codeText] = body.split(";");
|
|
8311
8323
|
if (codeText && /^[0-9]+$/.test(codeText)) {
|
|
8312
8324
|
const code = Number(codeText);
|
|
@@ -8320,6 +8332,8 @@ function mapKeySequenceForPty(seq) {
|
|
|
8320
8332
|
}
|
|
8321
8333
|
if (seq.startsWith(csi) && seq.endsWith("~")) {
|
|
8322
8334
|
const body = seq.slice(csi.length, -1);
|
|
8335
|
+
if (parseKittyEventType(body) === 3)
|
|
8336
|
+
return seq;
|
|
8323
8337
|
if (body === "3" || body.startsWith("3;"))
|
|
8324
8338
|
return "\x1B[3~";
|
|
8325
8339
|
}
|
|
@@ -52765,24 +52779,7 @@ function createDumpGlyphRender(options) {
|
|
|
52765
52779
|
});
|
|
52766
52780
|
const uniforms = new Float32Array([outW, outH, 0, 0, 0, 0, 0, 0]);
|
|
52767
52781
|
state2.device.queue.writeBuffer(uniformBuffer, 0, uniforms);
|
|
52768
|
-
const instance = new Float32Array([
|
|
52769
|
-
0,
|
|
52770
|
-
0,
|
|
52771
|
-
outW,
|
|
52772
|
-
outH,
|
|
52773
|
-
u02,
|
|
52774
|
-
v02,
|
|
52775
|
-
u12,
|
|
52776
|
-
v12,
|
|
52777
|
-
1,
|
|
52778
|
-
1,
|
|
52779
|
-
1,
|
|
52780
|
-
1,
|
|
52781
|
-
0,
|
|
52782
|
-
0,
|
|
52783
|
-
0,
|
|
52784
|
-
1
|
|
52785
|
-
]);
|
|
52782
|
+
const instance = new Float32Array([0, 0, outW, outH, u02, v02, u12, v12, 1, 1, 1, 1, 0, 0, 0, 1]);
|
|
52786
52783
|
const instanceBuffer = state2.device.createBuffer({
|
|
52787
52784
|
size: instance.byteLength,
|
|
52788
52785
|
usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
|
|
@@ -52889,7 +52886,10 @@ function createSetupDebugExpose(options, diagnoseCodepoint) {
|
|
|
52889
52886
|
debugWindow.dumpAtlasRegion = createDumpAtlasRegion(options);
|
|
52890
52887
|
debugWindow.dumpGlyphRender = createDumpGlyphRender(options);
|
|
52891
52888
|
};
|
|
52892
|
-
function createDumpGlyphMetrics({
|
|
52889
|
+
function createDumpGlyphMetrics({
|
|
52890
|
+
pickFontIndexForText: pickFontIndexForText2,
|
|
52891
|
+
fontState
|
|
52892
|
+
}) {
|
|
52893
52893
|
return (cp) => {
|
|
52894
52894
|
const text2 = String.fromCodePoint(cp);
|
|
52895
52895
|
const fontIndex = pickFontIndexForText2(text2, 1);
|
|
@@ -52937,9 +52937,7 @@ function createSetupDebugExpose(options, diagnoseCodepoint) {
|
|
|
52937
52937
|
return { fontIndex, glyphId };
|
|
52938
52938
|
};
|
|
52939
52939
|
}
|
|
52940
|
-
function createDumpAtlasRegion({
|
|
52941
|
-
getActiveState
|
|
52942
|
-
}) {
|
|
52940
|
+
function createDumpAtlasRegion({ getActiveState }) {
|
|
52943
52941
|
return async (fontIndex, x3, y, width, height) => {
|
|
52944
52942
|
const state2 = getActiveState();
|
|
52945
52943
|
if (!state2 || !("device" in state2)) {
|
|
@@ -52951,7 +52949,10 @@ function createSetupDebugExpose(options, diagnoseCodepoint) {
|
|
|
52951
52949
|
console.warn("atlas not ready");
|
|
52952
52950
|
return null;
|
|
52953
52951
|
}
|
|
52954
|
-
const image = await readTextureToImageData(state2.device, atlasState.texture, width, height, {
|
|
52952
|
+
const image = await readTextureToImageData(state2.device, atlasState.texture, width, height, {
|
|
52953
|
+
x: x3,
|
|
52954
|
+
y
|
|
52955
|
+
});
|
|
52955
52956
|
const canvas = document.createElement("canvas");
|
|
52956
52957
|
canvas.width = width;
|
|
52957
52958
|
canvas.height = height;
|
|
@@ -53222,6 +53223,21 @@ function bindImeEvents(options) {
|
|
|
53222
53223
|
keydownBeforeinputDedupeMs
|
|
53223
53224
|
} = bindOptions;
|
|
53224
53225
|
let suppressNextInput = false;
|
|
53226
|
+
let lastNormalizedKeydownSeq = "";
|
|
53227
|
+
let lastNormalizedKeydownSeqSource = "";
|
|
53228
|
+
const getNormalizedLastKeydownSeq = () => {
|
|
53229
|
+
const source = getLastKeydownSeq();
|
|
53230
|
+
if (!source) {
|
|
53231
|
+
lastNormalizedKeydownSeqSource = "";
|
|
53232
|
+
lastNormalizedKeydownSeq = "";
|
|
53233
|
+
return "";
|
|
53234
|
+
}
|
|
53235
|
+
if (source === lastNormalizedKeydownSeqSource)
|
|
53236
|
+
return lastNormalizedKeydownSeq;
|
|
53237
|
+
lastNormalizedKeydownSeqSource = source;
|
|
53238
|
+
lastNormalizedKeydownSeq = inputHandler.mapKeyForPty(source);
|
|
53239
|
+
return lastNormalizedKeydownSeq;
|
|
53240
|
+
};
|
|
53225
53241
|
const onCompositionStart = (event) => {
|
|
53226
53242
|
imeState.composing = true;
|
|
53227
53243
|
setPreedit2(event.data || imeInput.value || "");
|
|
@@ -53263,8 +53279,10 @@ function bindImeEvents(options) {
|
|
|
53263
53279
|
}
|
|
53264
53280
|
const text2 = inputHandler.encodeBeforeInput(event);
|
|
53265
53281
|
if (text2) {
|
|
53282
|
+
const normalizedText = inputHandler.mapKeyForPty(text2);
|
|
53283
|
+
const normalizedLastKeydownSeq = getNormalizedLastKeydownSeq();
|
|
53266
53284
|
const now = performance.now();
|
|
53267
|
-
if (
|
|
53285
|
+
if (normalizedLastKeydownSeq && normalizedText === normalizedLastKeydownSeq && now - getLastKeydownSeqAt() <= keydownBeforeinputDedupeMs) {
|
|
53268
53286
|
event.preventDefault();
|
|
53269
53287
|
suppressNextInput = true;
|
|
53270
53288
|
imeInput.value = "";
|
|
@@ -57883,10 +57901,7 @@ function createFontRuntimeTextHelpers(options) {
|
|
|
57883
57901
|
(entry) => hasBoldHint(entry) && hasItalicHint(entry),
|
|
57884
57902
|
(entry) => hasBoldHint(entry),
|
|
57885
57903
|
(entry) => hasItalicHint(entry)
|
|
57886
|
-
] : stylePreference === "bold" ? [
|
|
57887
|
-
(entry) => hasBoldHint(entry) && !hasItalicHint(entry),
|
|
57888
|
-
(entry) => hasBoldHint(entry)
|
|
57889
|
-
] : stylePreference === "italic" ? [
|
|
57904
|
+
] : stylePreference === "bold" ? [(entry) => hasBoldHint(entry) && !hasItalicHint(entry), (entry) => hasBoldHint(entry)] : stylePreference === "italic" ? [
|
|
57890
57905
|
(entry) => hasItalicHint(entry) && !hasBoldHint(entry),
|
|
57891
57906
|
(entry) => hasItalicHint(entry)
|
|
57892
57907
|
] : [];
|
|
@@ -59845,7 +59860,19 @@ function createResttyApp(options) {
|
|
|
59845
59860
|
lastRenderState = value;
|
|
59846
59861
|
}
|
|
59847
59862
|
});
|
|
59848
|
-
const readRuntimeAppApiState = () => ({
|
|
59863
|
+
const readRuntimeAppApiState = () => ({
|
|
59864
|
+
wasm,
|
|
59865
|
+
wasmExports,
|
|
59866
|
+
wasmHandle,
|
|
59867
|
+
wasmReady,
|
|
59868
|
+
activeState,
|
|
59869
|
+
needsRender,
|
|
59870
|
+
lastRenderTime,
|
|
59871
|
+
currentContextType,
|
|
59872
|
+
isFocused,
|
|
59873
|
+
lastKeydownSeq,
|
|
59874
|
+
lastKeydownSeqAt
|
|
59875
|
+
});
|
|
59849
59876
|
const writeRuntimeAppApiState = (patch) => {
|
|
59850
59877
|
({
|
|
59851
59878
|
wasm = wasm,
|
package/dist/internal.js
CHANGED
package/dist/restty.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ResttyApp, ResttyAppOptions } from "./types";
|
|
2
2
|
export { createResttyAppSession, getDefaultResttyAppSession } from "./session";
|
|
3
|
-
export { createResttyPaneManager
|
|
3
|
+
export { createResttyPaneManager } from "../surface/panes/manager";
|
|
4
4
|
export { createDefaultResttyPaneContextMenuItems, getResttyShortcutModifierLabel, } from "../surface/panes/default-context-menu-items";
|
|
5
5
|
export type { ResttyAppElements, ResttyAppCallbacks, FontSource, ResttyFontSource, ResttyTouchSelectionMode, ResttyUrlFontSource, ResttyBufferFontSource, ResttyLocalFontSource, ResttyWasmLogListener, ResttyAppSession, ResttyAppInputPayload, ResttyShaderStage, ResttyShaderStageMode, ResttyShaderStageBackend, ResttyShaderStageSource, ResttyAppOptions, ResttyApp, } from "./types";
|
|
6
6
|
export type { ResttyPaneSplitDirection, ResttyPaneContextMenuItem, ResttyPaneDefinition, ResttyPaneStyleOptions, ResttyPaneStylesOptions, ResttyPaneShortcutsOptions, ResttyPaneContextMenuOptions, CreateResttyPaneManagerOptions, ResttyPaneManager, ResttyPaneWithApp, CreateDefaultResttyPaneContextMenuItemsOptions, } from "../surface/panes-types";
|
package/dist/xterm.js
CHANGED