0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-03-03 09:31:22 -05:00

fix(repl): accept tab when previous character is whitespace (#14898)

This commit is contained in:
sigmaSd 2022-06-20 23:47:25 +01:00 committed by GitHub
parent a7339f756c
commit ac2cf2cb3e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 57 additions and 0 deletions

View file

@ -804,3 +804,25 @@ fn pty_clear_function() {
assert!(output.contains("3234"));
});
}
#[test]
fn pty_tab_handler() {
// If the last character is **not** whitespace, we show the completions
util::with_pty(&["repl"], |mut console| {
console.write_line("a\t\t");
console.write_line("close();");
let output = console.read_all_output();
assert!(output.contains("addEventListener"));
assert!(output.contains("alert"));
assert!(output.contains("atob"));
});
// If the last character is whitespace, we just insert a tab
util::with_pty(&["repl"], |mut console| {
console.write_line("a \t\t"); // last character is whitespace
console.write_line("close();");
let output = console.read_all_output();
assert!(!output.contains("addEventListener"));
assert!(!output.contains("alert"));
assert!(!output.contains("atob"));
});
}

View file

@ -23,6 +23,7 @@ use rustyline::EventHandler;
use rustyline::KeyCode;
use rustyline::KeyEvent;
use rustyline::Modifiers;
use rustyline::{ConditionalEventHandler, Event, EventContext, RepeatCount};
use rustyline_derive::{Helper, Hinter};
use std::borrow::Cow;
use std::path::PathBuf;
@ -369,6 +370,10 @@ impl ReplEditor {
KeyEvent(KeyCode::Char('s'), Modifiers::CTRL),
EventHandler::Simple(Cmd::Newline),
);
editor.bind_sequence(
KeyEvent::from('\t'),
EventHandler::Conditional(Box::new(TabEventHandler)),
);
ReplEditor {
inner: Arc::new(Mutex::new(editor)),
@ -391,3 +396,33 @@ impl ReplEditor {
Ok(())
}
}
/// A custom tab key event handler
/// It uses a heuristic to determine if the user is requesting completion or if they want to insert an actual tab
/// The heuristic goes like this:
/// - If the last character before the cursor is whitespace, the the user wants to insert a tab
/// - Else the user is requesting completion
struct TabEventHandler;
impl ConditionalEventHandler for TabEventHandler {
fn handle(
&self,
evt: &Event,
n: RepeatCount,
_: bool,
ctx: &EventContext,
) -> Option<Cmd> {
debug_assert_eq!(*evt, Event::from(KeyEvent::from('\t')));
if ctx.line().is_empty()
|| ctx.line()[..ctx.pos()]
.chars()
.rev()
.next()
.filter(|c| c.is_whitespace())
.is_some()
{
Some(Cmd::Insert(n, "\t".into()))
} else {
None // default complete
}
}
}