use crate::commands::{self, application, Result};
use crate::errors::*;
use crate::input::Key;
use crate::models::application::modes::open::DisplayablePath;
use crate::models::application::modes::SearchSelectMode;
use crate::models::application::{Application, Mode};
use std::mem;
pub fn accept(app: &mut Application) -> Result {
let mut app_mode = mem::replace(&mut app.mode, Mode::Normal);
match app_mode {
Mode::Command(ref mode) => {
let selection = mode.selection().ok_or("No command selected")?;
(selection.command)(app)?;
}
Mode::Open(ref mut mode) => {
let DisplayablePath(path) = mode
.selection()
.ok_or("Couldn't find a selected path to open")?;
let syntax_definition = app
.preferences
.borrow()
.syntax_definition_name(path)
.and_then(|name| app.workspace.syntax_set.find_syntax_by_name(&name).cloned());
app.workspace
.open_buffer(path)
.chain_err(|| "Couldn't open a buffer for the specified path.")?;
let buffer = app.workspace.current_buffer.as_mut().unwrap();
if syntax_definition.is_some() {
buffer.syntax_definition = syntax_definition;
}
app.view.initialize_buffer(buffer)?;
}
Mode::Theme(ref mut mode) => {
let theme_key = mode.selection().ok_or("No theme selected")?;
app.preferences.borrow_mut().set_theme(theme_key.as_str());
}
Mode::SymbolJump(ref mut mode) => {
let buffer = app
.workspace
.current_buffer
.as_mut()
.ok_or(BUFFER_MISSING)?;
let position = mode
.selection()
.ok_or("Couldn't find a position for the selected symbol")?
.position;
if !buffer.cursor.move_to(position) {
bail!("Couldn't move to the selected symbol's position");
}
}
Mode::Syntax(ref mut mode) => {
let name = mode.selection().ok_or("No syntax selected")?;
let syntax = app.workspace.syntax_set.find_syntax_by_name(name).cloned();
let buffer = app
.workspace
.current_buffer
.as_mut()
.ok_or(BUFFER_MISSING)?;
buffer.syntax_definition = syntax;
}
_ => bail!("Can't accept selection outside of search select mode."),
}
commands::view::scroll_cursor_to_center(app).ok();
Ok(())
}
pub fn search(app: &mut Application) -> Result {
match app.mode {
Mode::Command(ref mut mode) => mode.search(),
Mode::Open(ref mut mode) => mode.search(),
Mode::Theme(ref mut mode) => mode.search(),
Mode::SymbolJump(ref mut mode) => mode.search(),
Mode::Syntax(ref mut mode) => mode.search(),
_ => bail!("Can't search outside of search select mode."),
};
Ok(())
}
pub fn select_next(app: &mut Application) -> Result {
match app.mode {
Mode::Command(ref mut mode) => mode.select_next(),
Mode::Open(ref mut mode) => mode.select_next(),
Mode::Theme(ref mut mode) => mode.select_next(),
Mode::SymbolJump(ref mut mode) => mode.select_next(),
Mode::Syntax(ref mut mode) => mode.select_next(),
_ => bail!("Can't change selection outside of search select mode."),
}
Ok(())
}
pub fn select_previous(app: &mut Application) -> Result {
match app.mode {
Mode::Command(ref mut mode) => mode.select_previous(),
Mode::Open(ref mut mode) => mode.select_previous(),
Mode::Theme(ref mut mode) => mode.select_previous(),
Mode::SymbolJump(ref mut mode) => mode.select_previous(),
Mode::Syntax(ref mut mode) => mode.select_previous(),
_ => bail!("Can't change selection outside of search select mode."),
}
Ok(())
}
pub fn enable_insert(app: &mut Application) -> Result {
match app.mode {
Mode::Command(ref mut mode) => mode.set_insert_mode(true),
Mode::Open(ref mut mode) => mode.set_insert_mode(true),
Mode::Theme(ref mut mode) => mode.set_insert_mode(true),
Mode::SymbolJump(ref mut mode) => mode.set_insert_mode(true),
Mode::Syntax(ref mut mode) => mode.set_insert_mode(true),
_ => bail!("Can't change search insert state outside of search select mode"),
}
Ok(())
}
pub fn disable_insert(app: &mut Application) -> Result {
match app.mode {
Mode::Command(ref mut mode) => mode.set_insert_mode(false),
Mode::Open(ref mut mode) => mode.set_insert_mode(false),
Mode::Theme(ref mut mode) => mode.set_insert_mode(false),
Mode::SymbolJump(ref mut mode) => mode.set_insert_mode(false),
Mode::Syntax(ref mut mode) => mode.set_insert_mode(false),
_ => bail!("Can't change search insert state outside of search select mode"),
}
Ok(())
}
pub fn push_search_char(app: &mut Application) -> Result {
if let Some(Key::Char(c)) = *app.view.last_key() {
match app.mode {
Mode::Command(ref mut mode) => mode.push_search_char(c),
Mode::Open(ref mut mode) => mode.push_search_char(c),
Mode::Theme(ref mut mode) => mode.push_search_char(c),
Mode::SymbolJump(ref mut mode) => mode.push_search_char(c),
Mode::Syntax(ref mut mode) => mode.push_search_char(c),
_ => bail!("Can't push search character outside of search select mode"),
}
}
search(app)
}
pub fn pop_search_token(app: &mut Application) -> Result {
match app.mode {
Mode::Command(ref mut mode) => mode.pop_search_token(),
Mode::Open(ref mut mode) => mode.pop_search_token(),
Mode::Theme(ref mut mode) => mode.pop_search_token(),
Mode::SymbolJump(ref mut mode) => mode.pop_search_token(),
Mode::Syntax(ref mut mode) => mode.pop_search_token(),
_ => bail!("Can't pop search token outside of search select mode"),
}
search(app)?;
Ok(())
}
pub fn step_back(app: &mut Application) -> Result {
let result_count = match app.mode {
Mode::Command(ref mut mode) => mode.results().count(),
Mode::Open(ref mut mode) => mode.results().count(),
Mode::Theme(ref mut mode) => mode.results().count(),
Mode::SymbolJump(ref mut mode) => mode.results().count(),
Mode::Syntax(ref mut mode) => mode.results().count(),
_ => bail!("Can't pop search token outside of search select mode"),
};
if result_count == 0 {
application::switch_to_normal_mode(app)
} else {
disable_insert(app)
}
}