Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.7.1 #181

Merged
merged 16 commits into from
Nov 15, 2024
Merged

0.7.1 #181

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
56 changes: 35 additions & 21 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 3 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,17 @@ resolver = "2"
members = [
"kaolinite",
]
exclude = ["cactus"]

[package]
name = "ox"
version = "0.7.0"
version = "0.7.1"
edition = "2021"
authors = ["Curlpipe <11898833+curlpipe@users.noreply.github.com>"]
description = "A Rust powered text editor."
description = "A simple but flexible text editor."
homepage = "https://github.com/curlpipe/ox"
repository = "https://github.com/curlpipe/ox"
readme = "README.md"
include = ["src/*.rs", "Cargo.toml", "config/.oxrc"]
exclude = ["kaolinite/examples/cactus"]
categories = ["text-editors"]
keywords = ["text-editor", "editor", "terminal", "tui"]
license = "GPL-2.0"
Expand All @@ -42,4 +40,4 @@ kaolinite = { path = "./kaolinite" }
mlua = { version = "0.10", features = ["lua54", "vendored"] }
error_set = "0.7"
shellexpand = "3.1.0"
synoptic = "2.2.6"
synoptic = "2.2.7"
3 changes: 3 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,6 @@ cp target/x86_64-apple-darwin/release/ox target/pkgs/ox-macos
cargo build --release --target x86_64-pc-windows-gnu
strip -s target/x86_64-pc-windows-gnu/release/ox.exe
cp target/x86_64-pc-windows-gnu/release/ox.exe target/pkgs/ox.exe

# Clean up
rm .intentionally-empty-file.o
29 changes: 25 additions & 4 deletions kaolinite/src/document/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,22 +345,43 @@ impl Document {

/// Will return the bounds of the current active selection
#[must_use]
pub fn selection_loc_bound(&self) -> (Loc, Loc) {
pub fn selection_loc_bound_disp(&self) -> (Loc, Loc) {
let mut left = self.cursor.loc;
let mut right = self.cursor.selection_end;
// Convert into character indices
left.x = self.character_idx(&left);
right.x = self.character_idx(&right);
if left > right {
std::mem::swap(&mut left, &mut right);
}
(left, right)
}

/// Will return the bounds of the current active selection
#[must_use]
pub fn selection_loc_bound(&self) -> (Loc, Loc) {
let (mut left, mut right) = self.selection_loc_bound_disp();
// Convert into character indices
left.x = self.character_idx(&left);
right.x = self.character_idx(&right);
(left, right)
}

/// Returns true if the provided location is within the current active selection
#[must_use]
pub fn is_loc_selected(&self, loc: Loc) -> bool {
let (left, right) = self.selection_loc_bound();
self.is_this_loc_selected(loc, self.selection_loc_bound())
}

/// Returns true if the provided location is within the provided selection argument
#[must_use]
pub fn is_this_loc_selected(&self, loc: Loc, selection_bound: (Loc, Loc)) -> bool {
let (left, right) = selection_bound;
left <= loc && loc < right
}

/// Returns true if the provided location is within the provided selection argument
#[must_use]
pub fn is_this_loc_selected_disp(&self, loc: Loc, selection_bound: (Loc, Loc)) -> bool {
let (left, right) = selection_bound;
left <= loc && loc < right
}

Expand Down
40 changes: 38 additions & 2 deletions kaolinite/src/document/disk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::utils::get_absolute_path;
use crate::{Document, Loc, Size};
use ropey::Rope;
use std::fs::File;
use std::io::{BufReader, BufWriter};
use std::io::{BufRead, BufReader, BufWriter, Read};

/// A document info struct to store information about the file it represents
#[derive(Clone, PartialEq, Eq, Debug)]
Expand Down Expand Up @@ -54,7 +54,7 @@ impl Document {
#[cfg(not(tarpaulin_include))]
pub fn open<S: Into<String>>(size: Size, file_name: S) -> Result<Self> {
let file_name = file_name.into();
let file = Rope::from_reader(BufReader::new(File::open(&file_name)?))?;
let file = load_rope_from_reader(BufReader::new(File::open(&file_name)?));
let file_name = get_absolute_path(&file_name);
Ok(Self {
info: DocumentInfo {
Expand Down Expand Up @@ -140,3 +140,39 @@ impl Document {
}
}
}

pub fn load_rope_from_reader<T: Read + BufRead>(mut reader: T) -> Rope {
let mut buffer = [0u8; 2048]; // Buffer to read chunks
let mut valid_string = String::new();
let mut incomplete_bytes = Vec::new(); // Buffer to handle partial UTF-8 sequences

while let Ok(bytes_read) = reader.read(&mut buffer) {
if bytes_read == 0 {
break; // EOF reached
}

// Combine leftover bytes with current chunk
incomplete_bytes.extend_from_slice(&buffer[..bytes_read]);

// Attempt to decode as much UTF-8 as possible
match String::from_utf8(incomplete_bytes.clone()) {
Ok(decoded) => {
valid_string.push_str(&decoded); // Append valid data
incomplete_bytes.clear(); // Clear incomplete bytes
}
Err(err) => {
// Handle valid and invalid parts separately
let valid_up_to = err.utf8_error().valid_up_to();
valid_string.push_str(&String::from_utf8_lossy(&incomplete_bytes[..valid_up_to]));
incomplete_bytes = incomplete_bytes[valid_up_to..].to_vec(); // Retain invalid/partial
}
}
}

// Append any remaining valid UTF-8 data
if !incomplete_bytes.is_empty() {
valid_string.push_str(&String::from_utf8_lossy(&incomplete_bytes));
}

Rope::from_str(&valid_string)
}
Loading
Loading