Files
terminal-lab/xterminal/docs/guide/prompt.md
douboer@gmail.com 3b7c1d558a first commit
2026-03-03 13:23:14 +08:00

168 lines
4.4 KiB
Markdown

# Input
## Prompt Style
In most terminal emulators, the prompt style appears before the cursor. This is from the backing shell (e.g bash, zsh, fish) that prints it in the terminal.
For example:
<browser-preview hidelabel>
user@host:~ $ ▊
</browser-preview>
Or even
<browser-preview hidelabel>
┌[user@host]
└$ ▊
</browser-preview>
In the same way, you can organize the flow of input with a prompt style just before the cursor.
Suppose the state of our app defines the `username` and `hostname` like so
```js
const state = {
username: 'root',
hostname: 'web'
};
```
Create a function to write our prompt style to the terminal, let it be `ask()`.
```js
function ask() {
term.write(`┌[${state.username}@${state.hostname}]\n`);
term.write('└$ ');
}
```
## Pause & Resume
Using [term.pause()](../api/index.md#term-pause) will pause or deactivate the terminal from recieving user input whereas [term.resume()](../api/index.md#term-resume) will do the opposite.
When invoked, [term.pause()](../api/index.md#term-pause) will trigger the [pause](./events.md#default-events) event whereas [term.resume()](../api/index.md#term-resume) will trigger the [resume](./events.md#default-events) event.
:::warning Note
In both cases, _input_ is affected but not the _output_. You can still do write operations even when the input is deactivated.
:::
**Example:** Pause input for five (5) seconds and resume thereafter while listening for events.
```js
const term = new XTerminal();
term.mount('#app');
// capture `pause` event
term.on("pause", () => term.writeln("pausing..."));
// capture `resume` event
term.on("resume", () => term.writeln("resuming..."));
term.pause(); // triggers the `pause` event
setTimeout(() => {
term.resume(); // triggers the `resume` event
}, 5000);
```
In the five seconds, any keypress won't do anything but we can observe to write operations in order of the events.
---
Suppose that you want to do an async operation, it is a good
practice to [pause](../api/index.md#term-pause) the terminal for input and [resume](../api/index.md#term-resume) later when the operation is done.
Whenever the input is recieved, you can pause the terminal and handle the async operation first.
```js
term.on("data", async input => {
term.pause();
// ...
// do async task
// ...
term.resume();
});
```
Everytime you write the prompt style, you may want to be able to capture the next command input from the user. In this case, you can use the
[term.resume()](../api/index.md#term-resume) method.
```js
function ask() {
term.write(`┌[${state.username}@${state.hostname}]\n`);
term.write('└$ ');
term.resume(); // [!code ++]
}
```
## Focus & Blur
You can programmatically focus the terminal input, toggling the keyboard in case of mobile devices, using the [term.focus()](../api/index.md#term-focus) method on the terminal instance.
Focus the input everytime you ask for input using:
```js
function ask() {
term.writeln(`┌[${state.username}@${state.hostname}]`);
term.write('└$ ');
term.resume();
term.focus(); // [!code ++]
}
```
In the same way, you might want to blur the terminal for some reason, say after entering
data and pressing the Enter key. You can achieve that using the `data` event and the [term.blur()](../api/index.md#term-blur) method.
```js
term.on('data', () => {
term.blur();
});
```
## Set & Clear
Use [term.setInput()](../api/index.md#term-setinput) to simulate user input by modifying the value of the input buffer.
This is useful in many scenarios, one of which is to preset some input in the terminal a user can use/modify/execute (so that they don't have to type it themselves).
Here is an example:
```js
term.setInput("help")
```
<browser-preview hidelabel>
user@host:~ $ help▊
</browser-preview>
Given that we can now change the input buffer, [term.clearInput()](../api/index.md#term-clearinput) allows for clearing the input buffer, for instance, when you want to discard any user input or contents of the input buffer.
```js
term.clearInput()
```
results into
<browser-preview hidelabel>
user@host:~ $ ▊
</browser-preview>
A complete example to illustrate both methods in action: the input is set to `help` and cleared after 2 seconds
```js
term.setInput("help")
setTimeout(() => {
term.clearInput()
}, 2000)
```
## Next Step
Learn about the history stack that stores all inputs