From 08ab867b1bfed69c59f56d4beafca1e147e8a38e Mon Sep 17 00:00:00 2001 From: mattwparas Date: Fri, 18 Aug 2023 22:02:08 -0700 Subject: [PATCH] indent stuff --- helix-core/src/extensions.rs | 136 ++++++++++++++++++++++++++++++++++- helix-core/src/indent.rs | 3 +- 2 files changed, 135 insertions(+), 4 deletions(-) diff --git a/helix-core/src/extensions.rs b/helix-core/src/extensions.rs index c661eb760..9939b5f41 100644 --- a/helix-core/src/extensions.rs +++ b/helix-core/src/extensions.rs @@ -1,9 +1,10 @@ use std::{borrow::Cow, cell::Cell, rc::Rc}; use ropey::iter::Chars; +use smallvec::SmallVec; use steel::{ gc::unsafe_erased_pointers::CustomReference, - rvals::Custom, + rvals::{Custom, SteelString}, steel_vm::{builtin::BuiltInModule, register_fn::RegisterFn, register_fn::RegisterFnBorrowed}, }; @@ -60,7 +61,7 @@ impl<'a> SRopeSlice<'a> { pub fn slice(&'a self, lower: usize, upper: usize) -> SRopeSlice<'a> { SRopeSlice { - slice: self.slice.byte_slice(lower..upper), + slice: self.slice.slice(lower..upper), } } @@ -99,6 +100,7 @@ pub fn rope_slice_module() -> BuiltInModule { // TODO: Note the difficulty of the lifetime params here module.register_fn("slice->string", SRopeSlice::to_string); + module.register_fn("slice-char->byte", SRopeSlice::char_to_byte); // module // .register_fn("slice-char->byte", SRopeSlice::char_to_byte) @@ -109,3 +111,133 @@ pub fn rope_slice_module() -> BuiltInModule { module } + +#[derive(Clone, Copy, Debug)] +enum SliceKind { + Normal(usize, usize), + Byte(usize, usize), + Line(usize), +} + +#[derive(Clone)] +pub struct SteelRopeSlice { + text: crate::Rope, + ranges: SmallVec<[SliceKind; 5]>, +} + +// #[derive(Clone)] +// pub struct SteelRopeString { +// slice: SteelRopeSlice, +// operations: SmallVec<[StringOperation; 5]>, +// } + +// #[derive(Clone)] +// enum StringOperation { +// TrimStart, +// StartsWith(SteelString), +// } + +// impl SteelRopeString { +// pub fn evaluate(&self) -> SteelVal { +// todo!() +// } +// } + +impl Custom for SteelRopeSlice {} +// impl Custom for SteelRopeString {} + +impl SteelRopeSlice { + pub fn from_string(string: SteelString) -> Self { + Self { + text: crate::Rope::from_str(string.as_str()), + ranges: SmallVec::default(), + } + } + + pub fn new(rope: crate::Rope) -> Self { + Self { + text: rope, + ranges: SmallVec::default(), + } + } + + fn to_slice(&self) -> crate::RopeSlice<'_> { + let mut slice = self.text.slice(..); + + for range in &self.ranges { + match range { + SliceKind::Normal(l, r) => slice = slice.slice(l..r), + SliceKind::Byte(l, r) => slice = slice.byte_slice(l..r), + SliceKind::Line(index) => slice = slice.line(*index), + } + } + + slice + } + + pub fn slice(mut self, lower: usize, upper: usize) -> Self { + self.ranges.push(SliceKind::Normal(lower, upper)); + self + } + + pub fn char_to_byte(&self, pos: usize) -> usize { + self.to_slice().char_to_byte(pos) + } + + pub fn byte_slice(mut self, lower: usize, upper: usize) -> Self { + self.ranges.push(SliceKind::Byte(lower, upper)); + self + } + + pub fn line(mut self, cursor: usize) -> Self { + self.ranges.push(SliceKind::Line(cursor)); + self + } + + pub fn to_string(&self) -> String { + self.to_slice().to_string() + } + + pub fn len_chars(&self) -> usize { + self.to_slice().len_chars() + } + + pub fn get_char(&self, index: usize) -> Option { + self.to_slice().get_char(index) + } + + pub fn len_lines(&self) -> usize { + self.to_slice().len_lines() + } + + pub fn trimmed_starts_with(&self, pat: SteelString) -> bool { + let maybe_owned = Cow::from(self.to_slice()); + + maybe_owned.trim_start().starts_with(pat.as_str()) + } + + // pub fn as_cow(&'a self) -> SRopeSliceCowStr<'a> { + // SRopeSliceCowStr(std::borrow::Cow::from(self.slice)) + // } +} + +pub fn rope_module() -> BuiltInModule { + let mut module = BuiltInModule::new("helix/core/text"); + + module + .register_fn("string->slice", SteelRopeSlice::from_string) + .register_fn("slice->slice", SteelRopeSlice::slice) + .register_fn("slice-char->byte", SteelRopeSlice::char_to_byte) + .register_fn("slice->byte-slice", SteelRopeSlice::byte_slice) + .register_fn("slice->line", SteelRopeSlice::line) + .register_fn("slice->string", SteelRopeSlice::to_string) + .register_fn("slice-len-chars", SteelRopeSlice::len_chars) + .register_fn("slice-char-ref", SteelRopeSlice::get_char) + .register_fn("slice-len-lines", SteelRopeSlice::len_lines) + .register_fn( + "slice-trim-and-starts-with?", + SteelRopeSlice::trimmed_starts_with, + ); + + module +} diff --git a/helix-core/src/indent.rs b/helix-core/src/indent.rs index 59f9e7125..8da8c02aa 100644 --- a/helix-core/src/indent.rs +++ b/helix-core/src/indent.rs @@ -814,8 +814,7 @@ pub fn custom_indent_for_newline( let offset = line.len_chars() - index; - let mut char_iter_from_paren = - line.chars_at(line.len_chars() - index).enumerate(); + let mut char_iter_from_paren = line.chars_at(offset).enumerate(); let end;