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:
parent
a7339f756c
commit
ac2cf2cb3e
2 changed files with 57 additions and 0 deletions
|
@ -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"));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue