Make Keymap class

This commit is contained in:
Shin'ya UEOKA 2019-10-04 04:01:35 +00:00
parent b496cea582
commit 410ffbb037
15 changed files with 223 additions and 129 deletions

View file

@ -1,5 +1,6 @@
import * as operations from './operations';
import Settings, * as settings from './Settings';
import Keymaps from './settings/Keymaps';
export class FormKeymaps {
private data: {[op: string]: string};
@ -8,8 +9,8 @@ export class FormKeymaps {
this.data = data;
}
toKeymaps(): settings.Keymaps {
let keymaps: settings.Keymaps = {};
toKeymaps(): Keymaps {
let keymaps: { [key: string]: operations.Operation } = {};
for (let name of Object.keys(this.data)) {
let [type, argStr] = name.split('?');
let args = {};
@ -19,7 +20,7 @@ export class FormKeymaps {
let key = this.data[name];
keymaps[key] = operations.valueOf({ type, ...args });
}
return keymaps;
return Keymaps.fromJSON(keymaps);
}
toJSON(): {[op: string]: string} {
@ -42,10 +43,11 @@ export class FormKeymaps {
return new FormKeymaps(data);
}
static fromKeymaps(keymaps: settings.Keymaps): FormKeymaps {
static fromKeymaps(keymaps: Keymaps): FormKeymaps {
let json = keymaps.toJSON();
let data: {[op: string]: string} = {};
for (let key of Object.keys(keymaps)) {
let op = keymaps[key];
for (let key of Object.keys(json)) {
let op = json[key];
let args = { ...op };
delete args.type;
@ -109,27 +111,32 @@ export class FormSearch {
}
}
export class JSONSettings {
private json: string;
constructor(json: any) {
this.json = json;
export class JSONTextSettings {
constructor(
private json: string,
) {
}
toSettings(): Settings {
return settings.valueOf(JSON.parse(this.json));
}
toJSON(): string {
toJSONText(): string {
return this.json;
}
static valueOf(o: ReturnType<JSONSettings['toJSON']>): JSONSettings {
return new JSONSettings(o);
static fromText(o: string): JSONTextSettings {
return new JSONTextSettings(o);
}
static fromSettings(data: Settings): JSONSettings {
return new JSONSettings(JSON.stringify(data, undefined, 2));
static fromSettings(data: Settings): JSONTextSettings {
let json = {
keymaps: data.keymaps.toJSON(),
search: data.search,
properties: data.properties,
blacklist: data.blacklist,
};
return new JSONTextSettings(JSON.stringify(json, undefined, 2));
}
}
@ -192,7 +199,7 @@ export class FormSettings {
toSettings(): Settings {
return settings.valueOf({
keymaps: this.keymaps.toKeymaps(),
keymaps: this.keymaps.toKeymaps().toJSON(),
search: this.search.toSearchSettings(),
properties: this.properties,
blacklist: this.blacklist,
@ -244,7 +251,7 @@ export enum SettingSource {
export default class SettingData {
private source: SettingSource;
private json?: JSONSettings;
private json?: JSONTextSettings;
private form?: FormSettings;
@ -252,7 +259,7 @@ export default class SettingData {
source, json, form
}: {
source: SettingSource,
json?: JSONSettings,
json?: JSONTextSettings,
form?: FormSettings,
}) {
this.source = source;
@ -264,7 +271,7 @@ export default class SettingData {
return this.source;
}
getJSON(): JSONSettings {
getJSON(): JSONTextSettings {
if (!this.json) {
throw new TypeError('json settings not set');
}
@ -283,7 +290,7 @@ export default class SettingData {
case SettingSource.JSON:
return {
source: this.source,
json: (this.json as JSONSettings).toJSON(),
json: (this.json as JSONTextSettings).toJSONText(),
};
case SettingSource.Form:
return {
@ -313,8 +320,8 @@ export default class SettingData {
case SettingSource.JSON:
return new SettingData({
source: o.source,
json: JSONSettings.valueOf(
o.json as ReturnType<JSONSettings['toJSON']>),
json: JSONTextSettings.fromText(
o.json as ReturnType<JSONTextSettings['toJSONText']>),
});
case SettingSource.Form:
return new SettingData({

View file

@ -1,7 +1,5 @@
import * as operations from './operations';
import * as PropertyDefs from './property-defs';
export type Keymaps = {[key: string]: operations.Operation};
import Keymaps from './settings/Keymaps';
export interface Search {
default: string;
@ -21,14 +19,6 @@ export default interface Settings {
blacklist: string[];
}
export const keymapsValueOf = (o: any): Keymaps => {
return Object.keys(o).reduce((keymaps: Keymaps, key: string): Keymaps => {
let op = operations.valueOf(o[key]);
keymaps[key] = op;
return keymaps;
}, {});
};
export const searchValueOf = (o: any): Search => {
if (typeof o.default !== 'string') {
throw new TypeError('string field "default" not set"');
@ -97,7 +87,7 @@ export const valueOf = (o: any): Settings => {
for (let key of Object.keys(o)) {
switch (key) {
case 'keymaps':
settings.keymaps = keymapsValueOf(o.keymaps);
settings.keymaps = Keymaps.fromJSON(o.keymaps);
break;
case 'search':
settings.search = searchValueOf(o.search);
@ -115,8 +105,17 @@ export const valueOf = (o: any): Settings => {
return settings;
};
export const toJSON = (settings: Settings): any => {
return {
keymaps: settings.keymaps.toJSON(),
search: settings.search,
properties: settings.properties,
blacklist: settings.blacklist,
};
};
export const DefaultSetting: Settings = {
keymaps: {
keymaps: Keymaps.fromJSON({
'0': { 'type': 'scroll.home' },
':': { 'type': 'command.show' },
'o': { 'type': 'command.show.open', 'alter': false },
@ -179,7 +178,7 @@ export const DefaultSetting: Settings = {
'N': { 'type': 'find.prev' },
'.': { 'type': 'repeat.last' },
'<S-Esc>': { 'type': 'addon.toggle.enabled' }
},
}),
search: {
default: 'google',
engines: {

View file

@ -0,0 +1,37 @@
import * as operations from '../operations';
export type KeymapsJSON = { [key: string]: operations.Operation };
export default class Keymaps {
constructor(
private readonly data: KeymapsJSON,
) {
}
static fromJSON(json: any): Keymaps {
if (typeof json !== 'object' || json === null) {
throw new TypeError('invalid keymaps type: ' + JSON.stringify(json));
}
let data: KeymapsJSON = {};
for (let key of Object.keys(json)) {
data[key] = operations.valueOf(json[key]);
}
return new Keymaps(data);
}
combine(other: Keymaps): Keymaps {
return new Keymaps({
...this.data,
...other.data,
});
}
toJSON(): KeymapsJSON {
return this.data;
}
entries(): [string, operations.Operation][] {
return Object.entries(this.data);
}
}