Browse Source

Feat insert (#23)

* Insert mode
Z YS 7 months ago
parent
commit
f277e13458

+ 10 - 0
src/application/handler/app.rs

@@ -6,3 +6,13 @@ pub fn exit(app: &mut Application) -> Result<()> {
     app.switch_mode(ModeKey::Exit);
     Ok(())
 }
+
+pub fn to_insert_mode(app: &mut Application) -> Result<()> {
+    app.switch_mode(ModeKey::Insert);
+    Ok(())
+}
+
+pub fn to_normal_mode(app: &mut Application) -> Result<()> {
+    app.switch_mode(ModeKey::Normal);
+    Ok(())
+}

+ 13 - 1
src/application/handler/buffer.rs

@@ -4,5 +4,17 @@ use crate::application::Application;
 use crate::errors::*;
 
 pub fn insert_char(app: &mut Application) -> Result<()> {
-    todo!()
+    if let Some(key) = app.monitor.last_key {
+        if let KeyCode::Char(c) = key.code {
+            app.workspace.current_buffer.as_mut().unwrap().insert(c);
+        }
+    }
+    Ok(())
+}
+
+pub fn new_line(app: &mut Application) -> Result<()> {
+    if let Some(ref mut buffer) = app.workspace.current_buffer {
+        buffer.insert('\n');
+    }
+    Ok(())
 }

+ 7 - 0
src/application/handler/cursor.rs

@@ -32,3 +32,10 @@ pub fn move_down(app: &mut Application) -> Result<()> {
     }
     Ok(())
 }
+
+pub fn move_to_start_of_line(app: &mut Application) -> Result<()> {
+    if let Some(ref mut buffer) = app.workspace.current_buffer {
+        buffer.cursor.move_to_start_of_line();
+    }
+    Ok(())
+}

+ 14 - 0
src/application/handler/insert.rs

@@ -0,0 +1,14 @@
+use crate::application::Application;
+use crate::errors::*;
+use crate::util::position::Position;
+
+pub fn backspace(app: &mut Application) -> Result<()> {
+    if let Some(ref mut buffer) = app.workspace.current_buffer {
+        // 在第一行第一列时不执行删除操作
+        if buffer.cursor.position != Position::new(0, 0) {
+            buffer.cursor.move_left();
+            buffer.delete();
+        }
+    }
+    Ok(())
+}

+ 1 - 0
src/application/handler/mod.rs

@@ -5,6 +5,7 @@ use crate::errors::*;
 mod app;
 mod buffer;
 mod cursor;
+mod insert;
 mod monitor;
 mod workspace;
 

+ 15 - 0
src/application/handler/workspace.rs

@@ -1 +1,16 @@
+use crate::application::Application;
+use crate::errors::*;
 
+pub fn save_file(app: &mut Application) -> Result<()> {
+    if let Some(ref mut buffer) = app.workspace.current_buffer {
+        buffer.save()?;
+    }
+    Ok(())
+}
+
+pub fn undo(app: &mut Application) -> Result<()> {
+    if let Some(ref mut buffer) = app.workspace.current_buffer {
+        buffer.undo();
+    }
+    Ok(())
+}

+ 12 - 1
src/application/mod.rs

