diff --git a/src/editor_view.rs b/src/editor_view.rs index 776f66b..65ef294 100644 --- a/src/editor_view.rs +++ b/src/editor_view.rs @@ -2,12 +2,12 @@ use std::rc::Rc; use anyhow::Error; use itertools::Itertools; -use wasm_bindgen::{closure::Closure, prelude::wasm_bindgen}; -use wasm_bindgen_futures::js_sys::Object; +use wasm_bindgen::{closure::Closure, prelude::wasm_bindgen, JsCast}; +use wasm_bindgen_futures::js_sys::{Function, Object, Reflect}; use web_sys::{window, HtmlElement}; use yew::{ - function_component, html, use_effect_with, use_node_ref, use_state, use_state_eq, AttrValue, - Callback, Html, Properties, UseStateHandle, + function_component, html, use_effect_with, use_memo, use_node_ref, use_state, use_state_eq, + AttrValue, Callback, Html, Properties, UseStateHandle, }; use crate::{FrameId, GlobalLayoutState, GlobalMemoCell, PanelDirection, SplitPanel}; @@ -199,6 +199,21 @@ extern "C" { fn editorstate_allow_multiple_selections_of(v: bool) -> CMExtension; } +#[wasm_bindgen(getter_with_clone)] +struct CustomKeyBinding { + pub key: String, + pub mac: String, + pub run: Function, +} + +fn custom_key_binding(inp: CustomKeyBinding) -> KeyBinding { + let kb = Object::new(); + let _ = Reflect::set(&kb, &"key".into(), &inp.key.into()); + let _ = Reflect::set(&kb, &"mac".into(), &inp.mac.into()); + let _ = Reflect::set(&kb, &"run".into(), &inp.run.into()); + kb.unchecked_into() +} + #[wasm_bindgen(module = "@codemirror/view")] extern "C" { type EditorView; @@ -287,6 +302,8 @@ extern "C" { extern "C" { #[wasm_bindgen(js_name = defaultKeymap, thread_local)] static DEFAULT_KEYMAP: Vec; + #[wasm_bindgen(js_name = emacsStyleKeymap, thread_local)] + static EMACS_STYLE_KEYMAP: Vec; #[wasm_bindgen(js_name = historyKeymap, thread_local)] static HISTORY_KEYMAP: Vec; @@ -373,12 +390,54 @@ fn editor_area(props: &EditorViewDetailProps) -> Html { }); { let view = view.clone(); + + let current_script = props.editor_state.open_file.clone(); + + let set_err_state = props.editor_state.clone(); + let set_err = Rc::new(move |msg: Option<&str>| { + let mut new_state = (*set_err_state.as_ref()).clone(); + new_state.error_msg = msg.map(|v| AttrValue::from(String::from(v))); + set_err_state.set(new_state.into()); + }); + + let global_memo_runkey = props.global_memo.clone(); + let runkey_closure = use_memo((), |()| { + Closure:: bool>::new(move |_ed_state| { + run_script(¤t_script, &global_memo_runkey, set_err.clone()); + true + }) + }); + use_effect_with(props.editor_state.open_file.clone(), move |open_file| { + let mut keymaps: Vec = vec![custom_key_binding(CustomKeyBinding { + key: "Ctrl-Enter".to_owned(), + mac: "Cmd-Enter".to_owned(), + run: runkey_closure + .as_ref() + .as_ref() + .unchecked_ref::() + .clone(), + })]; + keymaps.append( + &mut vec![ + &CLOSE_BRACKETS_KEYMAP, + &DEFAULT_KEYMAP, + &EMACS_STYLE_KEYMAP, + &SEARCH_KEYMAP, + &HISTORY_KEYMAP, + &FOLD_KEYMAP, + &COMPLETION_KEYMAP, + &LINT_KEYMAP, + ] + .into_iter() + .flat_map(|k| k.with(|v| v.clone()).into_iter()) + .collect_vec(), + ); + view.set_state(&EditorState::create(EditorStateConfig { doc: load_file_contents(open_file) .unwrap_or_else(|e| format!("Error loading content: {}", e.to_string())), extensions: vec![ - // BASIC_SETUP.with(CMExtension::clone), line_numbers(), highlight_active_line_gutter(), highlight_special_chars(), @@ -399,20 +458,7 @@ fn editor_area(props: &EditorViewDetailProps) -> Html { crosshair_cursor(), highlight_active_line(), highlight_selection_matches(), - keymap_of( - vec![ - &CLOSE_BRACKETS_KEYMAP, - &DEFAULT_KEYMAP, - &SEARCH_KEYMAP, - &HISTORY_KEYMAP, - &FOLD_KEYMAP, - &COMPLETION_KEYMAP, - &LINT_KEYMAP, - ] - .into_iter() - .flat_map(|k| k.with(|v| v.clone()).into_iter()) - .collect(), - ), + keymap_of(keymaps), StreamLanguage::streamlanguage_define(LUA.with(StreamLanguage::clone)), editorview_updatelistener_of(&closures.change_closure), ],