Skip to content

Commit

Permalink
Merge pull request #455 from tailhook/factor_out_execute
Browse files Browse the repository at this point in the history
Factored out execute function for the main loop
  • Loading branch information
gwenn authored Nov 11, 2020
2 parents 8aa4ed2 + 76e2686 commit 90742b3
Show file tree
Hide file tree
Showing 2 changed files with 272 additions and 235 deletions.
235 changes: 235 additions & 0 deletions src/command.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
use std::sync::{Arc, Mutex};

use crate::{Helper, Result};
use crate::{complete_hint_line};
use crate::config::Config;
use crate::edit::State;
use crate::error;
use crate::history::{Direction};
use crate::keymap::{Anchor, At, Cmd, Movement, Word};
use crate::kill_ring::{KillRing, Mode};
use crate::line_buffer::WordAction;
use crate::keymap::{InputState, Refresher};


pub enum Status {
Proceed,
Submit,
}

pub fn execute<H: Helper>(
cmd: Cmd,
s: &mut State<'_, '_, H>,
input_state: &InputState,
kill_ring: &Arc<Mutex<KillRing>>,
config: &Config,
) -> Result<Status> {
use Status::*;

match cmd {
Cmd::CompleteHint => {
complete_hint_line(s)?;
}
Cmd::SelfInsert(n, c) => {
s.edit_insert(c, n)?;
}
Cmd::Insert(n, text) => {
s.edit_yank(&input_state, &text, Anchor::Before, n)?;
}
Cmd::Move(Movement::BeginningOfLine) => {
// Move to the beginning of line.
s.edit_move_home()?
}
Cmd::Move(Movement::ViFirstPrint) => {
s.edit_move_home()?;
s.edit_move_to_next_word(At::Start, Word::Big, 1)?
}
Cmd::Move(Movement::BackwardChar(n)) => {
// Move back a character.
s.edit_move_backward(n)?
}
Cmd::ReplaceChar(n, c) => s.edit_replace_char(c, n)?,
Cmd::Replace(mvt, text) => {
s.edit_kill(&mvt)?;
if let Some(text) = text {
s.edit_insert_text(&text)?
}
}
Cmd::Overwrite(c) => {
s.edit_overwrite_char(c)?;
}
Cmd::EndOfFile => {
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() {
return Ok(Submit);
}
}
}
Cmd::Move(Movement::EndOfLine) => {
// Move to the end of line.
s.edit_move_end()?
}
Cmd::Move(Movement::ForwardChar(n)) => {
// Move forward a character.
s.edit_move_forward(n)?
}
Cmd::ClearScreen => {
// Clear the screen leaving the current line at the top of the screen.
s.clear_screen()?;
s.refresh_line()?
}
Cmd::NextHistory => {
// Fetch the next command from the history list.
s.edit_history_next(false)?
}
Cmd::PreviousHistory => {
// Fetch the previous command from the history list.
s.edit_history_next(true)?
}
Cmd::LineUpOrPreviousHistory(n) => {
if !s.edit_move_line_up(n)? {
s.edit_history_next(true)?
}
}
Cmd::LineDownOrNextHistory(n) => {
if !s.edit_move_line_down(n)? {
s.edit_history_next(false)?
}
}
Cmd::HistorySearchBackward => s.edit_history_search(Direction::Reverse)?,
Cmd::HistorySearchForward => s.edit_history_search(Direction::Forward)?,
Cmd::TransposeChars => {
// Exchange the char before cursor with the character at cursor.
s.edit_transpose_chars()?
}
Cmd::Yank(n, anchor) => {
// retrieve (yank) last item killed
let mut kill_ring = kill_ring.lock().unwrap();
if let Some(text) = kill_ring.yank() {
s.edit_yank(&input_state, text, anchor, n)?
}
}
Cmd::ViYankTo(ref mvt) => {
if let Some(text) = s.line.copy(mvt) {
let mut kill_ring = kill_ring.lock().unwrap();
kill_ring.kill(&text, Mode::Append)
}
}
Cmd::AcceptLine | Cmd::AcceptOrInsertLine { .. } | Cmd::Newline => {
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)?;
}
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,
_,
) => {
return Ok(Submit);
}
(Cmd::Newline, ..)
| (Cmd::AcceptOrInsertLine { .. }, false, _)
| (Cmd::AcceptOrInsertLine { .. }, true, false) => {
s.edit_insert('\n', 1)?;
}
_ => unreachable!(),
}
}
Cmd::BeginningOfHistory => {
// move to first entry in history
s.edit_history(true)?
}
Cmd::EndOfHistory => {
// move to last entry in history
s.edit_history(false)?
}
Cmd::Move(Movement::BackwardWord(n, word_def)) => {
// move backwards one word
s.edit_move_to_prev_word(word_def, n)?
}
Cmd::CapitalizeWord => {
// capitalize word after point
s.edit_word(WordAction::CAPITALIZE)?
}
Cmd::Kill(ref mvt) => {
s.edit_kill(mvt)?;
}
Cmd::Move(Movement::ForwardWord(n, at, word_def)) => {
// move forwards one word
s.edit_move_to_next_word(at, word_def, n)?
}
Cmd::Move(Movement::LineUp(n)) => {
s.edit_move_line_up(n)?;
}
Cmd::Move(Movement::LineDown(n)) => {
s.edit_move_line_down(n)?;
}
Cmd::Move(Movement::BeginningOfBuffer) => {
// Move to the start of the buffer.
s.edit_move_buffer_start()?
}
Cmd::Move(Movement::EndOfBuffer) => {
// Move to the end of the buffer.
s.edit_move_buffer_end()?
}
Cmd::DowncaseWord => {
// lowercase word after point
s.edit_word(WordAction::LOWERCASE)?
}
Cmd::TransposeWords(n) => {
// transpose words
s.edit_transpose_words(n)?
}
Cmd::UpcaseWord => {
// uppercase word after point
s.edit_word(WordAction::UPPERCASE)?
}
Cmd::YankPop => {
// yank-pop
let mut kill_ring = kill_ring.lock().unwrap();
if let Some((yank_size, text)) = kill_ring.yank_pop() {
s.edit_yank_pop(yank_size, text)?
}
}
Cmd::Move(Movement::ViCharSearch(n, cs)) => s.edit_move_to(cs, n)?,
Cmd::Undo(n) => {
if s.changes.borrow_mut().undo(&mut s.line, n) {
s.refresh_line()?;
}
}
Cmd::Dedent(mvt) => {
s.edit_indent(&mvt, config.indent_size(), true)?;
}
Cmd::Indent(mvt) => {
s.edit_indent(&mvt, config.indent_size(), false)?;
}
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);
}
_ => {
// Ignore the character typed.
}
}
return Ok(Proceed);
}
Loading

0 comments on commit 90742b3

Please sign in to comment.