@@ -14,7 +14,8 @@ use smallvec::SmallVec;
 use std::{
     cell::RefCell,
     collections::HashMap,
-    io, mem,
+    io::{self, Read},
+    mem,
     path::{Path, PathBuf},
     rc::Rc,
     sync::Arc,
@@ -97,6 +98,7 @@ impl Application {
 
     fn init_modes(&mut self) {
         self.mode_history.insert(ModeKey::Normal, ModeData::Normal);
+        self.mode_history.insert(ModeKey::Insert, ModeData::Insert);
         self.mode_history
             .insert(ModeKey::Error, ModeData::Error(Error::default()));
         self.mode_history.insert(ModeKey::Exit, ModeData::Exit);
@@ -166,6 +168,9 @@ impl Application {
     }
 
     fn handle_input(&mut self, event: Event) -> Result<()> {
+        if let Event::Key(key_event) = event {
+            self.monitor.last_key = Some(key_event);
+        }
         let key = InputMapper::event_map_str(event);
         if key.is_none() {
             return Ok(());
@@ -178,6 +183,12 @@ impl Application {
                     for command in commands {
                         command(self)?;
                     }
+                } else {
+                    if let Some(commands) = mapper.get("_").cloned() {
+                        for command in commands {
+                            command(self)?;
+                        }
+                    }
                 }
             }
         }

+ 39 - 0
src/application/mode/insert.rs

@@ -0,0 +1,39 @@
+use crate::view::{
+    colors::colors::Colors,
+    status_data::{buffer_status_data, StatusLineData},
+    style::CharStyle,
+};
+
+use super::ModeRenderer;
+
+pub(super) struct InsertRenderer;
+
+impl ModeRenderer for InsertRenderer {
+    fn render(
+        workspace: &mut crate::workspace::Workspace,
+        monitor: &mut crate::view::monitor::Monitor,
+        mode: &mut super::ModeData,
+    ) -> super::Result<()> {
+        let mut presenter = monitor.build_presenter()?;
+
+        if let Some(buffer) = &workspace.current_buffer {
+            let data = buffer.data();
+            presenter.print_buffer(buffer, &data, &workspace.syntax_set, None, None)?;
+
+            let mode_name_data = StatusLineData {
+                content: " INSERT ".to_string(),
+                color: Colors::Inverted,
+                style: CharStyle::Bold,
+            };
+            presenter.print_status_line(&[
+                mode_name_data,
+                buffer_status_data(&workspace.current_buffer),
+            ])?;
+
+            presenter.present()?;
+        } else {
+        }
+
+        Ok(())
+    }
+}

+ 6 - 0
src/application/mode/mod.rs

@@ -4,6 +4,7 @@ use crate::errors::*;
 use crate::{view::monitor::Monitor, workspace::Workspace};
 use error::ErrorRenderer;
 use error_chain::bail;
+use insert::InsertRenderer;
 use linked_hash_map::LinkedHashMap;
 use normal::NormalRenderer;
 use smallvec::SmallVec;
@@ -14,6 +15,7 @@ use super::handler::handle_map;
 use super::Application;
 
 pub mod error;
+mod insert;
 mod normal;
 
 #[derive(Debug)]
@@ -21,6 +23,7 @@ pub enum ModeData {
     Normal,
     Error(Error),
     Exit,
+    Insert,
     // Other(OtherData)
 }
 
@@ -29,12 +32,14 @@ pub enum ModeKey {
     Normal,
     Error,
     Exit,
+    Insert,
 }
 
 impl ModeKey {
     pub fn to_string(&self) -> Option<String> {
         match self {
             ModeKey::Normal => Some("normal".into()),
+            ModeKey::Insert => Some("insert".into()),
             _ => None,
         }
     }
@@ -129,6 +134,7 @@ impl ModeRenderer for ModeRouter {
         match mode {
             ModeData::Normal => NormalRenderer::render(workspace, monitor, mode),
             ModeData::Error(_) => ErrorRenderer::render(workspace, monitor, mode),
+            ModeData::Insert => InsertRenderer::render(workspace, monitor, mode),
             ModeData::Exit => todo!(),
         }
     }

+ 4 - 4
src/buffer/gap_buffer.rs

@@ -52,12 +52,12 @@ impl GapBuffer {
             Some(offset) => offset,
             None => return,
         };
-        println!("{:?}", self.data);
+        // println!("{:?}", self.data);
         self.move_gap(offset);
-        println!("{:?}", self.data);
+        // println!("{:?}", self.data);
         self.write_to_gap(data);
-        println!("{:?}", self.data);
-        println!("start {} length {}", self.gap_start, self.gap_length);
+        // println!("{:?}", self.data);
+        // println!("start {} length {}", self.gap_start, self.gap_length);
     }
 
     pub fn read(&self, range: &Range) -> Option<String> {

+ 20 - 1
src/modules/input/default.yaml

@@ -3,4 +3,23 @@ normal:
   right: cursor::move_right
   up: cursor::move_up
   down: cursor::move_down
-  ctrl-c: app::exit
+  ctrl-c: app::exit
+  i: app::to_insert_mode
+  backspace: cursor::move_left
+insert:
+  escape: app::to_normal_mode
+  left: cursor::move_left
+  right: cursor::move_right
+  up: cursor::move_up
+  down: cursor::move_down
+  ctrl-c: app::exit
+  ctrl-s: workspace::save_file
+  ctrl-z: workspace::undo
+  enter: 
+    - buffer::new_line
+    - cursor::move_down
+    - cursor::move_to_start_of_line
+  backspace: insert::backspace
+  _: 
+    - buffer::insert_char
+    - cursor::move_right