Skip to content

Commit

Permalink
Add initial function calls from strings & discard useless keys
Browse files Browse the repository at this point in the history
  • Loading branch information
bovine3dom committed Jul 8, 2017
1 parent 7a9c835 commit ceb6e32
Showing 1 changed file with 43 additions and 30 deletions.
73 changes: 43 additions & 30 deletions addon/src/parsercontrol.ts
Expand Up @@ -48,17 +48,29 @@ interface NormalResponse {
ex_str?: string
}

const ex_strs = {
t: "tabopen",
j: "scrolldown",
k: "scrollup",
gt: "nextab",
gT: "prevtab",
gr: "reader",
":": "colon",
s: "o google",
const key_strs_to_ex_strs = {
t: "tabopen",
j: "scrolldown",
k: "scrollup",
gt: "nextab",
gT: "prevtab",
gr: "reader",
":": "exmode",
s: "open google",
xx: "something",
}

const ex_str_to_func = {
tabopen: console.log,
scrolldown: console.log,
scrollup: console.log,
nextab: console.log,
prevtab: console.log,
reader: console.log,
exmode: console.log,
open: console.log,
something: console.log,
}

// Extracts the first number with capturing parentheses
const FIRST_NUM_REGEX = /^([0-9]+)/
Expand All @@ -73,7 +85,7 @@ function keyarr_from_keys(keys: string[]){
}

function get_ex_str_from_key_str(keystr): string {
return ex_strs[keystr]
return key_strs_to_ex_strs[keystr]
//return "olie is the best"
}

Expand All @@ -88,28 +100,29 @@ function get_ex_str(keys): string {

function get_poss_ex_str(keys): string[] {
let [count, keystr] = keyarr_from_keys(keys)
let posskeystrs = Object.keys(ex_strs)
let atstart = RegExp("^" + keystr)
return posskeystrs.filter((key)=>atstart.exec(key))
let posskeystrs = Object.keys(key_strs_to_ex_strs)
return posskeystrs.filter((key)=>key.startsWith(keystr))
}

function normal_mode_parser(keys): NormalResponse {
// If there aren't any possible matches, throw away keys until there are
while ((get_poss_ex_str(keys).length == 0) && (keys.length)) {
keys = keys.slice(1)
}

// If keys map to an ex_str, send it
let ex_str = get_ex_str(keys)
if (ex_str){
// if keys maps to an ex_str, send it
return {ex_str}
} else if (get_poss_ex_str(keys)) {
// if match possible, keep collecting keys
return {}
} else {
// otherwise delete keys (eg if ESC is pressed, provided no-body binds it)
return {keys: []}
}
}
// Otherwise, return the keys that might be used in a future command
return {keys}
}

function ex_str_parser(ex_str){
let [func,...args] = ex_str.split(" ")
return [func, args]
// Todo: work out how to map these to functions that can be executed
return [ex_str_to_func[func], args]
}

function *ParserController () {
Expand All @@ -118,27 +131,27 @@ function *ParserController () {
let keys = []
while (true) {

console.log("waitin4push")
// keys.push(yield)
console.log(yield)
keys.push(yield)
let response = normal_mode_parser(keys)
console.log(response)
console.log(keys, response)

if (response.ex_str){
ex_str = response.ex_str
break
} else if (response.keys){
} else {
keys = response.keys
}
}

let [func, args] = ex_str_parser(ex_str)

// func(...args)
console.log(func, args)
func(...args)
// console.log("Executing: ", args)
}

}

let generator = ParserController()
var generator = ParserController() // var rather than let stops weirdness in repl.
generator.next()

// test using "keysinput".split("").map((x)=>generator.next(x))

5 comments on commit ceb6e32

@cmcaine
Copy link
Member

@cmcaine cmcaine commented on ceb6e32 Jul 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Converting keys[] to a string will produce odd results for special keys.

the .key value of backspace is "Backspace", for example.

@bovine3dom
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It mostly works OK at the moment: the entire key is dropped if it doesn't match something, in one go.

The main problem is that it will stop people binding things to some capital letters (e.g. S for Shift).

The current method has the added bonus that you can type the key out - "B a c k s p a c e".

I'm unsure how much of this should go in Tridactyl, and how much should be in the keyboard API. It might make more sense if the keyboard API sent keycodes?

Otherwise, we could fix this by prepending a special character to any .key with length greater than 1, e.g something in Unicode like 🄰.

@cmcaine
Copy link
Member

@cmcaine cmcaine commented on ceb6e32 Jul 9, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having "Shi" be kept because it could map to "Shift" is clearly bonkers. Prefixing with an untypeable character is OK, but should be done by API consumers, not the API.

Keyboard API will send a shallow copy of the keyboardevent, but .code is not appropriate for finding 'Shift' and friends: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code

We'll just want to drop all the modifier keys anyway: we don't want users to map Shift or Control on their own, we just want them as modifier keys (which is detected with e.g. keyevent.ctrlKey property).

Arrow keys, backspace, etc. we will want to be mappable.

To think about:

  • prompt_toolkit has a vi mode, maybe check it out
  • How do we want to allow users to map to special keys (vim-style names and/or js .key names)?
  • If we want to introduce escapes for modifier keys in the mappings and keys or if we want to move away from a string based approach

@dumblob
Copy link

@dumblob dumblob commented on ceb6e32 Jul 9, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll just want to drop all the modifier keys anyway: we don't want users to map Shift or Control on their own, we just want them as modifier keys (which is detected with e.g. keyevent.ctrlKey property).

Dumb, but for me a very important question: why don't we want user to map Shift or Control on their own?

I have already come across special use cases (especially when one wants something cross platform), when exactly mapping modifiers was the only or at least the best solution.

@cmcaine
Copy link
Member

@cmcaine cmcaine commented on ceb6e32 Jul 9, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're trying to move discussion to #3

So I'll reply in both places then lock this.

When ctrl+s is pressed, browsers generate a ctrl keydown event, then a keydown event with .key === 's' and .ctrlKey === true, then keyup events for each.

If the user was allowed to bind ctrl with no modifier then they would face the surprising situation of Ctrl+s triggering the maps for both Ctrl and Ctrl+s.

This can be solved, but it would complicate the parser significantly by introducing a notion of timeliness.

Please sign in to comment.