Implemented display rendering and relative positioning for new offset

This commit is contained in:
Ceferino Patino 2025-01-12 23:11:51 -06:00
commit 264440eb6a
Signed by: c4patino
SSH key fingerprint: SHA256:Wu+cU1t+7zVT9wzew/4meNmeulo66NzMqc22MdDBgXI
4 changed files with 74 additions and 26 deletions

19
.github/workflows/ci.yml vendored Normal file
View 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

View file

@ -149,13 +149,13 @@ impl Editor {
KeyCode::Char(c) => {
let (x, y) = self.display.cursor.position;
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 => {
let (x, y) = self.display.cursor.position;
let remaining = self.buffer[y as usize].split_off(x as usize);
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 => {
let (x, y) = self.display.cursor.position;
@ -170,12 +170,12 @@ impl Editor {
let (x, y) = self.display.cursor.position;
if x > 0 {
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 {
let prev_line_len = self.buffer[(y - 1) as usize].len() as u16;
let current_line = self.buffer.remove(y as usize);
self.buffer[(y - 1) as usize].push_str(&current_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);
}
}
_ => {}

View file

@ -93,22 +93,22 @@ macro_rules! add_keybind {
pub fn default_keybinds(editor: &mut Editor) {
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(())
});
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(())
});
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(())
});
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(())
});
@ -139,39 +139,39 @@ pub fn default_keybinds(editor: &mut Editor) {
add_keybind!(editor, "n", "$", |e| {
let (_x, y) = e.display.cursor.position;
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(())
});
add_keybind!(editor, "n", "_", |e| {
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()) {
e.display.cursor.move_x(index as u16, &e.buffer);
e.display.cursor_move_x(index as u16, &e.buffer);
}
Ok(())
});
add_keybind!(editor, "n", "gg", |e| {
e.display.cursor.move_y(0, &e.buffer);
e.display.cursor_move_y(0, &e.buffer);
Ok(())
});
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(())
});
add_keybind!(editor, "n", "o", |e| {
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;
Ok(())
});
add_keybind!(editor, "n", "O", |e| {
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;
Ok(())
});

View file

@ -26,7 +26,7 @@ impl Cursor {
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| {
if delta.is_negative() {
pos.saturating_sub(delta.abs() as u16)
@ -51,14 +51,14 @@ impl Cursor {
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.max_column = new_x;
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.validate_cursor(buffer);
}
@ -110,23 +110,22 @@ impl Display {
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..]
.iter()
.enumerate()
.take(max_lines)
.map(|(i, line)| {
let absolute_line = i + self.offset.1 as usize;
let relative_number = if absolute_line == cursor_line {
absolute_line.to_string()
let rendering_line = self.offset.1 as usize + i;
let relative_number = if rendering_line == cursor_line {
self.cursor.position.1.to_string()
} 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 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 end = (start + max_columns).min(line.len());
&line[start..end]
@ -166,7 +165,7 @@ impl Display {
Mode::INSERT => queue!(
self.out,
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!(
self.out,
@ -179,11 +178,41 @@ impl Display {
_ => queue!(
self.out,
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()?;
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;
}
}
}