aboutsummaryrefslogtreecommitdiffstats
path: root/src/parser.rs
AgeCommit message (Collapse)Author
2018-10-01Fill in `action_parses_map_with_simple_characters()` testTeddy Wing
A simple test to check parsing of a simple string without any special keys or modifiers.
2018-09-30Fill in `action_parses_map_with_multiple_modifiers()`Teddy Wing
Make this test do something, validating that it parses multiple modifier prefixes in a special key.
2018-09-30action_parses_map_with_less_than_escape(): Add `>` to end of test stringTeddy Wing
Add a '>' closing bracket to the end of the test string to make sure that the '<' gets escaped even with a '>' following it.
2018-09-30special_key(): Handle modifier + character special keysTeddy Wing
Previously we were able to parse modifier + KeyCode (`<C-Enter>`) special keys and plain KeyCode ones (`<Esc>`). This change adds parsing support for the final type of special key, modifier + character (e.g. `<C-l>`). action_character(): Move the `map` outside of this function and into `action_map()` to allow us to reuse the parsed `char` in `special_key()`. key_modifier(): * Move the `many()` parser and `Option` handling outside of this function and into `special_key()`. Doing so enables us to say: <C-l> // Character special keys _require_ a modifier (thus // `many1`) <[C-]Left> // KeyCode special keys may or may not have a modifier // (thus `many`) * Rename from `key_modifiers()` to singular now that it only parses a single modifier. special_key(): Parse both character and KeyCode special keys with modifiers. action_parses_map_with_modifier(): Change input string to include a KeyCode-style special key with a modifier since we didn't have one previously. This ensures we test both kinds of special keys.
2018-09-30Try to parse modifier keys (WIP)Teddy Wing
Add some parsing code for modifier keys inside special keys (`<`- `>`-wrapped keys). Currently only works for special keys defined in `special_key()`. Needs to be extended to work for modified character keys (e.g. <C-l>), thus the test in this commit doesn't pass.
2018-09-30action_map(): Add backslash escapingTeddy Wing
Escape '<' and '\' by prepending a backslash. Since special characters are enclosed in '<' '>' brackets, in order to type a literal '<', we need a way to escape it. Use backslash, like in Vim.
2018-09-30Extract action normal character parsing to a functionTeddy Wing
Splits up the `action_map()` function and gives the parser a name.
2018-09-30Get `action_map()` parser workingTeddy Wing
Additionally, fix a problem in `key_code()` when using special key names that start with the same character (like any of the F keys, or Enter and Esc). The parser would discard the first character, like in the `definitions()` parser. Use the same solution here, by wrapping the parser choices in `try()`s. Add `Esc` to the test to confirm that it fails not just for the F keys but for all key names that start similarly.
2018-09-30parser: Add `key_code` and `special_key` parsersTeddy Wing
Still need to test them though. They'll be used in conjunction with another new parser, `action_map`, which will parser map-type action strings. `key_code` parses `autopilot::key::KeyCode`s, basically all special keys and modifiers. `special_key` parses key codes inside `<` `>` braces. Change the test to use `easy_parse` to give a clear error message. Add `recursion_limit` to the crate on the advice of the compiler in order for the `choice!` macro in `key_code()` to work properly. Otherwise it spits out a giant error message complaining about `rustc --explain E0277`. If I remove a handful of elements from the `choice!`, it compiles, so it seems there's an upper bound restricted by the recursion limit. Modifier keys are included in a commented section as these are part of the 'autopilot' `KeyCode` enum, but they'll be handled in a separate parser.
2018-09-29Start filling new action parser testsTeddy Wing
* Some stub ideas for test text * Fill in the test for special keys * Add some convenience methods to more easily create the expected test result objects
2018-09-29parser: Add some stub tests for a new `Action` parserTeddy Wing
Ideas for some things we should be testing.
2018-09-29parser: Correct tests to use new `Action` enum typeTeddy Wing
Fix these tests that were based on the `String` version of `Action`, before b02e7366c3c4b9edb5afa0d012952fad369b66a9.
2018-09-29Change `parser::Action` to an enumTeddy Wing
It will now be a different type of `Vec` depending on whether it represents a string map or a command. We'll have new parsers to parse the action definition in a more fine-grained way. The `String` variant is just there for temporary backward compatibility while I figure out parsing for the other two. Still need to update the tests for this change.
2018-09-29Revert "Try to propagate KeyCodeConvertible from Action to everywhere"Teddy Wing
This reverts commit 16cd3895f7b111544927d71904aab912d9abbf59. See that commit message for details.
2018-09-29Try to propagate KeyCodeConvertible from Action to everywhereTeddy Wing
Such a pain. As soon as I clear one set of compilation errors, another set crops up. The last one was like the following: error[E0277]: the trait bound `K: std::default::Default` is not satisfied --> src/cocoa_bridge.rs:117:1 | 117 | / pub extern "C" fn state_new<K>() -> *mut State<K> 118 | | where K: KeyCodeConvertible { 119 | | Box::into_raw(Box::new(State::default())) 120 | | } | |_^ the trait `std::default::Default` is not implemented for `K` | = help: consider adding a `where K: std::default::Default` bound note: required by `cocoa_bridge::State` --> src/cocoa_bridge.rs:100:1 | 100 | / pub struct State<K: KeyCodeConvertible> 101 | | where K: Default { 102 | | in_mode: Option<Vec<HeadphoneButton>>, 103 | | map_group: Option<MapGroup<K>>, 104 | | } | |_^ error[E0277]: the trait bound `K: std::default::Default` is not satisfied I'm done with this. Just going to make a darn enum of 'autopilot's `Character` and `KeyCode` structs so I don't have to deal with this mess.
2018-09-28Revert "parser::map(): Try to parse Action with a dependency on MapKind"Teddy Wing
This reverts commit 76ab45d4a5890c4c348b33c32775e45a7c320c58. See that commit for details.
2018-09-28parser::map(): Try to parse Action with a dependency on MapKindTeddy Wing
Some non-working code where I was trying to get an `Action2` to parse correctly, with a dependency on the result of the `map_kind()` parser. Couldn't figure out how to get this to work though, as I couldn't escape errors like this one: error[E0271]: type mismatch resolving `<[closure@src/parser.rs:157:36: 186:6] as std::ops::FnOnce<(_,)>>::Output == std::result::Result<parser::Map, <I as combine::StreamOnce>::Error>` --> src/parser.rs:137:16 | 137 | fn map<I>() -> impl Parser<Input = I, Output = Map> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found struct `parser::Map` | = note: expected type `std::result::Result<std::result::Result<(parser::Map, _), _>, _>` found type `std::result::Result<parser::Map, _>` = note: required because of the requirements on the impl of `combine::Parser` for `combine::combinator::FlatMap<combine::combinator::TakeUntil<_, combine::char::Newline<I>>, [closure@src/parser.rs:157:36: 186:6]>` = note: the return type of a function must have a statically known size error: aborting due to previous error For more information about this error, try `rustc --explain E0271`. Feeling like I've spent way too long stuck on this, so I'm just going to parse actions into new action type (`Action2` for now) by doing a second parsing pass. It's not going to be as performant, but at least I'm confident that will work. We can always come back to this later. I'll be reverting this commit.
2018-09-27parser: Make a new `Action` typeTeddy Wing
With this new type, I'm trying to set up a way to parse actions more precisely, to allow us to get special keys and modifier-flagged keys. Still trying to work out how this is going to work at the parser level though, since the action parser is going to need to depend on the map kind parser.
2018-09-24run_key_action_for_mode(): Keep track of `in_mode` in `state`Teddy Wing
Instead of letting the Objective-C code keep track of `in_mode` by passing it around in `CKeyActionResult`, keep track of it in a `State` struct. Derive `Clone` on `HeadphoneButton` to resolve this error: error[E0277]: the trait bound `parser::HeadphoneButton: std::clone::Clone` is not satisfied --> src/cocoa_bridge.rs:273:38 | 273 | state.in_mode = Some(trigger.to_vec()); | ^^^^^^ the trait `std::clone::Clone` is not implemented for `parser::HeadphoneButton`
2018-09-01parser: Make `Trigger` private againTeddy Wing
This was added for a432dd2824499959635ac9a7cabec25a31dddb14, but since we didn't end up using it, we can revert this. Might end up making the type public again later, but for now it doesn't need to be.
2018-09-01KeyActionResult: Make a pseudo-builder for the struct (WIP)Teddy Wing
Make a builder for a new `KeyActionResult`, but without a new "builder" type (seems like I should be able to get away without one in this simple case). I had make `parser::Trigger` public because at first I was using them in `KeyActionResult` for the `in_mode` field. Oh yeah, there's a new `in_mode` field on `KeyActionResult`. We'll be using that to store and pass back the current mode to our FFI caller. This field can be used to call `c_run_key_action()` with that mode scope. Well, the idea is here, but I'm getting move errors: error[E0507]: cannot move out of borrowed content --> src/cocoa_bridge.rs:79:9 | 79 | *self | ^^^^^ cannot move out of borrowed content error[E0596]: cannot borrow immutable borrowed content as mutable --> src/cocoa_bridge.rs:162:30 | 162 | *KeyActionResult::new(MapKind::Map) | ______________________________^ 163 | | .with_action(&map.action) | |_________________________________________________________^ cannot borrow as mutable error[E0507]: cannot move out of borrowed content --> src/cocoa_bridge.rs:162:29 | 162 | / *KeyActionResult::new(MapKind::Map) 163 | | .with_action(&map.action) 164 | | .in_mode(trigger) | |_________________________________________________^ cannot move out of borrowed content Looks like I'll need to change the `KeyActionResult` impl code to pass by value instead of reference. Committing what I have now, though, because it's been a while and it's become kind of a mess.
2018-08-26Link library with a test C programTeddy Wing
Make a test `includer.c` program that includes the Rust library and calls our `c_run_key_action()` to see if it actually works. Currently it doesn't, we get `(null)` printed to stdout. Add a Makefile with the build command for the C program. cbindgen.toml: Remove `KeyActionResult` from exported types, as the `Option` field it contains caused `gcc` to complain. cocoa_bridge.rs: * Comment out all 'cocoa' crate related code as the 'cocoa' code was interfering with GCC compilation as a result of my not linking to Cocoa frameworks. * Add a new test map definition that corresponds with the one we look for in `includer.c`. parser.rs: Add `#[repr(C)]` to `MapKind` because it needs to be exported in the library and generated into our C header file.
2018-08-25Configure for importing from C/FFITeddy Wing
* Add `#[repr(C)]` on `HeadphoneButton` to hopefully be able to use it outside Rust * Add `#[no_mangle]` to `run_key_action()` * Export `run_key_action()` as a public function * Build the crate as a static library (But holy cow, a 19 MB library file?)
2018-08-23cocoa_bridge: Continue outline of Objective C callableTeddy Wing
Add some more structure to the function that will be called from Objective C code. * Give it a name, `parse_mappings` (not very thoroughly considered) * Initialise some Foundation data structures to mirror our Rust ones * Add the beginning of a struct that will be the ObjC version of our `MapGroup` struct, containing `NSDictionary`ies. * Move the `extern crate` into `lib.rs`, I keep forgetting that's where they go. * Add a test that just calls `parse_mappings` to check that the code compiles. parser::MapGroup: Make both its fields public to enable us to access them from `cocoa_bridge`. Used this helpful example as a reference for the Rust Cocoa code: https://github.com/servo/core-foundation-rs/blob/c99c05c/cocoa/examples/hello_world.rs
2018-08-22Add `MapGroup::parse()`; Start Cocoa functionTeddy Wing
Add a new `cocoa` module which will hold code to be called from Objective-C. Currently contains a sketch of a function that will be called via FFI from Objective-C. Haven't thought of a name for it yet. For now contains a sample map definition "file" in a hard-coded string. Tells `MapGroup` to parse the map definitions. Will try to create some Cocoa objects in the `unsafe` block. `MapGroup`: Add `parse()` method. Given a map definition string, this new function will parse the string into a `MapGroup` and return the result. It will serve as the entry point to parsing DomeKey map definitions. Thanks to these references for Combine parser error handling: - https://github.com/ordian/toml_edit/blob/b02bc3/src/parser/document.rs - https://github.com/ordian/toml_edit/blob/ee6895f/src/parser/errors.rs - https://github.com/Marwes/combine/blob/54bcfed/examples/ini.rs
2018-08-22Move all code in `lib.rs` to `parser.rs`Teddy Wing
Put our parsing code in its own module. We'll be creating a new `cocoa` module and doing this allows us to keep `lib` free as a module container.