Appearance
Input Engine
The input engine is Klix's thin wrapper around prompt_toolkit. It provides the prompt session, input modes, key bindings, and CI-safe fallback behavior.
See also:
Why It Exists
Klix needs one place to own terminal input behavior so that:
- prompt history is consistent
- key bindings are centralized
- modes can influence prompt behavior
- CI and pipe mode can bypass interactive UI cleanly
Without that layer, every input component would need to reinvent prompt setup.
What The Engine Handles
Current responsibilities:
PromptSessionsetup- session-backed command history
- current
InputMode Ctrl+Lbinding- multiline bindings
- password mode flagging
- optional clear-after-submit behavior
- optional themed prompt styling
- CI/non-TTY fallback via
stdin.readline()
CI And Non-Interactive Behavior
When Klix selects CIRenderer, the input engine avoids interactive prompt_toolkit use and reads lines from stdin instead.
That is why tests can do things like:
bash
printf '/hello hi\n/exit\n' | python main.pyThis is great for automation, but it also means some richer widgets are effectively interactive-only. See Input Components.
Modes
The engine currently understands:
COMMANDMULTILINESELECTSEARCHCONFIRMPASSWORDINTERRUPT
In the current implementation, not every mode changes low-level prompt behavior equally. Some modes are primarily semantic signals used by higher-level components.
Examples:
PASSWORDchanges prompt maskingMULTILINEchanges Enter behaviorCOMMANDmode participates in session history navigation- selector-style inputs are implemented through prompt_toolkit dialogs in
session.ui.input, not directly throughprompt_async()
Realistic Example
python
@app.command("/notes", help="Capture a multiline note")
async def notes(session: klix.Session):
session.input_engine.set_mode(klix.InputMode.MULTILINE)
text = await session.input_engine.prompt_async("Note > ")
session.input_engine.set_mode(klix.InputMode.COMMAND)
session.ui.output.panel(text, title="Captured Note", border_color="accent")Key Bindings
Current built-ins:
Ctrl+Lclears the screen- Up/Down navigate session history through prompt_toolkit
- in multiline mode:
Escape+Enterinserts a newlineCtrl+Jinserts a newline in terminals that emit LFEntersubmits
When AppConfig(clear_input_on_submit=True) is enabled, the active prompt line is also erased after submit.
If ThemeConfig(input_background=...) is set, prompt_toolkit applies a themed input bar background in interactive terminals.
Pitfalls
Assuming every input component goes through prompt_async()
Simple prompts do. Richer selectors often build their own prompt_toolkit sessions or dialogs on top of the same engine-level context.
Forgetting to reset mode
If you manually change modes in custom flows, return to COMMAND when you are done.
Expecting rich dialogs in CI
CI fallback is intentionally plain.