Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/app/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ pub struct EditorContext {
pub file_path: Option<PathBuf>,
pub current_message: Option<Message>,
pub savedialog: bool,
pub quit_after_save: bool
pub quit_after_save: bool,
pub viewport_top: usize
}
12 changes: 3 additions & 9 deletions src/commands/executor.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,23 @@
use std::{
io::stdout,
path::{self, Path, PathBuf},
path::{PathBuf},
};

use crossterm::{
execute,
terminal::{self, LeaveAlternateScreen},
};

use crate::{Buffer, Status};
use crate::{
app::{
context::{self, EditorContext},
messages::MessageLevel,
},
gui::status_bar::send_message,
io::save::save,
};

use super::parser::Command;

pub fn execute(
command: Command,
buffer: &Buffer,
path: &Option<PathBuf>,
buffer: &mut Buffer,
path: &mut Option<PathBuf>,
) -> std::io::Result<Status> {
match command {
Command::Quit => Ok(Status::Quit),
Expand Down
68 changes: 68 additions & 0 deletions src/editor/buffer.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use std::{fs::read_to_string, io::ErrorKind};

use crate::editor::buffer;

#[derive(Debug)]
pub struct Buffer {
pub lines: Vec<String>,
pub row: usize,
pub column: usize,
pub modified: bool,
}

pub fn fetch(file: &str) -> Result<Buffer, std::io::Error> {
Expand Down Expand Up @@ -35,5 +38,70 @@ pub fn fetch(file: &str) -> Result<Buffer, std::io::Error> {
lines: result,
row: 0,
column: 0,
modified: false,
})
}

impl Buffer {
pub fn line(&self, index: usize) -> Option<&str> {
self.lines.get(index).map(|line| line.as_str())
}

pub fn line_mut(&mut self, index: usize) -> Option<&mut String> {
self.lines.get_mut(index)
}

pub fn line_count(&self) -> usize {
self.lines.len()
}

pub fn char_at(&self, row: usize, column: usize) -> Option<char> {
let Some(line) = self.line(column) else {
return None;
};

line.chars().nth(row)
}

pub fn insert_char_at(&mut self, row: usize, column: usize, c: char) -> bool {
let Some(line) = self.line_mut(column) else {
return false;
};
let byte_index = line
.char_indices()
.nth(row)
.map(|(index, _)| index)
.unwrap_or(line.len());
line.insert(byte_index, c);

true
}

pub fn char_count(&self, row: usize) -> Option<usize> {
let Some(line) = self.line(row) else {
return None;
};

return Some(line.chars().count());
}

pub fn remove_char_at(&mut self, row: usize, column: usize) -> Option<char> {
let Some(line) = self.line_mut(column) else {
return None;
};

let Some(index) = line.char_indices().nth(row).map(|(index, _)| index) else {
return None;
};

Some(line.remove(index))
}

pub fn mark_modified(&mut self) {
self.modified = true;
}

pub fn mark_saved(&mut self) {
self.modified = false;
}
}
53 changes: 25 additions & 28 deletions src/editor/editing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,17 @@ use crate::app::mode::Mode;
use crate::editor::buffer::Buffer;

pub fn insert_char(c: char, buffer: &mut Buffer) {
let Some(line) = buffer.lines.get_mut(buffer.column) else {
let modified = buffer.insert_char_at(buffer.row, buffer.column, c);
if modified {
buffer.row += 1;
buffer.mark_modified();
} else {
return;
};
let byte_index = line
.char_indices()
.nth(buffer.row)
.map(|(index, _)| index)
.unwrap_or(line.len());
line.insert(byte_index, c);
buffer.row += 1;
}
}

pub fn insert_forward(buffer: &mut Buffer, context: &mut EditorContext) {
let line_len = buffer.lines[buffer.column].chars().count();
let line_len = buffer.char_count(buffer.column).unwrap_or(0);

if line_len > 0 && buffer.row < line_len {
buffer.row += 1;
Expand All @@ -35,26 +32,23 @@ pub fn insert_backward(buffer: &mut Buffer, context: &mut EditorContext) {

pub fn remove_char(buffer: &mut Buffer) {
if buffer.row > 0 {
let Some(line) = buffer.lines.get_mut(buffer.column) else {
let modified = buffer.remove_char_at(buffer.row - 1, buffer.column);
if modified.is_some() {
buffer.row -= 1;
buffer.mark_modified();
} else {
return;
};

let Some(index) = line
.char_indices()
.nth(buffer.row - 1)
.map(|(index, _)| index)
else {
return
};

line.remove(index);
buffer.row -= 1;
}
} else if buffer.column > 0 {
let current_line = buffer.lines[buffer.column].clone();
let previous_len = buffer.lines[buffer.column - 1].chars().count();
let Some(current_line) = buffer.line(buffer.column) else {
return;
};
let current_line = current_line.to_string();

let previous_len = buffer.char_count(buffer.column - 1).unwrap_or(0);

{
let Some(previous) = buffer.lines.get_mut(buffer.column - 1) else {
let Some(previous) = buffer.line_mut(buffer.column - 1) else {
return;
};

Expand All @@ -64,18 +58,20 @@ pub fn remove_char(buffer: &mut Buffer) {
buffer.lines.remove(buffer.column);
buffer.column -= 1;
buffer.row = previous_len;
buffer.mark_modified();
}
}

pub fn insert_newline(buffer: &mut Buffer) {
let row = buffer.row;
let rest = {
let Some(line) = buffer.lines.get_mut(buffer.column) else {
let Some(line) = buffer.line_mut(buffer.column) else {
return;
};

let index = line
.char_indices()
.nth(buffer.row)
.nth(row)
.map(|(index, _)| index)
.unwrap_or(line.len());

Expand All @@ -85,4 +81,5 @@ pub fn insert_newline(buffer: &mut Buffer) {
buffer.lines.insert(buffer.column + 1, rest);
buffer.column += 1;
buffer.row = 0;
buffer.mark_modified();
}
Loading
Loading