From c60f1a655333f41460e21a2e193734864f43211c Mon Sep 17 00:00:00 2001
From: Jan Hrastnik <jan.hrastnik2@gmail.com>
Date: Fri, 9 Oct 2020 22:55:45 +0200
Subject: [PATCH] created prompt.rs

---
 helix-term/src/editor.rs   | 23 ++++++++++++++++++-----
 helix-view/src/commands.rs |  9 ++++++++-
 helix-view/src/lib.rs      |  1 +
 helix-view/src/prompt.rs   | 18 ++++++++++++++++++
 4 files changed, 45 insertions(+), 6 deletions(-)
 create mode 100644 helix-view/src/prompt.rs

diff --git a/helix-term/src/editor.rs b/helix-term/src/editor.rs
index 819196f5..ba0bc648 100644
--- a/helix-term/src/editor.rs
+++ b/helix-term/src/editor.rs
@@ -1,6 +1,6 @@
 use clap::ArgMatches as Args;
 use helix_core::{indent::TAB_WIDTH, state::Mode, syntax::HighlightEvent, Position, Range, State};
-use helix_view::{commands, keymap, View};
+use helix_view::{commands, keymap, prompt::Prompt, View};
 
 use std::{
     borrow::Cow,
@@ -36,6 +36,7 @@ pub struct Editor {
     size: (u16, u16),
     surface: Surface,
     cache: Surface,
+    prompt: Prompt,
 }
 
 impl Editor {
@@ -45,6 +46,7 @@ impl Editor {
         let mut terminal = Terminal::new(backend)?;
         let size = terminal::size().unwrap();
         let area = Rect::new(0, 0, size.0, size.1);
+        let prompt = Prompt::new();
 
         let mut editor = Editor {
             terminal,
@@ -52,6 +54,8 @@ impl Editor {
             size,
             surface: Surface::empty(area),
             cache: Surface::empty(area),
+            // TODO; move to state
+            prompt,
         };
 
         if let Some(file) = args.values_of_t::<PathBuf>("files").unwrap().pop() {
@@ -264,8 +268,14 @@ impl Editor {
             Rect::new(0, self.size.1 - 1, self.size.0, 1),
             view.theme.get("ui.statusline"),
         );
+        // render buffer text
+        let buffer_string = &self.prompt.buffer;
+        self.surface
+            .set_string(2, self.size.1 - 1, buffer_string, text_color);
+
         self.surface
             .set_string(1, self.size.1 - 1, mode, text_color);
+
         self.terminal
             .backend_mut()
             .draw(self.cache.diff(&self.surface).into_iter());
@@ -282,7 +292,7 @@ impl Editor {
             mode => write!(stdout, "\x1B[2 q"),
         };
         if view.state.mode() == Mode::Command {
-            pos = Position::new(self.size.0 as usize, 2);
+            pos = Position::new(self.size.0 as usize, 2 + self.prompt.buffer.len());
         } else {
             if let Some(path) = view.state.path() {
                 self.surface
@@ -349,12 +359,16 @@ impl Editor {
                                     commands::insert::insert_char(view, c);
                                 }
                                 view.ensure_cursor_in_view();
-                                self.render();
                             }
                             Mode::Command => {
                                 if let Some(command) = keymap[&Mode::Command].get(&keys) {
                                     command(view, 1);
-                                    self.render();
+                                } else if let KeyEvent {
+                                    code: KeyCode::Char(c),
+                                    ..
+                                } = event
+                                {
+                                    commands::insert_char_prompt(&mut self.prompt, c)
                                 }
                             }
                             mode => {
@@ -363,7 +377,6 @@ impl Editor {
 
                                     // TODO: simplistic ensure cursor in view for now
                                     view.ensure_cursor_in_view();
-                                    self.render();
                                 }
                             }
                         }
diff --git a/helix-view/src/commands.rs b/helix-view/src/commands.rs
index 0e3f7ce8..6efbf98d 100644
--- a/helix-view/src/commands.rs
+++ b/helix-view/src/commands.rs
@@ -8,7 +8,10 @@ use helix_core::{
 };
 use once_cell::sync::Lazy;
 
-use crate::view::{View, PADDING};
+use crate::{
+    prompt::Prompt,
+    view::{View, PADDING},
+};
 
 /// A command is a function that takes the current state and a count, and does a side-effect on the
 /// state (usually by creating and applying a transaction).
@@ -478,6 +481,10 @@ pub mod insert {
     }
 }
 
+pub fn insert_char_prompt(prompt: &mut Prompt, c: char) {
+    prompt.insert_char(c);
+}
+
 // Undo / Redo
 
 pub fn undo(view: &mut View, _count: usize) {
diff --git a/helix-view/src/lib.rs b/helix-view/src/lib.rs
index 2a000f32..e0a230ca 100644
--- a/helix-view/src/lib.rs
+++ b/helix-view/src/lib.rs
@@ -1,5 +1,6 @@
 pub mod commands;
 pub mod keymap;
+pub mod prompt;
 pub mod theme;
 pub mod view;
 
diff --git a/helix-view/src/prompt.rs b/helix-view/src/prompt.rs
new file mode 100644
index 00000000..4aaf770b
--- /dev/null
+++ b/helix-view/src/prompt.rs
@@ -0,0 +1,18 @@
+use std::string::String;
+
+pub struct Prompt {
+    pub buffer: String,
+}
+
+impl Prompt {
+    pub fn new() -> Prompt {
+        let prompt = Prompt {
+            buffer: String::from(""),
+        };
+        prompt
+    }
+
+    pub fn insert_char(&mut self, c: char) {
+        self.buffer.push(c);
+    }
+}