-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implements Commands Key mapping #1876
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 _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 {cfgPath, cfgDir} = require('./config/paths'); | ||
|
||
const watchers = []; | ||
|
||
// watch for changes on config every 2s on windows | ||
// https://github.com/zeit/hyper/pull/1772 | ||
const watchCfg = process.platform === 'win32' ? {interval: 2000} : {}; | ||
let cfg = {}; | ||
|
||
function watch() { | ||
// 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) { | ||
const _watch = function () { | ||
gaze(cfgPath, watchCfg, 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 cfgDir; | ||
}; | ||
|
||
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; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm.. I don't like mutating stuff like this. But I think we do this in other places? Maybe that's a job for another PR. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah we do this alot... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm OK with this for now, but we should clean it all up |
||
} | ||
}; | ||
|
||
exports.setup = function () { | ||
cfg = _import(); | ||
_watch(); | ||
}; | ||
|
||
exports.getWin = win.get; | ||
exports.winRecord = win.recordState; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
const {writeFileSync, readFileSync} = require('fs'); | ||
const {defaultCfg, cfgPath} = require('./paths'); | ||
const _init = require('./init'); | ||
const _keymaps = 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 _defaultCfg = readFileSync(defaultCfg, 'utf8'); | ||
try { | ||
const _cfgPath = readFileSync(cfgPath, 'utf8'); | ||
return {userCfg: _cfgPath, defaultCfg: _defaultCfg}; | ||
} catch (err) { | ||
_write(cfgPath, defaultCfg); | ||
return {userCfg: {}, defaultCfg: _defaultCfg}; | ||
} | ||
} catch (err) { | ||
console.log(err); | ||
} | ||
}; | ||
|
||
const _import = function () { | ||
const cfg = _init(_importConf()); | ||
|
||
if (cfg) { | ||
cfg.keymaps = _keymaps.import(cfg.keymaps); | ||
} | ||
return cfg; | ||
}; | ||
|
||
module.exports = _import; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
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) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 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
}
} tested: _syntaxValidation(`
const c = 'a'
const b = 'd'
const c = '2'
`) notify: Error loading config: SyntaxError, see DevTools for more info Error loading config:
.hyper.js:4
const c = '2'
^^^
SyntaxError: Identifier 'c' has already been declared There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are you commenting as an error or a test? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. haha the comment was to update _syntaxValidation to the code i wrote in my comment, the blocks under is to show what it does There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done 👍 |
||
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) { | ||
return _extract(_syntaxValidation(cfg)); | ||
}; | ||
|
||
// init config | ||
const _init = function (cfg) { | ||
const script = _syntaxValidation(cfg.userCfg); | ||
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.defaultCfg); | ||
} | ||
return _cfg; | ||
} | ||
return _extractDefault(cfg.defaultCfg); | ||
}; | ||
|
||
module.exports = _init; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR changes from displaying a dialog to just a notification, correct?
I think it's nice with the dialog since you need to click "OK" to close it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I won't change it since using a dialog prevent hyper from opening.