A fork of https://github.com/ueokande/vim-vixen
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
74 lines
2.5 KiB
74 lines
2.5 KiB
import { injectable, inject } from 'tsyringe'; |
|
import KeymapRepository from '../repositories/KeymapRepository'; |
|
import SettingRepository from '../repositories/SettingRepository'; |
|
import AddonEnabledRepository from '../repositories/AddonEnabledRepository'; |
|
import * as operations from '../../shared/operations'; |
|
import Keymaps from '../../shared/settings/Keymaps'; |
|
import Key from '../../shared/settings/Key'; |
|
import KeySequence from '../../shared/settings/KeySequence'; |
|
|
|
type KeymapEntityMap = Map<KeySequence, operations.Operation>; |
|
|
|
const reservedKeymaps = Keymaps.fromJSON({ |
|
'<Esc>': { type: operations.CANCEL }, |
|
'<C-[>': { type: operations.CANCEL }, |
|
}); |
|
|
|
@injectable() |
|
export default class KeymapUseCase { |
|
constructor( |
|
@inject('KeymapRepository') |
|
private repository: KeymapRepository, |
|
|
|
@inject('SettingRepository') |
|
private settingRepository: SettingRepository, |
|
|
|
@inject('AddonEnabledRepository') |
|
private addonEnabledRepository: AddonEnabledRepository, |
|
) { |
|
} |
|
|
|
nextOp(key: Key): operations.Operation | null { |
|
let sequence = this.repository.enqueueKey(key); |
|
|
|
let keymaps = this.keymapEntityMap(); |
|
let matched = Array.from(keymaps.keys()).filter( |
|
(mapping: KeySequence) => { |
|
return mapping.startsWith(sequence); |
|
}); |
|
if (!this.addonEnabledRepository.get()) { |
|
// available keymaps are only ADDON_ENABLE and ADDON_TOGGLE_ENABLED if |
|
// the addon disabled |
|
matched = matched.filter((keymap) => { |
|
let type = (keymaps.get(keymap) as operations.Operation).type; |
|
return type === operations.ADDON_ENABLE || |
|
type === operations.ADDON_TOGGLE_ENABLED; |
|
}); |
|
} |
|
if (matched.length === 0) { |
|
// No operations to match with inputs |
|
this.repository.clear(); |
|
return null; |
|
} else if (matched.length > 1 || |
|
matched.length === 1 && sequence.length() < matched[0].length()) { |
|
// More than one operations are matched |
|
return null; |
|
} |
|
// Exactly one operation is matched |
|
let operation = keymaps.get(matched[0]) as operations.Operation; |
|
this.repository.clear(); |
|
return operation; |
|
} |
|
|
|
clear(): void { |
|
this.repository.clear(); |
|
} |
|
|
|
private keymapEntityMap(): KeymapEntityMap { |
|
let keymaps = this.settingRepository.get().keymaps.combine(reservedKeymaps); |
|
let entries = keymaps.entries().map( |
|
([keys, op]) => [KeySequence.fromMapKeys(keys), op] |
|
) as [KeySequence, operations.Operation][]; |
|
return new Map<KeySequence, operations.Operation>(entries); |
|
} |
|
}
|
|
|