summaryrefslogtreecommitdiffstats
path: root/src/edit/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/edit/mod.rs')
-rw-r--r--src/edit/mod.rs162
1 files changed, 159 insertions, 3 deletions
diff --git a/src/edit/mod.rs b/src/edit/mod.rs
index 7083f01..2f500be 100644
--- a/src/edit/mod.rs
+++ b/src/edit/mod.rs
@@ -1,4 +1,160 @@
-#[allow(clippy::module_inception)]
-mod edit;
+use crate::display::display_color::DisplayColor;
+use crate::git_interactive::GitInteractive;
+use crate::input::input_handler::InputHandler;
+use crate::input::Input;
+use crate::process::handle_input_result::HandleInputResult;
+use crate::process::process_module::ProcessModule;
+use crate::process::process_result::{ProcessResult, ProcessResultBuilder};
+use crate::process::state::State;
+use crate::view::View;
+use unicode_segmentation::UnicodeSegmentation;
-pub use self::edit::Edit;
+#[derive(Clone, Copy, Debug, PartialEq)]
+enum EditState {
+ Active,
+ Finish,
+}
+
+pub(crate) struct Edit {
+ content: String,
+ cursor_position: usize,
+ state: EditState,
+}
+
+impl ProcessModule for Edit {
+ fn activate(&mut self, _state: State, application: &GitInteractive) {
+ self.state = EditState::Active;
+ self.content = application.get_selected_line_edit_content().clone();
+ self.cursor_position = UnicodeSegmentation::graphemes(self.content.as_str(), true).count();
+ }
+
+ fn deactivate(&mut self) {
+ self.content.clear();
+ self.cursor_position = 0;
+ }
+
+ fn process(&mut self, git_interactive: &mut GitInteractive, _view: &View) -> ProcessResult {
+ let mut result = ProcessResultBuilder::new();
+ match self.state {
+ EditState::Active => {},
+ EditState::Finish => {
+ git_interactive.edit_selected_line(self.content.as_str());
+ result = result.state(State::List(false));
+ },
+ };
+ result.build()
+ }
+
+ fn handle_input(
+ &mut self,
+ input_handler: &InputHandler,
+ _git_interactive: &mut GitInteractive,
+ _view: &View,
+ ) -> HandleInputResult
+ {
+ if self.state == EditState::Finish {
+ return HandleInputResult::new(Input::Enter);
+ }
+ let mut input;
+ loop {
+ input = input_handler.get_character();
+ match input {
+ Input::Character(c) => {
+ let start = UnicodeSegmentation::graphemes(self.content.as_str(), true)
+ .take(self.cursor_position)
+ .collect::<String>();
+ let end = UnicodeSegmentation::graphemes(self.content.as_str(), true)
+ .skip(self.cursor_position)
+ .collect::<String>();
+ self.content = format!("{}{}{}", start, c, end);
+ self.cursor_position += 1;
+ },
+ Input::Backspace => {
+ if self.cursor_position == 0 {
+ break;
+ }
+ let start = UnicodeSegmentation::graphemes(self.content.as_str(), true)
+ .take(self.cursor_position - 1)
+ .collect::<String>();
+ let end = UnicodeSegmentation::graphemes(self.content.as_str(), true)
+ .skip(self.cursor_position)
+ .collect::<String>();
+ self.content = format!("{}{}", start, end);
+ self.cursor_position -= 1;
+ },
+ Input::Delete => {
+ let length = UnicodeSegmentation::graphemes(self.content.as_str(), true).count();
+ if self.cursor_position == length {
+ break;
+ }
+ let start = UnicodeSegmentation::graphemes(self.content.as_str(), true)
+ .take(self.cursor_position)
+ .collect::<String>();
+ let end = UnicodeSegmentation::graphemes(self.content.as_str(), true)
+ .skip(self.cursor_position + 1)
+ .collect::<String>();
+ self.content = format!("{}{}", start, end);
+ },
+ Input::MoveCursorRight => {
+ let length = UnicodeSegmentation::graphemes(self.content.as_str(), true).count();
+ if self.cursor_position < length {
+ self.cursor_position += 1;
+ }
+ },
+ Input::MoveCursorLeft => {
+ if self.cursor_position != 0 {
+ self.cursor_position -= 1;
+ }
+ },
+ Input::Enter => self.state = EditState::Finish,
+ _ => {
+ continue;
+ },
+ }
+ break;
+ }
+ HandleInputResult::new(input)
+ }
+
+ fn render(&self, view: &View, _git_interactive: &GitInteractive) {
+ let line = self.content.as_str();
+ let pointer = self.cursor_position;
+
+ view.draw_title(false);
+ view.set_style(false, true, false);
+ view.set_color(DisplayColor::Normal, false);
+
+ // this could probably be made way more efficient
+ let graphemes = UnicodeSegmentation::graphemes(line, true);
+ let segment_length = graphemes.clone().count();
+ for (counter, c) in graphemes.enumerate() {
+ if counter == pointer {
+ view.set_style(false, true, false);
+ view.draw_str(c);
+ view.set_style(false, false, false);
+ }
+ else {
+ view.draw_str(c);
+ }
+ }
+ if pointer >= segment_length {
+ view.set_style(false, true, false);
+ view.draw_str(" ");
+ view.set_style(false, false, false);
+ }
+
+ view.draw_str("\n\n");
+ view.set_color(DisplayColor::IndicatorColor, false);
+ view.draw_str("Enter to finish");
+ }
+}
+
+impl Edit {
+ pub(crate) fn new() -> Self {
+ Self {
+ content: String::from(""),
+ cursor_position: 0,
+ state: EditState::Active,
+ }
+ }
+}