diff --git a/packages/core/src/renderables/Input.test.ts b/packages/core/src/renderables/Input.test.ts index dd98deeaa..5a969d839 100644 --- a/packages/core/src/renderables/Input.test.ts +++ b/packages/core/src/renderables/Input.test.ts @@ -173,6 +173,59 @@ describe("InputRenderable", () => { expect(input.value).toBe("hel") }) + it("should emit INPUT event on Ctrl+W (delete-word-backward)", () => { + const { input } = createInputRenderable({ + value: "hello world", + }) + + input.focus() + + const inputValues: string[] = [] + input.on(InputRenderableEvents.INPUT, (value: string) => { + inputValues.push(value) + }) + + // Ctrl+W should delete "world" and emit INPUT with updated value + mockInput.pressKey("w", { ctrl: true }) + expect(input.value).toBe("hello ") + expect(inputValues).toEqual(["hello "]) + }) + + it("should emit INPUT event on Alt+Backspace (delete-word-backward)", () => { + const { input } = createInputRenderable({ + value: "foo bar baz", + }) + + input.focus() + + const inputValues: string[] = [] + input.on(InputRenderableEvents.INPUT, (value: string) => { + inputValues.push(value) + }) + + // Alt+Backspace is also bound to delete-word-backward + mockInput.pressBackspace({ meta: true }) + expect(input.value).toBe("foo bar ") + expect(inputValues).toEqual(["foo bar "]) + }) + + it("should emit INPUT event on deleteLine()", () => { + const { input } = createInputRenderable({ + value: "hello world", + }) + + input.focus() + + const inputValues: string[] = [] + input.on(InputRenderableEvents.INPUT, (value: string) => { + inputValues.push(value) + }) + + input.deleteLine() + expect(input.value).toBe("") + expect(inputValues).toEqual([""]) + }) + it("should handle delete correctly", () => { const { input } = createInputRenderable({ value: "hello", diff --git a/packages/core/src/renderables/Input.ts b/packages/core/src/renderables/Input.ts index 9161308eb..099d3c16b 100644 --- a/packages/core/src/renderables/Input.ts +++ b/packages/core/src/renderables/Input.ts @@ -167,6 +167,48 @@ export class InputRenderable extends TextareaRenderable { return result } + public override deleteLine(): boolean { + const result = super.deleteLine() + this.emit(InputRenderableEvents.INPUT, this.plainText) + return result + } + + public override deleteWordBackward(): boolean { + const result = super.deleteWordBackward() + this.emit(InputRenderableEvents.INPUT, this.plainText) + return result + } + + public override deleteWordForward(): boolean { + const result = super.deleteWordForward() + this.emit(InputRenderableEvents.INPUT, this.plainText) + return result + } + + public override deleteToLineStart(): boolean { + const result = super.deleteToLineStart() + this.emit(InputRenderableEvents.INPUT, this.plainText) + return result + } + + public override deleteToLineEnd(): boolean { + const result = super.deleteToLineEnd() + this.emit(InputRenderableEvents.INPUT, this.plainText) + return result + } + + public override undo(): boolean { + const result = super.undo() + this.emit(InputRenderableEvents.INPUT, this.plainText) + return result + } + + public override redo(): boolean { + const result = super.redo() + this.emit(InputRenderableEvents.INPUT, this.plainText) + return result + } + public deleteCharacter(direction: "backward" | "forward"): void { if (direction === "backward") { this.deleteCharBackward()