-
Notifications
You must be signed in to change notification settings - Fork 184
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Flexible AcceptLine, fix bug in multi-line accept #379
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -281,15 +281,16 @@ fn page_completions<C: Candidate, H: Helper>( | |
&& cmd != Cmd::SelfInsert(1, ' ') | ||
&& cmd != Cmd::Kill(Movement::BackwardChar(1)) | ||
&& cmd != Cmd::AcceptLine | ||
&& cmd != Cmd::AcceptOrInsertLine | ||
&& cmd != Cmd::Newline | ||
&& matches!(cmd, Cmd::AcceptOrInsertLine { .. }) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed |
||
{ | ||
cmd = s.next_cmd(input_state, rdr, false)?; | ||
} | ||
match cmd { | ||
Cmd::SelfInsert(1, 'y') | Cmd::SelfInsert(1, 'Y') | Cmd::SelfInsert(1, ' ') => { | ||
pause_row += s.out.get_rows() - 1; | ||
} | ||
Cmd::AcceptLine | Cmd::AcceptOrInsertLine => { | ||
Cmd::AcceptLine | Cmd::Newline | Cmd::AcceptOrInsertLine { .. } => { | ||
pause_row += 1; | ||
} | ||
_ => break, | ||
|
@@ -427,6 +428,7 @@ fn readline_edit<H: Helper>( | |
editor.reset_kill_ring(); // TODO recreate a new kill ring vs Arc<Mutex<KillRing>> | ||
let ctx = Context::new(&editor.history); | ||
let mut s = State::new(&mut stdout, prompt, helper, ctx); | ||
|
||
let mut input_state = InputState::new(&editor.config, Arc::clone(&editor.custom_bindings)); | ||
|
||
s.line.set_delete_listener(editor.kill_ring.clone()); | ||
|
@@ -509,8 +511,12 @@ fn readline_edit<H: Helper>( | |
s.edit_overwrite_char(c)?; | ||
} | ||
Cmd::EndOfFile => { | ||
if s.has_hint() || !s.is_default_prompt() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Only if line is empty or in vi mode ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed. But I'm not sure that |
||
// Force a refresh without hints to leave the previous | ||
// line as the user typed it after a newline. | ||
s.refresh_line_with_msg(None)?; | ||
} | ||
if !input_state.is_emacs_mode() && !s.line.is_empty() { | ||
s.edit_move_end()?; | ||
break; | ||
} else if s.line.is_empty() { | ||
return Err(error::ReadlineError::Eof); | ||
|
@@ -575,7 +581,7 @@ fn readline_edit<H: Helper>( | |
kill_ring.kill(&text, Mode::Append) | ||
} | ||
} | ||
Cmd::AcceptLine | Cmd::AcceptOrInsertLine => { | ||
Cmd::AcceptLine | Cmd::AcceptOrInsertLine { .. } => { | ||
#[cfg(test)] | ||
{ | ||
editor.term.cursor = s.layout.cursor.col; | ||
|
@@ -585,13 +591,23 @@ fn readline_edit<H: Helper>( | |
// line as the user typed it after a newline. | ||
s.refresh_line_with_msg(None)?; | ||
} | ||
// Only accept value if cursor is at the end of the buffer | ||
if s.validate()? && (cmd == Cmd::AcceptLine || s.line.is_end_of_input()) { | ||
break; | ||
} else { | ||
s.edit_insert('\n', 1)?; | ||
let valid = s.validate()?; | ||
let end = s.line.is_end_of_input(); | ||
match (cmd, valid, end) { | ||
| (Cmd::AcceptLine, _, _) | ||
| (Cmd::AcceptOrInsertLine { .. }, true, true) | ||
| (Cmd::AcceptOrInsertLine { accept_in_the_middle: true }, true, _) | ||
=> { | ||
break; | ||
} | ||
| (Cmd::Newline, _, _) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unreachable ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed. Thanks! (this is actually why I'd like the top-level match to be exhaustive, as this error would have been spotted by the compiler) |
||
| (Cmd::AcceptOrInsertLine { .. }, false, _) | ||
| (Cmd::AcceptOrInsertLine { .. }, true, false) | ||
=> { | ||
s.edit_insert('\n', 1)?; | ||
} | ||
_ => unreachable!(), | ||
} | ||
continue; | ||
} | ||
Cmd::BeginningOfHistory => { | ||
// move to first entry in history | ||
|
@@ -656,6 +672,10 @@ fn readline_edit<H: Helper>( | |
} | ||
} | ||
Cmd::Interrupt => { | ||
// Move to end, in case cursor was in the middle of the | ||
// line, so that next thing application prints goes after | ||
// the input | ||
s.edit_move_end()?; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. edit_move_buffer_end ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that's better. Thanks! |
||
return Err(error::ReadlineError::Interrupted); | ||
} | ||
#[cfg(unix)] | ||
|
@@ -671,6 +691,11 @@ fn readline_edit<H: Helper>( | |
} | ||
} | ||
} | ||
|
||
// Move to end, in case cursor was in the middle of the line, so that | ||
// next thing application prints goes after the input | ||
s.edit_move_buffer_end()?; | ||
|
||
if cfg!(windows) { | ||
let _ = original_mode; // silent warning | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AcceptLine == AcceptOrInsertLine { accept_in_the_middle: true }
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, accept whatever is fully formed command or insert a newline otherwies. That's for backwards compatibility. As described in the docstring above this is what makes most sense for mostly-single-line cases (i.e. a command-line like in nushell).