From cf8686f413a076ff79b82deb05057173f78ac792 Mon Sep 17 00:00:00 2001 From: ppot Date: Fri, 26 May 2017 12:36:40 -0400 Subject: [PATCH 1/5] Include keymap@2 --- app/accelerators.js | 136 ------------------------------------- app/config.js | 127 +++++++--------------------------- app/config/import.js | 41 +++++++++++ app/config/init.js | 43 ++++++++++++ app/config/keymaps.js | 57 ++++++++++++++++ app/config/paths.js | 10 ++- app/config/windows.js | 21 ++++++ app/index.js | 10 +-- app/keymaps/darwin.json | 34 ++++++++++ app/keymaps/linux.json | 33 +++++++++ app/keymaps/win32.json | 33 +++++++++ app/menus/menu.js | 17 +++-- app/menus/menus/darwin.js | 5 +- app/menus/menus/edit.js | 19 +++--- app/menus/menus/plugins.js | 6 +- app/menus/menus/shell.js | 16 ++--- app/menus/menus/view.js | 16 ++--- app/menus/menus/window.js | 19 +++--- app/plugins.js | 13 +++- lib/command-registry.js | 23 +++++++ lib/components/terms.js | 2 + lib/hterm.js | 16 +++-- lib/utils/keymaps.js | 34 ++++++++++ 23 files changed, 428 insertions(+), 303 deletions(-) delete mode 100644 app/accelerators.js create mode 100644 app/config/import.js create mode 100644 app/config/init.js create mode 100644 app/config/keymaps.js create mode 100644 app/config/windows.js create mode 100644 app/keymaps/darwin.json create mode 100644 app/keymaps/linux.json create mode 100644 app/keymaps/win32.json create mode 100644 lib/command-registry.js create mode 100644 lib/utils/keymaps.js diff --git a/app/accelerators.js b/app/accelerators.js deleted file mode 100644 index ddd76ae148a9..000000000000 --- a/app/accelerators.js +++ /dev/null @@ -1,136 +0,0 @@ -const platform = process.platform; - -const isMac = platform === 'darwin'; - -const prefix = isMac ? 'Cmd' : 'Ctrl'; - -const applicationMenu = { // app/menu.js - preferences: ',', - quit: isMac ? 'Q' : '', - - // Shell/File menu - newWindow: 'N', - newTab: 'T', - splitVertically: isMac ? 'D' : 'Shift+E', - splitHorizontally: isMac ? 'Shift+D' : 'Shift+O', - closeSession: 'W', - closeWindow: 'Shift+W', - - // Edit menu - undo: 'Z', - redo: 'Shift+Z', - cut: 'X', - copy: isMac ? 'C' : 'Shift+C', - paste: 'V', - selectAll: 'A', - clear: 'K', - emojis: isMac ? 'Ctrl+Cmd+Space' : '', - - // View menu - reload: 'R', - fullReload: 'Shift+R', - toggleDevTools: isMac ? 'Alt+I' : 'Shift+I', - resetZoom: '0', - zoomIn: 'plus', - zoomOut: '-', - - // Plugins menu - updatePlugins: 'Shift+U', - - // Window menu - minimize: 'M', - showPreviousTab: 'Alt+Left', - showNextTab: 'Alt+Right', - selectNextPane: 'Ctrl+Alt+Tab', - selectPreviousPane: 'Ctrl+Shift+Alt+Tab', - enterFullScreen: isMac ? 'Ctrl+Cmd+F' : 'F11' -}; - -const mousetrap = { // lib/containers/hyper.js - moveTo1: '1', - moveTo2: '2', - moveTo3: '3', - moveTo4: '4', - moveTo5: '5', - moveTo6: '6', - moveTo7: '7', - moveTo8: '8', - moveToLast: '9', - - // here `1`, `2` etc are used to "emulate" something like `moveLeft: ['...', '...', etc]` - moveLeft1: 'Shift+Left', - moveRight1: 'Shift+Right', - moveLeft2: 'Shift+{', - moveRight2: 'Shift+}', - moveLeft3: 'Alt+Left', - moveRight3: 'Alt+Right', - moveLeft4: 'Ctrl+Shift+Tab', - moveRight4: 'Ctrl+Tab', - - // here we add `+` at the beginning to prevent the prefix from being added - moveWordLeft: '+Alt+Left', - moveWordRight: '+Alt+Right', - deleteWordLeft: '+Alt+Backspace', - deleteWordRight: '+Alt+Delete', - deleteLine: 'Backspace', - moveToStart: 'Left', - moveToEnd: 'Right', - selectAll: 'A' -}; - -const allAccelerators = Object.assign({}, applicationMenu, mousetrap); -const cache = []; -// ^ here we store the shortcuts so we don't need to -// look into the `allAccelerators` everytime - -for (const key in allAccelerators) { - if ({}.hasOwnProperty.call(allAccelerators, key)) { - let value = allAccelerators[key]; - if (value) { - if (value.startsWith('+')) { - // we don't need to add the prefix to accelerators starting with `+` - value = value.slice(1); - } else if (!value.startsWith('Ctrl')) { // nor to the ones starting with `Ctrl` - value = `${prefix}+${value}`; - } - cache.push(value.toLowerCase()); - allAccelerators[key] = value; - } - } -} - -// decides if a keybard event is a Hyper Accelerator -function isAccelerator(e) { - let keys = []; - if (!e.ctrlKey && !e.metaKey && !e.altKey) { - // all accelerators needs Ctrl or Cmd or Alt - return false; - } - - if (e.ctrlKey) { - keys.push('ctrl'); - } - if (e.metaKey && isMac) { - keys.push('cmd'); - } - if (e.shiftKey) { - keys.push('shift'); - } - if (e.altKey) { - keys.push('alt'); - } - - if (e.key === ' ') { - keys.push('space'); - } else { - // we need `toLowerCase` for when the shortcut has `shift` - // we need to replace `arrow` when the shortcut uses the arrow keys - keys.push(e.key.toLowerCase().replace('arrow', '')); - } - - keys = keys.join('+'); - return cache.includes(keys); -} - -module.exports.isAccelerator = isAccelerator; -module.exports.accelerators = allAccelerators; diff --git a/app/config.js b/app/config.js index b2da8b79176e..d72e1f8c5a9c 100644 --- a/app/config.js +++ b/app/config.js @@ -1,82 +1,31 @@ -const {statSync, renameSync, readFileSync, writeFileSync} = require('fs'); -const vm = require('vm'); - -const {dialog} = require('electron'); const gaze = require('gaze'); -const Config = require('electron-config'); const notify = require('./notify'); -const _paths = require('./config/paths'); +const _import = require('./config/import'); +const {confPath, confDir} = require('./config/paths'); const _openConfig = require('./config/open'); - -// local storage -const winCfg = new Config({ - defaults: { - windowPosition: [50, 50], - windowSize: [540, 380] - } -}); - -const path = _paths.confPath; -const pathLegacy = _paths.pathLegacy; +const win = require('./config/windows'); const watchers = []; - +const scanInterval = 2000; let cfg = {}; -function watch() { +const _watch = function () { // watch for changes on config every 2s // windows interval: https://github.com/zeit/hyper/pull/1772 - gaze(path, process.platform === 'win32' ? {interval: 2000} : {}, function (err) { + gaze(confPath, process.platform === 'win32' ? {interval: scanInterval} : {}, function (err) { if (err) { throw err; } this.on('changed', () => { - try { - if (exec(readFileSync(path, 'utf8'))) { - notify('Hyper configuration reloaded!'); - watchers.forEach(fn => fn()); - } - } catch (err) { - dialog.showMessageBox({ - message: `An error occurred loading your configuration (${path}): ${err.message}`, - buttons: ['Ok'] - }); - } + cfg = _import(); + notify('Configuration updated', 'Hyper configuration reloaded!'); + watchers.forEach(fn => fn()); }); this.on('error', () => { // Ignore file watching errors }); }); -} - -let _str; // last script -function exec(str) { - if (str === _str) { - return false; - } - _str = str; - const script = new vm.Script(str); - const module = {}; - script.runInNewContext({module}); - if (!module.exports) { - throw new Error('Error reading configuration: `module.exports` not set'); - } - const _cfg = module.exports; - if (!_cfg.config) { - throw new Error('Error reading configuration: `config` key is missing'); - } - _cfg.plugins = _cfg.plugins || []; - _cfg.localPlugins = _cfg.localPlugins || []; - cfg = _cfg; - return true; -} - -// 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. -function crlfify(str) { - return str.replace(/\r?\n/g, '\r\n'); -} +}; exports.subscribe = function (fn) { watchers.push(fn); @@ -85,39 +34,9 @@ exports.subscribe = function (fn) { }; }; -exports.init = function () { - // for backwards compatibility with hyperterm - // (prior to the rename), we try to rename - // on behalf of the user - try { - statSync(pathLegacy); - renameSync(pathLegacy, path); - } catch (err) { - // ignore - } - - try { - exec(readFileSync(path, 'utf8')); - } catch (err) { - console.log('read error', path, err.message); - const defaultConfig = readFileSync(_paths.defaultConfig); - try { - console.log('attempting to write default config to', path); - exec(defaultConfig); - - writeFileSync( - path, - process.platform === 'win32' ? crlfify(defaultConfig.toString()) : defaultConfig); - } catch (err) { - throw new Error(`Failed to write config to ${path}: ${err.message}`); - } - } - watch(); -}; - exports.getConfigDir = function () { // expose config directory to load plugin from the right place - return _paths.confDir; + return confDir; }; exports.getConfig = function () { @@ -135,14 +54,20 @@ exports.getPlugins = function () { }; }; -exports.window = { - get() { - const position = winCfg.get('windowPosition'); - const size = winCfg.get('windowSize'); - return {position, size}; - }, - recordState(win) { - winCfg.set('windowPosition', win.getPosition()); - winCfg.set('windowSize', win.getSize()); +exports.getKeymaps = function () { + return cfg.keymaps; +}; + +exports.extendKeymaps = function (keymaps) { + if (keymaps) { + cfg.keymaps = keymaps; } }; + +exports.setup = function () { + cfg = _import(); + _watch(); +}; + +exports.getWin = win.get; +exports.winRecord = win.recordState; diff --git a/app/config/import.js b/app/config/import.js new file mode 100644 index 000000000000..0593808df2bf --- /dev/null +++ b/app/config/import.js @@ -0,0 +1,41 @@ +const {writeFileSync, readFileSync} = require('fs'); +const {defaultConfig, confPath} = require('./paths'); +const _init = require('./init'); +const _keys = require('./keymaps'); + +const _write = function (path, data) { + // 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 = function (str) { + return str.replace(/\r?\n/g, '\r\n'); + }; + const format = process.platform === 'win32' ? crlfify(data.toString()) : data; + writeFileSync(path, format, 'utf8'); +}; + +const _importConf = function () { + try { + const defaultConf = readFileSync(defaultConfig, 'utf8'); + try { + const conf = readFileSync(confPath, 'utf8'); + return {userConf: conf, defaultConf}; + } catch (err) { + _write(confPath, defaultConf); + return {userConf: {}, defaultConf}; + } + } catch (err) { + console.log(err); + } +}; + +const _import = function () { + const cfg = _init(_importConf()); + + if (cfg) { + cfg.keymaps = _keys.import(cfg.keymaps); + } + return cfg; +}; + +module.exports = _import; diff --git a/app/config/init.js b/app/config/init.js new file mode 100644 index 000000000000..d0e7490ac665 --- /dev/null +++ b/app/config/init.js @@ -0,0 +1,43 @@ +const vm = require('vm'); +const notify = require('../notify'); + +const _extract = function (script) { + const module = {}; + script.runInNewContext({module}); + if (!module.exports) { + throw new Error('Error reading configuration: `module.exports` not set'); + } + return module.exports; +}; + +const _syntaxValidation = function (cfg) { + try { + return new vm.Script(cfg); + } catch (err) { + notify('Error reading configuration: Syntax error found'); + return undefined; + } +}; + +const _extractDefault = function (cfg) { + return _extract(_syntaxValidation(cfg)); +}; + +// init config +const _init = function (cfg) { + const script = _syntaxValidation(cfg.userConf); + if (script) { + const _cfg = _extract(script); + if (!_cfg.config) { + _cfg.plugins = _cfg.plugins || []; + _cfg.localPlugins = _cfg.localPlugins || []; + _cfg.keymaps = _cfg.keymaps || {}; + notify('Error reading configuration: `config` key is missing'); + return _extractDefault(cfg.defaultConf); + } + return _cfg; + } + return _extractDefault(cfg.defaultConf); +}; + +module.exports = _init; diff --git a/app/config/keymaps.js b/app/config/keymaps.js new file mode 100644 index 000000000000..0311e0cf6fa7 --- /dev/null +++ b/app/config/keymaps.js @@ -0,0 +1,57 @@ +const {readFileSync} = require('fs'); +const {darwinKeys, win32Keys, linuxKeys} = require('./paths'); + +const commands = {}; +const keys = {}; + +const _setKeysForCommands = function (keymap) { + for (const command in keymap) { + if (command) { + commands[command] = keymap[command].toLowerCase(); + } + } +}; + +const _setCommandsForKeys = function (commands) { + for (const command in commands) { + if (command) { + keys[commands[command]] = command; + } + } +}; + +const _import = function (customsKeys) { + const path = () => { + switch (process.platform) { + case 'darwin': return darwinKeys; + case 'win32': return win32Keys; + case 'linux': return linuxKeys; + default: return darwinKeys; + } + }; + try { + const mapping = JSON.parse(readFileSync(path())); + _setKeysForCommands(mapping); + _setKeysForCommands(customsKeys); + _setCommandsForKeys(commands); + + return {commands, keys}; + } catch (err) {} +}; + +const _extend = function (customsKeys) { + if (customsKeys) { + for (const command in customsKeys) { + if (command) { + commands[command] = customsKeys[command]; + keys[customsKeys[command]] = command; + } + } + } + return {commands, keys}; +}; + +module.exports = { + import: _import, + extend: _extend +}; diff --git a/app/config/paths.js b/app/config/paths.js index 64aae928672e..4fe5887e653f 100644 --- a/app/config/paths.js +++ b/app/config/paths.js @@ -6,7 +6,6 @@ const isDev = require('electron-is-dev'); const conf = '.hyper.js'; const defaultConf = 'config-default.js'; -const legacyConf = '.hyperterm.js'; const homeDir = homedir(); let confPath = resolve(homeDir, conf); @@ -15,10 +14,14 @@ let confDir = homeDir; const devDir = resolve(__dirname, '../..'); const devConfig = resolve(devDir, conf); const defaultConfig = resolve(__dirname, defaultConf); -const pathLegacy = resolve(homeDir, legacyConf); const icon = resolve(__dirname, '../static/icon.png'); +const keymapPath = resolve(__dirname, '../keymaps'); +const darwinKeys = resolve(keymapPath, 'darwin.json'); +const win32Keys = resolve(keymapPath, 'win32.json'); +const linuxKeys = resolve(keymapPath, 'linux.json'); + if (isDev) { // if a local config file exists, use it try { @@ -32,5 +35,6 @@ if (isDev) { } module.exports = { - pathLegacy, confDir, confPath, conf, defaultConfig, defaultConf, icon + confDir, confPath, conf, defaultConfig, icon, + darwinKeys, win32Keys, linuxKeys }; diff --git a/app/config/windows.js b/app/config/windows.js new file mode 100644 index 000000000000..a8cef7644c93 --- /dev/null +++ b/app/config/windows.js @@ -0,0 +1,21 @@ +const Config = require('electron-config'); + +// local storage +const cfg = new Config({ + defaults: { + windowPosition: [50, 50], + windowSize: [540, 380] + } +}); + +module.exports = { + get() { + const position = cfg.get('windowPosition'); + const size = cfg.get('windowSize'); + return {position, size}; + }, + recordState(win) { + cfg.set('windowPosition', win.getPosition()); + cfg.set('windowSize', win.getSize()); + } +}; diff --git a/app/index.js b/app/index.js index fe41ee4381ee..563578f7b404 100644 --- a/app/index.js +++ b/app/index.js @@ -53,13 +53,12 @@ const AppMenu = require('./menus/menu'); const createRPC = require('./rpc'); const notify = require('./notify'); const fetchNotifications = require('./notifications'); +const config = require('./config'); app.commandLine.appendSwitch('js-flags', '--harmony-async-await'); // set up config -const config = require('./config'); - -config.init(); +config.setup(); const plugins = require('./plugins'); const Session = require('./session'); @@ -106,7 +105,7 @@ app.on('ready', () => installDevExtensions(isDev).then(() => { function createWindow(fn, options = {}) { let cfg = plugins.getDecoratedConfig(); - const winSet = app.config.window.get(); + const winSet = config.getWin(); let [startX, startY] = winSet.position; const [width, height] = options.size ? options.size : (cfg.windowSize || winSet.size); @@ -353,7 +352,7 @@ app.on('ready', () => installDevExtensions(isDev).then(() => { // the window can be closed by the browser process itself win.on('close', () => { - app.config.window.recordState(win); + config.winRecord(win); windowSet.delete(win); rpc.destroy(); deleteSessions(); @@ -415,6 +414,7 @@ app.on('ready', () => installDevExtensions(isDev).then(() => { const load = () => { plugins.onApp(app); + plugins.extendKeymaps(); makeMenu(); }; diff --git a/app/keymaps/darwin.json b/app/keymaps/darwin.json new file mode 100644 index 000000000000..e336335333a9 --- /dev/null +++ b/app/keymaps/darwin.json @@ -0,0 +1,34 @@ +{ + "window:devtools":"cmd+alt+i", + "window:reload":"cmd+r", + "window:reloadFull":"cmd+shift+r", + "window:preferences":"cmd+,", + "zoom:reset":"cmd+0", + "zoom:in":"cmd+plus", + "zoom:out":"cmd+-", + "window:new":"cmd+n", + "window:minimize": "cmd+m", + "window:zoom": "ctrl+alt+cmd+m", + "window:full": "cmd+ctrl+f", + "window:close":"cmd+shift+w", + + "tab:new":"cmd+t", + "tab:next":"cmd+shift+]", + "tab:prev":"cmd+shift+[", + "pane:next":"cmd+]", + "pane:prev":"cmd+[", + "pane:vertical":"cmd+d", + "pane:horizontal":"cmd+shift+d", + "pane:close":"cmd+w", + + "editor:undo":"cmd+z", + "editor:redo":"cmd+y", + "editor:cut":"cmd+x", + "editor:copy":"cmd+c", + "editor:paste":"cmd+v", + "editor:selectAll":"cmd+a", + "editor:clearBuffer":"cmd+k", + "editor:emojis": "cmd+ctrl+space", + + "plugins:update": "cmd+shift+u" +} \ No newline at end of file diff --git a/app/keymaps/linux.json b/app/keymaps/linux.json new file mode 100644 index 000000000000..ddf5ff118854 --- /dev/null +++ b/app/keymaps/linux.json @@ -0,0 +1,33 @@ +{ + "window:devtools":"ctrl+shift+i", + "window:reload":"ctrl+shift+r", + "window:reloadFull":"ctrl+shift+f5", + "window:preferences":"ctrl+,", + "zoom:reset":"ctrl+0", + "zoom:in":"ctrl+plus", + "zoom:out":"ctrl+-", + "window:new":"ctrl+shift+n", + "window:minimize": "ctrl+shift+m", + "window:zoom": "ctrl+shift+alt+m", + "window:full": "f11", + "window:close":"ctrl+shift+w", + + "tab:new":"ctrl+shift+t", + "tab:next":"ctrl+tab", + "tab:prev":"ctrl+shift+tab", + "pane:next":"ctrl+pageup", + "pane:prev":"ctrl+pagedown", + "pane:vertical":"ctrl+shift+d", + "pane:horizontal":"ctrl+shift+e", + "pane:close":"ctrl+shift+w", + + "editor:undo":"ctrl+shift+z", + "editor:redo":"ctrl+shift+y", + "editor:cut":"ctrl+shift+x", + "editor:copy":"ctrl+shift+c", + "editor:paste":"ctrl+shift+v", + "editor:selectAll":"ctrl+shift+a", + "editor:clearBuffer":"ctrl+shift+k", + + "plugins:update": "ctrl+shift+u" +} \ No newline at end of file diff --git a/app/keymaps/win32.json b/app/keymaps/win32.json new file mode 100644 index 000000000000..2469b3b0657e --- /dev/null +++ b/app/keymaps/win32.json @@ -0,0 +1,33 @@ +{ + "window:devtools":"ctrl+shift+i", + "window:reload":"ctrl+shift+r", + "window:reloadFull":"ctrl+shift+f5", + "window:preferences":"ctrl+,", + "zoom:reset":"ctrl+0", + "zoom:in":"ctrl+plus", + "zoom:out":"ctrl+-", + "window:new":"ctrl+shift+n", + "window:minimize": "ctrl+m", + "window:zoom": "ctrl+shift+alt+m", + "window:full": "f11", + "window:close":"ctrl+shift+w", + + "tab:new":"ctrl+shift+t", + "tab:next":"ctrl+tab", + "tab:prev":"ctrl+shift+tab", + "pane:next":"ctrl+pageup", + "pane:prev":"ctrl+pagedown", + "pane:vertical":"ctrl+shift+d", + "pane:horizontal":"ctrl+shift+e", + "pane:close":"ctrl+shift+w", + + "editor:undo":"ctrl+shift+z", + "editor:redo":"ctrl+shift+y", + "editor:cut":"ctrl+shift+x", + "editor:copy":"ctrl+shift+c", + "editor:paste":"ctrl+shift+v", + "editor:selectAll":"ctrl+shift+a", + "editor:clearBuffer":"ctrl+shift+k", + + "plugins:update": "ctrl+shift+u" +} diff --git a/app/menus/menu.js b/app/menus/menu.js index c10fa2a4e7d3..32b3ba018bc9 100644 --- a/app/menus/menu.js +++ b/app/menus/menu.js @@ -1,3 +1,5 @@ +const {getKeymaps} = require('../config'); + // menus const viewMenu = require('./menus/view'); const shellMenu = require('./menus/shell'); @@ -8,18 +10,19 @@ const helpMenu = require('./menus/help'); const darwinMenu = require('./menus/darwin'); module.exports = (createWindow, updatePlugins) => { + const commands = getKeymaps().commands; const menu = [].concat( - shellMenu(createWindow), - editMenu(), - viewMenu(), - pluginsMenu(updatePlugins), - windowMenu(), - helpMenu() + shellMenu(commands, createWindow), + editMenu(commands), + viewMenu(commands), + pluginsMenu(commands, updatePlugins), + windowMenu(commands), + helpMenu(commands) ); if (process.platform === 'darwin') { menu.unshift( - darwinMenu() + darwinMenu(commands) ); } diff --git a/app/menus/menus/darwin.js b/app/menus/menus/darwin.js index 4a5a2fd03a08..98266ce8f780 100644 --- a/app/menus/menus/darwin.js +++ b/app/menus/menus/darwin.js @@ -1,10 +1,9 @@ // This menu label is overrided by OSX to be the appName // The label is set to appName here so it matches actual behavior const {app} = require('electron'); -const {accelerators} = require('../../accelerators'); const {openConfig} = require('../../config'); -module.exports = function () { +module.exports = function (commands) { return { label: `${app.getName()}`, submenu: [ @@ -16,7 +15,7 @@ module.exports = function () { }, { label: 'Preferences...', - accelerator: accelerators.preferences, + accelerator: commands['window:preferences'], click() { openConfig(); } diff --git a/app/menus/menus/edit.js b/app/menus/menus/edit.js index a0596e364cee..aa6f5d7d2bdf 100644 --- a/app/menus/menus/edit.js +++ b/app/menus/menus/edit.js @@ -1,41 +1,40 @@ -const {accelerators} = require('../../accelerators'); const {openConfig} = require('../../config'); -module.exports = function () { +module.exports = function (commands) { const submenu = [ { role: 'undo', - accelerator: accelerators.undo + accelerator: commands['editor:undo'] }, { role: 'redo', - accelerator: accelerators.redo + accelerator: commands['editor:redo'] }, { type: 'separator' }, { role: 'cut', - accelerator: accelerators.cut + accelerator: commands['editor:cut'] }, { role: 'copy', - accelerator: accelerators.copy + accelerator: commands['editor:copy'] }, { role: 'paste', - accelerator: accelerators.paste + accelerator: commands['editor:paste'] }, { role: 'selectall', - accelerator: accelerators.selectAll + accelerator: commands['editor:selectAll'] }, { type: 'separator' }, { label: 'Clear Buffer', - accelerator: accelerators.clear, + accelerator: commands['editor:clearBuffer'], click(item, focusedWindow) { if (focusedWindow) { focusedWindow.rpc.emit('session clear req'); @@ -49,7 +48,7 @@ module.exports = function () { {type: 'separator'}, { label: 'Preferences...', - accelerator: accelerators.preferences, + accelerator: commands['window:preferences'], click() { openConfig(); } diff --git a/app/menus/menus/plugins.js b/app/menus/menus/plugins.js index 1abc1b53e555..d7dee3fe0ec0 100644 --- a/app/menus/menus/plugins.js +++ b/app/menus/menus/plugins.js @@ -1,12 +1,10 @@ -const {accelerators} = require('../../accelerators'); - -module.exports = function (update) { +module.exports = function (commands, update) { return { label: 'Plugins', submenu: [ { label: 'Update', - accelerator: accelerators.updatePlugins, + accelerator: commands['plugins:update'], click() { update(); } diff --git a/app/menus/menus/shell.js b/app/menus/menus/shell.js index c632bbaf5dda..c630fd121469 100644 --- a/app/menus/menus/shell.js +++ b/app/menus/menus/shell.js @@ -1,6 +1,4 @@ -const {accelerators} = require('../../accelerators'); - -module.exports = function (createWindow) { +module.exports = function (commands, createWindow) { const isMac = process.platform === 'darwin'; return { @@ -8,14 +6,14 @@ module.exports = function (createWindow) { submenu: [ { label: 'New Window', - accelerator: accelerators.newWindow, + accelerator: commands['window:new'], click() { createWindow(); } }, { label: 'New Tab', - accelerator: accelerators.newTab, + accelerator: commands['tab:new'], click(item, focusedWindow) { if (focusedWindow) { focusedWindow.rpc.emit('termgroup add req'); @@ -29,7 +27,7 @@ module.exports = function (createWindow) { }, { label: 'Split Vertically', - accelerator: accelerators.splitVertically, + accelerator: commands['pane:vertical'], click(item, focusedWindow) { if (focusedWindow) { focusedWindow.rpc.emit('split request vertical'); @@ -38,7 +36,7 @@ module.exports = function (createWindow) { }, { label: 'Split Horizontally', - accelerator: accelerators.splitHorizontally, + accelerator: commands['pane:horizontal'], click(item, focusedWindow) { if (focusedWindow) { focusedWindow.rpc.emit('split request horizontal'); @@ -50,7 +48,7 @@ module.exports = function (createWindow) { }, { label: 'Close Session', - accelerator: accelerators.closeSession, + accelerator: commands['pane:close'], click(item, focusedWindow) { if (focusedWindow) { focusedWindow.rpc.emit('termgroup close req'); @@ -60,7 +58,7 @@ module.exports = function (createWindow) { { label: isMac ? 'Close Window' : 'Quit', role: 'close', - accelerator: accelerators.closeWindow + accelerator: commands['window:close'] } ] }; diff --git a/app/menus/menus/view.js b/app/menus/menus/view.js index d1b98cbe7c2b..3c64253826d6 100644 --- a/app/menus/menus/view.js +++ b/app/menus/menus/view.js @@ -1,12 +1,10 @@ -const {accelerators} = require('../../accelerators'); - -module.exports = function () { +module.exports = function (commands) { return { label: 'View', submenu: [ { label: 'Reload', - accelerator: accelerators.reload, + accelerator: commands['window:reload'], click(item, focusedWindow) { if (focusedWindow) { focusedWindow.rpc.emit('reload'); @@ -15,7 +13,7 @@ module.exports = function () { }, { label: 'Full Reload', - accelerator: accelerators.fullReload, + accelerator: commands['window:reloadFull'], click(item, focusedWindow) { if (focusedWindow) { focusedWindow.reload(); @@ -24,7 +22,7 @@ module.exports = function () { }, { label: 'Developer Tools', - accelerator: accelerators.toggleDevTools, + accelerator: commands['window:devtools'], click(item, focusedWindow) { if (focusedWindow) { const webContents = focusedWindow.webContents; @@ -41,7 +39,7 @@ module.exports = function () { }, { label: 'Reset Zoom Level', - accelerator: accelerators.resetZoom, + accelerator: commands['zoom:reset'], click(item, focusedWindow) { if (focusedWindow) { focusedWindow.rpc.emit('reset fontSize req'); @@ -50,7 +48,7 @@ module.exports = function () { }, { label: 'Zoom In', - accelerator: accelerators.zoomIn, + accelerator: commands['zoom:in'], click(item, focusedWindow) { if (focusedWindow) { focusedWindow.rpc.emit('increase fontSize req'); @@ -59,7 +57,7 @@ module.exports = function () { }, { label: 'Zoom Out', - accelerator: accelerators.zoomOut, + accelerator: commands['zoom:out'], click(item, focusedWindow) { if (focusedWindow) { focusedWindow.rpc.emit('decrease fontSize req'); diff --git a/app/menus/menus/window.js b/app/menus/menus/window.js index b467b051c3bd..6e0ef658181f 100644 --- a/app/menus/menus/window.js +++ b/app/menus/menus/window.js @@ -1,15 +1,14 @@ -const {accelerators} = require('../../accelerators'); - -module.exports = function () { +module.exports = function (commands) { return { role: 'window', submenu: [ { role: 'minimize', - accelerator: accelerators.minimize + accelerator: commands['window:minimize'] }, { - role: 'zoom' + role: 'zoom', + accelerator: commands['window:zoom'] }, { type: 'separator' @@ -19,7 +18,7 @@ module.exports = function () { submenu: [ { label: 'Previous', - accelerator: accelerators.showPreviousTab, + accelerator: commands['tab:prev'], click(item, focusedWindow) { if (focusedWindow) { focusedWindow.rpc.emit('move left req'); @@ -28,7 +27,7 @@ module.exports = function () { }, { label: 'Next', - accelerator: accelerators.showNextTab, + accelerator: commands['tab:next'], click(item, focusedWindow) { if (focusedWindow) { focusedWindow.rpc.emit('move right req'); @@ -45,7 +44,7 @@ module.exports = function () { submenu: [ { label: 'Previous', - accelerator: accelerators.selectNextPane, + accelerator: commands['pane:prev'], click(item, focusedWindow) { if (focusedWindow) { focusedWindow.rpc.emit('prev pane req'); @@ -54,7 +53,7 @@ module.exports = function () { }, { label: 'Next', - accelerator: accelerators.selectPreviousPane, + accelerator: commands['pane:next'], click(item, focusedWindow) { if (focusedWindow) { focusedWindow.rpc.emit('next pane req'); @@ -71,7 +70,7 @@ module.exports = function () { }, { role: 'togglefullscreen', - accelerators: accelerators.enterFullScreen + accelerators: commands['window:full'] } ] }; diff --git a/app/plugins.js b/app/plugins.js index 91781700f8df..32926c9ce4fc 100644 --- a/app/plugins.js +++ b/app/plugins.js @@ -10,6 +10,7 @@ const shellEnv = require('shell-env'); const config = require('./config'); const notify = require('./notify'); +const _keys = require('./config/keymaps'); // local storage const cache = new Config(); @@ -30,7 +31,8 @@ const availableExtensions = new Set([ 'mapHyperTermState', 'mapTermsState', 'mapHeaderState', 'mapNotificationsState', 'mapHyperTermDispatch', 'mapTermsDispatch', - 'mapHeaderDispatch', 'mapNotificationsDispatch' + 'mapHeaderDispatch', 'mapNotificationsDispatch', + 'extendKeymaps' ]); // init plugin directories if not present @@ -354,6 +356,15 @@ function decorateObject(base, key) { return decorated; } +exports.extendKeymaps = function () { + modules.forEach(plugin => { + if (plugin.extendKeymaps) { + const keys = _keys.extend(plugin.extendKeymaps()); + config.extendKeymaps(keys); + } + }); +}; + exports.decorateMenu = function (tpl) { return decorateObject(tpl, 'decorateMenu'); }; diff --git a/lib/command-registry.js b/lib/command-registry.js new file mode 100644 index 000000000000..4ea711398e62 --- /dev/null +++ b/lib/command-registry.js @@ -0,0 +1,23 @@ +const commands = {}; + +class CommandRegistry { + register(cmds) { + if (cmds) { + for (const command in cmds) { + if (command) { + commands[command] = cmds[command]; + } + } + } + } + + getCommand(cmd) { + return commands[cmd] !== undefined; + } + + exec(cmd, e) { + commands[cmd](e); + } +} + +export default new CommandRegistry(); diff --git a/lib/components/terms.js b/lib/components/terms.js index fd596cbe641c..f50026d542f5 100644 --- a/lib/components/terms.js +++ b/lib/components/terms.js @@ -1,6 +1,7 @@ import React from 'react'; import Component from '../component'; import {decorate, getTermGroupProps} from '../utils/plugins'; +import CommandRegistry from '../command-registry'; import TermGroup_ from './term-group'; const TermGroup = decorate(TermGroup_, 'TermGroup'); @@ -13,6 +14,7 @@ export default class Terms extends Component { this.terms = {}; this.bound = new WeakMap(); this.onRef = this.onRef.bind(this); + this.registerCommands = CommandRegistry.register; props.ref_(this); } diff --git a/lib/hterm.js b/lib/hterm.js index 6282e77efeea..67a660da0724 100644 --- a/lib/hterm.js +++ b/lib/hterm.js @@ -1,11 +1,10 @@ import {clipboard} from 'electron'; import {hterm, lib} from 'hterm-umdjs'; import runes from 'runes'; - -import {isAccelerator} from '../app/accelerators'; - import fromCharCode from './utils/key-code'; import selection from './utils/selection'; +import returnKey from './utils/keymaps'; +import CommandRegistry from './command-registry'; hterm.defaultStorage = new lib.Storage.Memory(); @@ -232,8 +231,15 @@ hterm.Keyboard.prototype.onKeyDown_ = function (e) { e.preventDefault(); } - // hterm shouldn't consume a hyper accelerator - if (e.altKey || e.metaKey || isAccelerator(e)) { + // test key from keymaps before moving forward with actions + const key = returnKey(e); + if (key) { + if (CommandRegistry.getCommand(key)) { + CommandRegistry.exec(key, e); + } + } + + if (e.altKey || e.metaKey || key) { // If the `hyperCaret` was removed on `selectAll`, we need to insert it back if (e.key === 'v' && this.terminal.hyperCaret.parentNode !== this.terminal.cursorNode_) { this.terminal.focusHyperCaret(); diff --git a/lib/utils/keymaps.js b/lib/utils/keymaps.js new file mode 100644 index 000000000000..dc590b81c6f2 --- /dev/null +++ b/lib/utils/keymaps.js @@ -0,0 +1,34 @@ +import {remote} from 'electron'; + +const {getKeymaps} = remote.require('./config'); + +export default function returnKey(e) { + let keys = []; + + if (e.metaKey && process.platform === 'darwin') { + keys.push('cmd'); + } else if (e.metaKey) { + keys.push(e.key); + } + + if (e.ctrlKey) { + keys.push('ctrl'); + } + + if (e.shiftKey) { + keys.push('shift'); + } + + if (e.altKey) { + keys.push('alt'); + } + + if (e.key === ' ') { + keys.push('space'); + } else if (e.key !== 'Meta' && e.key !== 'Control' && e.key !== 'Shift' && e.key !== 'Alt') { + keys.push(e.key.replace('Arrow', '')); + } + + keys = keys.join('+'); + return getKeymaps().keys[keys.toLowerCase()]; +} From ee89466dc7d237dc911a570c2af5b39133ff1815 Mon Sep 17 00:00:00 2001 From: ppot Date: Sat, 27 May 2017 23:08:18 -0400 Subject: [PATCH 2/5] First part fix --- app/config.js | 8 ++--- app/config/import.js | 4 +-- app/config/init.js | 13 +++++---- app/config/keymaps.js | 12 ++------ app/config/paths.js | 26 ++++++++++++----- app/keymaps/darwin.json | 61 +++++++++++++++++++-------------------- app/keymaps/linux.json | 53 ++++++++++++++++------------------ app/keymaps/win32.json | 61 +++++++++++++++++++-------------------- app/menus/menu.js | 23 ++++++--------- app/menus/menus/shell.js | 4 +-- app/menus/menus/window.js | 2 +- 11 files changed, 128 insertions(+), 139 deletions(-) diff --git a/app/config.js b/app/config.js index d72e1f8c5a9c..65aec2995e8d 100644 --- a/app/config.js +++ b/app/config.js @@ -6,13 +6,13 @@ const _openConfig = require('./config/open'); const win = require('./config/windows'); const watchers = []; -const scanInterval = 2000; +// watch for changes on config every 2s on windows +// https://github.com/zeit/hyper/pull/1772 +const watchConfig = process.platform === 'win32' ? { interval: 2000 } : {} let cfg = {}; const _watch = function () { - // watch for changes on config every 2s - // windows interval: https://github.com/zeit/hyper/pull/1772 - gaze(confPath, process.platform === 'win32' ? {interval: scanInterval} : {}, function (err) { + gaze(confPath, watchConfig, function (err) { if (err) { throw err; } diff --git a/app/config/import.js b/app/config/import.js index 0593808df2bf..0c30c3f39a00 100644 --- a/app/config/import.js +++ b/app/config/import.js @@ -1,7 +1,7 @@ const {writeFileSync, readFileSync} = require('fs'); const {defaultConfig, confPath} = require('./paths'); const _init = require('./init'); -const _keys = require('./keymaps'); +const _keymaps = require('./keymaps'); const _write = function (path, data) { // This method will take text formatted as Unix line endings and transform it @@ -33,7 +33,7 @@ const _import = function () { const cfg = _init(_importConf()); if (cfg) { - cfg.keymaps = _keys.import(cfg.keymaps); + cfg.keymaps = _keymaps.import(cfg.keymaps); } return cfg; }; diff --git a/app/config/init.js b/app/config/init.js index d0e7490ac665..c953c1b02d6e 100644 --- a/app/config/init.js +++ b/app/config/init.js @@ -11,12 +11,13 @@ const _extract = function (script) { }; const _syntaxValidation = function (cfg) { - try { - return new vm.Script(cfg); - } catch (err) { - notify('Error reading configuration: Syntax error found'); - return undefined; - } + try { + return new vm.Script(cfg, { filename: '.hyper.js', displayErrors: true }) + } catch (error) { + notify(`Error loading config: ${error.name}, see DevTools for more info`) + console.error('Error loading config:', error) + return + } }; const _extractDefault = function (cfg) { diff --git a/app/config/keymaps.js b/app/config/keymaps.js index 0311e0cf6fa7..22602c08fb91 100644 --- a/app/config/keymaps.js +++ b/app/config/keymaps.js @@ -1,5 +1,5 @@ const {readFileSync} = require('fs'); -const {darwinKeys, win32Keys, linuxKeys} = require('./paths'); +const {defaultPlatformKeyPath} = require('./paths'); const commands = {}; const keys = {}; @@ -21,16 +21,8 @@ const _setCommandsForKeys = function (commands) { }; const _import = function (customsKeys) { - const path = () => { - switch (process.platform) { - case 'darwin': return darwinKeys; - case 'win32': return win32Keys; - case 'linux': return linuxKeys; - default: return darwinKeys; - } - }; try { - const mapping = JSON.parse(readFileSync(path())); + const mapping = JSON.parse(readFileSync(defaultPlatformKeyPath())); _setKeysForCommands(mapping); _setKeysForCommands(customsKeys); _setCommandsForKeys(commands); diff --git a/app/config/paths.js b/app/config/paths.js index 4fe5887e653f..98e148ffd2a4 100644 --- a/app/config/paths.js +++ b/app/config/paths.js @@ -1,26 +1,35 @@ // This module exports paths, names, and other metadata that is referenced const {homedir} = require('os'); const {statSync} = require('fs'); -const {resolve} = require('path'); +const {resolve, join} = require('path'); const isDev = require('electron-is-dev'); const conf = '.hyper.js'; const defaultConf = 'config-default.js'; const homeDir = homedir(); -let confPath = resolve(homeDir, conf); +let confPath = join(homeDir, conf); let confDir = homeDir; const devDir = resolve(__dirname, '../..'); -const devConfig = resolve(devDir, conf); +const devConfig = join(devDir, conf); const defaultConfig = resolve(__dirname, defaultConf); const icon = resolve(__dirname, '../static/icon.png'); const keymapPath = resolve(__dirname, '../keymaps'); -const darwinKeys = resolve(keymapPath, 'darwin.json'); -const win32Keys = resolve(keymapPath, 'win32.json'); -const linuxKeys = resolve(keymapPath, 'linux.json'); +const darwinKeys = join(keymapPath, 'darwin.json'); +const win32Keys = join(keymapPath, 'win32.json'); +const linuxKeys = join(keymapPath, 'linux.json'); + +defaultPlatformKeyPath = () => { + switch (process.platform) { + case 'darwin': return darwinKeys; + case 'win32': return win32Keys; + case 'linux': return linuxKeys; + default: return darwinKeys; + } +}; if (isDev) { // if a local config file exists, use it @@ -35,6 +44,7 @@ if (isDev) { } module.exports = { - confDir, confPath, conf, defaultConfig, icon, - darwinKeys, win32Keys, linuxKeys + confDir, confPath, conf, defaultConfig, icon, defaultPlatformKeyPath }; + + diff --git a/app/keymaps/darwin.json b/app/keymaps/darwin.json index e336335333a9..64c81bc90a3b 100644 --- a/app/keymaps/darwin.json +++ b/app/keymaps/darwin.json @@ -1,34 +1,31 @@ { - "window:devtools":"cmd+alt+i", - "window:reload":"cmd+r", - "window:reloadFull":"cmd+shift+r", - "window:preferences":"cmd+,", - "zoom:reset":"cmd+0", - "zoom:in":"cmd+plus", - "zoom:out":"cmd+-", - "window:new":"cmd+n", - "window:minimize": "cmd+m", - "window:zoom": "ctrl+alt+cmd+m", - "window:full": "cmd+ctrl+f", - "window:close":"cmd+shift+w", - - "tab:new":"cmd+t", - "tab:next":"cmd+shift+]", - "tab:prev":"cmd+shift+[", - "pane:next":"cmd+]", - "pane:prev":"cmd+[", - "pane:vertical":"cmd+d", - "pane:horizontal":"cmd+shift+d", - "pane:close":"cmd+w", - - "editor:undo":"cmd+z", - "editor:redo":"cmd+y", - "editor:cut":"cmd+x", - "editor:copy":"cmd+c", - "editor:paste":"cmd+v", - "editor:selectAll":"cmd+a", - "editor:clearBuffer":"cmd+k", - "editor:emojis": "cmd+ctrl+space", - - "plugins:update": "cmd+shift+u" + "window:devtools": "cmd+alt+i", + "window:reload": "cmd+r", + "window:reloadFull": "cmd+shift+r", + "window:preferences": "cmd+,", + "zoom:reset": "cmd+0", + "zoom:in": "cmd+plus", + "zoom:out": "cmd+-", + "window:new": "cmd+n", + "window:minimize": "cmd+m", + "window:zoom": "ctrl+alt+cmd+m", + "window:toggleFullScreen": "cmd+ctrl+f", + "window:close": "cmd+shift+w", + "tab:new": "cmd+t", + "tab:next": "cmd+shift+]", + "tab:prev": "cmd+shift+[", + "pane:next": "cmd+]", + "pane:prev": "cmd+[", + "pane:splitVertical": "cmd+d", + "pane:splitHorizontal": "cmd+shift+d", + "pane:close": "cmd+w", + "editor:undo": "cmd+z", + "editor:redo": "cmd+y", + "editor:cut": "cmd+x", + "editor:copy": "cmd+c", + "editor:paste": "cmd+v", + "editor:selectAll": "cmd+a", + "editor:clearBuffer": "cmd+k", + "editor:emojis": "cmd+ctrl+space", + "plugins:update": "cmd+shift+u" } \ No newline at end of file diff --git a/app/keymaps/linux.json b/app/keymaps/linux.json index ddf5ff118854..d0d9b9879e51 100644 --- a/app/keymaps/linux.json +++ b/app/keymaps/linux.json @@ -1,33 +1,30 @@ { - "window:devtools":"ctrl+shift+i", - "window:reload":"ctrl+shift+r", - "window:reloadFull":"ctrl+shift+f5", - "window:preferences":"ctrl+,", - "zoom:reset":"ctrl+0", - "zoom:in":"ctrl+plus", - "zoom:out":"ctrl+-", - "window:new":"ctrl+shift+n", + "window:devtools": "ctrl+shift+i", + "window:reload": "ctrl+shift+r", + "window:reloadFull": "ctrl+shift+f5", + "window:preferences": "ctrl+,", + "zoom:reset": "ctrl+0", + "zoom:in": "ctrl+plus", + "zoom:out": "ctrl+-", + "window:new": "ctrl+shift+n", "window:minimize": "ctrl+shift+m", "window:zoom": "ctrl+shift+alt+m", - "window:full": "f11", - "window:close":"ctrl+shift+w", - - "tab:new":"ctrl+shift+t", - "tab:next":"ctrl+tab", - "tab:prev":"ctrl+shift+tab", - "pane:next":"ctrl+pageup", - "pane:prev":"ctrl+pagedown", - "pane:vertical":"ctrl+shift+d", - "pane:horizontal":"ctrl+shift+e", - "pane:close":"ctrl+shift+w", - - "editor:undo":"ctrl+shift+z", - "editor:redo":"ctrl+shift+y", - "editor:cut":"ctrl+shift+x", - "editor:copy":"ctrl+shift+c", - "editor:paste":"ctrl+shift+v", - "editor:selectAll":"ctrl+shift+a", - "editor:clearBuffer":"ctrl+shift+k", - + "window:toggleFullScreen": "f11", + "window:close": "ctrl+shift+w", + "tab:new": "ctrl+shift+t", + "tab:next": "ctrl+tab", + "tab:prev": "ctrl+shift+tab", + "pane:next": "ctrl+pageup", + "pane:prev": "ctrl+pagedown", + "pane:splitVertical": "ctrl+shift+d", + "pane:splitHorizontal": "ctrl+shift+e", + "pane:close": "ctrl+shift+w", + "editor:undo": "ctrl+shift+z", + "editor:redo": "ctrl+shift+y", + "editor:cut": "ctrl+shift+x", + "editor:copy": "ctrl+shift+c", + "editor:paste": "ctrl+shift+v", + "editor:selectAll": "ctrl+shift+a", + "editor:clearBuffer": "ctrl+shift+k", "plugins:update": "ctrl+shift+u" } \ No newline at end of file diff --git a/app/keymaps/win32.json b/app/keymaps/win32.json index 2469b3b0657e..33485c9964a6 100644 --- a/app/keymaps/win32.json +++ b/app/keymaps/win32.json @@ -1,33 +1,30 @@ { - "window:devtools":"ctrl+shift+i", - "window:reload":"ctrl+shift+r", - "window:reloadFull":"ctrl+shift+f5", - "window:preferences":"ctrl+,", - "zoom:reset":"ctrl+0", - "zoom:in":"ctrl+plus", - "zoom:out":"ctrl+-", - "window:new":"ctrl+shift+n", - "window:minimize": "ctrl+m", - "window:zoom": "ctrl+shift+alt+m", - "window:full": "f11", - "window:close":"ctrl+shift+w", - - "tab:new":"ctrl+shift+t", - "tab:next":"ctrl+tab", - "tab:prev":"ctrl+shift+tab", - "pane:next":"ctrl+pageup", - "pane:prev":"ctrl+pagedown", - "pane:vertical":"ctrl+shift+d", - "pane:horizontal":"ctrl+shift+e", - "pane:close":"ctrl+shift+w", - - "editor:undo":"ctrl+shift+z", - "editor:redo":"ctrl+shift+y", - "editor:cut":"ctrl+shift+x", - "editor:copy":"ctrl+shift+c", - "editor:paste":"ctrl+shift+v", - "editor:selectAll":"ctrl+shift+a", - "editor:clearBuffer":"ctrl+shift+k", - - "plugins:update": "ctrl+shift+u" -} + "window:devtools": "ctrl+shift+i", + "window:reload": "ctrl+shift+r", + "window:reloadFull": "ctrl+shift+f5", + "window:preferences": "ctrl+,", + "zoom:reset": "ctrl+0", + "zoom:in": "ctrl+plus", + "zoom:out": "ctrl+-", + "window:new": "ctrl+shift+n", + "window:minimize": "ctrl+m", + "window:zoom": "ctrl+shift+alt+m", + "window:toggleFullScreen": "f11", + "window:close": "ctrl+shift+w", + "tab:new": "ctrl+shift+t", + "tab:next": "ctrl+tab", + "tab:prev": "ctrl+shift+tab", + "pane:next": "ctrl+pageup", + "pane:prev": "ctrl+pagedown", + "pane:splitVertical": "ctrl+shift+d", + "pane:splitHorizontal": "ctrl+shift+e", + "pane:close": "ctrl+shift+w", + "editor:undo": "ctrl+shift+z", + "editor:redo": "ctrl+shift+y", + "editor:cut": "ctrl+shift+x", + "editor:copy": "ctrl+shift+c", + "editor:paste": "ctrl+shift+v", + "editor:selectAll": "ctrl+shift+a", + "editor:clearBuffer": "ctrl+shift+k", + "plugins:update": "ctrl+shift+u" +} \ No newline at end of file diff --git a/app/menus/menu.js b/app/menus/menu.js index 32b3ba018bc9..e9be00bbe7c4 100644 --- a/app/menus/menu.js +++ b/app/menus/menu.js @@ -11,20 +11,15 @@ const darwinMenu = require('./menus/darwin'); module.exports = (createWindow, updatePlugins) => { const commands = getKeymaps().commands; - const menu = [].concat( - shellMenu(commands, createWindow), - editMenu(commands), - viewMenu(commands), - pluginsMenu(commands, updatePlugins), - windowMenu(commands), - helpMenu(commands) - ); - - if (process.platform === 'darwin') { - menu.unshift( - darwinMenu(commands) - ); - } + const menu = [ + ...(process.platform === 'darwin' ? darwinMenu(commands) : []), + ...shellMenu(commands, createWindow), + ...editMenu(commands), + ...viewMenu(commands), + ...pluginsMenu(commands, updatePlugins), + ...windowMenu(commands), + ...helpMenu(commands) + ]; return menu; }; diff --git a/app/menus/menus/shell.js b/app/menus/menus/shell.js index c630fd121469..56b0d7d02f01 100644 --- a/app/menus/menus/shell.js +++ b/app/menus/menus/shell.js @@ -27,7 +27,7 @@ module.exports = function (commands, createWindow) { }, { label: 'Split Vertically', - accelerator: commands['pane:vertical'], + accelerator: commands['pane:splitVertical'], click(item, focusedWindow) { if (focusedWindow) { focusedWindow.rpc.emit('split request vertical'); @@ -36,7 +36,7 @@ module.exports = function (commands, createWindow) { }, { label: 'Split Horizontally', - accelerator: commands['pane:horizontal'], + accelerator: commands['pane:splitHorizontal'], click(item, focusedWindow) { if (focusedWindow) { focusedWindow.rpc.emit('split request horizontal'); diff --git a/app/menus/menus/window.js b/app/menus/menus/window.js index 6e0ef658181f..33e6e38774d2 100644 --- a/app/menus/menus/window.js +++ b/app/menus/menus/window.js @@ -70,7 +70,7 @@ module.exports = function (commands) { }, { role: 'togglefullscreen', - accelerators: commands['window:full'] + accelerators: commands['window:toggleFullScreen'] } ] }; From 053754a24e53504164717e43aad0de84d45b39fb Mon Sep 17 00:00:00 2001 From: ppot Date: Sat, 27 May 2017 23:36:22 -0400 Subject: [PATCH 3/5] lint --- app/config.js | 2 +- app/config/init.js | 14 +++++++------- app/config/paths.js | 4 +--- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/app/config.js b/app/config.js index 65aec2995e8d..562dc73ffd1e 100644 --- a/app/config.js +++ b/app/config.js @@ -8,7 +8,7 @@ const win = require('./config/windows'); const watchers = []; // watch for changes on config every 2s on windows // https://github.com/zeit/hyper/pull/1772 -const watchConfig = process.platform === 'win32' ? { interval: 2000 } : {} +const watchConfig = process.platform === 'win32' ? {interval: 2000} : {}; let cfg = {}; const _watch = function () { diff --git a/app/config/init.js b/app/config/init.js index c953c1b02d6e..0d87508a87e7 100644 --- a/app/config/init.js +++ b/app/config/init.js @@ -11,13 +11,13 @@ const _extract = function (script) { }; const _syntaxValidation = function (cfg) { - try { - return new vm.Script(cfg, { filename: '.hyper.js', displayErrors: true }) - } catch (error) { - notify(`Error loading config: ${error.name}, see DevTools for more info`) - console.error('Error loading config:', error) - return - } + try { + return new vm.Script(cfg, {filename: '.hyper.js', displayErrors: true}); + } catch (err) { + notify(`Error loading config: ${err.name}, see DevTools for more info`); + console.error('Error loading config:', err); + return; + } }; const _extractDefault = function (cfg) { diff --git a/app/config/paths.js b/app/config/paths.js index 98e148ffd2a4..c9039fed3060 100644 --- a/app/config/paths.js +++ b/app/config/paths.js @@ -22,7 +22,7 @@ const darwinKeys = join(keymapPath, 'darwin.json'); const win32Keys = join(keymapPath, 'win32.json'); const linuxKeys = join(keymapPath, 'linux.json'); -defaultPlatformKeyPath = () => { +const defaultPlatformKeyPath = () => { switch (process.platform) { case 'darwin': return darwinKeys; case 'win32': return win32Keys; @@ -46,5 +46,3 @@ if (isDev) { module.exports = { confDir, confPath, conf, defaultConfig, icon, defaultPlatformKeyPath }; - - From 886551b8af9ca95f24667ad016959ae8b3b33753 Mon Sep 17 00:00:00 2001 From: ppot Date: Sun, 28 May 2017 16:18:12 -0400 Subject: [PATCH 4/5] const renaming --- app/config.js | 8 ++++---- app/config/import.js | 12 ++++++------ app/config/init.js | 6 +++--- app/config/open.js | 8 ++++---- app/config/paths.js | 22 +++++++++++----------- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/app/config.js b/app/config.js index 562dc73ffd1e..c3f4cbe09f48 100644 --- a/app/config.js +++ b/app/config.js @@ -1,18 +1,18 @@ const gaze = require('gaze'); const notify = require('./notify'); const _import = require('./config/import'); -const {confPath, confDir} = require('./config/paths'); const _openConfig = require('./config/open'); const win = require('./config/windows'); +const {cfgPath, cfgDir} = require('./config/paths'); const watchers = []; // watch for changes on config every 2s on windows // https://github.com/zeit/hyper/pull/1772 -const watchConfig = process.platform === 'win32' ? {interval: 2000} : {}; +const watchCfg = process.platform === 'win32' ? {interval: 2000} : {}; let cfg = {}; const _watch = function () { - gaze(confPath, watchConfig, function (err) { + gaze(cfgPath, watchCfg, function (err) { if (err) { throw err; } @@ -36,7 +36,7 @@ exports.subscribe = function (fn) { exports.getConfigDir = function () { // expose config directory to load plugin from the right place - return confDir; + return cfgDir; }; exports.getConfig = function () { diff --git a/app/config/import.js b/app/config/import.js index 0c30c3f39a00..3f18678ca243 100644 --- a/app/config/import.js +++ b/app/config/import.js @@ -1,5 +1,5 @@ const {writeFileSync, readFileSync} = require('fs'); -const {defaultConfig, confPath} = require('./paths'); +const {defaultCfg, cfgPath} = require('./paths'); const _init = require('./init'); const _keymaps = require('./keymaps'); @@ -16,13 +16,13 @@ const _write = function (path, data) { const _importConf = function () { try { - const defaultConf = readFileSync(defaultConfig, 'utf8'); + const _defaultCfg = readFileSync(defaultCfg, 'utf8'); try { - const conf = readFileSync(confPath, 'utf8'); - return {userConf: conf, defaultConf}; + const _cfgPath = readFileSync(cfgPath, 'utf8'); + return {userCfg: _cfgPath, defaultCfg: _defaultCfg}; } catch (err) { - _write(confPath, defaultConf); - return {userConf: {}, defaultConf}; + _write(cfgPath, defaultCfg); + return {userCfg: {}, defaultCfg: _defaultCfg}; } } catch (err) { console.log(err); diff --git a/app/config/init.js b/app/config/init.js index 0d87508a87e7..d761d558403f 100644 --- a/app/config/init.js +++ b/app/config/init.js @@ -26,7 +26,7 @@ const _extractDefault = function (cfg) { // init config const _init = function (cfg) { - const script = _syntaxValidation(cfg.userConf); + const script = _syntaxValidation(cfg.userCfg); if (script) { const _cfg = _extract(script); if (!_cfg.config) { @@ -34,11 +34,11 @@ const _init = function (cfg) { _cfg.localPlugins = _cfg.localPlugins || []; _cfg.keymaps = _cfg.keymaps || {}; notify('Error reading configuration: `config` key is missing'); - return _extractDefault(cfg.defaultConf); + return _extractDefault(cfg.defaultCfg); } return _cfg; } - return _extractDefault(cfg.defaultConf); + return _extractDefault(cfg.defaultCfg); }; module.exports = _init; diff --git a/app/config/open.js b/app/config/open.js index ed8e457a5785..9d7d0aa96a6e 100644 --- a/app/config/open.js +++ b/app/config/open.js @@ -1,7 +1,7 @@ const {shell} = require('electron'); -const {confPath} = require('./paths'); +const {cfgPath} = require('./paths'); -module.exports = () => Promise.resolve(shell.openItem(confPath)); +module.exports = () => Promise.resolve(shell.openItem(cfgPath)); if (process.platform === 'win32') { const exec = require('child_process').exec; @@ -28,6 +28,6 @@ if (process.platform === 'win32') { }); module.exports = () => canOpenNative() - .then(() => shell.openItem(confPath)) - .catch(() => openNotepad(confPath)); + .then(() => shell.openItem(cfgPath)) + .catch(() => openNotepad(cfgPath)); } diff --git a/app/config/paths.js b/app/config/paths.js index c9039fed3060..60cf52d24290 100644 --- a/app/config/paths.js +++ b/app/config/paths.js @@ -4,16 +4,16 @@ const {statSync} = require('fs'); const {resolve, join} = require('path'); const isDev = require('electron-is-dev'); -const conf = '.hyper.js'; -const defaultConf = 'config-default.js'; +const cfgFile = '.hyper.js'; +const defaultCfgFile = 'config-default.js'; const homeDir = homedir(); -let confPath = join(homeDir, conf); -let confDir = homeDir; +let cfgPath = join(homeDir, cfgFile); +let cfgDir = homeDir; const devDir = resolve(__dirname, '../..'); -const devConfig = join(devDir, conf); -const defaultConfig = resolve(__dirname, defaultConf); +const devCfg = join(devDir, cfgFile); +const defaultCfg = resolve(__dirname, defaultCfgFile); const icon = resolve(__dirname, '../static/icon.png'); @@ -34,15 +34,15 @@ const defaultPlatformKeyPath = () => { if (isDev) { // if a local config file exists, use it try { - statSync(devConfig); - confPath = devConfig; - confDir = devDir; - console.log('using config file:', confPath); + statSync(devCfg); + cfgPath = devCfg; + cfgDir = devDir; + console.log('using config file:', cfgPath); } catch (err) { // ignore } } module.exports = { - confDir, confPath, conf, defaultConfig, icon, defaultPlatformKeyPath + cfgDir, cfgPath, cfgFile, defaultCfg, icon, defaultPlatformKeyPath }; From d8f6ea0489ef3d3c4dd001d5d2044b14eb0c761a Mon Sep 17 00:00:00 2001 From: ppot Date: Sun, 28 May 2017 16:31:16 -0400 Subject: [PATCH 5/5] Fix menu loading --- app/menus/menu.js | 14 +++++++------- app/menus/menus/window.js | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/menus/menu.js b/app/menus/menu.js index e9be00bbe7c4..1d4851805df8 100644 --- a/app/menus/menu.js +++ b/app/menus/menu.js @@ -12,13 +12,13 @@ const darwinMenu = require('./menus/darwin'); module.exports = (createWindow, updatePlugins) => { const commands = getKeymaps().commands; const menu = [ - ...(process.platform === 'darwin' ? darwinMenu(commands) : []), - ...shellMenu(commands, createWindow), - ...editMenu(commands), - ...viewMenu(commands), - ...pluginsMenu(commands, updatePlugins), - ...windowMenu(commands), - ...helpMenu(commands) + (process.platform === 'darwin' ? darwinMenu(commands) : []), + shellMenu(commands, createWindow), + editMenu(commands), + viewMenu(commands), + pluginsMenu(commands, updatePlugins), + windowMenu(commands), + helpMenu(commands) ]; return menu; diff --git a/app/menus/menus/window.js b/app/menus/menus/window.js index 33e6e38774d2..42eba8f2a05e 100644 --- a/app/menus/menus/window.js +++ b/app/menus/menus/window.js @@ -7,12 +7,12 @@ module.exports = function (commands) { accelerator: commands['window:minimize'] }, { + type: 'separator' + }, + { // It's the same thing as clicking the green traffc-light on macOS role: 'zoom', accelerator: commands['window:zoom'] }, - { - type: 'separator' - }, { label: 'Select Tab', submenu: [