From ed03ec92a825b8e42005f2f8506b0f3db4923fa5 Mon Sep 17 00:00:00 2001
From: Jan Hrastnik <jan.hrastnik2@gmail.com>
Date: Tue, 13 Oct 2020 00:23:48 +0200
Subject: [PATCH] moved prompt command matching to prompt.rs

---
 helix-core/src/state.rs    |  2 +-
 helix-term/src/editor.rs   | 29 +++++++++++++----------------
 helix-view/src/commands.rs | 16 ++++++++++++++--
 helix-view/src/keymap.rs   |  4 ++--
 helix-view/src/prompt.rs   | 20 +++++++++++++++++++-
 5 files changed, 49 insertions(+), 22 deletions(-)

diff --git a/helix-core/src/state.rs b/helix-core/src/state.rs
index bd14850f..805940fb 100644
--- a/helix-core/src/state.rs
+++ b/helix-core/src/state.rs
@@ -10,7 +10,7 @@ pub enum Mode {
     Normal,
     Insert,
     Goto,
-    Command,
+    Prompt,
 }
 
 /// A state represents the current editor state of a single buffer.
diff --git a/helix-term/src/editor.rs b/helix-term/src/editor.rs
index e32c7507..22ede486 100644
--- a/helix-term/src/editor.rs
+++ b/helix-term/src/editor.rs
@@ -237,7 +237,7 @@ impl Editor {
             Mode::Insert => "INS",
             Mode::Normal => "NOR",
             Mode::Goto => "GOTO",
-            Mode::Command => "COM", // command mode i guess
+            Mode::Prompt => "PRO", // prompt?
         };
         // statusline
         self.surface.set_style(
@@ -252,9 +252,14 @@ impl Editor {
         use tui::backend::Backend;
         let view = self.view.as_ref().unwrap();
         // render buffer text
-        let buffer_string = &self.prompt.buffer;
-        self.surface
-            .set_string(2, self.size.1 - 1, buffer_string, text_color);
+        let buffer_string;
+        if view.state.mode == Mode::Prompt {
+            buffer_string = &self.prompt.buffer;
+            self.surface
+                .set_string(1, self.size.1 - 1, buffer_string, text_color);
+        } else {
+            buffer_string = &String::from("");
+        }
 
         // TODO: theres probably a better place for this
         self.terminal
@@ -272,8 +277,8 @@ impl Editor {
             Mode::Insert => write!(stdout, "\x1B[6 q"),
             mode => write!(stdout, "\x1B[2 q"),
         };
-        if view.state.mode() == Mode::Command {
-            pos = Position::new(self.size.0 as usize, 2 + self.prompt.buffer.len());
+        if view.state.mode() == Mode::Prompt {
+            pos = Position::new(self.size.0 as usize, 1 + self.prompt.buffer.len());
         } else {
             if let Some(path) = view.state.path() {
                 self.surface
@@ -341,16 +346,8 @@ impl Editor {
                                 }
                                 view.ensure_cursor_in_view();
                             }
-                            Mode::Command => {
-                                if let Some(command) = keymap[&Mode::Command].get(&keys) {
-                                    command(view, 1);
-                                } else if let KeyEvent {
-                                    code: KeyCode::Char(c),
-                                    ..
-                                } = event
-                                {
-                                    commands::insert_char_prompt(&mut self.prompt, c)
-                                }
+                            Mode::Prompt => {
+                                self.prompt.handle_keyevent(event, view);
                             }
                             mode => {
                                 if let Some(command) = keymap[&mode].get(&keys) {
diff --git a/helix-view/src/commands.rs b/helix-view/src/commands.rs
index 6efbf98d..888317e7 100644
--- a/helix-view/src/commands.rs
+++ b/helix-view/src/commands.rs
@@ -307,8 +307,20 @@ pub fn append_mode(view: &mut View, _count: usize) {
     })
 }
 
-pub fn command_mode(view: &mut View, _count: usize) {
-    view.state.mode = Mode::Command;
+pub fn prompt_mode(view: &mut View, _count: usize) {
+    view.state.mode = Mode::Prompt;
+}
+
+pub fn move_char_left_prompt(prompt: &mut Prompt, _char: char) {
+    if prompt.cursor_loc > 1 {
+        prompt.cursor_loc -= 1;
+    }
+}
+
+pub fn move_char_right_prompt(prompt: &mut Prompt, _char: char) {
+    if prompt.cursor_loc < prompt.buffer.len() {
+        prompt.cursor_loc += 1;
+    }
 }
 
 // TODO: I, A, o and O can share a lot of the primitives.
diff --git a/helix-view/src/keymap.rs b/helix-view/src/keymap.rs
index 96a37e6b..d6d44779 100644
--- a/helix-view/src/keymap.rs
+++ b/helix-view/src/keymap.rs
@@ -163,7 +163,7 @@ pub fn default() -> Keymaps {
                 vec![key!('p')] => commands::paste,
                 vec![key!('>')] => commands::indent,
                 vec![key!('<')] => commands::unindent,
-                vec![key!(':')] => commands::command_mode,
+                vec![key!(':')] => commands::prompt_mode,
                 vec![Key {
                     code: KeyCode::Esc,
                     modifiers: Modifiers::NONE
@@ -209,7 +209,7 @@ pub fn default() -> Keymaps {
                 vec![key!('g')] => commands::move_file_start as Command,
                 vec![key!('e')] => commands::move_file_end as Command,
             ),
-            state::Mode::Command => hashmap!(
+            state::Mode::Prompt => hashmap!(
                 vec![Key {
                     code: KeyCode::Esc,
                     modifiers: Modifiers::NONE
diff --git a/helix-view/src/prompt.rs b/helix-view/src/prompt.rs
index 4aaf770b..f1920daa 100644
--- a/helix-view/src/prompt.rs
+++ b/helix-view/src/prompt.rs
@@ -1,13 +1,18 @@
+use crate::commands;
+use crate::View;
+use crossterm::event::{KeyCode, KeyEvent};
 use std::string::String;
 
 pub struct Prompt {
     pub buffer: String,
+    pub cursor_loc: usize,
 }
 
 impl Prompt {
     pub fn new() -> Prompt {
         let prompt = Prompt {
-            buffer: String::from(""),
+            buffer: String::from(":"), // starting prompt symbol
+            cursor_loc: 0,
         };
         prompt
     }
@@ -15,4 +20,17 @@ impl Prompt {
     pub fn insert_char(&mut self, c: char) {
         self.buffer.push(c);
     }
+
+    pub fn handle_keyevent(&mut self, key_event: KeyEvent, view: &mut View) {
+        match key_event {
+            KeyEvent {
+                code: KeyCode::Char(c),
+                ..
+            } => self.insert_char(c),
+            KeyEvent {
+                code: KeyCode::Esc, ..
+            } => commands::normal_mode(view, 1),
+            _ => (),
+        }
+    }
 }