mirror of
https://github.com/quine-global/hyper.git
synced 2026-01-12 20:18:41 -09:00
port config/, ui/ & commands.js in app/ to ts
This commit is contained in:
parent
1ea935988f
commit
c04b51874c
10 changed files with 63 additions and 36 deletions
|
|
@ -1,9 +1,9 @@
|
|||
import {app, Menu} from 'electron';
|
||||
import {app, Menu, BrowserWindow} from 'electron';
|
||||
import {openConfig, getConfig} from './config';
|
||||
import {updatePlugins} from './plugins';
|
||||
import {installCLI} from './utils/cli-install';
|
||||
|
||||
const commands = {
|
||||
const commands: Record<string, (focusedWindow?: BrowserWindow) => void> = {
|
||||
'window:new': () => {
|
||||
// If window is created on the same tick, it will consume event too
|
||||
setTimeout(app.createWindow, 0);
|
||||
|
|
@ -31,7 +31,7 @@ const commands = {
|
|||
focusedWindow && focusedWindow.rpc.emit('session clear req');
|
||||
},
|
||||
'editor:selectAll': focusedWindow => {
|
||||
focusedWindow.rpc.emit('term selectAll');
|
||||
focusedWindow && focusedWindow.rpc.emit('term selectAll');
|
||||
},
|
||||
'plugins:update': () => {
|
||||
updatePlugins();
|
||||
|
|
@ -112,20 +112,20 @@ const commands = {
|
|||
},
|
||||
'window:hamburgerMenu': () => {
|
||||
if (getConfig().showHamburgerMenu) {
|
||||
Menu.getApplicationMenu().popup({x: 15, y: 15});
|
||||
Menu.getApplicationMenu()!.popup({x: 15, y: 15});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//Special numeric command
|
||||
[1, 2, 3, 4, 5, 6, 7, 8, 'last'].forEach(cmdIndex => {
|
||||
([1, 2, 3, 4, 5, 6, 7, 8, 'last'] as const).forEach(cmdIndex => {
|
||||
const index = cmdIndex === 'last' ? cmdIndex : cmdIndex - 1;
|
||||
commands[`tab:jump:${cmdIndex}`] = focusedWindow => {
|
||||
focusedWindow && focusedWindow.rpc.emit('move jump req', index);
|
||||
};
|
||||
});
|
||||
|
||||
export const execCommand = (command, focusedWindow) => {
|
||||
export const execCommand = (command: string, focusedWindow?: BrowserWindow) => {
|
||||
const fn = commands[command];
|
||||
if (fn) {
|
||||
fn(focusedWindow);
|
||||
|
|
@ -4,13 +4,13 @@ import {defaultCfg, cfgPath, legacyCfgPath, plugs, defaultPlatformKeyPath} from
|
|||
import {_init, _extractDefault} from './init';
|
||||
import notify from '../notify';
|
||||
|
||||
let defaultConfig;
|
||||
let defaultConfig: Record<string, any> | undefined;
|
||||
|
||||
const _write = (path, data) => {
|
||||
const _write = (path: string, data: any) => {
|
||||
// This method will take text formatted as Unix line endings and transform it
|
||||
// to text formatted with DOS line endings. We do this because the default
|
||||
// text editor on Windows (notepad) doesn't Deal with LF files. Still. In 2017.
|
||||
const crlfify = str => {
|
||||
const crlfify = (str: string) => {
|
||||
return str.replace(/\r?\n/g, '\r\n');
|
||||
};
|
||||
const format = process.platform === 'win32' ? crlfify(data.toString()) : data;
|
||||
|
|
@ -19,7 +19,7 @@ const _write = (path, data) => {
|
|||
|
||||
// Saves a file as backup by appending '.backup' or '.backup2', '.backup3', etc.
|
||||
// so as to not override any existing files
|
||||
const saveAsBackup = src => {
|
||||
const saveAsBackup = (src: string) => {
|
||||
let attempt = 1;
|
||||
while (attempt < 100) {
|
||||
try {
|
||||
|
|
@ -99,7 +99,7 @@ const _importConf = () => {
|
|||
// Importing platform specific keymap
|
||||
try {
|
||||
const content = readFileSync(defaultPlatformKeyPath(), 'utf8');
|
||||
const mapping = JSON.parse(content);
|
||||
const mapping = JSON.parse(content) as Record<string, string | string[]>;
|
||||
_defaultCfg.keymaps = mapping;
|
||||
} catch (err) {
|
||||
//eslint-disable-next-line no-console
|
||||
|
|
@ -122,14 +122,14 @@ const _importConf = () => {
|
|||
|
||||
export const _import = () => {
|
||||
const imported = _importConf();
|
||||
defaultConfig = imported.defaultCfg;
|
||||
const result = _init(imported);
|
||||
defaultConfig = imported?.defaultCfg;
|
||||
const result = _init(imported!);
|
||||
return result;
|
||||
};
|
||||
|
||||
export const getDefaultConfig = () => {
|
||||
if (!defaultConfig) {
|
||||
defaultConfig = _extractDefault(_importConf().defaultCfg);
|
||||
defaultConfig = _importConf()?.defaultCfg;
|
||||
}
|
||||
return defaultConfig;
|
||||
};
|
||||
|
|
@ -2,16 +2,16 @@ import vm from 'vm';
|
|||
import notify from '../notify';
|
||||
import mapKeys from '../utils/map-keys';
|
||||
|
||||
const _extract = script => {
|
||||
const module = {};
|
||||
script.runInNewContext({module});
|
||||
const _extract = (script?: vm.Script): Record<string, any> => {
|
||||
const module: Record<string, any> = {};
|
||||
script?.runInNewContext({module});
|
||||
if (!module.exports) {
|
||||
throw new Error('Error reading configuration: `module.exports` not set');
|
||||
}
|
||||
return module.exports;
|
||||
};
|
||||
|
||||
const _syntaxValidation = cfg => {
|
||||
const _syntaxValidation = (cfg: string) => {
|
||||
try {
|
||||
return new vm.Script(cfg, {filename: '.hyper.js', displayErrors: true});
|
||||
} catch (err) {
|
||||
|
|
@ -19,12 +19,12 @@ const _syntaxValidation = cfg => {
|
|||
}
|
||||
};
|
||||
|
||||
const _extractDefault = cfg => {
|
||||
const _extractDefault = (cfg: string) => {
|
||||
return _extract(_syntaxValidation(cfg));
|
||||
};
|
||||
|
||||
// init config
|
||||
const _init = cfg => {
|
||||
const _init = (cfg: {userCfg: string; defaultCfg: Record<string, any>}) => {
|
||||
const script = _syntaxValidation(cfg.userCfg);
|
||||
if (script) {
|
||||
const _cfg = _extract(script);
|
||||
|
|
@ -5,12 +5,12 @@ export default () => Promise.resolve(shell.openItem(cfgPath));
|
|||
// Windows opens .js files with WScript.exe by default
|
||||
// If the user hasn't set up an editor for .js files, we fallback to notepad.
|
||||
if (process.platform === 'win32') {
|
||||
const Registry = require('winreg');
|
||||
const {exec} = require('child_process');
|
||||
const Registry = require('winreg') as typeof import('winreg');
|
||||
const {exec} = require('child_process') as typeof import('child_process');
|
||||
|
||||
const getUserChoiceKey = async () => {
|
||||
// Load FileExts keys for .js files
|
||||
const keys = await new Promise((resolve, reject) => {
|
||||
const keys: Winreg.Registry[] = await new Promise((resolve, reject) => {
|
||||
new Registry({
|
||||
hive: Registry.HKCU,
|
||||
key: '\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\.js'
|
||||
|
|
@ -29,11 +29,11 @@ if (process.platform === 'win32') {
|
|||
};
|
||||
|
||||
const hasDefaultSet = async () => {
|
||||
let userChoice = await getUserChoiceKey();
|
||||
const userChoice = await getUserChoiceKey();
|
||||
if (!userChoice) return false;
|
||||
|
||||
// Load key values
|
||||
let values = await new Promise((resolve, reject) => {
|
||||
const values: string[] = await new Promise((resolve, reject) => {
|
||||
userChoice.values((error, items) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
|
|
@ -51,7 +51,7 @@ if (process.platform === 'win32') {
|
|||
};
|
||||
|
||||
// This mimics shell.openItem, true if it worked, false if not.
|
||||
const openNotepad = file =>
|
||||
const openNotepad = (file: string) =>
|
||||
new Promise(resolve => {
|
||||
exec(`start notepad.exe ${file}`, error => {
|
||||
resolve(!error);
|
||||
|
|
@ -20,7 +20,7 @@ const applicationDirectory =
|
|||
|
||||
let cfgDir = applicationDirectory;
|
||||
let cfgPath = join(applicationDirectory, cfgFile);
|
||||
let legacyCfgPath = join(homeDirectory, cfgFile); // Hyper 2 config location
|
||||
const legacyCfgPath = join(homeDirectory, cfgFile); // Hyper 2 config location
|
||||
|
||||
const devDir = resolve(__dirname, '../..');
|
||||
const devCfg = join(devDir, cfgFile);
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
import Config from 'electron-store';
|
||||
import {BrowserWindow} from 'electron';
|
||||
|
||||
const defaults = {
|
||||
windowPosition: [50, 50],
|
||||
|
|
@ -15,7 +16,7 @@ export default {
|
|||
const size = cfg.get('windowSize');
|
||||
return {position, size};
|
||||
},
|
||||
recordState(win) {
|
||||
recordState(win: BrowserWindow) {
|
||||
cfg.set('windowPosition', win.getPosition());
|
||||
cfg.set('windowSize', win.getSize());
|
||||
}
|
||||
|
|
@ -36,7 +36,7 @@ export class Server extends EventEmitter {
|
|||
super.emit(ev, data);
|
||||
}
|
||||
|
||||
emit(ch: string, data: any): any {
|
||||
emit(ch: string, data: any = {}): any {
|
||||
// This check is needed because data-batching can cause extra data to be
|
||||
// emitted after the window has already closed
|
||||
if (!this.win.isDestroyed()) {
|
||||
|
|
|
|||
|
|
@ -2,26 +2,30 @@ import editMenu from '../menus/menus/edit';
|
|||
import shellMenu from '../menus/menus/shell';
|
||||
import {execCommand} from '../commands';
|
||||
import {getDecoratedKeymaps} from '../plugins';
|
||||
const separator = {type: 'separator'};
|
||||
import {MenuItemConstructorOptions, BrowserWindow} from 'electron';
|
||||
const separator: MenuItemConstructorOptions = {type: 'separator'};
|
||||
|
||||
const getCommandKeys = keymaps =>
|
||||
Object.keys(keymaps).reduce((commandKeys, command) => {
|
||||
const getCommandKeys = (keymaps: Record<string, string[]>): Record<string, string> =>
|
||||
Object.keys(keymaps).reduce((commandKeys: Record<string, string>, command) => {
|
||||
return Object.assign(commandKeys, {
|
||||
[command]: keymaps[command][0]
|
||||
});
|
||||
}, {});
|
||||
|
||||
// only display cut/copy when there's a cursor selection
|
||||
const filterCutCopy = (selection, menuItem) => {
|
||||
if (/^cut$|^copy$/.test(menuItem.role) && !selection) {
|
||||
const filterCutCopy = (selection: string, menuItem: MenuItemConstructorOptions) => {
|
||||
if (/^cut$|^copy$/.test(menuItem.role!) && !selection) {
|
||||
return;
|
||||
}
|
||||
return menuItem;
|
||||
};
|
||||
|
||||
export default (createWindow, selection) => {
|
||||
export default (
|
||||
createWindow: (fn?: (win: BrowserWindow) => void, options?: Record<string, any>) => BrowserWindow,
|
||||
selection: string
|
||||
) => {
|
||||
const commandKeys = getCommandKeys(getDecoratedKeymaps());
|
||||
const _shell = shellMenu(commandKeys, execCommand).submenu;
|
||||
const _shell = shellMenu(commandKeys, execCommand).submenu as MenuItemConstructorOptions[];
|
||||
const _edit = editMenu(commandKeys, execCommand).submenu.filter(filterCutCopy.bind(null, selection));
|
||||
return _edit
|
||||
.concat(separator, _shell)
|
||||
|
|
@ -300,6 +300,8 @@
|
|||
"@types/color": "3.0.0",
|
||||
"@types/columnify": "^1.5.0",
|
||||
"@types/electron-devtools-installer": "2.2.0",
|
||||
"@types/fs-extra": "8.0.1",
|
||||
"@types/mkdirp": "0.5.2",
|
||||
"@types/mousetrap": "^1.6.3",
|
||||
"@types/node": "^12.12.21",
|
||||
"@types/pify": "3.0.2",
|
||||
|
|
@ -311,6 +313,7 @@
|
|||
"@types/styled-jsx": "2.2.8",
|
||||
"@types/uuid": "3.4.6",
|
||||
"@types/webdriverio": "^4.8.0",
|
||||
"@types/winreg": "1.2.30",
|
||||
"@typescript-eslint/eslint-plugin": "2.11.0",
|
||||
"@typescript-eslint/parser": "2.12.0",
|
||||
"ava": "2.4.0",
|
||||
|
|
|
|||
19
yarn.lock
19
yarn.lock
|
|
@ -650,6 +650,13 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7"
|
||||
integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==
|
||||
|
||||
"@types/fs-extra@8.0.1":
|
||||
version "8.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-8.0.1.tgz#a2378d6e7e8afea1564e44aafa2e207dadf77686"
|
||||
integrity sha512-J00cVDALmi/hJOYsunyT52Hva5TnJeKP5yd1r+mH/ZU0mbYZflR0Z5kw5kITtKTRYMhm1JMClOFYdHnQszEvqw==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/glob@^7.1.1":
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575"
|
||||
|
|
@ -689,6 +696,13 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
|
||||
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
|
||||
|
||||
"@types/mkdirp@0.5.2":
|
||||
version "0.5.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-0.5.2.tgz#503aacfe5cc2703d5484326b1b27efa67a339c1f"
|
||||
integrity sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/mousetrap@^1.6.3":
|
||||
version "1.6.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/mousetrap/-/mousetrap-1.6.3.tgz#3159a01a2b21c9155a3d8f85588885d725dc987d"
|
||||
|
|
@ -780,6 +794,11 @@
|
|||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/winreg@1.2.30":
|
||||
version "1.2.30"
|
||||
resolved "https://registry.yarnpkg.com/@types/winreg/-/winreg-1.2.30.tgz#91d6710e536d345b9c9b017c574cf6a8da64c518"
|
||||
integrity sha1-kdZxDlNtNFucmwF8V0z2qNpkxRg=
|
||||
|
||||
"@typescript-eslint/eslint-plugin@2.11.0":
|
||||
version "2.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.11.0.tgz#4477c33491ccf0a9a3f4a30ef84978fa0ea0cad2"
|
||||
|
|
|
|||
Loading…
Reference in a new issue