mirror of https://github.com/helix-editor/helix
add new xtask for code generation of core libraries
parent
38f344c21c
commit
eb20adbaad
|
@ -1488,9 +1488,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "im-lists"
|
name = "im-lists"
|
||||||
version = "0.7.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0c07eff2c41645923382085ea8627509e5184f7a668f75d0c1e16091f7af4798"
|
checksum = "3e7233fb8b1ffc0b1d6033fd311a74a0443164628c62abbc871185ee95098b63"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"smallvec",
|
"smallvec",
|
||||||
]
|
]
|
||||||
|
@ -1742,6 +1742,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214"
|
checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-traits",
|
"num-traits",
|
||||||
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1775,6 +1776,7 @@ dependencies = [
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
"num-integer",
|
"num-integer",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2307,7 +2309,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "steel-core"
|
name = "steel-core"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
source = "git+https://github.com/mattwparas/steel.git#ad307d9ab163b99ac6dc0bc06a04601042a3f325"
|
source = "git+https://github.com/mattwparas/steel.git#1fb88e561474c723a4fd2675553d6091a380aef1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"abi_stable",
|
"abi_stable",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
@ -2335,6 +2337,7 @@ dependencies = [
|
||||||
"steel-derive",
|
"steel-derive",
|
||||||
"steel-gen",
|
"steel-gen",
|
||||||
"steel-parser",
|
"steel-parser",
|
||||||
|
"strsim",
|
||||||
"weak-table",
|
"weak-table",
|
||||||
"which 4.4.2",
|
"which 4.4.2",
|
||||||
]
|
]
|
||||||
|
@ -2342,7 +2345,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "steel-derive"
|
name = "steel-derive"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
source = "git+https://github.com/mattwparas/steel.git#ad307d9ab163b99ac6dc0bc06a04601042a3f325"
|
source = "git+https://github.com/mattwparas/steel.git#1fb88e561474c723a4fd2675553d6091a380aef1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -2352,7 +2355,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "steel-gen"
|
name = "steel-gen"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/mattwparas/steel.git#ad307d9ab163b99ac6dc0bc06a04601042a3f325"
|
source = "git+https://github.com/mattwparas/steel.git#1fb88e561474c723a4fd2675553d6091a380aef1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"codegen",
|
"codegen",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -2362,15 +2365,16 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "steel-parser"
|
name = "steel-parser"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
source = "git+https://github.com/mattwparas/steel.git#ad307d9ab163b99ac6dc0bc06a04601042a3f325"
|
source = "git+https://github.com/mattwparas/steel.git#1fb88e561474c723a4fd2675553d6091a380aef1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fxhash",
|
"fxhash",
|
||||||
"lasso",
|
"lasso",
|
||||||
"num-bigint",
|
"num",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"pretty",
|
"pretty",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
|
"smallvec",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2379,6 +2383,12 @@ version = "0.4.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e9557cb6521e8d009c51a8666f09356f4b817ba9ba0981a305bd86aee47bd35c"
|
checksum = "e9557cb6521e8d009c51a8666f09356f4b817ba9ba0981a305bd86aee47bd35c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strsim"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.109"
|
version = "1.0.109"
|
||||||
|
|
|
@ -81,7 +81,6 @@ use ignore::{DirEntry, WalkBuilder, WalkState};
|
||||||
|
|
||||||
pub type OnKeyCallback = Box<dyn FnOnce(&mut Context, KeyEvent)>;
|
pub type OnKeyCallback = Box<dyn FnOnce(&mut Context, KeyEvent)>;
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct Context<'a> {
|
pub struct Context<'a> {
|
||||||
pub register: Option<char>,
|
pub register: Option<char>,
|
||||||
pub count: Option<NonZeroUsize>,
|
pub count: Option<NonZeroUsize>,
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use arc_swap::ArcSwapAny;
|
use arc_swap::ArcSwapAny;
|
||||||
use helix_core::syntax::Configuration;
|
use helix_view::{document::Mode, input::KeyEvent};
|
||||||
use helix_view::{document::Mode, input::KeyEvent, Theme};
|
|
||||||
|
|
||||||
use std::{borrow::Cow, sync::Arc};
|
use std::{borrow::Cow, sync::Arc};
|
||||||
|
|
||||||
|
@ -11,7 +10,7 @@ use crate::{
|
||||||
ui::{self, PromptEvent},
|
ui::{self, PromptEvent},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{shell_impl, Context, MappableCommand, TYPABLE_COMMAND_LIST};
|
use super::{Context, MappableCommand, TYPABLE_COMMAND_LIST};
|
||||||
|
|
||||||
#[cfg(feature = "steel")]
|
#[cfg(feature = "steel")]
|
||||||
mod components;
|
mod components;
|
||||||
|
@ -138,6 +137,12 @@ impl ScriptingEngine {
|
||||||
.flat_map(|kind| manual_dispatch!(kind, available_commands()))
|
.flat_map(|kind| manual_dispatch!(kind, available_commands()))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn generate_sources() {
|
||||||
|
for kind in PLUGIN_PRECEDENCE {
|
||||||
|
manual_dispatch!(kind, generate_sources())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PluginSystem for NoEngine {
|
impl PluginSystem for NoEngine {
|
||||||
|
@ -215,4 +220,6 @@ pub trait PluginSystem {
|
||||||
fn available_commands<'a>(&self) -> Vec<Cow<'a, str>> {
|
fn available_commands<'a>(&self) -> Vec<Cow<'a, str>> {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn generate_sources(&self) {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,17 +21,19 @@ use helix_view::{
|
||||||
Document, DocumentId, Editor, ViewId,
|
Document, DocumentId, Editor, ViewId,
|
||||||
};
|
};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use serde_json::Value;
|
|
||||||
use steel::{
|
use steel::{
|
||||||
gc::unsafe_erased_pointers::CustomReference,
|
gc::unsafe_erased_pointers::CustomReference,
|
||||||
rerrs::ErrorKind,
|
rerrs::ErrorKind,
|
||||||
rvals::{as_underlying_type, FromSteelVal, IntoSteelVal, SteelString},
|
rvals::{as_underlying_type, FromSteelVal, IntoSteelVal, SteelString},
|
||||||
steel_vm::{engine::Engine, register_fn::RegisterFn},
|
steel_vm::{engine::Engine, register_fn::RegisterFn},
|
||||||
steelerr, List, SteelErr, SteelVal,
|
steelerr, SteelErr, SteelVal,
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Cow, collections::HashMap, ops::Deref, path::PathBuf, sync::atomic::AtomicUsize,
|
borrow::Cow,
|
||||||
|
collections::HashMap,
|
||||||
|
path::PathBuf,
|
||||||
|
sync::atomic::{AtomicUsize, Ordering},
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -56,13 +58,20 @@ use components::SteelDynamicComponent;
|
||||||
use super::{components, Context, MappableCommand, TYPABLE_COMMAND_LIST};
|
use super::{components, Context, MappableCommand, TYPABLE_COMMAND_LIST};
|
||||||
use insert::{insert_char, insert_string};
|
use insert::{insert_char, insert_string};
|
||||||
|
|
||||||
|
static ENGINE_COUNT: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// I'm not entirely sure this is correct, however from observation it seems that
|
// I'm not entirely sure this is correct, however from observation it seems that
|
||||||
// interactions with this really only happen on one thread. I haven't yet found
|
// interactions with this really only happen on one thread. I haven't yet found
|
||||||
// multiple instances of the engine getting created. I'll need to go observe how
|
// multiple instances of the engine getting created. I'll need to go observe how
|
||||||
// and when the engine gets accessed.
|
// and when the engine gets accessed.
|
||||||
thread_local! {
|
thread_local! {
|
||||||
pub static ENGINE: std::rc::Rc<std::cell::RefCell<steel::steel_vm::engine::Engine>> = configure_engine();
|
pub static ENGINE: std::rc::Rc<std::cell::RefCell<steel::steel_vm::engine::Engine>> = {
|
||||||
|
if ENGINE_COUNT.fetch_add(1, Ordering::SeqCst) != 0 {
|
||||||
|
panic!("More than one instance of the steel runtime is not allowed!");
|
||||||
|
}
|
||||||
|
configure_engine()
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct KeyMapApi {
|
pub struct KeyMapApi {
|
||||||
|
@ -94,7 +103,8 @@ impl KeyMapApi {
|
||||||
// and can instead just refer to the single configuration object.
|
// and can instead just refer to the single configuration object.
|
||||||
//
|
//
|
||||||
// Possibly also introduce buffer / language specific keybindings
|
// Possibly also introduce buffer / language specific keybindings
|
||||||
// there as well.
|
// there as well, however how that interaction is done is still up
|
||||||
|
// for debate.
|
||||||
thread_local! {
|
thread_local! {
|
||||||
pub static BUFFER_OR_EXTENSION_KEYBINDING_MAP: SteelVal =
|
pub static BUFFER_OR_EXTENSION_KEYBINDING_MAP: SteelVal =
|
||||||
SteelVal::boxed(SteelVal::empty_hashmap());
|
SteelVal::boxed(SteelVal::empty_hashmap());
|
||||||
|
@ -135,11 +145,14 @@ fn load_keymap_api(engine: &mut Engine, api: KeyMapApi) {
|
||||||
engine.register_module(module);
|
engine.register_module(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_static_commands(engine: &mut Engine) {
|
fn load_static_commands(engine: &mut Engine, generate_sources: bool) {
|
||||||
let mut module = BuiltInModule::new("helix/core/static");
|
let mut module = BuiltInModule::new("helix/core/static");
|
||||||
|
|
||||||
let mut builtin_static_command_module =
|
let mut builtin_static_command_module = if generate_sources {
|
||||||
"(require-builtin helix/core/static as helix.static.)".to_string();
|
"(require-builtin helix/core/static as helix.static.)".to_string()
|
||||||
|
} else {
|
||||||
|
"".to_string()
|
||||||
|
};
|
||||||
|
|
||||||
for command in TYPABLE_COMMAND_LIST {
|
for command in TYPABLE_COMMAND_LIST {
|
||||||
let func = |cx: &mut Context| {
|
let func = |cx: &mut Context| {
|
||||||
|
@ -161,6 +174,7 @@ fn load_static_commands(engine: &mut Engine) {
|
||||||
if let MappableCommand::Static { name, fun, .. } = command {
|
if let MappableCommand::Static { name, fun, .. } = command {
|
||||||
module.register_fn(name, fun);
|
module.register_fn(name, fun);
|
||||||
|
|
||||||
|
if generate_sources {
|
||||||
builtin_static_command_module.push_str(&format!(
|
builtin_static_command_module.push_str(&format!(
|
||||||
r#"
|
r#"
|
||||||
(provide {})
|
(provide {})
|
||||||
|
@ -171,8 +185,10 @@ fn load_static_commands(engine: &mut Engine) {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mut template_function_arity_1 = |name: &str| {
|
let mut template_function_arity_1 = |name: &str| {
|
||||||
|
if generate_sources {
|
||||||
builtin_static_command_module.push_str(&format!(
|
builtin_static_command_module.push_str(&format!(
|
||||||
r#"
|
r#"
|
||||||
(provide {})
|
(provide {})
|
||||||
|
@ -181,6 +197,7 @@ fn load_static_commands(engine: &mut Engine) {
|
||||||
"#,
|
"#,
|
||||||
name, name, name
|
name, name, name
|
||||||
));
|
));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Adhoc static commands that probably needs evaluating
|
// Adhoc static commands that probably needs evaluating
|
||||||
|
@ -209,6 +226,7 @@ fn load_static_commands(engine: &mut Engine) {
|
||||||
template_function_arity_1("cx->current-file");
|
template_function_arity_1("cx->current-file");
|
||||||
|
|
||||||
let mut template_function_arity_0 = |name: &str| {
|
let mut template_function_arity_0 = |name: &str| {
|
||||||
|
if generate_sources {
|
||||||
builtin_static_command_module.push_str(&format!(
|
builtin_static_command_module.push_str(&format!(
|
||||||
r#"
|
r#"
|
||||||
(provide {})
|
(provide {})
|
||||||
|
@ -217,6 +235,7 @@ fn load_static_commands(engine: &mut Engine) {
|
||||||
"#,
|
"#,
|
||||||
name, name, name
|
name, name, name
|
||||||
));
|
));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Arity 0
|
// Arity 0
|
||||||
|
@ -242,6 +261,7 @@ fn load_static_commands(engine: &mut Engine) {
|
||||||
template_function_arity_0("move-window-far-right");
|
template_function_arity_0("move-window-far-right");
|
||||||
|
|
||||||
let mut template_function_no_context = |name: &str| {
|
let mut template_function_no_context = |name: &str| {
|
||||||
|
if generate_sources {
|
||||||
builtin_static_command_module.push_str(&format!(
|
builtin_static_command_module.push_str(&format!(
|
||||||
r#"
|
r#"
|
||||||
(provide {})
|
(provide {})
|
||||||
|
@ -249,6 +269,7 @@ fn load_static_commands(engine: &mut Engine) {
|
||||||
"#,
|
"#,
|
||||||
name, name, name
|
name, name, name
|
||||||
))
|
))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.register_fn("get-helix-scm-path", get_helix_scm_path);
|
module.register_fn("get-helix-scm-path", get_helix_scm_path);
|
||||||
|
@ -257,6 +278,7 @@ fn load_static_commands(engine: &mut Engine) {
|
||||||
template_function_no_context("get-helix-scm-path");
|
template_function_no_context("get-helix-scm-path");
|
||||||
template_function_no_context("get-init-scm-path");
|
template_function_no_context("get-init-scm-path");
|
||||||
|
|
||||||
|
if generate_sources {
|
||||||
let mut target_directory = helix_runtime_search_path();
|
let mut target_directory = helix_runtime_search_path();
|
||||||
|
|
||||||
if !target_directory.exists() {
|
if !target_directory.exists() {
|
||||||
|
@ -266,40 +288,20 @@ fn load_static_commands(engine: &mut Engine) {
|
||||||
target_directory.push("static.scm");
|
target_directory.push("static.scm");
|
||||||
|
|
||||||
std::fs::write(target_directory, builtin_static_command_module).unwrap();
|
std::fs::write(target_directory, builtin_static_command_module).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
engine.register_module(module);
|
engine.register_module(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_typed_commands(engine: &mut Engine) {
|
fn load_typed_commands(engine: &mut Engine, generate_sources: bool) {
|
||||||
let mut module = BuiltInModule::new("helix/core/typable".to_string());
|
let mut module = BuiltInModule::new("helix/core/typable".to_string());
|
||||||
let mut builtin_typable_command_module =
|
|
||||||
"(require-builtin helix/core/typable as helix.)".to_string();
|
|
||||||
|
|
||||||
{
|
let mut builtin_typable_command_module = if generate_sources {
|
||||||
let func = |cx: &mut Context, args: &[Cow<str>]| {
|
"(require-builtin helix/core/typable as helix.)".to_string()
|
||||||
let mut cx = compositor::Context {
|
} else {
|
||||||
editor: cx.editor,
|
"".to_string()
|
||||||
scroll: None,
|
|
||||||
jobs: cx.jobs,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
set_options(&mut cx, args, PromptEvent::Validate)
|
|
||||||
};
|
|
||||||
|
|
||||||
module.register_fn("set-options", func);
|
|
||||||
let name = "set-options";
|
|
||||||
|
|
||||||
builtin_typable_command_module.push_str(&format!(
|
|
||||||
r#"
|
|
||||||
(provide {})
|
|
||||||
|
|
||||||
(define ({} . args)
|
|
||||||
(helix.{} *helix.cx* args))
|
|
||||||
"#,
|
|
||||||
name, name, name
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register everything in the typable command list. Now these are all available
|
// Register everything in the typable command list. Now these are all available
|
||||||
for command in TYPABLE_COMMAND_LIST {
|
for command in TYPABLE_COMMAND_LIST {
|
||||||
let func = |cx: &mut Context, args: &[Cow<str>]| {
|
let func = |cx: &mut Context, args: &[Cow<str>]| {
|
||||||
|
@ -314,6 +316,7 @@ fn load_typed_commands(engine: &mut Engine) {
|
||||||
|
|
||||||
module.register_fn(command.name, func);
|
module.register_fn(command.name, func);
|
||||||
|
|
||||||
|
if generate_sources {
|
||||||
// Create an ephemeral builtin module to reference until I figure out how
|
// Create an ephemeral builtin module to reference until I figure out how
|
||||||
// to wrap the functions with a reference to the engine context better.
|
// to wrap the functions with a reference to the engine context better.
|
||||||
builtin_typable_command_module.push_str(&format!(
|
builtin_typable_command_module.push_str(&format!(
|
||||||
|
@ -340,7 +343,9 @@ fn load_typed_commands(engine: &mut Engine) {
|
||||||
command.name
|
command.name
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if generate_sources {
|
||||||
let mut target_directory = helix_runtime_search_path();
|
let mut target_directory = helix_runtime_search_path();
|
||||||
if !target_directory.exists() {
|
if !target_directory.exists() {
|
||||||
std::fs::create_dir(&target_directory).unwrap();
|
std::fs::create_dir(&target_directory).unwrap();
|
||||||
|
@ -349,6 +354,7 @@ fn load_typed_commands(engine: &mut Engine) {
|
||||||
target_directory.push("commands.scm");
|
target_directory.push("commands.scm");
|
||||||
|
|
||||||
std::fs::write(target_directory, builtin_typable_command_module).unwrap();
|
std::fs::write(target_directory, builtin_typable_command_module).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
engine.register_module(module);
|
engine.register_module(module);
|
||||||
}
|
}
|
||||||
|
@ -389,7 +395,27 @@ fn fp_max_depth(config: &mut FilePickerConfig, option: Option<usize>) {
|
||||||
config.max_depth = option;
|
config.max_depth = option;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_configuration_api(engine: &mut Engine) {
|
fn sw_enable(config: &mut SoftWrap, option: Option<bool>) {
|
||||||
|
config.enable = option;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sw_max_wrap(config: &mut SoftWrap, option: Option<u16>) {
|
||||||
|
config.max_wrap = option;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sw_max_indent_retain(config: &mut SoftWrap, option: Option<u16>) {
|
||||||
|
config.max_indent_retain = option;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sw_wrap_indicator(config: &mut SoftWrap, option: Option<String>) {
|
||||||
|
config.wrap_indicator = option;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wrap_at_text_width(config: &mut SoftWrap, option: Option<bool>) {
|
||||||
|
config.wrap_at_text_width = option;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_configuration_api(engine: &mut Engine, generate_sources: bool) {
|
||||||
let mut module = BuiltInModule::new("helix/core/configuration");
|
let mut module = BuiltInModule::new("helix/core/configuration");
|
||||||
|
|
||||||
module.register_fn("update-configuration!", |ctx: &mut Context| {
|
module.register_fn("update-configuration!", |ctx: &mut Context| {
|
||||||
|
@ -400,56 +426,6 @@ fn load_configuration_api(engine: &mut Engine) {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut builtin_configuration_module =
|
|
||||||
"(require-builtin helix/core/configuration as helix.)".to_string();
|
|
||||||
|
|
||||||
builtin_configuration_module.push_str(&format!(
|
|
||||||
r#"
|
|
||||||
(provide update-configuration!)
|
|
||||||
(define (update-configuration!)
|
|
||||||
(helix.update-configuration! *helix.cx*))
|
|
||||||
"#,
|
|
||||||
));
|
|
||||||
|
|
||||||
let mut template_file_picker_function = |name: &str| {
|
|
||||||
builtin_configuration_module.push_str(&format!(
|
|
||||||
r#"
|
|
||||||
(provide {})
|
|
||||||
(define ({} arg)
|
|
||||||
(lambda (picker)
|
|
||||||
(helix.{} picker arg)
|
|
||||||
picker))
|
|
||||||
"#,
|
|
||||||
name, name, name
|
|
||||||
));
|
|
||||||
};
|
|
||||||
|
|
||||||
let file_picker_functions = &[
|
|
||||||
"fp-hidden",
|
|
||||||
"fp-follow-symlinks",
|
|
||||||
"fp-deduplicate-links",
|
|
||||||
"fp-parents",
|
|
||||||
"fp-ignore",
|
|
||||||
"fp-git-ignore",
|
|
||||||
"fp-git-global",
|
|
||||||
"fp-git-exclude",
|
|
||||||
"fp-max-depth",
|
|
||||||
];
|
|
||||||
|
|
||||||
for name in file_picker_functions {
|
|
||||||
template_file_picker_function(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
builtin_configuration_module.push_str(&format!(
|
|
||||||
r#"
|
|
||||||
(provide file-picker)
|
|
||||||
(define (file-picker . args)
|
|
||||||
(helix.register-file-picker
|
|
||||||
*helix.config*
|
|
||||||
(foldl (lambda (func config) (func config)) (helix.raw-file-picker) args)))
|
|
||||||
"#,
|
|
||||||
));
|
|
||||||
|
|
||||||
module
|
module
|
||||||
.register_fn("raw-file-picker", || FilePickerConfig::default())
|
.register_fn("raw-file-picker", || FilePickerConfig::default())
|
||||||
.register_fn("register-file-picker", HelixConfiguration::file_picker)
|
.register_fn("register-file-picker", HelixConfiguration::file_picker)
|
||||||
|
@ -463,61 +439,14 @@ fn load_configuration_api(engine: &mut Engine) {
|
||||||
.register_fn("fp-git-exclude", fp_git_exclude)
|
.register_fn("fp-git-exclude", fp_git_exclude)
|
||||||
.register_fn("fp-max-depth", fp_max_depth);
|
.register_fn("fp-max-depth", fp_max_depth);
|
||||||
|
|
||||||
let mut template_function_arity_1 = |name: &str| {
|
module
|
||||||
builtin_configuration_module.push_str(&format!(
|
.register_fn("raw-soft-wrap", || SoftWrap::default())
|
||||||
r#"
|
.register_fn("register-soft-wrap", HelixConfiguration::soft_wrap)
|
||||||
(provide {})
|
.register_fn("sw-enable", sw_enable)
|
||||||
(define ({} arg)
|
.register_fn("sw-max-wrap", sw_max_wrap)
|
||||||
(helix.{} *helix.config* arg))
|
.register_fn("sw-max-indent-retain", sw_max_indent_retain)
|
||||||
"#,
|
.register_fn("sw-wrap-indicator", sw_wrap_indicator)
|
||||||
name, name, name
|
.register_fn("sw-wrap-at-text-width", wrap_at_text_width);
|
||||||
));
|
|
||||||
};
|
|
||||||
|
|
||||||
let functions = &[
|
|
||||||
"scrolloff",
|
|
||||||
"scroll_lines",
|
|
||||||
"mouse",
|
|
||||||
"shell",
|
|
||||||
"line-number",
|
|
||||||
"cursorline",
|
|
||||||
"cursorcolumn",
|
|
||||||
"middle-click-paste",
|
|
||||||
"auto-pairs",
|
|
||||||
"auto-completion",
|
|
||||||
"auto-format",
|
|
||||||
"auto-save",
|
|
||||||
"text-width",
|
|
||||||
"idle-timeout",
|
|
||||||
"completion-timeout",
|
|
||||||
"preview-completion-insert",
|
|
||||||
"completion-trigger-len",
|
|
||||||
"completion-replace",
|
|
||||||
"auto-info",
|
|
||||||
"cursor-shape",
|
|
||||||
"true-color",
|
|
||||||
"insert-final-newline",
|
|
||||||
"color-modes",
|
|
||||||
"gutters",
|
|
||||||
// "file-picker",
|
|
||||||
"statusline",
|
|
||||||
"undercurl",
|
|
||||||
"search",
|
|
||||||
"lsp",
|
|
||||||
"terminal",
|
|
||||||
"rulers",
|
|
||||||
"whitespace",
|
|
||||||
"bufferline",
|
|
||||||
"indent-guides",
|
|
||||||
// "soft-wrap",
|
|
||||||
"workspace-lsp-roots",
|
|
||||||
"default-line-ending",
|
|
||||||
"smart-tab",
|
|
||||||
];
|
|
||||||
|
|
||||||
for func in functions {
|
|
||||||
template_function_arity_1(func);
|
|
||||||
}
|
|
||||||
|
|
||||||
module
|
module
|
||||||
.register_fn("scrolloff", HelixConfiguration::scrolloff)
|
.register_fn("scrolloff", HelixConfiguration::scrolloff)
|
||||||
|
@ -570,7 +499,7 @@ fn load_configuration_api(engine: &mut Engine) {
|
||||||
.register_fn("whitespace", HelixConfiguration::whitespace)
|
.register_fn("whitespace", HelixConfiguration::whitespace)
|
||||||
.register_fn("bufferline", HelixConfiguration::bufferline)
|
.register_fn("bufferline", HelixConfiguration::bufferline)
|
||||||
.register_fn("indent-guides", HelixConfiguration::indent_guides)
|
.register_fn("indent-guides", HelixConfiguration::indent_guides)
|
||||||
// .register_fn("soft-wrap", HelixConfiguration::soft_wrap)
|
.register_fn("soft-wrap", HelixConfiguration::soft_wrap)
|
||||||
.register_fn(
|
.register_fn(
|
||||||
"workspace-lsp-roots",
|
"workspace-lsp-roots",
|
||||||
HelixConfiguration::workspace_lsp_roots,
|
HelixConfiguration::workspace_lsp_roots,
|
||||||
|
@ -581,6 +510,163 @@ fn load_configuration_api(engine: &mut Engine) {
|
||||||
)
|
)
|
||||||
.register_fn("smart-tab", HelixConfiguration::smart_tab);
|
.register_fn("smart-tab", HelixConfiguration::smart_tab);
|
||||||
|
|
||||||
|
// Keybinding stuff
|
||||||
|
module
|
||||||
|
.register_fn("keybindings", HelixConfiguration::keybindings)
|
||||||
|
.register_fn("get-keybindings", HelixConfiguration::get_keybindings);
|
||||||
|
|
||||||
|
if generate_sources {
|
||||||
|
let mut builtin_configuration_module =
|
||||||
|
"(require-builtin helix/core/configuration as helix.)".to_string();
|
||||||
|
|
||||||
|
builtin_configuration_module.push_str(&format!(
|
||||||
|
r#"
|
||||||
|
(provide update-configuration!)
|
||||||
|
(define (update-configuration!)
|
||||||
|
(helix.update-configuration! *helix.cx*))
|
||||||
|
"#,
|
||||||
|
));
|
||||||
|
|
||||||
|
// Register the get keybindings function
|
||||||
|
builtin_configuration_module.push_str(&format!(
|
||||||
|
r#"
|
||||||
|
(provide get-keybindings)
|
||||||
|
(define (get-keybindings)
|
||||||
|
(helix.get-keybindings *helix.cx*))
|
||||||
|
"#,
|
||||||
|
));
|
||||||
|
|
||||||
|
let mut template_soft_wrap = |name: &str| {
|
||||||
|
builtin_configuration_module.push_str(&format!(
|
||||||
|
r#"
|
||||||
|
(provide {})
|
||||||
|
(define ({} arg)
|
||||||
|
(lambda (picker)
|
||||||
|
(helix.{} picker arg)
|
||||||
|
picker))
|
||||||
|
"#,
|
||||||
|
name, name, name
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
|
let soft_wrap_functions = &[
|
||||||
|
"sw-enable",
|
||||||
|
"sw-max-wrap",
|
||||||
|
"sw-max-indent-retain",
|
||||||
|
"sw-wrap-indicator",
|
||||||
|
"sw-wrap-at-text-width",
|
||||||
|
];
|
||||||
|
|
||||||
|
for name in soft_wrap_functions {
|
||||||
|
template_soft_wrap(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut template_file_picker_function = |name: &str| {
|
||||||
|
builtin_configuration_module.push_str(&format!(
|
||||||
|
r#"
|
||||||
|
(provide {})
|
||||||
|
(define ({} arg)
|
||||||
|
(lambda (picker)
|
||||||
|
(helix.{} picker arg)
|
||||||
|
picker))
|
||||||
|
"#,
|
||||||
|
name, name, name
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
|
let file_picker_functions = &[
|
||||||
|
"fp-hidden",
|
||||||
|
"fp-follow-symlinks",
|
||||||
|
"fp-deduplicate-links",
|
||||||
|
"fp-parents",
|
||||||
|
"fp-ignore",
|
||||||
|
"fp-git-ignore",
|
||||||
|
"fp-git-global",
|
||||||
|
"fp-git-exclude",
|
||||||
|
"fp-max-depth",
|
||||||
|
];
|
||||||
|
|
||||||
|
for name in file_picker_functions {
|
||||||
|
template_file_picker_function(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
builtin_configuration_module.push_str(&format!(
|
||||||
|
r#"
|
||||||
|
(provide file-picker)
|
||||||
|
(define (file-picker . args)
|
||||||
|
(helix.register-file-picker
|
||||||
|
*helix.config*
|
||||||
|
(foldl (lambda (func config) (func config)) (helix.raw-file-picker) args)))
|
||||||
|
"#,
|
||||||
|
));
|
||||||
|
|
||||||
|
builtin_configuration_module.push_str(&format!(
|
||||||
|
r#"
|
||||||
|
(provide soft-wrap)
|
||||||
|
(define (soft-wrap . args)
|
||||||
|
(helix.register-soft-wrap
|
||||||
|
*helix.config*
|
||||||
|
(foldl (lambda (func config) (func config)) (helix.raw-soft-wrap) args)))
|
||||||
|
"#,
|
||||||
|
));
|
||||||
|
|
||||||
|
let mut template_function_arity_1 = |name: &str| {
|
||||||
|
builtin_configuration_module.push_str(&format!(
|
||||||
|
r#"
|
||||||
|
(provide {})
|
||||||
|
(define ({} arg)
|
||||||
|
(helix.{} *helix.config* arg))
|
||||||
|
"#,
|
||||||
|
name, name, name
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
|
let functions = &[
|
||||||
|
"scrolloff",
|
||||||
|
"scroll_lines",
|
||||||
|
"mouse",
|
||||||
|
"shell",
|
||||||
|
"line-number",
|
||||||
|
"cursorline",
|
||||||
|
"cursorcolumn",
|
||||||
|
"middle-click-paste",
|
||||||
|
"auto-pairs",
|
||||||
|
"auto-completion",
|
||||||
|
"auto-format",
|
||||||
|
"auto-save",
|
||||||
|
"text-width",
|
||||||
|
"idle-timeout",
|
||||||
|
"completion-timeout",
|
||||||
|
"preview-completion-insert",
|
||||||
|
"completion-trigger-len",
|
||||||
|
"completion-replace",
|
||||||
|
"auto-info",
|
||||||
|
"cursor-shape",
|
||||||
|
"true-color",
|
||||||
|
"insert-final-newline",
|
||||||
|
"color-modes",
|
||||||
|
"gutters",
|
||||||
|
// "file-picker",
|
||||||
|
"statusline",
|
||||||
|
"undercurl",
|
||||||
|
"search",
|
||||||
|
"lsp",
|
||||||
|
"terminal",
|
||||||
|
"rulers",
|
||||||
|
"whitespace",
|
||||||
|
"bufferline",
|
||||||
|
"indent-guides",
|
||||||
|
// "soft-wrap",
|
||||||
|
"workspace-lsp-roots",
|
||||||
|
"default-line-ending",
|
||||||
|
"smart-tab",
|
||||||
|
"keybindings",
|
||||||
|
];
|
||||||
|
|
||||||
|
for func in functions {
|
||||||
|
template_function_arity_1(func);
|
||||||
|
}
|
||||||
|
|
||||||
let mut target_directory = helix_runtime_search_path();
|
let mut target_directory = helix_runtime_search_path();
|
||||||
|
|
||||||
if !target_directory.exists() {
|
if !target_directory.exists() {
|
||||||
|
@ -590,13 +676,46 @@ fn load_configuration_api(engine: &mut Engine) {
|
||||||
target_directory.push("configuration.scm");
|
target_directory.push("configuration.scm");
|
||||||
|
|
||||||
std::fs::write(target_directory, builtin_configuration_module).unwrap();
|
std::fs::write(target_directory, builtin_configuration_module).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
engine.register_module(module);
|
engine.register_module(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_editor_api(engine: &mut Engine) {
|
fn load_editor_api(engine: &mut Engine, generate_sources: bool) {
|
||||||
let mut module = BuiltInModule::new("helix/core/editor");
|
let mut module = BuiltInModule::new("helix/core/editor");
|
||||||
|
|
||||||
|
// Arity 0
|
||||||
|
module.register_fn("editor-focus", cx_current_focus);
|
||||||
|
module.register_fn("editor-mode", cx_get_mode);
|
||||||
|
module.register_fn("cx->themes", get_themes);
|
||||||
|
module.register_fn("editor-all-documents", cx_editor_all_documents);
|
||||||
|
module.register_fn("cx->cursor", |cx: &mut Context| cx.editor.cursor());
|
||||||
|
|
||||||
|
// Arity 1
|
||||||
|
module.register_fn("editor->doc-id", cx_get_document_id);
|
||||||
|
module.register_fn("editor-switch!", cx_switch);
|
||||||
|
module.register_fn("editor-set-focus!", |cx: &mut Context, view_id: ViewId| {
|
||||||
|
cx.editor.focus(view_id)
|
||||||
|
});
|
||||||
|
module.register_fn("editor-set-mode!", cx_set_mode);
|
||||||
|
module.register_fn("editor-doc-in-view?", cx_is_document_in_view);
|
||||||
|
module.register_fn("set-scratch-buffer-name!", set_scratch_buffer_name);
|
||||||
|
module.register_fn("editor-doc-exists?", cx_document_exists);
|
||||||
|
|
||||||
|
// Arity 1
|
||||||
|
RegisterFn::<
|
||||||
|
_,
|
||||||
|
steel::steel_vm::register_fn::MarkerWrapper8<(
|
||||||
|
Context,
|
||||||
|
DocumentId,
|
||||||
|
Document,
|
||||||
|
Document,
|
||||||
|
Context,
|
||||||
|
)>,
|
||||||
|
Document,
|
||||||
|
>::register_fn(&mut module, "editor->get-document", cx_get_document); // I do not like this
|
||||||
|
|
||||||
|
if generate_sources {
|
||||||
let mut builtin_editor_command_module =
|
let mut builtin_editor_command_module =
|
||||||
"(require-builtin helix/core/editor as helix.)".to_string();
|
"(require-builtin helix/core/editor as helix.)".to_string();
|
||||||
|
|
||||||
|
@ -611,13 +730,6 @@ fn load_editor_api(engine: &mut Engine) {
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
|
|
||||||
// Arity 0
|
|
||||||
module.register_fn("editor-focus", cx_current_focus);
|
|
||||||
module.register_fn("editor-mode", cx_get_mode);
|
|
||||||
module.register_fn("cx->themes", get_themes);
|
|
||||||
module.register_fn("editor-all-documents", cx_editor_all_documents);
|
|
||||||
module.register_fn("cx->cursor", |cx: &mut Context| cx.editor.cursor());
|
|
||||||
|
|
||||||
template_function_arity_0("editor-focus");
|
template_function_arity_0("editor-focus");
|
||||||
template_function_arity_0("editor-mode");
|
template_function_arity_0("editor-mode");
|
||||||
template_function_arity_0("cx->themes");
|
template_function_arity_0("cx->themes");
|
||||||
|
@ -635,17 +747,6 @@ fn load_editor_api(engine: &mut Engine) {
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
|
|
||||||
// Arity 1
|
|
||||||
module.register_fn("editor->doc-id", cx_get_document_id);
|
|
||||||
module.register_fn("editor-switch!", cx_switch);
|
|
||||||
module.register_fn("editor-set-focus!", |cx: &mut Context, view_id: ViewId| {
|
|
||||||
cx.editor.focus(view_id)
|
|
||||||
});
|
|
||||||
module.register_fn("editor-set-mode!", cx_set_mode);
|
|
||||||
module.register_fn("editor-doc-in-view?", cx_is_document_in_view);
|
|
||||||
module.register_fn("set-scratch-buffer-name!", set_scratch_buffer_name);
|
|
||||||
module.register_fn("editor-doc-exists?", cx_document_exists);
|
|
||||||
|
|
||||||
template_function_arity_1("editor->doc-id");
|
template_function_arity_1("editor->doc-id");
|
||||||
template_function_arity_1("editor-switch!");
|
template_function_arity_1("editor-switch!");
|
||||||
template_function_arity_1("editor-set-focus!");
|
template_function_arity_1("editor-set-focus!");
|
||||||
|
@ -655,41 +756,6 @@ fn load_editor_api(engine: &mut Engine) {
|
||||||
template_function_arity_1("editor-doc-exists?");
|
template_function_arity_1("editor-doc-exists?");
|
||||||
template_function_arity_1("editor->get-document");
|
template_function_arity_1("editor->get-document");
|
||||||
|
|
||||||
// Doesn't use the context
|
|
||||||
// module.register_fn("doc-id->usize", document_id_to_usize);
|
|
||||||
|
|
||||||
// Arity 1
|
|
||||||
RegisterFn::<
|
|
||||||
_,
|
|
||||||
steel::steel_vm::register_fn::MarkerWrapper8<(
|
|
||||||
Context,
|
|
||||||
DocumentId,
|
|
||||||
Document,
|
|
||||||
Document,
|
|
||||||
Context,
|
|
||||||
)>,
|
|
||||||
Document,
|
|
||||||
>::register_fn(&mut module, "editor->get-document", cx_get_document); // I do not like this
|
|
||||||
|
|
||||||
// module.register_fn("Document-path", document_path);
|
|
||||||
|
|
||||||
// module.register_fn("helix.context?", is_context);
|
|
||||||
// module.register_type::<DocumentId>("DocumentId?");
|
|
||||||
|
|
||||||
// TODO:
|
|
||||||
// Position related functions. These probably should be defined alongside the actual impl for Custom in the core crate
|
|
||||||
// module.register_fn("position", helix_core::Position::new);
|
|
||||||
// module.register_fn("position-default", helix_core::Position::default);
|
|
||||||
// module.register_fn("position-row", |position: helix_core::Position| {
|
|
||||||
// position.row
|
|
||||||
// });
|
|
||||||
|
|
||||||
// module.register_fn("cx->themes", get_themes);
|
|
||||||
|
|
||||||
// Not the best usage here, duplicating it in a bunch of spots for now
|
|
||||||
// let mut target_directory = PathBuf::from(std::env::var("HELIX_RUNTIME").unwrap());
|
|
||||||
// target_directory.push("cogs");
|
|
||||||
// target_directory.push("helix");
|
|
||||||
let mut target_directory = helix_runtime_search_path();
|
let mut target_directory = helix_runtime_search_path();
|
||||||
|
|
||||||
if !target_directory.exists() {
|
if !target_directory.exists() {
|
||||||
|
@ -699,6 +765,7 @@ fn load_editor_api(engine: &mut Engine) {
|
||||||
target_directory.push("editor.scm");
|
target_directory.push("editor.scm");
|
||||||
|
|
||||||
std::fs::write(target_directory, builtin_editor_command_module).unwrap();
|
std::fs::write(target_directory, builtin_editor_command_module).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
engine.register_module(module);
|
engine.register_module(module);
|
||||||
}
|
}
|
||||||
|
@ -853,6 +920,12 @@ impl super::PluginSystem for SteelScriptingEngine {
|
||||||
.map(|x| x.clone().into())
|
.map(|x| x.clone().into())
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn generate_sources(&self) {
|
||||||
|
// Generate sources directly with a fresh engine
|
||||||
|
let mut engine = Engine::new();
|
||||||
|
configure_builtin_sources(&mut engine, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SteelScriptingEngine {
|
impl SteelScriptingEngine {
|
||||||
|
@ -1089,6 +1162,17 @@ impl HelixConfiguration {
|
||||||
self.configuration.store(Arc::new(config));
|
self.configuration.store(Arc::new(config));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Overlay new keybindings
|
||||||
|
fn keybindings(&self, keybindings: EmbeddedKeyMap) {
|
||||||
|
let mut app_config = self.load_config();
|
||||||
|
merge_keys(&mut app_config.keys, keybindings.0);
|
||||||
|
self.store_config(app_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_keybindings(&self) -> EmbeddedKeyMap {
|
||||||
|
EmbeddedKeyMap(self.load_config().keys.clone())
|
||||||
|
}
|
||||||
|
|
||||||
fn scrolloff(&self, lines: usize) {
|
fn scrolloff(&self, lines: usize) {
|
||||||
let mut app_config = self.load_config();
|
let mut app_config = self.load_config();
|
||||||
app_config.editor.scrolloff = lines;
|
app_config.editor.scrolloff = lines;
|
||||||
|
@ -1424,9 +1508,6 @@ fn run_initialization_script(cx: &mut Context, configuration: Arc<ArcSwapAny<Arc
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub static KEYBINDING_QUEUE: Lazy<SharedKeyBindingsEventQueue> =
|
|
||||||
// Lazy::new(|| SharedKeyBindingsEventQueue::new());
|
|
||||||
|
|
||||||
pub static EXPORTED_IDENTIFIERS: Lazy<ExportedIdentifiers> =
|
pub static EXPORTED_IDENTIFIERS: Lazy<ExportedIdentifiers> =
|
||||||
Lazy::new(|| ExportedIdentifiers::default());
|
Lazy::new(|| ExportedIdentifiers::default());
|
||||||
|
|
||||||
|
@ -1648,7 +1729,7 @@ impl SteelEngine {
|
||||||
pub fn call_function_by_name(
|
pub fn call_function_by_name(
|
||||||
&mut self,
|
&mut self,
|
||||||
function_name: SteelString,
|
function_name: SteelString,
|
||||||
args: List<SteelVal>,
|
args: Vec<SteelVal>,
|
||||||
) -> steel::rvals::Result<SteelVal> {
|
) -> steel::rvals::Result<SteelVal> {
|
||||||
self.0
|
self.0
|
||||||
.call_function_by_name_with_args(function_name.as_str(), args.into_iter().collect())
|
.call_function_by_name_with_args(function_name.as_str(), args.into_iter().collect())
|
||||||
|
@ -1659,7 +1740,7 @@ impl SteelEngine {
|
||||||
pub fn call_function(
|
pub fn call_function(
|
||||||
&mut self,
|
&mut self,
|
||||||
function: SteelVal,
|
function: SteelVal,
|
||||||
args: List<SteelVal>,
|
args: Vec<SteelVal>,
|
||||||
) -> steel::rvals::Result<SteelVal> {
|
) -> steel::rvals::Result<SteelVal> {
|
||||||
self.0
|
self.0
|
||||||
.call_function_with_args(function, args.into_iter().collect())
|
.call_function_with_args(function, args.into_iter().collect())
|
||||||
|
@ -1716,12 +1797,17 @@ fn load_engine_api(engine: &mut Engine) {
|
||||||
.register_fn("helix.controller.id->engine", id_to_engine);
|
.register_fn("helix.controller.id->engine", id_to_engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_misc_api(engine: &mut Engine) {
|
fn load_misc_api(engine: &mut Engine, generate_sources: bool) {
|
||||||
let mut module = BuiltInModule::new("helix/core/misc");
|
let mut module = BuiltInModule::new("helix/core/misc");
|
||||||
|
|
||||||
let mut builtin_misc_module = "(require-builtin helix/core/misc as helix.)".to_string();
|
let mut builtin_misc_module = if generate_sources {
|
||||||
|
"(require-builtin helix/core/misc as helix.)".to_string()
|
||||||
|
} else {
|
||||||
|
"".to_string()
|
||||||
|
};
|
||||||
|
|
||||||
let mut template_function_arity_0 = |name: &str| {
|
let mut template_function_arity_0 = |name: &str| {
|
||||||
|
if generate_sources {
|
||||||
builtin_misc_module.push_str(&format!(
|
builtin_misc_module.push_str(&format!(
|
||||||
r#"
|
r#"
|
||||||
(provide {})
|
(provide {})
|
||||||
|
@ -1730,6 +1816,7 @@ fn load_misc_api(engine: &mut Engine) {
|
||||||
"#,
|
"#,
|
||||||
name, name, name
|
name, name, name
|
||||||
));
|
));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Arity 0
|
// Arity 0
|
||||||
|
@ -1738,6 +1825,7 @@ fn load_misc_api(engine: &mut Engine) {
|
||||||
template_function_arity_0("hx.cx->pos");
|
template_function_arity_0("hx.cx->pos");
|
||||||
|
|
||||||
let mut template_function_arity_1 = |name: &str| {
|
let mut template_function_arity_1 = |name: &str| {
|
||||||
|
if generate_sources {
|
||||||
builtin_misc_module.push_str(&format!(
|
builtin_misc_module.push_str(&format!(
|
||||||
r#"
|
r#"
|
||||||
(provide {})
|
(provide {})
|
||||||
|
@ -1746,6 +1834,7 @@ fn load_misc_api(engine: &mut Engine) {
|
||||||
"#,
|
"#,
|
||||||
name, name, name
|
name, name, name
|
||||||
));
|
));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Arity 1
|
// Arity 1
|
||||||
|
@ -1758,6 +1847,7 @@ fn load_misc_api(engine: &mut Engine) {
|
||||||
template_function_arity_1("enqueue-thread-local-callback");
|
template_function_arity_1("enqueue-thread-local-callback");
|
||||||
|
|
||||||
let mut template_function_arity_2 = |name: &str| {
|
let mut template_function_arity_2 = |name: &str| {
|
||||||
|
if generate_sources {
|
||||||
builtin_misc_module.push_str(&format!(
|
builtin_misc_module.push_str(&format!(
|
||||||
r#"
|
r#"
|
||||||
(provide {})
|
(provide {})
|
||||||
|
@ -1766,6 +1856,7 @@ fn load_misc_api(engine: &mut Engine) {
|
||||||
"#,
|
"#,
|
||||||
name, name, name
|
name, name, name
|
||||||
));
|
));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Arity 2
|
// Arity 2
|
||||||
|
@ -1780,6 +1871,7 @@ fn load_misc_api(engine: &mut Engine) {
|
||||||
template_function_arity_2("enqueue-thread-local-callback-with-delay");
|
template_function_arity_2("enqueue-thread-local-callback-with-delay");
|
||||||
template_function_arity_2("helix-await-callback");
|
template_function_arity_2("helix-await-callback");
|
||||||
|
|
||||||
|
if generate_sources {
|
||||||
let mut target_directory = helix_runtime_search_path();
|
let mut target_directory = helix_runtime_search_path();
|
||||||
|
|
||||||
if !target_directory.exists() {
|
if !target_directory.exists() {
|
||||||
|
@ -1789,6 +1881,7 @@ fn load_misc_api(engine: &mut Engine) {
|
||||||
target_directory.push("misc.scm");
|
target_directory.push("misc.scm");
|
||||||
|
|
||||||
std::fs::write(target_directory, builtin_misc_module).unwrap();
|
std::fs::write(target_directory, builtin_misc_module).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
engine.register_module(module);
|
engine.register_module(module);
|
||||||
}
|
}
|
||||||
|
@ -1797,6 +1890,19 @@ fn helix_runtime_search_path() -> PathBuf {
|
||||||
helix_loader::config_dir().join("helix")
|
helix_loader::config_dir().join("helix")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn configure_builtin_sources(engine: &mut Engine, generate_sources: bool) {
|
||||||
|
load_editor_api(engine, generate_sources);
|
||||||
|
load_configuration_api(engine, generate_sources);
|
||||||
|
load_typed_commands(engine, generate_sources);
|
||||||
|
load_static_commands(engine, generate_sources);
|
||||||
|
if !generate_sources {
|
||||||
|
// Note: This is going to be completely revamped soon.
|
||||||
|
load_keymap_api(engine, KeyMapApi::new());
|
||||||
|
}
|
||||||
|
load_rope_api(engine);
|
||||||
|
load_misc_api(engine, generate_sources);
|
||||||
|
}
|
||||||
|
|
||||||
fn configure_engine_impl(mut engine: Engine) -> Engine {
|
fn configure_engine_impl(mut engine: Engine) -> Engine {
|
||||||
log::info!("Loading engine!");
|
log::info!("Loading engine!");
|
||||||
|
|
||||||
|
@ -1805,13 +1911,8 @@ fn configure_engine_impl(mut engine: Engine) -> Engine {
|
||||||
engine.register_value("*helix.cx*", SteelVal::Void);
|
engine.register_value("*helix.cx*", SteelVal::Void);
|
||||||
engine.register_value("*helix.config*", SteelVal::Void);
|
engine.register_value("*helix.config*", SteelVal::Void);
|
||||||
|
|
||||||
load_editor_api(&mut engine);
|
// Don't generate source directories here
|
||||||
load_configuration_api(&mut engine);
|
configure_builtin_sources(&mut engine, false);
|
||||||
load_typed_commands(&mut engine);
|
|
||||||
load_static_commands(&mut engine);
|
|
||||||
load_keymap_api(&mut engine, KeyMapApi::new());
|
|
||||||
load_rope_api(&mut engine);
|
|
||||||
load_misc_api(&mut engine);
|
|
||||||
|
|
||||||
// Hooks
|
// Hooks
|
||||||
engine.register_fn("register-hook!", register_hook);
|
engine.register_fn("register-hook!", register_hook);
|
||||||
|
@ -1922,9 +2023,7 @@ fn configure_engine_impl(mut engine: Engine) -> Engine {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
engine.register_fn(
|
engine.register_fn("picker", |values: Vec<String>| -> WrappedDynComponent {
|
||||||
"picker",
|
|
||||||
|values: steel::List<String>| -> WrappedDynComponent {
|
|
||||||
let picker = ui::Picker::new(
|
let picker = ui::Picker::new(
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
PathBuf::from(""),
|
PathBuf::from(""),
|
||||||
|
@ -1952,8 +2051,7 @@ fn configure_engine_impl(mut engine: Engine) -> Engine {
|
||||||
WrappedDynComponent {
|
WrappedDynComponent {
|
||||||
inner: Some(Box::new(ui::overlay::overlaid(picker))),
|
inner: Some(Box::new(ui::overlay::overlaid(picker))),
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
engine.register_fn("Component::Text", |contents: String| WrappedDynComponent {
|
engine.register_fn("Component::Text", |contents: String| WrappedDynComponent {
|
||||||
inner: Some(Box::new(crate::ui::Text::new(contents))),
|
inner: Some(Box::new(crate::ui::Text::new(contents))),
|
||||||
|
@ -2017,7 +2115,7 @@ fn configure_engine_impl(mut engine: Engine) -> Engine {
|
||||||
engine
|
engine
|
||||||
}
|
}
|
||||||
|
|
||||||
fn configure_engine() -> std::rc::Rc<std::cell::RefCell<steel::steel_vm::engine::Engine>> {
|
pub fn configure_engine() -> std::rc::Rc<std::cell::RefCell<steel::steel_vm::engine::Engine>> {
|
||||||
let engine = configure_engine_impl(steel::steel_vm::engine::Engine::new());
|
let engine = configure_engine_impl(steel::steel_vm::engine::Engine::new());
|
||||||
|
|
||||||
std::rc::Rc::new(std::cell::RefCell::new(engine))
|
std::rc::Rc::new(std::cell::RefCell::new(engine))
|
||||||
|
@ -2366,53 +2464,6 @@ fn create_directory(path: String) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Change config at runtime. Access nested values by dot syntax, for
|
|
||||||
/// example to disable smart case search, use `:set search.smart-case false`.
|
|
||||||
fn set_options(
|
|
||||||
cx: &mut compositor::Context,
|
|
||||||
args: &[Cow<str>],
|
|
||||||
event: PromptEvent,
|
|
||||||
) -> anyhow::Result<()> {
|
|
||||||
if event != PromptEvent::Validate {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
if args.len() % 2 != 0 {
|
|
||||||
anyhow::bail!("Bad arguments. Usage: `:set key field`");
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut config = serde_json::json!(&cx.editor.config().deref());
|
|
||||||
// let key_error = || anyhow::anyhow!("Unknown key `{}`", key);
|
|
||||||
// let field_error = |_| anyhow::anyhow!("Could not parse field `{}`", arg);
|
|
||||||
|
|
||||||
for args in args.chunks_exact(2) {
|
|
||||||
let (key, arg) = (&args[0].to_lowercase(), &args[1]);
|
|
||||||
|
|
||||||
let key_error = || anyhow::anyhow!("Unknown key `{}`", key);
|
|
||||||
let field_error = |_| anyhow::anyhow!("Could not parse field `{}`", arg);
|
|
||||||
|
|
||||||
// let mut config = serde_json::json!(&cx.editor.config().deref());
|
|
||||||
let pointer = format!("/{}", key.replace('.', "/"));
|
|
||||||
let value = config.pointer_mut(&pointer).ok_or_else(key_error)?;
|
|
||||||
|
|
||||||
*value = if value.is_string() {
|
|
||||||
// JSON strings require quotes, so we can't .parse() directly
|
|
||||||
Value::String(arg.to_string())
|
|
||||||
} else {
|
|
||||||
arg.parse().map_err(field_error)?
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
let config =
|
|
||||||
serde_json::from_value(config).map_err(|_| anyhow::anyhow!("Could not parse config"))?;
|
|
||||||
|
|
||||||
cx.editor
|
|
||||||
.config_events
|
|
||||||
.0
|
|
||||||
.send(ConfigEvent::Update(config))?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn cx_pos_within_text(cx: &mut Context) -> usize {
|
pub fn cx_pos_within_text(cx: &mut Context) -> usize {
|
||||||
let (view, doc) = current_ref!(cx.editor);
|
let (view, doc) = current_ref!(cx.editor);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
use helix_term::commands::ScriptingEngine;
|
||||||
|
|
||||||
|
pub fn code_gen() {
|
||||||
|
ScriptingEngine::generate_sources()
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
mod codegen;
|
||||||
mod docgen;
|
mod docgen;
|
||||||
mod helpers;
|
mod helpers;
|
||||||
mod path;
|
mod path;
|
||||||
|
@ -9,6 +10,7 @@ use std::{env, error::Error};
|
||||||
type DynError = Box<dyn Error>;
|
type DynError = Box<dyn Error>;
|
||||||
|
|
||||||
pub mod tasks {
|
pub mod tasks {
|
||||||
|
use crate::codegen::code_gen;
|
||||||
use crate::docgen::{lang_features, typable_commands, write};
|
use crate::docgen::{lang_features, typable_commands, write};
|
||||||
use crate::docgen::{LANG_SUPPORT_MD_OUTPUT, TYPABLE_COMMANDS_MD_OUTPUT};
|
use crate::docgen::{LANG_SUPPORT_MD_OUTPUT, TYPABLE_COMMANDS_MD_OUTPUT};
|
||||||
use crate::querycheck::query_check;
|
use crate::querycheck::query_check;
|
||||||
|
@ -32,6 +34,10 @@ pub mod tasks {
|
||||||
query_check()
|
query_check()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn codegen() {
|
||||||
|
code_gen()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn print_help() {
|
pub fn print_help() {
|
||||||
println!(
|
println!(
|
||||||
"
|
"
|
||||||
|
@ -54,6 +60,7 @@ fn main() -> Result<(), DynError> {
|
||||||
"docgen" => tasks::docgen()?,
|
"docgen" => tasks::docgen()?,
|
||||||
"themelint" => tasks::themelint(env::args().nth(2))?,
|
"themelint" => tasks::themelint(env::args().nth(2))?,
|
||||||
"query-check" => tasks::querycheck()?,
|
"query-check" => tasks::querycheck()?,
|
||||||
|
"code-gen" => tasks::codegen(),
|
||||||
invalid => return Err(format!("Invalid task name: {}", invalid).into()),
|
invalid => return Err(format!("Invalid task name: {}", invalid).into()),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue