Table of Contents

smudgy:core — Command input

Generated from smudgy v0.4.2-dev (smudgy-core.d.ts @ 5110ac599715). Index: scriptref.

Read and edit the command line, contribute tab-completion words, inspect command history, and observe or intercept submitted commands. Import the main input from smudgy:core; pane inputs expose the same handle through Pane.input.

Input state and editing

input

export const input: InputHandle;

Your session's command input (see InputHandle).

InputHandle

export interface InputHandle {
  readonly value: string;
  readonly cursor: number;
  readonly selection: { start: number; end: number } | null;
  readonly focused: boolean;
  masked: boolean;
 
  replace(text: string): void;
  append(text: string): void;
  clear(): void;
  propose(text: string): void;
 
  setCursor(pos: number): void;
  select(start: number, end: number): void;
  selectAll(): void;
 
  focus(): void;
  blur(): void;
  submit(): void;
 
  readonly completion: WordSetRegistry & { readonly blacklist: WordSetRegistry };
 
  readonly history: InputHistory;
}

Inspect or edit a command input. The main input is exported as input; a pane with its own input exposes the same API through Pane.input.

Input state is synchronized from the UI and can briefly trail very recent typing. Text delivered by the submit event is exact.

The command line belongs to the user. Use propose() to offer a command without overwriting text they are editing. The proposed text is selected: Enter submits it, while typing replaces it. Use replace() only when the script should overwrite the current contents.

Cursor and selection positions count UTF-16 code units, the same units as JavaScript string indexing into value.

import { input } from "smudgy:core";
// Offer a command for the user to confirm or amend.
input.propose("cast 'heal' Tom");
input.focus();

WordSetRegistry

export interface WordSetRegistry {
  add(...words: string[]): void;
  delete(word: string): boolean;
  has(word: string): boolean;
  list(): string[];
  clear(): void;
}

Tab-completion words registered by this script (see InputHandle.completion). Registry methods expose only this script's words; the input combines contributions from every script when it offers completions.

Words are case-insensitive single tokens of at most 64 characters. A registry holds up to 512 words. Adding an existing word is idempotent and updates its stored casing. Registrations do not persist across reloads.

import { input } from "smudgy:core";
input.completion.add("fireball", "featherfall", "Fjord");
input.completion.blacklist.add("ooc");

InputHistory

export interface InputHistory {
  list(): string[];
  push(text: string): void;
  clear(): void;
}

An input's shared command history: the lines the Up arrow recalls (see InputHandle.history). Every script sees and changes the same history for that input.

list() reflects history as of the most recent submission (or scripted change). Password-mode submissions never enter history, so they never appear here.

import { input, createAlias } from "smudgy:core";
// "again 2" offers back the command typed two submissions ago. When
// the alias runs, list()[0] is the "again 2" line itself, so the
// command before it sits at [1].
createAlias(/^again (?<n>\d+)$/, ({ n }) => {
  const entry = input.history.list()[Number(n)];
  if (entry) input.propose(entry);
});

Submitted commands

submission

export const submission: Submission;

The submission a submit event handler is processing (see Submission).

Submission

export interface Submission {
  readonly text: string;
  replace(text: string): void;
  cancel(): void;
}

The submission a submit event handler is processing: what the user typed, on its way into the client. Only meaningful inside a handler for the submit event from smudgy:events/sys; anywhere else it throws.

Handlers run in order and act on the same submission, so a later handler reads any replacement an earlier one made, and a cancel from any handler is final.

Submission event: smudgy:events/sys

submit

export const submit: EventConsumer<{ text: string }>;

Fires when a command is submitted from the command input, whether the user pressed Enter or a script called input.submit(). text is the line exactly as typed, before aliases, command splitting, or prefix handling. Lines sent by scripts do not fire it, and neither do masked (password) submissions.

Inside the handler, the ambient submission from smudgy:core refers to this same submission: submission.replace() changes what the rest of the client processes, and submission.cancel() discards it. The pairing mirrors receive and the ambient line.

Input events: smudgy:events/input

change

export const change: EventConsumer<{
  value?: string;
  masked?: true;
  pane?: string;
  source: "user" | "script" | "link" | "other";
}>;

Fires after a command input's text changes. source identifies whether the change came from the user, a script, a command link, or another client action such as history recall. pane is absent for the main input.

Use this event to observe edits. To replace or cancel a submitted command, use submit from smudgy:events/sys.

Identical consecutive states are coalesced. While the input is masked, typing emits no events and no text is reported. The event that begins masking contains masked: true without value; the event that ends it contains the restored text. Read input.masked when the current masking state matters.

Changing the input from a handler emits another change event. Only write when the new value differs, or the handler can loop.

import { change } from "smudgy:events/input";
change.on(({ value, source }) => {
  if (source === "user") console.log("draft:", value ?? "");
});

focus

export const focus: EventConsumer<{
  focused: boolean;
  masked?: true;
  pane?: string;
}>;

Fires when a command input gains or loses keyboard focus. pane names the pane whose input it is; it is absent for the main input. masked is present (and true) while that input is in password mode.


Script API reference · ← smudgy:core — Sessions & settings · smudgy:core — Lines & buffer → · Scripting manual