Implemented display rendering and relative positioning for new offset
This commit is contained in:
parent
883d25f4b8
commit
264440eb6a
4 changed files with 74 additions and 26 deletions
19
.github/workflows/ci.yml
vendored
Normal file
19
.github/workflows/ci.yml
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
name: ci
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: ["main"]
|
||||||
|
tags: ["v*.*.*"]
|
||||||
|
pull_request:
|
||||||
|
types: [opened, reopened, synchronize]
|
||||||
|
branches: ["*"]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
format:
|
||||||
|
uses: c4patino/actions/.github/workflows/format.yml@main
|
||||||
|
with:
|
||||||
|
language: rust
|
||||||
|
|
@ -149,13 +149,13 @@ impl Editor {
|
||||||
KeyCode::Char(c) => {
|
KeyCode::Char(c) => {
|
||||||
let (x, y) = self.display.cursor.position;
|
let (x, y) = self.display.cursor.position;
|
||||||
self.buffer[y as usize].insert(x as usize, c);
|
self.buffer[y as usize].insert(x as usize, c);
|
||||||
self.display.cursor.move_by((1, 0), &self.buffer);
|
self.display.cursor_move_by((1, 0), &self.buffer);
|
||||||
}
|
}
|
||||||
KeyCode::Enter => {
|
KeyCode::Enter => {
|
||||||
let (x, y) = self.display.cursor.position;
|
let (x, y) = self.display.cursor.position;
|
||||||
let remaining = self.buffer[y as usize].split_off(x as usize);
|
let remaining = self.buffer[y as usize].split_off(x as usize);
|
||||||
self.buffer.insert((y + 1) as usize, remaining);
|
self.buffer.insert((y + 1) as usize, remaining);
|
||||||
self.display.cursor.move_by((-(x as i16), 1), &self.buffer)
|
self.display.cursor_move_by((-(x as i16), 1), &self.buffer)
|
||||||
}
|
}
|
||||||
KeyCode::Delete => {
|
KeyCode::Delete => {
|
||||||
let (x, y) = self.display.cursor.position;
|
let (x, y) = self.display.cursor.position;
|
||||||
|
|
@ -170,12 +170,12 @@ impl Editor {
|
||||||
let (x, y) = self.display.cursor.position;
|
let (x, y) = self.display.cursor.position;
|
||||||
if x > 0 {
|
if x > 0 {
|
||||||
self.buffer[y as usize].remove((x - 1) as usize);
|
self.buffer[y as usize].remove((x - 1) as usize);
|
||||||
self.display.cursor.move_by((-1, 0), &self.buffer);
|
self.display.cursor_move_by((-1, 0), &self.buffer);
|
||||||
} else if y > 0 {
|
} else if y > 0 {
|
||||||
let prev_line_len = self.buffer[(y - 1) as usize].len() as u16;
|
let prev_line_len = self.buffer[(y - 1) as usize].len() as u16;
|
||||||
let current_line = self.buffer.remove(y as usize);
|
let current_line = self.buffer.remove(y as usize);
|
||||||
self.buffer[(y - 1) as usize].push_str(¤t_line);
|
self.buffer[(y - 1) as usize].push_str(¤t_line);
|
||||||
self.display.cursor.move_by((prev_line_len as i16, -1), &self.buffer);
|
self.display.cursor_move_by((prev_line_len as i16, -1), &self.buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
|
||||||
|
|
@ -93,22 +93,22 @@ macro_rules! add_keybind {
|
||||||
|
|
||||||
pub fn default_keybinds(editor: &mut Editor) {
|
pub fn default_keybinds(editor: &mut Editor) {
|
||||||
add_keybind!(editor, "n", "k", |e| {
|
add_keybind!(editor, "n", "k", |e| {
|
||||||
e.display.cursor.move_by((0, -1), &e.buffer);
|
e.display.cursor_move_by((0, -1), &e.buffer);
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
|
|
||||||
add_keybind!(editor, "n", "j", |e| {
|
add_keybind!(editor, "n", "j", |e| {
|
||||||
e.display.cursor.move_by((0, 1), &e.buffer);
|
e.display.cursor_move_by((0, 1), &e.buffer);
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
|
|
||||||
add_keybind!(editor, "n", "h", |e| {
|
add_keybind!(editor, "n", "h", |e| {
|
||||||
e.display.cursor.move_by((-1, 0), &e.buffer);
|
e.display.cursor_move_by((-1, 0), &e.buffer);
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
|
|
||||||
add_keybind!(editor, "n", "l", |e| {
|
add_keybind!(editor, "n", "l", |e| {
|
||||||
e.display.cursor.move_by((1, 0), &e.buffer);
|
e.display.cursor_move_by((1, 0), &e.buffer);
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -139,39 +139,39 @@ pub fn default_keybinds(editor: &mut Editor) {
|
||||||
add_keybind!(editor, "n", "$", |e| {
|
add_keybind!(editor, "n", "$", |e| {
|
||||||
let (_x, y) = e.display.cursor.position;
|
let (_x, y) = e.display.cursor.position;
|
||||||
let line_len = e.buffer[y as usize].len() as u16 - 1;
|
let line_len = e.buffer[y as usize].len() as u16 - 1;
|
||||||
e.display.cursor.move_x(line_len, &e.buffer);
|
e.display.cursor_move_x(line_len, &e.buffer);
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
|
|
||||||
add_keybind!(editor, "n", "_", |e| {
|
add_keybind!(editor, "n", "_", |e| {
|
||||||
let current_line = &e.buffer[e.display.cursor.position.1 as usize];
|
let current_line = &e.buffer[e.display.cursor.position.1 as usize];
|
||||||
if let Some((index, _)) = current_line.char_indices().find(|&(_, c)| !c.is_whitespace()) {
|
if let Some((index, _)) = current_line.char_indices().find(|&(_, c)| !c.is_whitespace()) {
|
||||||
e.display.cursor.move_x(index as u16, &e.buffer);
|
e.display.cursor_move_x(index as u16, &e.buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
|
|
||||||
add_keybind!(editor, "n", "gg", |e| {
|
add_keybind!(editor, "n", "gg", |e| {
|
||||||
e.display.cursor.move_y(0, &e.buffer);
|
e.display.cursor_move_y(0, &e.buffer);
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
|
|
||||||
add_keybind!(editor, "n", "G", |e| {
|
add_keybind!(editor, "n", "G", |e| {
|
||||||
e.display.cursor.move_y(e.buffer.len() as u16, &e.buffer);
|
e.display.cursor_move_y(e.buffer.len() as u16, &e.buffer);
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
|
|
||||||
add_keybind!(editor, "n", "o", |e| {
|
add_keybind!(editor, "n", "o", |e| {
|
||||||
e.buffer.insert(e.display.cursor.position.1 as usize + 1, String::new());
|
e.buffer.insert(e.display.cursor.position.1 as usize + 1, String::new());
|
||||||
e.display.cursor.move_by((0, 1), &e.buffer);
|
e.display.cursor_move_by((0, 1), &e.buffer);
|
||||||
e.mode = Mode::INSERT;
|
e.mode = Mode::INSERT;
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
|
|
||||||
add_keybind!(editor, "n", "O", |e| {
|
add_keybind!(editor, "n", "O", |e| {
|
||||||
e.buffer.insert(e.display.cursor.position.1 as usize, String::new());
|
e.buffer.insert(e.display.cursor.position.1 as usize, String::new());
|
||||||
e.display.cursor.move_by((0, 0), &e.buffer);
|
e.display.cursor_move_by((0, 0), &e.buffer);
|
||||||
e.mode = Mode::INSERT;
|
e.mode = Mode::INSERT;
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ impl Cursor {
|
||||||
Self { position: (0, 0), max_column: 0 }
|
Self { position: (0, 0), max_column: 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_by(&mut self, delta: (i16, i16), buffer: &Vec<String>) {
|
fn move_by(&mut self, delta: (i16, i16), buffer: &Vec<String>) {
|
||||||
let saturate = |pos: u16, delta: i16| {
|
let saturate = |pos: u16, delta: i16| {
|
||||||
if delta.is_negative() {
|
if delta.is_negative() {
|
||||||
pos.saturating_sub(delta.abs() as u16)
|
pos.saturating_sub(delta.abs() as u16)
|
||||||
|
|
@ -51,14 +51,14 @@ impl Cursor {
|
||||||
self.validate_cursor(buffer);
|
self.validate_cursor(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_x(&mut self, new_x: u16, buffer: &Vec<String>) {
|
fn move_x(&mut self, new_x: u16, buffer: &Vec<String>) {
|
||||||
self.position.0 = new_x;
|
self.position.0 = new_x;
|
||||||
self.max_column = new_x;
|
self.max_column = new_x;
|
||||||
|
|
||||||
self.validate_cursor(buffer);
|
self.validate_cursor(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_y(&mut self, new_y: u16, buffer: &Vec<String>) {
|
fn move_y(&mut self, new_y: u16, buffer: &Vec<String>) {
|
||||||
self.position.1 = new_y;
|
self.position.1 = new_y;
|
||||||
self.validate_cursor(buffer);
|
self.validate_cursor(buffer);
|
||||||
}
|
}
|
||||||
|
|
@ -110,23 +110,22 @@ impl Display {
|
||||||
|
|
||||||
let max_columns = self.size.0 as usize;
|
let max_columns = self.size.0 as usize;
|
||||||
|
|
||||||
let cursor_line = self.cursor.position.1 as usize + self.offset.1 as usize;
|
let cursor_line = self.cursor.position.1 as usize;
|
||||||
|
|
||||||
let render = buffer[self.offset.1 as usize..]
|
let render = buffer[self.offset.1 as usize..]
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.take(max_lines)
|
.take(max_lines)
|
||||||
.map(|(i, line)| {
|
.map(|(i, line)| {
|
||||||
let absolute_line = i + self.offset.1 as usize;
|
let rendering_line = self.offset.1 as usize + i;
|
||||||
let relative_number = if absolute_line == cursor_line {
|
let relative_number = if rendering_line == cursor_line {
|
||||||
absolute_line.to_string()
|
self.cursor.position.1.to_string()
|
||||||
} else {
|
} else {
|
||||||
(absolute_line as isize - cursor_line as isize).abs().to_string()
|
(cursor_line as isize - rendering_line as isize).abs().to_string()
|
||||||
};
|
};
|
||||||
|
|
||||||
let padded_number = format!("{:>4} ", relative_number);
|
let padded_number = format!("{:>4} ", relative_number);
|
||||||
|
|
||||||
let trimmed_line = if line.len() > self.offset.0 as usize {
|
let trimmed_line = if line.len() > self.cursor.position.0 as usize {
|
||||||
let start = self.offset.0 as usize;
|
let start = self.offset.0 as usize;
|
||||||
let end = (start + max_columns).min(line.len());
|
let end = (start + max_columns).min(line.len());
|
||||||
&line[start..end]
|
&line[start..end]
|
||||||
|
|
@ -166,7 +165,7 @@ impl Display {
|
||||||
Mode::INSERT => queue!(
|
Mode::INSERT => queue!(
|
||||||
self.out,
|
self.out,
|
||||||
cursor::SetCursorStyle::BlinkingBar,
|
cursor::SetCursorStyle::BlinkingBar,
|
||||||
cursor::MoveTo(self.cursor.position.0 + 6, self.cursor.position.1),
|
cursor::MoveTo(self.cursor.position.0 - self.offset.0 + 6, self.cursor.position.1 - self.offset.1),
|
||||||
)?,
|
)?,
|
||||||
Mode::COMMAND => queue!(
|
Mode::COMMAND => queue!(
|
||||||
self.out,
|
self.out,
|
||||||
|
|
@ -179,11 +178,41 @@ impl Display {
|
||||||
_ => queue!(
|
_ => queue!(
|
||||||
self.out,
|
self.out,
|
||||||
cursor::SetCursorStyle::DefaultUserShape,
|
cursor::SetCursorStyle::DefaultUserShape,
|
||||||
cursor::MoveTo(self.cursor.position.0 + 6, self.cursor.position.1)
|
cursor::MoveTo(self.cursor.position.0 - self.offset.0 + 6, self.cursor.position.1 - self.offset.1)
|
||||||
)?,
|
)?,
|
||||||
}
|
}
|
||||||
|
|
||||||
self.out.flush()?;
|
self.out.flush()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn cursor_move_by(&mut self, delta: (i16, i16), buffer: &Vec<String>) {
|
||||||
|
self.cursor.move_by(delta, buffer);
|
||||||
|
self.validate_offset();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cursor_move_x(&mut self, new_x: u16, buffer: &Vec<String>) {
|
||||||
|
self.cursor.move_x(new_x, buffer);
|
||||||
|
self.validate_offset();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cursor_move_y(&mut self, new_y: u16, buffer: &Vec<String>) {
|
||||||
|
self.cursor.move_y(new_y, buffer);
|
||||||
|
self.validate_offset();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn validate_offset(&mut self) {
|
||||||
|
if self.cursor.position.0 >= self.offset.0 + self.size.0 {
|
||||||
|
self.offset.1 = self.cursor.position.1 - self.size.0 + 1;
|
||||||
|
}
|
||||||
|
if self.cursor.position.1 >= self.offset.1 + self.size.1 {
|
||||||
|
self.offset.1 = self.cursor.position.1 - self.size.1 + 1;
|
||||||
|
}
|
||||||
|
if self.cursor.position.0 < self.offset.0 {
|
||||||
|
self.offset.0 = self.cursor.position.0;
|
||||||
|
}
|
||||||
|
if self.cursor.position.1 < self.offset.1 {
|
||||||
|
self.offset.1 = self.cursor.position.1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Reference in a new issue