🏡 index : quine-global/hyper.git

const fs = require('fs');
const notify = require('./notify');
const {_import, getDefaultConfig} = require('./config/import');
const _openConfig = require('./config/open');
const win = require('./config/windows');
const {cfgPath, cfgDir} = require('./config/paths');
const {getColorMap} = require('./utils/colors');

const watchers = [];
let cfg = {};
let _watcher;

const _watch = function() {
  if (_watcher) {
    return _watcher;
  }

  const onChange = () => {
    // Need to wait 100ms to ensure that write is complete
    setTimeout(() => {
      cfg = _import();
      notify('Configuration updated', 'Hyper configuration reloaded!');
      watchers.forEach(fn => fn());
      checkDeprecatedConfig();
    }, 100);
  };

  // Windows
  if (process.platform === 'win32') {
    // watch for changes on config every 2s on Windows
    // https://github.com/zeit/hyper/pull/1772
    _watcher = fs.watchFile(cfgPath, {interval: 2000}, (curr, prev) => {
      if (curr.mtime === 0) {
        //eslint-disable-next-line no-console
        console.error('error watching config');
      } else if (curr.mtime !== prev.mtime) {
        onChange();
      }
    });
    return;
  }
  // macOS/Linux
  setWatcher();
  function setWatcher() {
    try {
      _watcher = fs.watch(cfgPath, eventType => {
        if (eventType === 'rename') {
          _watcher.close();
          // Ensure that new file has been written
          setTimeout(() => setWatcher(), 500);
        }
      });
    } catch (e) {
      //eslint-disable-next-line no-console
      console.error('Failed to watch config file:', cfgPath, e);
      return;
    }
    _watcher.on('change', onChange);
    _watcher.on('error', error => {
      //eslint-disable-next-line no-console
      console.error('error watching config', error);
    });
  }
};

exports.subscribe = fn => {
  watchers.push(fn);
  return () => {
    watchers.splice(watchers.indexOf(fn), 1);
  };
};

exports.getConfigDir = () => {
  // expose config directory to load plugin from the right place
  return cfgDir;
};

exports.getConfig = () => {
  return cfg.config;
};

exports.openConfig = () => {
  return _openConfig();
};

exports.getPlugins = () => {
  return {
    plugins: cfg.plugins,
    localPlugins: cfg.localPlugins
  };
};

exports.getKeymaps = () => {
  return cfg.keymaps;
};

exports.setup = () => {
  cfg = _import();
  _watch();
  checkDeprecatedConfig();
};

exports.getWin = win.get;
exports.winRecord = win.recordState;
exports.windowDefaults = win.defaults;

const getDeprecatedCSS = function(config) {
  const deprecated = [];
  const deprecatedCSS = ['x-screen', 'x-row', 'cursor-node', '::selection'];
  deprecatedCSS.forEach(css => {
    if ((config.css && config.css.indexOf(css) !== -1) || (config.termCSS && config.termCSS.indexOf(css) !== -1)) {
      deprecated.push(css);
    }
  });
  return deprecated;
};
exports.getDeprecatedCSS = getDeprecatedCSS;

const checkDeprecatedConfig = function() {
  if (!cfg.config) {
    return;
  }
  const deprecated = getDeprecatedCSS(cfg.config);
  if (deprecated.length === 0) {
    return;
  }
  const deprecatedStr = deprecated.join(', ');
  notify('Configuration warning', `Your configuration uses some deprecated CSS classes (${deprecatedStr})`);
};

exports.fixConfigDefaults = decoratedConfig => {
  const defaultConfig = getDefaultConfig().config;
  decoratedConfig.colors = getColorMap(decoratedConfig.colors) || {};
  // We must have default colors for xterm css.
  decoratedConfig.colors = Object.assign({}, defaultConfig.colors, decoratedConfig.colors);
  return decoratedConfig;
};

exports.htermConfigTranslate = config => {
  const cssReplacements = {
    'x-screen x-row([ {.[])': '.xterm-rows > div$1',
    '.cursor-node([ {.[])': '.terminal-cursor$1',
    '::selection([ {.[])': '.terminal .xterm-selection div$1',
    'x-screen a([ {.[])': '.terminal a$1',
    'x-row a([ {.[])': '.terminal a$1'
  };
  Object.keys(cssReplacements).forEach(pattern => {
    const searchvalue = new RegExp(pattern, 'g');
    const newvalue = cssReplacements[pattern];
    config.css = config.css && config.css.replace(searchvalue, newvalue);
    config.termCSS = config.termCSS && config.termCSS.replace(searchvalue, newvalue);
  });
  return config;
};