summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Oram <dev@mitmaro.ca>2019-06-23 13:50:04 -0230
committerTim Oram <dev@mitmaro.ca>2019-06-23 13:50:04 -0230
commitbd98d8c365cfc714d57762cb8bdf0cbbd45f8e26 (patch)
tree7052ed1b5c4dd026ccaed984683dc3fe1c82aa3f
parent669f865a1d28be02f0cef10410492721888208af (diff)
Move external editor to module
-rw-r--r--src/application.rs120
-rw-r--r--src/external_editor/external_editor.rs141
-rw-r--r--src/external_editor/mod.rs4
-rw-r--r--src/main.rs1
-rw-r--r--src/process/state.rs4
5 files changed, 160 insertions, 110 deletions
diff --git a/src/application.rs b/src/application.rs
index f012ea3..fa97798 100644
--- a/src/application.rs
+++ b/src/application.rs
@@ -6,28 +6,19 @@ use crate::confirm_abort::ConfirmAbort;
use crate::confirm_rebase::ConfirmRebase;
use crate::constants::{LIST_HELP_LINES, VISUAL_MODE_HELP_LINES};
use crate::edit::Edit;
+use crate::external_editor::ExternalEditor;
use crate::input::{Input, InputHandler};
-use crate::process::{
- ExitStatus,
- HandleInputResult,
- HandleInputResultBuilder,
- ProcessModule,
- ProcessResult,
- ProcessResultBuilder,
- State,
-};
+use crate::process::{ExitStatus, HandleInputResult, HandleInputResultBuilder, ProcessModule, ProcessResult, State};
use crate::show_commit::ShowCommit;
use crate::view::View;
-use crate::window::Window;
use core::borrow::Borrow;
-use std::process::Command;
-use std::process::ExitStatus as ProcessExitStatus;
pub struct Application<'a> {
config: &'a Config,
confirm_abort: ConfirmAbort,
confirm_rebase: ConfirmRebase,
edit: Edit,
+ external_editor: ExternalEditor<'a>,
git_interactive: GitInteractive,
input_handler: &'a InputHandler<'a>,
show_commit: ShowCommit,
@@ -47,6 +38,7 @@ impl<'a> Application<'a> {
confirm_abort: ConfirmAbort::new(),
confirm_rebase: ConfirmRebase::new(),
edit: Edit::new(),
+ external_editor: ExternalEditor::new(config),
git_interactive,
input_handler,
show_commit: ShowCommit::new(),
@@ -65,9 +57,7 @@ impl<'a> Application<'a> {
State::Edit => self.edit.activate(state, &self.git_interactive),
State::Error { .. } => {},
State::Exiting => {},
- State::ExternalEditor(_) => {},
- State::ExternalEditorError => {},
- State::ExternalEditorFinish(_) => {},
+ State::ExternalEditor => self.external_editor.activate(state, &self.git_interactive),
State::Help(_) => {},
State::List => {},
State::ShowCommit => self.show_commit.activate(state, &self.git_interactive),
@@ -83,9 +73,7 @@ impl<'a> Application<'a> {
State::Edit => self.edit.deactivate(),
State::Error { .. } => {},
State::Exiting => {},
- State::ExternalEditor(_) => {},
- State::ExternalEditorError => {},
- State::ExternalEditorFinish(_) => {},
+ State::ExternalEditor => self.external_editor.deactivate(),
State::Help(_) => {},
State::List => {},
State::ShowCommit => self.show_commit.deactivate(),
@@ -101,9 +89,7 @@ impl<'a> Application<'a> {
State::Edit => self.edit.process(&mut self.git_interactive),
State::Error { .. } => ProcessResult::new(),
State::Exiting => ProcessResult::new(),
- State::ExternalEditor(return_state) => self.process_external_editor(return_state.borrow()),
- State::ExternalEditorError => self.process_external_editor_error(),
- State::ExternalEditorFinish(_) => self.process_external_editor_finish(),
+ State::ExternalEditor => self.external_editor.process(&mut self.git_interactive),
State::Help(_) => ProcessResult::new(),
State::List => self.process_list(),
State::ShowCommit => self.show_commit.process(&mut self.git_interactive),
@@ -112,48 +98,6 @@ impl<'a> Application<'a> {
}
}
- pub fn process_external_editor(&mut self, return_state: &State) -> ProcessResult {
- let mut result = ProcessResultBuilder::new();
-
- result = if let Err(e) = self.run_editor() {
- result.error(e.as_str(), State::ExternalEditorError)
- }
- else {
- result.state(State::ExternalEditorFinish(Box::new(return_state.clone())))
- };
-
- result.build()
- }
-
- pub fn process_external_editor_finish(&mut self) -> ProcessResult {
- let mut result = ProcessResultBuilder::new();
- result = if let Err(e) = self.git_interactive.reload_file(self.config.comment_char.as_str()) {
- result.error(e.as_str(), State::List)
- }
- else if self.git_interactive.get_lines().is_empty() {
- result.error("Rebase empty", State::List)
- }
- else {
- result.state(State::List)
- };
-
- result.build()
- }
-
- pub fn process_external_editor_error(&mut self) -> ProcessResult {
- ProcessResultBuilder::new()
- .state(State::Exiting)
- .exit_status(
- if self.git_interactive.get_lines().is_empty() {
- ExitStatus::Good
- }
- else {
- ExitStatus::StateError
- },
- )
- .build()
- }
-
pub fn process_list(&mut self) -> ProcessResult {
let lines = self.git_interactive.get_lines();
let selected_index = self.get_cursor_index();
@@ -173,9 +117,7 @@ impl<'a> Application<'a> {
State::Edit => self.edit.render(&self.view, &self.git_interactive),
State::Error { message, .. } => self.draw_error(message.as_str()),
State::Exiting => self.draw_exiting(),
- State::ExternalEditor(_) => {},
- State::ExternalEditorError => {},
- State::ExternalEditorFinish(_) => {},
+ State::ExternalEditor => self.external_editor.render(&self.view, &self.git_interactive),
State::Help(help_state) => self.draw_help(help_state.borrow()),
State::List => self.draw_main(false),
State::VisualMode => self.draw_main(true),
@@ -238,9 +180,10 @@ impl<'a> Application<'a> {
State::Edit => self.edit.handle_input(&self.input_handler, &mut self.git_interactive),
State::Error { return_state, .. } => self.handle_error_input(return_state.borrow()),
State::Exiting => HandleInputResult::new(Input::Other),
- State::ExternalEditor(return_state) => self.handle_external_editor_input(return_state.borrow()),
- State::ExternalEditorError => HandleInputResult::new(Input::Other),
- State::ExternalEditorFinish(_) => HandleInputResult::new(Input::Other),
+ State::ExternalEditor => {
+ self.external_editor
+ .handle_input(&self.input_handler, &mut self.git_interactive)
+ },
State::Help(help_state) => self.handle_help_input(help_state.borrow()),
State::List => self.handle_list_input(),
State::VisualMode => self.handle_visual_mode_input(),
@@ -326,18 +269,6 @@ impl<'a> Application<'a> {
result.build()
}
- pub fn handle_external_editor_input(&mut self, return_state: &State) -> HandleInputResult {
- let input = self.get_input();
- let mut result = HandleInputResultBuilder::new(input);
- match input {
- Input::Resize => {},
- _ => {
- result = result.state(return_state.clone());
- },
- }
- result.build()
- }
-
pub fn handle_list_input(&mut self) -> HandleInputResult {
let input = self.get_input();
let mut result = HandleInputResultBuilder::new(input);
@@ -386,7 +317,7 @@ impl<'a> Application<'a> {
self.git_interactive.start_visual_mode();
result = result.state(State::VisualMode);
},
- Input::OpenInEditor => result = result.state(State::ExternalEditor(Box::new(State::List))),
+ Input::OpenInEditor => result = result.state(State::ExternalEditor),
_ => {},
}
result.build()
@@ -396,31 +327,6 @@ impl<'a> Application<'a> {
HandleInputResult::new(self.get_input())
}
- pub fn run_editor(&mut self) -> Result<(), String> {
- self.git_interactive.write_file()?;
- let filepath = self.git_interactive.get_filepath();
- let callback = || -> Result<ProcessExitStatus, String> {
- // TODO: This doesn't handle editor with arguments (e.g. EDITOR="edit --arg")
- Command::new(&self.config.editor)
- .arg(filepath.as_os_str())
- .status()
- .map_err(|e| {
- format!(
- "Unable to run editor ({}):\n{}",
- self.config.editor.to_string_lossy(),
- e.to_string()
- )
- })
- };
- let exit_status: ProcessExitStatus = Window::leave_temporarily(callback)?;
-
- if !exit_status.success() {
- return Err(String::from("Editor returned non-zero exit status."));
- }
-
- Ok(())
- }
-
pub fn write_file(&self) -> Result<(), String> {
self.git_interactive.write_file()
}
diff --git a/src/external_editor/external_editor.rs b/src/external_editor/external_editor.rs
new file mode 100644
index 0000000..b7fd186
--- /dev/null
+++ b/src/external_editor/external_editor.rs
@@ -0,0 +1,141 @@
+use crate::config::Config;
+use crate::git_interactive::GitInteractive;
+use crate::input::{Input, InputHandler};
+use crate::process::{
+ ExitStatus,
+ HandleInputResult,
+ HandleInputResultBuilder,
+ ProcessModule,
+ ProcessResult,
+ ProcessResultBuilder,
+ State,
+};
+use crate::view::View;
+use crate::window::Window;
+use std::process::Command;
+use std::process::ExitStatus as ProcessExitStatus;
+
+enum ExternalEditorState {
+ Active,
+ Error,
+ Finish,
+}
+
+pub struct ExternalEditor<'e> {
+ state: ExternalEditorState,
+ config: &'e Config,
+}
+
+impl<'e> ProcessModule for ExternalEditor<'e> {
+ fn activate(&mut self, _state: State, _git_interactive: &GitInteractive) {
+ self.state = ExternalEditorState::Active;
+ }
+
+ fn process(&mut self, git_interactive: &mut GitInteractive) -> ProcessResult {
+ match self.state {
+ ExternalEditorState::Active => self.process_active(git_interactive),
+ ExternalEditorState::Error => self.process_error(git_interactive),
+ ExternalEditorState::Finish => self.process_finish(git_interactive),
+ }
+ }
+
+ fn handle_input(
+ &mut self,
+ input_handler: &InputHandler,
+ _git_interactive: &mut GitInteractive,
+ ) -> HandleInputResult
+ {
+ match self.state {
+ ExternalEditorState::Active => self.handle_input_active(input_handler),
+ _ => HandleInputResult::new(Input::Other),
+ }
+ }
+
+ fn render(&self, _view: &View, _git_interactive: &GitInteractive) {}
+}
+
+impl<'e> ExternalEditor<'e> {
+ pub fn new(config: &'e Config) -> Self {
+ Self {
+ config,
+ state: ExternalEditorState::Active,
+ }
+ }
+
+ pub fn run_editor(&mut self, git_interactive: &GitInteractive) -> Result<(), String> {
+ git_interactive.write_file()?;
+ let filepath = git_interactive.get_filepath();
+ let callback = || -> Result<ProcessExitStatus, String> {
+ // TODO: This doesn't handle editor with arguments (e.g. EDITOR="edit --arg")
+ Command::new(&self.config.editor)
+ .arg(filepath.as_os_str())
+ .status()
+ .map_err(|e| {
+ format!(
+ "Unable to run editor ({}):\n{}",
+ self.config.editor.to_string_lossy(),
+ e.to_string()
+ )
+ })
+ };
+ let exit_status: ProcessExitStatus = Window::leave_temporarily(callback)?;
+
+ if !exit_status.success() {
+ return Err(String::from("Editor returned non-zero exit status."));
+ }
+
+ Ok(())
+ }
+
+ fn process_active(&mut self, git_interactive: &GitInteractive) -> ProcessResult {
+ let mut result = ProcessResultBuilder::new();
+ if let Err(e) = self.run_editor(git_interactive) {
+ result = result.error(e.as_str(), State::ExternalEditor);
+ self.state = ExternalEditorState::Error;
+ }
+ else {
+ self.state = ExternalEditorState::Finish;
+ }
+ result.build()
+ }
+
+ fn process_finish(&mut self, git_interactive: &mut GitInteractive) -> ProcessResult {
+ let mut result = ProcessResultBuilder::new();
+ if let Err(e) = git_interactive.reload_file(self.config.comment_char.as_str()) {
+ result = result.error(e.as_str(), State::ExternalEditor);
+ self.state = ExternalEditorState::Error;
+ }
+ else if git_interactive.get_lines().is_empty() {
+ result = result.error("Rebase TODO list is empty", State::ExternalEditor);
+ self.state = ExternalEditorState::Error;
+ }
+ else {
+ result = result.state(State::List);
+ }
+ result.build()
+ }
+
+ fn process_error(&self, git_interactive: &GitInteractive) -> ProcessResult {
+ let mut result = ProcessResultBuilder::new().state(State::Exiting);
+
+ if git_interactive.get_lines().is_empty() {
+ result = result.exit_status(ExitStatus::Good);
+ }
+ else {
+ result = result.exit_status(ExitStatus::StateError);
+ }
+ result.build()
+ }
+
+ pub fn handle_input_active(&self, input_handler: &InputHandler) -> HandleInputResult {
+ let input = input_handler.get_input();
+ let mut result = HandleInputResultBuilder::new(input);
+ match input {
+ Input::Resize => {},
+ _ => {
+ result = result.state(State::List);
+ },
+ }
+ result.build()
+ }
+}
diff --git a/src/external_editor/mod.rs b/src/external_editor/mod.rs
new file mode 100644
index 0000000..efa7480
--- /dev/null
+++ b/src/external_editor/mod.rs
@@ -0,0 +1,4 @@
+#[allow(clippy::module_inception)]
+mod external_editor;
+
+pub use self::external_editor::ExternalEditor;
diff --git a/src/main.rs b/src/main.rs
index a4983d3..4231db2 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -11,6 +11,7 @@ mod confirm_abort;
mod confirm_rebase;
mod constants;
mod edit;
+mod external_editor;
mod git_interactive;
mod input;
mod line;
diff --git a/src/process/state.rs b/src/process/state.rs
index d750982..b286cb9 100644
--- a/src/process/state.rs
+++ b/src/process/state.rs
@@ -5,9 +5,7 @@ pub enum State {
Edit,
Error { return_state: Box<State>, message: String },
Exiting,
- ExternalEditor(Box<State>),
- ExternalEditorError,
- ExternalEditorFinish(Box<State>),
+ ExternalEditor,
Help(Box<State>),
List,
ShowCommit,