diff --git a/crates/aceditor/src/lib.rs b/crates/aceditor/src/lib.rs index 88cf2e6..1d50d80 100644 --- a/crates/aceditor/src/lib.rs +++ b/crates/aceditor/src/lib.rs @@ -40,6 +40,15 @@ mod bindgen { #[wasm_bindgen(method, js_name = getSelectedText)] pub fn get_selected_text(this: &Editor) -> String; } + + #[wasm_bindgen] + extern "C" { + pub type CommandManager; + + #[wasm_bindgen(method, js_name = addCommand)] + pub fn add_command(this: &CommandManager, command: JsValue); + + } } type Result = std::result::Result; @@ -113,6 +122,22 @@ pub enum EditorError { DefineEx(JsValue), } +#[derive(Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Command { + pub name: String, + pub bind_key: BindKey, + #[serde(with = "serde_wasm_bindgen::preserve")] + pub exec: js_sys::Function, + pub read_only: bool, +} + +#[derive(Serialize, Deserialize)] +pub struct BindKey { + pub win: String, + pub mac: String, +} + pub struct Editor { js: bindgen::Editor, } @@ -171,6 +196,14 @@ impl Editor { Ok(()) } + pub fn add_command(&self, command: Command) { + let editor = self.js.clone(); + let manager = bindgen::CommandManager::from( + Reflect::get(&editor, &JsValue::from("commands")).unwrap(), + ); + manager.add_command(serde_wasm_bindgen::to_value(&command).unwrap()); + } + pub fn get_value(&self) -> String { self.js.get_value() } diff --git a/src/app/editor.rs b/src/app/editor.rs index 6f5d20a..288b222 100644 --- a/src/app/editor.rs +++ b/src/app/editor.rs @@ -1,7 +1,8 @@ -use aceditor::EditorOptionsBuilder; +use aceditor::{BindKey, EditorOptionsBuilder}; use istyles::istyles; use leptos::prelude::*; use reactive_stores::Store; +use wasm_bindgen::{JsCast, prelude::Closure}; use wasm_bindgen_futures::spawn_local; use web_sys::UrlSearchParams; @@ -38,7 +39,21 @@ pub fn Editor() -> impl IntoView { .build(); match aceditor::Editor::open("ace_editor", Some(&opt)) { - Ok(editor) => state.editor().set(Some(editor)), + Ok(editor) => { + let exec = Closure::::new(execute(state)); + let command = aceditor::Command { + name: "executeCode".into(), + bind_key: BindKey { + win: "Ctrl-Enter".into(), + mac: "Ctrl-Enter|Command-Enter".into(), + }, + exec: exec.as_ref().unchecked_ref::().clone(), + read_only: true, + }; + exec.forget(); + editor.add_command(command); + state.editor().set(Some(editor)); + } Err(err) => state .last_error() .set(Some(SQLightError::new_ace_editor(err))),