Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into key_mods
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/keymap.rs
  • Loading branch information
gwenn committed Oct 11, 2020
2 parents f1c7ec1 + caa710c commit 6dcfd61
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 45 deletions.
13 changes: 9 additions & 4 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@ name: Rust

on:
push:
branches:
- master
branches: [master]
paths:
- '**.rs'
- '**.toml'
- '.github/workflows/rust.yml'
pull_request:
branches:
- master
paths:
- '**.rs'
- '**.toml'
- '.github/workflows/rust.yml'

jobs:
build:
Expand Down
10 changes: 10 additions & 0 deletions src/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ impl Candidate for String {
}
}

impl Candidate for str {
fn display(&self) -> &str {
self
}

fn replacement(&self) -> &str {
self
}
}

/// Completion candidate pair
pub struct Pair {
/// Text to display when listing alternatives.
Expand Down
25 changes: 25 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ pub struct Config {
output_stream: OutputStreamType,
/// Horizontal space taken by a tab.
tab_stop: usize,
/// Check if cursor position is at leftmost before displaying prompt
check_cursor_position: bool,
}

impl Config {
Expand Down Expand Up @@ -145,6 +147,13 @@ impl Config {
pub(crate) fn set_tab_stop(&mut self, tab_stop: usize) {
self.tab_stop = tab_stop;
}

/// Check if cursor position is at leftmost before displaying prompt.
///
/// By default, we don't check.
pub fn check_cursor_position(&self) -> bool {
self.check_cursor_position
}
}

impl Default for Config {
Expand All @@ -162,6 +171,7 @@ impl Default for Config {
color_mode: ColorMode::Enabled,
output_stream: OutputStreamType::Stdout,
tab_stop: 8,
check_cursor_position: false,
}
}
}
Expand Down Expand Up @@ -357,6 +367,14 @@ impl Builder {
self
}

/// Check if cursor position is at leftmost before displaying prompt.
///
/// By default, we don't check.
pub fn check_cursor_position(mut self, yes: bool) -> Self {
self.set_check_cursor_position(yes);
self
}

/// Builds a `Config` with the settings specified so far.
pub fn build(self) -> Config {
self.p
Expand Down Expand Up @@ -451,4 +469,11 @@ pub trait Configurer {
fn set_tab_stop(&mut self, tab_stop: usize) {
self.config_mut().set_tab_stop(tab_stop);
}

/// Check if cursor position is at leftmost before displaying prompt.
///
/// By default, we don't check.
fn set_check_cursor_position(&mut self, yes: bool) {
self.config_mut().check_cursor_position = yes;
}
}
46 changes: 31 additions & 15 deletions src/keymap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ pub enum Cmd {
/// abort
Abort, // Miscellaneous Command
/// accept-line
///
/// See also AcceptOrInsertLine
AcceptLine,
/// beginning-of-history
BeginningOfHistory,
Expand Down Expand Up @@ -99,9 +101,23 @@ pub enum Cmd {
/// moves cursor to the line below or switches to next history entry if
/// the cursor is already on the last line
LineDownOrNextHistory(RepeatCount),
/// accepts the line when cursor is at the end of the text (non including
/// trailing whitespace), inserts newline character otherwise
AcceptOrInsertLine,
/// Inserts a newline
Newline,
/// Either accepts or inserts a newline
///
/// Always inserts newline if input is non-valid. Can also insert newline
/// if cursor is in the middle of the text
///
/// If you support multi-line input:
/// * Use `accept_in_the_middle: true` for mostly single-line cases, for
/// example command-line.
/// * Use `accept_in_the_middle: false` for mostly multi-line cases, for
/// example SQL or JSON input.
AcceptOrInsertLine {
/// Whether this commands accepts input if the cursor not at the end
/// of the current input
accept_in_the_middle: bool,
},
}

impl Cmd {
Expand All @@ -122,17 +138,15 @@ impl Cmd {
}

fn is_repeatable_change(&self) -> bool {
match *self {
Cmd::Insert(..)
| Cmd::Kill(_)
| Cmd::ReplaceChar(..)
| Cmd::Replace(..)
| Cmd::SelfInsert(..)
| Cmd::ViYankTo(_)
| Cmd::Yank(..) => true,
// Cmd::TransposeChars | TODO Validate
_ => false,
}
matches!(*self, Cmd::Insert(..)
| Cmd::Kill(_)
| Cmd::ReplaceChar(..)
| Cmd::Replace(..)
| Cmd::SelfInsert(..)
| Cmd::ViYankTo(_)
| Cmd::Yank(..)
// Cmd::TransposeChars | TODO Validate
)
}

fn is_repeatable(&self) -> bool {
Expand Down Expand Up @@ -943,7 +957,9 @@ impl InputState {
}
}
E(K::Char('J'), M::CTRL) |
E::ENTER => Cmd::AcceptLine,
E::ENTER => {
Cmd::AcceptOrInsertLine { accept_in_the_middle: true }
}
E(K::Down, M::NONE) => Cmd::LineDownOrNextHistory(1),
E(K::Up, M::NONE) => Cmd::LineUpOrPreviousHistory(1),
E(K::Char('R'), M::CTRL) => Cmd::ReverseSearchHistory,
Expand Down
68 changes: 48 additions & 20 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,7 @@ fn complete_line<H: Helper>(
{
cmd = s.next_cmd(input_state, rdr, false)?;
}
match cmd {
Cmd::SelfInsert(1, 'y') | Cmd::SelfInsert(1, 'Y') => true,
_ => false,
}
matches!(cmd, Cmd::SelfInsert(1, 'y') | Cmd::SelfInsert(1, 'Y'))
} else {
true
};
Expand Down Expand Up @@ -285,15 +282,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 { .. })
{
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,
Expand Down Expand Up @@ -431,6 +429,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());
Expand All @@ -442,7 +441,7 @@ fn readline_edit<H: Helper>(
}

let mut rdr = editor.term.create_reader(&editor.config)?;
if editor.term.is_output_tty() {
if editor.term.is_output_tty() && editor.config.check_cursor_position() {
if let Err(e) = s.move_cursor_at_leftmost(&mut rdr) {
if s.out.sigwinch() {
s.out.update_size();
Expand Down Expand Up @@ -519,13 +518,19 @@ fn readline_edit<H: Helper>(
s.edit_overwrite_char(c)?;
}
Cmd::EndOfFile => {
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);
} else {
if input_state.is_emacs_mode() && !s.line.is_empty() {
s.edit_delete(1)?
} else {
if s.has_hint() || !s.is_default_prompt() {
// 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 s.line.is_empty() {
return Err(error::ReadlineError::Eof);
} else if !input_state.is_emacs_mode() {
break;
}
}
}
Cmd::Move(Movement::EndOfLine) => {
Expand Down Expand Up @@ -585,7 +590,7 @@ fn readline_edit<H: Helper>(
kill_ring.kill(&text, Mode::Append)
}
}
Cmd::AcceptLine | Cmd::AcceptOrInsertLine => {
Cmd::AcceptLine | Cmd::AcceptOrInsertLine { .. } | Cmd::Newline => {
#[cfg(test)]
{
editor.term.cursor = s.layout.cursor.col;
Expand All @@ -595,13 +600,27 @@ 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, ..)
| (Cmd::AcceptOrInsertLine { .. }, false, _)
| (Cmd::AcceptOrInsertLine { .. }, true, false) => {
s.edit_insert('\n', 1)?;
}
_ => unreachable!(),
}
continue;
}
Cmd::BeginningOfHistory => {
// move to first entry in history
Expand Down Expand Up @@ -666,6 +685,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_buffer_end()?;
return Err(error::ReadlineError::Interrupted);
}
#[cfg(unix)]
Expand All @@ -681,6 +704,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
}
Expand Down
5 changes: 1 addition & 4 deletions src/line_buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1020,10 +1020,7 @@ impl LineBuffer {

/// Kill range specified by `mvt`.
pub fn kill(&mut self, mvt: &Movement) -> bool {
let notify = match *mvt {
Movement::ForwardChar(_) | Movement::BackwardChar(_) => false,
_ => true,
};
let notify = !matches!(*mvt, Movement::ForwardChar(_) | Movement::BackwardChar(_));
if notify {
if let Some(dl) = self.dl.as_ref() {
let mut dl = dl.lock().unwrap();
Expand Down
7 changes: 6 additions & 1 deletion src/test/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,12 @@ fn complete_line() {
let keys = vec![E::ENTER];
let mut rdr: IntoIter<KeyEvent> = keys.into_iter();
let cmd = super::complete_line(&mut rdr, &mut s, &mut input_state, &Config::default()).unwrap();
assert_eq!(Some(Cmd::AcceptLine), cmd);
assert_eq!(
Some(Cmd::AcceptOrInsertLine {
accept_in_the_middle: true
}),
cmd
);
assert_eq!("rust", s.line.as_str());
assert_eq!(4, s.line.pos());
}
Expand Down
2 changes: 1 addition & 1 deletion src/tty/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -824,7 +824,7 @@ impl Renderer for PosixRenderer {
}
// we have to generate our own newline on line wrap
if end_pos.col == 0 && end_pos.row > 0 && !self.buffer.ends_with('\n') {
self.buffer.push_str("\n");
self.buffer.push('\n');
}
// position the cursor
let new_cursor_row_movement = end_pos.row - cursor.row;
Expand Down

0 comments on commit 6dcfd61

Please sign in to comment.