mirror of
https://github.com/vale981/tridactyl
synced 2025-03-10 04:36:39 -04:00

Currently repeated use of `g;` will only take you to the most recently used input. Cycling through recently used inputs is a WIP.
80 lines
2.2 KiB
TypeScript
80 lines
2.2 KiB
TypeScript
/** Tridactyl shared state
|
|
|
|
Any context with access to browser.storage can safely import this file and
|
|
get a self-updating consistent copy of the shared program state.
|
|
|
|
Any context may modify their copy of the state and that modification will
|
|
be propagated to the rest of the program.
|
|
|
|
This works by proxying the state object such that setting any property
|
|
causes the entire state to be saved to storage and adding a listener that
|
|
listens for storage events and updates the proxied object on each storage
|
|
event.
|
|
|
|
If this turns out to be expensive there are improvements available.
|
|
*/
|
|
|
|
import Logger from "./logging"
|
|
const logger = new Logger("state")
|
|
|
|
export type ModeName =
|
|
| "normal"
|
|
| "insert"
|
|
| "hint"
|
|
| "ignore"
|
|
| "gobble"
|
|
| "input"
|
|
| "find"
|
|
class State {
|
|
mode: ModeName = "normal"
|
|
cmdHistory: string[] = []
|
|
prevInputs: { inputId: string; tab: number; jumppos?: number }[] = [
|
|
{
|
|
inputId: undefined,
|
|
tab: undefined,
|
|
jumppos: undefined,
|
|
},
|
|
]
|
|
last_ex_str: string = ""
|
|
}
|
|
|
|
// Don't change these from const or you risk breaking the Proxy below.
|
|
const defaults = Object.freeze(new State())
|
|
|
|
const overlay = {} as any
|
|
browser.storage.local
|
|
.get("state")
|
|
.then(res => {
|
|
if ("state" in res) {
|
|
logger.debug("Loaded initial state:", res.state)
|
|
Object.assign(overlay, res.state)
|
|
}
|
|
})
|
|
.catch((...args) => logger.error(...args))
|
|
|
|
const state = (new Proxy(overlay, {
|
|
/** Give defaults if overlay doesn't have the key */
|
|
get: function(target, property) {
|
|
if (property in target) {
|
|
return target[property]
|
|
} else {
|
|
return defaults[property]
|
|
}
|
|
},
|
|
|
|
/** Persist sets to storage immediately */
|
|
set: function(target, property, value) {
|
|
logger.debug("State changed!", property, value)
|
|
target[property] = value
|
|
browser.storage.local.set({ state: target })
|
|
return true
|
|
},
|
|
}) as any) as State
|
|
|
|
browser.storage.onChanged.addListener((changes, areaname) => {
|
|
if (areaname === "local" && "state" in changes) {
|
|
Object.assign(overlay, changes.state.newValue)
|
|
}
|
|
})
|
|
|
|
export { state as default }
|