Skip to content

Commit

Permalink
feat: start adding keymap management in rhai
Browse files Browse the repository at this point in the history
  • Loading branch information
justinpombrio committed Apr 18, 2024
1 parent 5733ef7 commit 9be06ca
Show file tree
Hide file tree
Showing 12 changed files with 109 additions and 13 deletions.
4 changes: 3 additions & 1 deletion data/json_lang.ron
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ LanguageSpec(
("Null", Literal("null")),
("True", Literal("true")),
("False", Literal("false")),
("String", Concat(Literal("\""), Concat(Text, Literal("\"")))),
("String",
Style(Properties(fg_color: Some(Base0B)),
Concat(Literal("\""), Concat(Text, Literal("\""))))),
("Number", Check(IsEmptyText, Here, Literal("•"), Text)),
("Array",
Count(
Expand Down
5 changes: 3 additions & 2 deletions scripts/base_module.rhai
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
fn block() {
loop {
let keyprog = ();
try {
synless_internals::display();
let keyprog = synless_internals::block_on_key();
keyprog = synless_internals::block_on_key();
} catch (err) {
log_caught_error(err);
s::abort();
}
};
if keyprog.close_menu {
s::close_menu();
return call(keyprog.prog);
Expand Down
9 changes: 9 additions & 0 deletions scripts/init.rhai
Original file line number Diff line number Diff line change
@@ -1,2 +1,11 @@
s::load_language("data/json_lang.ron");
s::open_doc("data/pokemon.json");

let keymap = new_keymap();
keymap.bind_key("h", "Say Hello", || print("hello world!"), true);
keymap.bind_key("q", "Quit", || s::abort(), true);

let layer = new_layer("default");
layer.add_mode_keymap("Tree", keymap);
s::register_layer(layer);
s::add_global_layer("default");
2 changes: 1 addition & 1 deletion scripts/main.rhai
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ loop {
try {
s::block(); // ignoring return value
} catch (err) {
log_caught_error(err);
s::log_caught_error(err);
if type_of(err) == "SynlessError" && err.category == "Abort" {
s::abort();
}
Expand Down
27 changes: 26 additions & 1 deletion src/keymap/keymap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use crate::frontends::Key;
use crate::language::Storage;
use crate::tree::Node;
use crate::util::{bug, bug_assert, OrderedMap, SynlessBug};
use crate::util::{bug, bug_assert, error, OrderedMap, SynlessBug};
use std::borrow::Borrow;
use std::collections::HashMap;

Expand Down Expand Up @@ -459,3 +459,28 @@ impl Keymap {
root
}
}

impl rhai::CustomType for Keymap {
fn build(mut builder: rhai::TypeBuilder<Self>) {
use std::str::FromStr;

// TODO add the other bind methods
builder
.with_name("Keymap")
.with_fn("new_keymap", Keymap::new)
.with_fn(
"bind_key",
|keymap: &mut Keymap,
key_str: &str,
hint: String,
prog: rhai::FnPtr,
close_menu: bool|
-> Result<(), Box<rhai::EvalAltResult>> {
let key =
Key::from_str(key_str).map_err(|err| error!(Keymap, "{err}: {key_str}"))?;
keymap.bind_key(key, hint, prog, close_menu);
Ok(())
},
);
}
}
23 changes: 23 additions & 0 deletions src/keymap/layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,29 @@ impl Layer {
}
}

impl rhai::CustomType for Layer {
fn build(mut builder: rhai::TypeBuilder<Self>) {
use std::str::FromStr;

builder
.with_name("Layer")
.with_get("name", |layer: &mut Layer| -> String { layer.name.clone() })
.with_fn("new_layer", Layer::new)
.with_fn(
"add_mode_keymap",
|layer: &mut Layer,
mode_str: &str,
keymap: Keymap|
-> Result<(), Box<rhai::EvalAltResult>> {
let mode = Mode::from_str(mode_str)
.map_err(|err| error!(Keymap, "{err}: {mode_str}"))?;
layer.add_mode_keymap(mode, keymap);
Ok(())
},
);
}
}

/****************
* LayerManager *
****************/
Expand Down
2 changes: 1 addition & 1 deletion src/keymap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ mod layer;
mod menu;

pub use keymap::{KeyProg, Keymap};
pub use layer::LayerManager;
pub use layer::{Layer, LayerManager};
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub mod parsing;

pub use engine::{DocName, Engine, Settings};
pub use frontends::Terminal;
pub use keymap::KeyProg;
pub use keymap::{KeyProg, Keymap, Layer};
pub use language::{
AritySpec, ConstructSpec, GrammarSpec, LanguageSpec, NotationSetSpec, SortSpec, Storage,
};
Expand Down
2 changes: 2 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ fn make_engine() -> rhai::Engine {
log!(Debug, "{src} @ {pos:?} > {msg}");
});

engine.build_type::<synless::Keymap>();
engine.build_type::<synless::Layer>();
engine.build_type::<synless::KeyProg>();
engine.build_type::<synless::SynlessError>();

Expand Down
26 changes: 21 additions & 5 deletions src/runtime.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::engine::{DocDisplayLabel, DocName, Engine, Settings};
use crate::frontends::{Event, Frontend, Key, MouseEvent};
use crate::keymap::{KeyProg, Keymap, LayerManager};
use crate::keymap::{KeyProg, Keymap, Layer, LayerManager};
use crate::language::Construct;
use crate::style::Style;
use crate::tree::Mode;
Expand Down Expand Up @@ -40,9 +40,17 @@ impl<F: Frontend<Style = Style> + 'static> Runtime<F> {
}
}

/****************
* Control Flow *
****************/
/***********
* Keymaps *
***********/

pub fn register_layer(&mut self, layer: Layer) {
self.layers.register_layer(layer);
}

pub fn add_global_layer(&mut self, layer_name: &str) -> Result<(), SynlessError> {
self.layers.add_global_layer(layer_name)
}

pub fn open_menu(&mut self, menu_name: String) -> Result<(), SynlessError> {
let doc_name = self.engine.visible_doc_name();
Expand All @@ -62,6 +70,10 @@ impl<F: Frontend<Style = Style> + 'static> Runtime<F> {
self.layers.close_menu();
}

/****************
* Control Flow *
****************/

pub fn prepare_to_abort(&mut self) {
log!(Error, "Synless is aborting!");
// TODO try to save docs
Expand Down Expand Up @@ -311,7 +323,11 @@ impl<F: Frontend<Style = Style> + 'static> Runtime<F> {
}

pub fn register_external_methods(rt: Rc<RefCell<Runtime<F>>>, module: &mut rhai::Module) {
// Control Flow
// Keymaps
register!(module, rt.register_layer(layer: Layer));
register!(module, rt.add_global_layer(layer_name: &str)?);
register!(module, rt.open_menu(menu_name: String)?);
register!(module, rt.open_menu_with_keymap(menu_name: String, keymap: Keymap)? as open_menu);
register!(module, rt.close_menu());

// Filesystem
Expand Down
18 changes: 18 additions & 0 deletions src/tree/location.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use super::node::Node;
use crate::language::{Arity, Storage};
use crate::util::{bug, SynlessBug};
use partial_pretty_printer as ppp;
use std::fmt;
use std::str::FromStr;

// The node in this LocationInner may not be valid (may have been deleted!)
#[derive(Debug, Clone, Copy)]
Expand Down Expand Up @@ -406,3 +408,19 @@ impl LocationInner {
}
}
}

#[derive(thiserror::Error, fmt::Debug)]
#[error("Failed to parse mode from string")]
pub struct ModeParseError;

impl FromStr for Mode {
type Err = ModeParseError;

fn from_str(s: &str) -> Result<Self, ModeParseError> {
match s {
"Tree" => Ok(Mode::Tree),
"Text" => Ok(Mode::Text),
_ => Err(ModeParseError),
}
}
}
2 changes: 1 addition & 1 deletion src/util/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ macro_rules! error {
$crate::error!($category, $message,)
};
($category:ident, $message:literal, $( $arg:expr ),*) => {
SynlessError {
$crate::util::SynlessError {
message: format!($message, $( $arg ),*),
category: $crate::util::ErrorCategory::$category,
}
Expand Down

0 comments on commit 9be06ca

Please sign in to comment.