add feature flag

pull/8675/merge^2
mattwparas 1 year ago
parent 81243247c6
commit 279f5eddb3

@ -13,6 +13,7 @@ include = ["src/**/*", "README.md"]
[features]
unicode-lines = ["ropey/unicode_lines"]
integration = []
steel = ["dep:steel-core"]
[dependencies]
helix-loader = { version = "0.6", path = "../helix-loader" }
@ -48,7 +49,7 @@ chrono = { version = "0.4", default-features = false, features = ["alloc", "std"
etcetera = "0.8"
textwrap = "0.16.0"
steel-core = { workspace = true }
steel-core = { workspace = true, optional = true }
[dev-dependencies]
quickcheck = { version = "1", default-features = false }

@ -1,243 +1,249 @@
use std::{borrow::Cow, cell::Cell, rc::Rc};
#[cfg(feature = "steel")]
pub mod steel_implementations {
use ropey::iter::Chars;
use smallvec::SmallVec;
use steel::{
gc::unsafe_erased_pointers::CustomReference,
rvals::{Custom, SteelString},
steel_vm::{builtin::BuiltInModule, register_fn::RegisterFn, register_fn::RegisterFnBorrowed},
};
use std::{borrow::Cow, cell::Cell, rc::Rc};
impl steel::rvals::Custom for crate::Position {}
impl steel::rvals::Custom for crate::Selection {}
use ropey::iter::Chars;
use smallvec::SmallVec;
use steel::{
gc::unsafe_erased_pointers::CustomReference,
rvals::{Custom, SteelString},
steel_vm::{
builtin::BuiltInModule, register_fn::RegisterFn, register_fn::RegisterFnBorrowed,
},
};
pub struct SRopeSlice<'a> {
slice: crate::RopeSlice<'a>,
}
impl steel::rvals::Custom for crate::Position {}
impl steel::rvals::Custom for crate::Selection {}
steel::custom_reference!(SRopeSlice<'a>);
impl<'a> CustomReference for SRopeSlice<'a> {}
pub struct SRopeSlice<'a> {
slice: crate::RopeSlice<'a>,
}
// impl Custom for SRopeSlice<'static> {}
steel::custom_reference!(SRopeSlice<'a>);
impl<'a> CustomReference for SRopeSlice<'a> {}
pub struct SRopeSliceCowStr<'a>(Cow<'a, str>);
steel::custom_reference!(SRopeSliceCowStr<'a>);
impl<'a> CustomReference for SRopeSliceCowStr<'a> {}
// impl Custom for SRopeSlice<'static> {}
struct CharIter<'a>(Chars<'a>);
pub struct SRopeSliceCowStr<'a>(Cow<'a, str>);
steel::custom_reference!(SRopeSliceCowStr<'a>);
impl<'a> CustomReference for SRopeSliceCowStr<'a> {}
impl<'a> SRopeSlice<'a> {
pub fn new(slice: crate::RopeSlice<'a>) -> Self {
Self { slice }
}
struct CharIter<'a>(Chars<'a>);
pub fn char_to_byte(&self, pos: usize) -> usize {
self.slice.char_to_byte(pos)
}
impl<'a> SRopeSlice<'a> {
pub fn new(slice: crate::RopeSlice<'a>) -> Self {
Self { slice }
}
pub fn byte_slice(&'a self, lower: usize, upper: usize) -> SRopeSlice<'a> {
SRopeSlice {
slice: self.slice.byte_slice(lower..upper),
pub fn char_to_byte(&self, pos: usize) -> usize {
self.slice.char_to_byte(pos)
}
}
pub fn line(&'a self, cursor: usize) -> SRopeSlice<'a> {
SRopeSlice {
slice: self.slice.line(cursor),
pub fn byte_slice(&'a self, lower: usize, upper: usize) -> SRopeSlice<'a> {
SRopeSlice {
slice: self.slice.byte_slice(lower..upper),
}
}
}
pub fn as_cow(&'a self) -> SRopeSliceCowStr<'a> {
SRopeSliceCowStr(std::borrow::Cow::from(self.slice))
}
pub fn line(&'a self, cursor: usize) -> SRopeSlice<'a> {
SRopeSlice {
slice: self.slice.line(cursor),
}
}
pub fn as_cow(&'a self) -> SRopeSliceCowStr<'a> {
SRopeSliceCowStr(std::borrow::Cow::from(self.slice))
}
pub fn to_string(&self) -> String {
self.slice.to_string()
}
pub fn len_chars(&'a self) -> usize {
self.slice.len_chars()
}
pub fn slice(&'a self, lower: usize, upper: usize) -> SRopeSlice<'a> {
SRopeSlice {
slice: self.slice.slice(lower..upper),
}
}
pub fn to_string(&self) -> String {
self.slice.to_string()
pub fn get_char(&'a self, index: usize) -> Option<char> {
self.slice.get_char(index)
}
}
pub fn len_chars(&'a self) -> usize {
self.slice.len_chars()
// RegisterFn::<
// _,
// steel::steel_vm::register_fn::MarkerWrapper7<(
// Context<'_>,
// helix_view::Editor,
// helix_view::Editor,
// Context<'static>,
// )>,
// helix_view::Editor,
// >::register_fn(&mut engine, "cx-editor!", get_editor);
pub fn rope_slice_module() -> BuiltInModule {
let mut module = BuiltInModule::new("helix/core/text");
// (SELF, ARG, SELFSTAT, RET, RETSTAT)
RegisterFnBorrowed::<
_,
steel::steel_vm::register_fn::MarkerWrapper9<(
SRopeSlice<'_>,
usize,
SRopeSlice<'static>,
SRopeSlice<'_>,
SRopeSlice<'static>,
)>,
SRopeSlice,
>::register_fn_borrowed(&mut module, "slice->line", SRopeSlice::line);
// 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)
// .register_fn_borrowed::<S("slice->line", SRopeSlice::line);
// .register_fn("slice->byte-slice", SRopeSlice::byte_slice);
// module.register_fn("slice-len-chars", SRopeSlice::len_chars);
module
}
pub fn slice(&'a self, lower: usize, upper: usize) -> SRopeSlice<'a> {
SRopeSlice {
slice: self.slice.slice(lower..upper),
}
#[derive(Clone, Copy, Debug)]
enum SliceKind {
Normal(usize, usize),
Byte(usize, usize),
Line(usize),
}
pub fn get_char(&'a self, index: usize) -> Option<char> {
self.slice.get_char(index)
#[derive(Clone)]
pub struct SteelRopeSlice {
text: crate::Rope,
ranges: SmallVec<[SliceKind; 5]>,
}
}
// RegisterFn::<
// _,
// steel::steel_vm::register_fn::MarkerWrapper7<(
// Context<'_>,
// helix_view::Editor,
// helix_view::Editor,
// Context<'static>,
// )>,
// helix_view::Editor,
// >::register_fn(&mut engine, "cx-editor!", get_editor);
pub fn rope_slice_module() -> BuiltInModule {
let mut module = BuiltInModule::new("helix/core/text");
// (SELF, ARG, SELFSTAT, RET, RETSTAT)
RegisterFnBorrowed::<
_,
steel::steel_vm::register_fn::MarkerWrapper9<(
SRopeSlice<'_>,
usize,
SRopeSlice<'static>,
SRopeSlice<'_>,
SRopeSlice<'static>,
)>,
SRopeSlice,
>::register_fn_borrowed(&mut module, "slice->line", SRopeSlice::line);
// 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)
// .register_fn_borrowed::<S("slice->line", SRopeSlice::line);
// .register_fn("slice->byte-slice", SRopeSlice::byte_slice);
// module.register_fn("slice-len-chars", SRopeSlice::len_chars);
module
}
// #[derive(Clone)]
// pub struct SteelRopeString {
// slice: SteelRopeSlice,
// operations: SmallVec<[StringOperation; 5]>,
// }
#[derive(Clone, Copy, Debug)]
enum SliceKind {
Normal(usize, usize),
Byte(usize, usize),
Line(usize),
}
// #[derive(Clone)]
// enum StringOperation {
// TrimStart,
// StartsWith(SteelString),
// }
#[derive(Clone)]
pub struct SteelRopeSlice {
text: crate::Rope,
ranges: SmallVec<[SliceKind; 5]>,
}
// impl SteelRopeString {
// pub fn evaluate(&self) -> SteelVal {
// todo!()
// }
// }
// #[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(),
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(),
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(..);
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),
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
}
slice
}
pub fn slice(mut self, lower: usize, upper: usize) -> Self {
self.ranges.push(SliceKind::Normal(lower, upper));
self
}
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 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 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 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 to_string(&self) -> String {
self.to_slice().to_string()
}
pub fn len_chars(&self) -> usize {
self.to_slice().len_chars()
}
pub fn len_chars(&self) -> usize {
self.to_slice().len_chars()
}
pub fn get_char(&self, index: usize) -> Option<char> {
self.to_slice().get_char(index)
}
pub fn get_char(&self, index: usize) -> Option<char> {
self.to_slice().get_char(index)
}
pub fn len_lines(&self) -> usize {
self.to_slice().len_lines()
}
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());
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())
}
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 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");
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
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
}
}

@ -156,14 +156,6 @@ pub fn log_file() -> PathBuf {
LOG_FILE.get().map(|path| path.to_path_buf()).unwrap()
}
pub fn helix_module_file() -> PathBuf {
config_dir().join("helix.scm")
}
pub fn steel_init_file() -> PathBuf {
config_dir().join("init.scm")
}
pub fn workspace_config_file() -> PathBuf {
find_workspace().0.join(".helix").join("config.toml")
}

@ -13,10 +13,12 @@ default-run = "hx"
rust-version = "1.65"
[features]
default = ["git"]
default = ["git", "steel"]
# default = ["git"]
unicode-lines = ["helix-core/unicode-lines"]
integration = []
git = ["helix-vcs/git"]
steel = ["dep:steel-core", "helix-core/steel", "helix-view/steel", "tui/steel"]
[[bin]]
name = "hx"
@ -67,7 +69,7 @@ grep-regex = "0.1.11"
grep-searcher = "0.1.11"
# plugin support
steel-core = { workspace = true }
steel-core = { workspace = true, optional = true }
[target.'cfg(not(windows))'.dependencies] # https://github.com/vorner/signal-hook/issues/100
signal-hook-tokio = { version = "0.3", features = ["futures-v0_3"] }

File diff suppressed because it is too large Load Diff

@ -8,7 +8,7 @@ use steel::{
};
use crate::{
commands::{engine::ENGINE, Context},
commands::{engine::scheme::ENGINE, Context},
compositor::{self, Component},
ui::{Popup, Prompt, PromptEvent},
};
@ -72,6 +72,7 @@ pub fn helix_component_module() -> BuiltInModule {
}
},
);
// prompt: Cow<'static, str>,
// history_register: Option<char>,
// completion_fn: impl FnMut(&Editor, &str) -> Vec<Completion> + 'static,

File diff suppressed because it is too large Load Diff

@ -2,7 +2,6 @@ use std::ops::Deref;
use crate::job::Job;
use super::engine::{compositor_present_error, present_error};
use super::*;
use helix_core::{encoding, shellwords::Shellwords};

@ -134,7 +134,11 @@ impl Config {
let local_config = fs::read_to_string(helix_loader::workspace_config_file())
.map_err(ConfigLoadError::Error);
let bindings = crate::commands::engine::SharedKeyBindingsEventQueue::get();
#[cfg(feature = "steel")]
let bindings = crate::commands::engine::scheme::SharedKeyBindingsEventQueue::get();
#[cfg(not(feature = "steel"))]
let bindings = None;
Config::load(global_config, local_config, bindings)
}

@ -803,20 +803,7 @@ impl EditorView {
self.pseudo_pending.extend(self.keymaps.pending());
// Check the engine for any buffer specific keybindings first
let key_result = ScriptingEngine::get_keymap_for_extension(cxt)
.and_then(|map| {
if let steel::SteelVal::Custom(inner) = map {
if let Some(underlying) = steel::rvals::as_underlying_type::<
commands::engine::EmbeddedKeyMap,
>(inner.borrow().as_ref())
{
return Some(self.keymaps.get_with_map(&underlying.0, mode, event));
}
}
None
})
.unwrap_or_else(|| self.keymaps.get(mode, event));
let key_result = ScriptingEngine::handle_keymap_event(self, mode, cxt, event);
cxt.editor.autoinfo = self.keymaps.sticky().map(|node| node.infobox());

@ -0,0 +1,11 @@
#[cfg(feature = "steel")]
mod steel_implementations {
use crate::{
compositor::Component,
ui::{Popup, Text},
};
impl steel::rvals::Custom for Text {}
impl<T: steel::rvals::IntoSteelVal + Component> steel::rvals::Custom for Popup<T> {}
}

@ -1,6 +1,7 @@
mod completion;
mod document;
pub(crate) mod editor;
mod extension;
mod fuzzy_match;
mod info;
pub mod lsp;

@ -3,7 +3,6 @@ use crate::{
compositor::{Callback, Component, Context, Event, EventResult},
ctrl, key,
};
use steel::rvals::Custom;
use tui::buffer::Buffer as Surface;
use helix_core::Position;
@ -15,8 +14,6 @@ use helix_view::{
// TODO: share logic with Menu, it's essentially Popup(render_fn), but render fn needs to return
// a width/height hint. maybe Popup(Box<Component>)
impl<T: steel::rvals::IntoSteelVal + Component> Custom for Popup<T> {}
pub struct Popup<T: Component> {
contents: T,
position: Option<Position>,

@ -8,10 +8,7 @@ use helix_view::{
Document, Editor, View,
};
use crate::{
commands::engine::{StatusLineMessage, STATUS_LINE_MESSAGE},
ui::ProgressSpinners,
};
use crate::ui::ProgressSpinners;
use helix_view::editor::StatusLineElement as StatusLineElementID;
use tui::buffer::Buffer as Surface;
@ -515,9 +512,9 @@ fn render_custom_text<F>(context: &mut RenderContext, write: F)
where
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
{
if let Some(message) = StatusLineMessage::get() {
write(context, message, None);
}
// if let Some(message) = StatusLineMessage::get() {
// write(context, message, None);
// }
}
fn render_register<F>(context: &mut RenderContext, write: F)

@ -3,8 +3,6 @@ use tui::buffer::Buffer as Surface;
use helix_view::graphics::Rect;
impl steel::rvals::Custom for Text {}
pub struct Text {
pub(crate) contents: tui::text::Text<'static>,
size: (u16, u16),

@ -14,6 +14,7 @@ include = ["src/**/*", "README.md"]
[features]
default = ["crossterm"]
steel = ["dep:steel-core", "helix-view/steel", "helix-core/steel"]
[dependencies]
bitflags = "2.4"
@ -26,4 +27,4 @@ once_cell = "1.18"
log = "~0.4"
helix-view = { version = "0.6", path = "../helix-view", features = ["term"] }
helix-core = { version = "0.6", path = "../helix-core" }
steel-core = { workspace = true }
steel-core = { workspace = true, optional = true }

@ -1,7 +1,11 @@
use crate::{buffer::Buffer, widgets::Widget};
#[cfg(feature = "steel")]
mod steel_implementations {
use steel::{gc::unsafe_erased_pointers::CustomReference, rvals::Custom};
use crate::{buffer::Buffer, widgets::Widget};
impl CustomReference for Buffer {}
use steel::{gc::unsafe_erased_pointers::CustomReference, rvals::Custom};
steel::custom_reference!(Buffer);
impl CustomReference for Buffer {}
steel::custom_reference!(Buffer);
}

@ -10,8 +10,8 @@ repository = "https://github.com/helix-editor/helix"
homepage = "https://helix-editor.com"
[features]
default = []
term = ["crossterm"]
steel = ["dep:steel-core", "helix-core/steel"]
[dependencies]
bitflags = "2.4"
@ -46,7 +46,7 @@ which = "4.4"
parking_lot = "0.12.1"
# plugin support
steel-core = { workspace = true }
steel-core = { workspace = true, optional = true }
[target.'cfg(windows)'.dependencies]

@ -874,11 +874,6 @@ pub struct Breakpoint {
use futures_util::stream::{Flatten, Once};
impl steel::gc::unsafe_erased_pointers::CustomReference for Editor {}
steel::custom_reference!(Editor);
impl steel::rvals::Custom for Mode {}
#[repr(C)]
pub struct Editor {
/// Current editing mode.

@ -1,15 +1,29 @@
use steel::{gc::unsafe_erased_pointers::CustomReference, rvals::Custom};
use crate::{graphics::Rect, input::Event, Document, DocumentId, ViewId};
// Reference types along with value types - This should allow for having users
impl CustomReference for Event {}
impl Custom for Rect {}
impl Custom for crate::graphics::CursorKind {}
impl Custom for DocumentId {}
impl Custom for ViewId {}
impl CustomReference for Document {}
use crate::DocumentId;
pub fn document_id_to_usize(doc_id: &DocumentId) -> usize {
doc_id.0.into()
}
#[cfg(feature = "steel")]
mod steel_implementations {
use steel::{gc::unsafe_erased_pointers::CustomReference, rvals::Custom};
use crate::{
document::Mode, graphics::Rect, input::Event, Document, DocumentId, Editor, ViewId,
};
impl steel::gc::unsafe_erased_pointers::CustomReference for Editor {}
steel::custom_reference!(Editor);
impl steel::rvals::Custom for Mode {}
impl steel::rvals::Custom for Event {}
// Reference types along with value types - This should allow for having users
impl CustomReference for Event {}
impl Custom for Rect {}
impl Custom for crate::graphics::CursorKind {}
impl Custom for DocumentId {}
impl Custom for ViewId {}
impl CustomReference for Document {}
}

@ -17,8 +17,6 @@ pub enum Event {
IdleTimeout,
}
impl steel::rvals::Custom for Event {}
#[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Copy, Hash)]
pub struct MouseEvent {
/// The kind of mouse event that was caused.

Loading…
Cancel
Save