@flowtty/core 1.0.0-alpha.4 → 1.0.0-alpha.6

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.
@@ -5,9 +5,25 @@ interface Key {
5
5
  * Canonical name of the key. For printable ASCII characters this is the
6
6
  * character itself ('a', '!', ' '). For named keys: 'return', 'escape',
7
7
  * 'tab', 'backspace', 'delete', 'up', 'down', 'left', 'right', 'home',
8
- * 'end', 'pageup', 'pagedown'.
8
+ * 'end', 'pageup', 'pagedown'. A bracketed paste is one key named 'paste'
9
+ * whose content is in `text`. Mouse wheel steps are 'wheelup' / 'wheeldown',
10
+ * positioned by `x` / `y`.
9
11
  */
10
12
  name: string;
13
+ /**
14
+ * Payload of a 'paste' key: the pasted text, line endings normalized to `\n`.
15
+ * A paste is delivered whole — its newlines and letters are text, never
16
+ * 'return' or single-letter keys — so an app inserts it instead of acting on it.
17
+ * Undefined for every other key.
18
+ */
19
+ text?: string;
20
+ /**
21
+ * Cell under the pointer for a mouse key ('wheelup' / 'wheeldown'): 0-based
22
+ * column and row, the same coordinates `onLayout` rects use. Undefined for
23
+ * every other key.
24
+ */
25
+ x?: number;
26
+ y?: number;
11
27
  /** Raw byte sequence as received from the source (empty for synthetic keys). */
12
28
  sequence: string;
13
29
  ctrl: boolean;
@@ -171,7 +171,14 @@ function refreshMeasure(inst, _Yoga) {
171
171
  inst.yogaNode.setMeasureFunc(null);
172
172
  }
173
173
  }
174
+ function detachForMove(parent, child) {
175
+ const i = parent.children.indexOf(child);
176
+ if (i < 0) return;
177
+ parent.children.splice(i, 1);
178
+ if (child.type === "box") parent.yogaNode.removeChild(child.yogaNode);
179
+ }
174
180
  function appendChild(parent, child, Yoga) {
181
+ detachForMove(parent, child);
175
182
  parent.children.push(child);
176
183
  if (child.type === "box") {
177
184
  parent.yogaNode.setMeasureFunc(null);
@@ -193,6 +200,7 @@ function removeChild(parent, child, Yoga) {
193
200
  refreshMeasure(parent);
194
201
  }
195
202
  function insertBefore(parent, child, before, Yoga) {
203
+ detachForMove(parent, child);
196
204
  const i = parent.children.indexOf(before);
197
205
  parent.children.splice(i < 0 ? parent.children.length : i, 0, child);
198
206
  if (child.type === "box") {
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { B as Buffer, C as Cell, S as Style } from './cells-CaXEx4lH.js';
2
- import { K as Key } from './backend-BcB7VR87.js';
3
- export { B as Backend } from './backend-BcB7VR87.js';
2
+ import { K as Key } from './backend-ode0Vc7y.js';
3
+ export { B as Backend } from './backend-ode0Vc7y.js';
4
4
  export { j as BorderChars, k as BorderStyle, n as BoxProps, D as DEFAULT_BORDER_STYLE, G as GRID_CHARS, p as GridChars } from './host-zpuR6C1c.js';
5
5
  import 'yoga-layout/load';
6
6
 
package/dist/index.js CHANGED
@@ -307,6 +307,11 @@ function wordRight(value, cursor) {
307
307
  function reduce(state, key) {
308
308
  const { value, cursor } = state;
309
309
  const clamp = (n) => Math.max(0, Math.min(value.length, n));
310
+ if (key.name === "paste") {
311
+ const text = (key.text ?? "").replace(/\n/g, " ");
312
+ if (text === "") return { kind: "noop" };
313
+ return { kind: "edit", state: { value: value.slice(0, cursor) + text + value.slice(cursor), cursor: cursor + text.length } };
314
+ }
310
315
  if (key.name === "left" && key.meta) return { kind: "edit", state: { value, cursor: wordLeft(value, cursor) } };
311
316
  if (key.name === "b" && key.meta) return { kind: "edit", state: { value, cursor: wordLeft(value, cursor) } };
312
317
  if (key.name === "right" && key.meta) return { kind: "edit", state: { value, cursor: wordRight(value, cursor) } };
@@ -1,5 +1,5 @@
1
1
  import { B as Buffer } from '../cells-CaXEx4lH.js';
2
- import { B as Backend, K as Key } from '../backend-BcB7VR87.js';
2
+ import { B as Backend, K as Key } from '../backend-ode0Vc7y.js';
3
3
 
4
4
  declare class TestBackend implements Backend {
5
5
  private readonly cols;
@@ -22,6 +22,10 @@ declare class TestBackend implements Backend {
22
22
  }): void;
23
23
  /** Emit one Key per character; printable chars only. */
24
24
  type(text: string): void;
25
+ /** Deliver `text` as ONE 'paste' key — what a TTY backend emits for a bracketed paste. */
26
+ paste(text: string): void;
27
+ /** Deliver one mouse-wheel step at cell (x, y) — what a TTY backend with `mouse` on emits. */
28
+ wheel(direction: 'up' | 'down', x?: number, y?: number): void;
25
29
  dispose(): void;
26
30
  }
27
31
 
@@ -31,6 +31,9 @@ var TestBackend = class {
31
31
  /** Synchronously deliver one Key to every subscriber. */
32
32
  press(key) {
33
33
  const k = {
34
+ ...key.text !== void 0 ? { text: key.text } : {},
35
+ ...key.x !== void 0 ? { x: key.x } : {},
36
+ ...key.y !== void 0 ? { y: key.y } : {},
34
37
  sequence: key.sequence ?? "",
35
38
  ctrl: key.ctrl ?? false,
36
39
  meta: key.meta ?? false,
@@ -43,6 +46,14 @@ var TestBackend = class {
43
46
  type(text) {
44
47
  for (const ch of text) this.press({ name: ch, sequence: ch });
45
48
  }
49
+ /** Deliver `text` as ONE 'paste' key — what a TTY backend emits for a bracketed paste. */
50
+ paste(text) {
51
+ this.press({ name: "paste", text: text.replace(/\r\n?/g, "\n") });
52
+ }
53
+ /** Deliver one mouse-wheel step at cell (x, y) — what a TTY backend with `mouse` on emits. */
54
+ wheel(direction, x = 0, y = 0) {
55
+ this.press({ name: direction === "up" ? "wheelup" : "wheeldown", x, y });
56
+ }
46
57
  // eslint-disable-next-line @typescript-eslint/no-empty-function
47
58
  dispose() {
48
59
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowtty/core",
3
- "version": "1.0.0-alpha.4",
3
+ "version": "1.0.0-alpha.6",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "repository": {