Skip to content
UrushiDocumentation

Placement and resize

The 0.1.0 prompt runtime draws inline into the primary terminal buffer. The form must know the left edge of the region it owns. These placement and resize options are specific to inline presentation; they are not general form-state settings.

PromptStart::NewLine is the default. It starts at column zero after emitting a carriage return and line feed. Prefer it when no surrounding line content must be preserved.

let form = Form::builder()
.start(PromptStart::NewLine)
.group(group)
.build()?;

The prefix remains untouched and the prompt begins on the following line:

Configuration:
┃ What is your name?
┃ › e.g. Alex

The application supplies the current column because the prompt does not query cursor position.

use std::io::{self, Write};
use urushi_prompt::{Form, PromptStart};
const PREFIX: &str = "Configuration: ";
let form = Form::builder()
.start(PromptStart::CurrentPosition {
column: PREFIX.len() as u16,
})
.width(32)
.group(group)
.build()?;
let stderr = io::stderr();
let mut output = stderr.lock();
write!(output, "{PREFIX}")?;
output.flush()?;
drop(output);
let outcome = form.run(&theme)?;

The prompt owns only the suffix beginning after Configuration: :

Configuration: ┃ What is your name?
               ┃ › e.g. Alex

The byte length is a valid column only because this prefix is ASCII. For other text, compute terminal display width rather than using str::len.

Use CurrentLine when the complete current line belongs to the application and may be overwritten:

let form = Form::builder()
.start(PromptStart::CurrentLine)
.group(group)
.build()?;
before: Configuration: waiting…
after:  ┃ What is your name?

width caps the prompt region; the actual width is also limited by the columns remaining after its left edge. At a width of 20 cells, long content wraps:

┃ What is your
┃ name?
┃ › e.g. Alexandra

Inline content can reflow in the primary buffer, so a prompt may no longer know where its previously drawn rows moved after a resize. The default policy is InlineResizePolicy::ReturnError, which restores the session and returns RunError::Resized without erasing an uncertain region:

use urushi_prompt::{Form, InlineResizePolicy, RunError};
let form = Form::builder()
.inline_resize_policy(InlineResizePolicy::ReturnError)
.group(group)
.build()?;
match form.run(&theme) {
Err(RunError::Resized { cleanup: None }) => {
eprintln!("Prompt stopped after terminal resize.");
}
Err(error) => return Err(error.into()),
Ok(outcome) => { /* handle submission or cancellation */ }
}
Program output after resize
Prompt stopped after terminal resize.
use urushi_prompt::InlineResizePolicy;
let form = Form::builder()
.inline_resize_policy(InlineResizePolicy::ClearViewportAndRedraw)
.group(group)
.build()?;

ClearViewportAndRedraw keeps the prompt running, but it clears every visible cell in the primary-buffer viewport, including content outside the prompt. Use it only when the application accepts that behavior.

The transition is deliberately destructive inside the visible viewport:

before resize
build log line 1
build log line 2
┃ Name

after resize
(all previous visible cells cleared)
┃ Name
┃ ›

The prompt remains running and redraws its current field state. Scrollback is not cleared. Compare every placement and resize default in the prompt reference.