summaryrefslogtreecommitdiff
path: root/runtime/ops/tty.rs
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/ops/tty.rs')
-rw-r--r--runtime/ops/tty.rs43
1 files changed, 42 insertions, 1 deletions
diff --git a/runtime/ops/tty.rs b/runtime/ops/tty.rs
index 3227ee562..6cc129883 100644
--- a/runtime/ops/tty.rs
+++ b/runtime/ops/tty.rs
@@ -5,6 +5,13 @@ use std::io::Error;
use deno_core::error::AnyError;
use deno_core::op2;
use deno_core::OpState;
+use rustyline::config::Configurer;
+use rustyline::error::ReadlineError;
+use rustyline::Cmd;
+use rustyline::Editor;
+use rustyline::KeyCode;
+use rustyline::KeyEvent;
+use rustyline::Modifiers;
#[cfg(unix)]
use deno_core::ResourceId;
@@ -43,7 +50,12 @@ use winapi::um::wincon;
deno_core::extension!(
deno_tty,
- ops = [op_stdin_set_raw, op_isatty, op_console_size],
+ ops = [
+ op_stdin_set_raw,
+ op_isatty,
+ op_console_size,
+ op_read_line_prompt
+ ],
state = |state| {
#[cfg(unix)]
state.put(TtyModeStore::default());
@@ -320,3 +332,32 @@ mod tests {
);
}
}
+
+#[op2]
+#[string]
+pub fn op_read_line_prompt(
+ #[string] prompt_text: &str,
+ #[string] default_value: &str,
+) -> Result<Option<String>, AnyError> {
+ let mut editor = Editor::<(), rustyline::history::DefaultHistory>::new()
+ .expect("Failed to create editor.");
+
+ editor.set_keyseq_timeout(1);
+ editor
+ .bind_sequence(KeyEvent(KeyCode::Esc, Modifiers::empty()), Cmd::Interrupt);
+
+ let read_result =
+ editor.readline_with_initial(prompt_text, (default_value, ""));
+ match read_result {
+ Ok(line) => Ok(Some(line)),
+ Err(ReadlineError::Interrupted) => {
+ // SAFETY: Disable raw mode and raise SIGINT.
+ unsafe {
+ libc::raise(libc::SIGINT);
+ }
+ Ok(None)
+ }
+ Err(ReadlineError::Eof) => Ok(None),
+ Err(err) => Err(err.into()),
+ }
+}