UNPKG

i3-cycle-focus

Version:

Simulates an alt-tab operation for the i3 window manager. Shifts the mouse cursor position to the center of focus. Cycles visible windows only.

197 lines (188 loc) 4.9 kB
/** * @author Justin Collier <jpcxme@gmail.com> * @license MIT * @see {@link http://github.com/jpcx/i3-cycle-focus|GitHub} */ 'use strict' /** * Searches file structure of build/templates folder and returns paths and template strings. * * @private * @param {Object} fs - I/O module. * @param {string} templatesLoc - Local folder location of templates. * @returns {Object} Mapping of paths and template strings. */ const loadTemplates = (fs, templatesLoc) => { const mappings = {} /** * Recursively searches directories and populates mappings object. * * @private * @param {string} path - Current path. */ const recurse = path => { fs.readdirSync( path ).forEach(child => { const childPath = path + '/' + child if (fs.statSync(process.cwd() + '/' + childPath).isDirectory()) { recurse(childPath) } else { const parsedPath = childPath.slice(templatesLoc.length + 1, -1) mappings[parsedPath] = fs.readFileSync( process.cwd() + '/' + childPath, 'utf8' ) } }) } recurse(templatesLoc) return mappings } /** * Replaces alias markers with alias values. * * @private * @param {string} string - Search string. * @param {Object} aliases - Mappings of alias names and values. * @returns {Object} Formatted string. */ const replaceAliases = (string, aliases) => string.split( /___{alias:([\s\S]*?)}___/g ).reduce( (newString, chunk, i) => { if (i % 2 === 0) { return newString + chunk } else { let data = aliases[chunk.split('___')[0]] const flags = chunk.split('___').filter((x, i) => i !== 0) for (let f of flags) { if (f === 'JSON') { data = JSON.stringify(data, null, 2) } } return newString + data } }, '' ) /** * Replaces match markers with retrieved content. * * @private * @param {string} string - Search string. * @param {Object} fs - I/O module. * @returns {string} Formatted string. */ const replaceMatches = (string, fs) => string.split( /___{file:([\s\S]*?)___split-?([gimuy]*?):([\s\S]*?)}___/g ).reduce( (opData, chunk, i) => { if (i % 4 === 0) { opData.newString += chunk return opData } else if ((i - 1) % 4 === 0) { opData.path = chunk return opData } else if ((i - 2) % 4 === 0) { opData.flags = chunk return opData } else if ((i - 3) % 4 === 0) { opData.newString += fs.readFileSync( process.cwd() + '/' + opData.path, 'utf8' ).split( RegExp(chunk, opData.flags) )[1] return { ...{ newString: opData.newString } } } }, { newString: '' } ).newString /** * Replaces marked sections within strings based on the type of marker. * * @private * @param {Object} fs - I/O module. * @param {Object} mappings - Mappings of file locations and template strings. * @param {Object} aliases - Mappings of alias names and values. * @returns {Object} Formatted templates. */ const replaceMarkers = (fs, mappings, aliases) => Object.entries( mappings ).reduce( (newMaps, entry) => { let formatted = entry[1] formatted = replaceAliases(formatted, aliases) formatted = replaceMatches(formatted, fs) if (entry[0].match(/.json$/gm) !== null) { formatted = JSON.stringify( JSON.parse(formatted), null, 2 ) + '\n' } newMaps[entry[0]] = formatted return newMaps }, {} ) /** * Writes template files based on templates locations and aliases. * * @private * @param {Object} info - Local folder location of templates and mappings of alias names and values. */ const buildFromTemplates = info => { const fs = require('fs') Object.entries( replaceMarkers( fs, loadTemplates(fs, info.templatesLoc), info.aliases ) ).forEach( entry => { fs.writeFileSync(process.cwd() + '/' + entry[0], entry[1]) } ) } /** * Converts config.json to relevant mappings. * * @private * @param {string} config - Config.json for repository information. * @retruns {Object} Local folder location of templates and mappings of alias names and values. */ const parseConfig = config => { const info = {} info.templatesLoc = config.templatesLoc info.aliases = {} Object.entries( config.packages ).forEach( packEntry => { Object.entries( packEntry[1] ).forEach( infoEntry => { info.aliases[packEntry[0] + '/' + infoEntry[0]] = infoEntry[1] } ) } ) if (config.hasOwnProperty('customAliases')) { Object.entries( config.customAliases ).forEach( aliasEntry => { info.aliases[aliasEntry[0]] = aliasEntry[1] } ) } return info } buildFromTemplates( parseConfig( require(process.cwd() + '/' + process.argv[2]) ) )