@theme-registry/refract 0.1.3 → 0.1.4

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.
@@ -10,10 +10,36 @@ export interface Choice<T> {
10
10
  /** Trailing grey note — what this option means. */
11
11
  readonly hint?: string;
12
12
  }
13
+ /** The keys a list prompt understands, after decoding an stdin chunk. */
14
+ export type ListKey = "up" | "down" | "space" | "submit" | "all" | "cancel" | "none";
15
+ /** Decode a raw stdin chunk into a {@link ListKey}. Arrows arrive as escape sequences; j/k mirror vim. */
16
+ export declare function decodeKey(chunk: string): ListKey;
13
17
  /**
14
- * A prompt session. Holds one readline interface for the whole interview so stdin is opened and
15
- * closed exactly once; `interactive` is false when there's no TTY, and every ask short-circuits to
16
- * its default.
18
+ * Split one stdin chunk into the keys it contains.
19
+ *
20
+ * A held-down arrow key, or fast typing, delivers several sequences in a single `data` event — so
21
+ * decoding the chunk as one key would swallow all but the first and make the list feel like it drops
22
+ * input. Escape sequences (`ESC [ <letter>`) are taken as a unit; everything else is one key each.
23
+ */
24
+ export declare function decodeKeys(chunk: string): ListKey[];
25
+ /** Where a list prompt currently stands. */
26
+ export interface ListState {
27
+ readonly cursor: number;
28
+ readonly selected: ReadonlySet<number>;
29
+ readonly done: boolean;
30
+ readonly cancelled: boolean;
31
+ }
32
+ /**
33
+ * Advance a list prompt by one key. Pure — no I/O — so navigation is testable without a terminal.
34
+ *
35
+ * The cursor **wraps** at both ends: with six options, up from the first should land on the last
36
+ * rather than stick. `space` and `a` toggle only in multi mode; in single mode Enter is the commit,
37
+ * so space would be ambiguous.
38
+ */
39
+ export declare function applyKey(state: ListState, key: ListKey, count: number, multi: boolean): ListState;
40
+ /**
41
+ * A prompt session. Holds at most one readline interface, so stdin is opened and closed once;
42
+ * `interactive` is false when there's no TTY, and every ask short-circuits to its default.
17
43
  */
18
44
  export declare class Prompter {
19
45
  private rl;
@@ -22,17 +48,29 @@ export declare class Prompter {
22
48
  private get io();
23
49
  close(): void;
24
50
  private question;
25
- /** Print a line to stdout. Kept on the prompter so command code never touches `process.stdout`. */
51
+ /** Raw write, no newline for cursor control during a live render. */
52
+ private out;
53
+ /** Print a line. Kept on the prompter so command code never touches `process.stdout`. */
26
54
  write(line?: string): void;
27
55
  /** Free-text, with a default shown in the prompt. Blank input takes the default. */
28
56
  text(label: string, fallback: string, validate?: (v: string) => string | undefined): Promise<string>;
29
57
  /** A number, validated as finite. */
30
58
  number(label: string, fallback: number, validate?: (v: number) => string | undefined): Promise<number>;
31
- /** Pick one. Answers are 1-based indices; blank takes the default (the first choice unless given). */
59
+ /** Pick one arrows to move, Enter to choose. */
32
60
  select<T>(label: string, choices: readonly Choice<T>[], defaultIndex?: number): Promise<T>;
61
+ /** Pick any — arrows to move, space to toggle, `a` for all/none, Enter to confirm. */
62
+ multiselect<T>(label: string, choices: readonly Choice<T>[], preselected: readonly number[]): Promise<T[]>;
33
63
  /**
34
- * Pick any. Answers are comma-separated indices; blank keeps the pre-selected set, and an explicit
35
- * `none` clears it otherwise there'd be no way to deselect everything with a line-based prompt.
64
+ * The raw-mode list loop. Renders in place: each keypress rewinds over the block just drawn and
65
+ * repaints it, so the list stays put instead of scrolling the terminal away.
66
+ *
67
+ * Any readline interface is closed first — it would otherwise swallow the keystrokes we need.
68
+ * `cleanup` always restores the terminal (raw mode off, cursor shown), including on cancel, so a
69
+ * Ctrl-C can't leave the shell in a state where typing is invisible.
36
70
  */
37
- multiselect<T>(label: string, choices: readonly Choice<T>[], preselected: readonly number[]): Promise<T[]>;
71
+ private runList;
72
+ /** Line-mode fallback: pick one by number. */
73
+ private selectByNumber;
74
+ /** Line-mode fallback: pick any by comma-separated numbers. */
75
+ private multiselectByNumber;
38
76
  }