@@ -9,36 +9,11 @@ use crossterm::{
9 terminal::{self, disable_raw_mode, enable_raw_mode},
9 terminal::{self, disable_raw_mode, enable_raw_mode},
11use futures::{future::FutureExt, select, StreamExt};
11use futures::{future::FutureExt, select, StreamExt};
12−use helix_core::{state::coords_at_pos, Buffer, State};
12+use helix_core::{state::coords_at_pos, state::Mode, Buffer, State};
13use std::io::{self, stdout, Write};
13use std::io::{self, stdout, Write};
14use std::path::PathBuf;
14use std::path::PathBuf;
15use std::time::Duration;
15use std::time::Duration;
17−pub struct BufferComponent<'a> {
20− contents: Vec<&'a str>,
23−impl BufferComponent<'_> {
24− pub fn render(&self) {
25− for (n, line) in self.contents.iter().enumerate() {
28− SetForegroundColor(Color::DarkCyan),
29− cursor::MoveTo(self.x, self.y + n as u16),
30− Print((n + 1).to_string())
34− SetForegroundColor(Color::Reset),
35− cursor::MoveTo(self.x + 2, self.y + n as u16),
42static EX: smol::Executor = smol::Executor::new();
17static EX: smol::Executor = smol::Executor::new();
44pub struct Editor {
19pub struct Editor {
@@ -70,21 +45,56 @@ impl Editor {
72 fn render(&mut self) {
47 fn render(&mut self) {
75 match &self.state {
48 match &self.state {
76− Some(s) => {
49+ Some(state) => {
77− let view = BufferComponent {
50+ let lines = state
80− contents: s
51+ .contents()
82− .lines_at(self.first_line as usize)
52+ .lines_at(self.first_line as usize)
83− .take(self.size.1 as usize)
53+ .take(self.size.1 as usize)
84− .map(|x| x.as_str().unwrap())
54+ .map(|x| x.as_str().unwrap());
85− .collect::<Vec<&str>>(),
55+
56+ let mut stdout = stdout();
58+ for (n, line) in lines.enumerate() {
61+ SetForegroundColor(Color::DarkCyan),
62+ cursor::MoveTo(0, n as u16),
63+ Print((n + 1).to_string())
67+ SetForegroundColor(Color::Reset),
68+ cursor::MoveTo(2, n as u16),
73+ let mode = match state.mode {
74+ Mode::Insert => "INS",
75+ Mode::Normal => "NOR",
80+ SetForegroundColor(Color::Reset),
81+ cursor::MoveTo(0, self.size.1),
87+ Mode::Insert => write!(stdout, "\x1B[6 q"),
88+ Mode::Normal => write!(stdout, "\x1B[2 q"),
87− view.render();
91+ // render the cursor
92+ let pos = state.selection.primary().head;
93+ let coords = coords_at_pos(&state.doc.contents.slice(..), pos);
96+ cursor::MoveTo((coords.1 + 2) as u16, coords.0 as u16)
89 None => (),
99 None => (),
@@ -108,22 +118,30 @@ impl Editor {
110 Some(Ok(Event::Key(event))) => {
120 Some(Ok(Event::Key(event))) => {
121+ if let Some(state) = &mut self.state {
126+ code: KeyCode::Esc, ..
127+ } => helix_core::commands::normal_mode(state, 1),
129+ code: KeyCode::Char(c),
131+ } => helix_core::commands::insert(state, c),
111− // TODO: handle modes and sequences (`gg`)
137+ // TODO: handle modes and sequences (`gg`)
112− if let Some(command) = keymap.get(&event) {
138+ if let Some(command) = keymap.get(&event) {
113− if let Some(state) = &mut self.state {
114− // TODO: handle count other than 1
139+ // TODO: handle count other than 1
115− command(state, 1);
140+ command(state, 1);
117− // render the cursor
142+ self.render();
118− let pos = self.state.as_ref().unwrap().selection.primary().head;
143+ }
119− let coords = coords_at_pos(
144+ }
120− &self.state.as_ref().unwrap().doc.contents.slice(..),
125− cursor::MoveTo((coords.1 + 2) as u16, coords.0 as u16)
@@ -145,6 +163,9 @@ impl Editor {
146 self.print_events().await;
164 self.print_events().await;
166+ // reset cursor shape
167+ write!(stdout, "\x1B[2 q");
148 execute!(stdout, terminal::LeaveAlternateScreen)?;
169 execute!(stdout, terminal::LeaveAlternateScreen)?;
150 disable_raw_mode()?;
171 disable_raw_mode()?;