From 8243539e77cbf2ce4a64a7ab1736526f7a66b000 Mon Sep 17 00:00:00 2001 From: Florrie Date: Sun, 12 Nov 2017 11:21:21 -0400 Subject: Add --show-keybindings and make a string dynamic "(Press I for track info!)" now displays the appropriate keybinding, rather than always showing "I". Also made the keybinder handler function async; it now waits for its given commands to finish. This doesn't particularly change anything but it Makes Sense. --- src/keybinder.js | 80 ++++++++++++++++++++++++++++++++++++++++++-------------- src/play.js | 30 ++++++++++++++++++--- 2 files changed, 86 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/keybinder.js b/src/keybinder.js index 784484c..f8d68a4 100644 --- a/src/keybinder.js +++ b/src/keybinder.js @@ -1,20 +1,27 @@ const splitChars = str => str.split('').map(char => char.charCodeAt(0)) const simpleKeybindings = { - space: [0x20], - esc: [0x1b], escape: [0x1b], - up: [0x1b, ...splitChars('[A')], - down: [0x1b, ...splitChars('[B')], - right: [0x1b, ...splitChars('[C')], - left: [0x1b, ...splitChars('[D')], - shiftUp: [0x1b, ...splitChars('[1;2A')], - shiftDown: [0x1b, ...splitChars('[1;2B')], - shiftRight: [0x1b, ...splitChars('[1;2C')], - shiftLeft: [0x1b, ...splitChars('[1;2D')], - delete: [0x7f] + space: ['Space', [0x20]], + esc: ['Escape', [0x1b]], + escape: ['Escape', [0x1b]], + up: ['Up', [0x1b, ...splitChars('[A')]], + down: ['Down', [0x1b, ...splitChars('[B')]], + right: ['Right', [0x1b, ...splitChars('[C')]], + left: ['Left', [0x1b, ...splitChars('[D')]], + shiftUp: ['Shift+Up', [0x1b, ...splitChars('[1;2A')]], + shiftDown: ['Shift+Down', [0x1b, ...splitChars('[1;2B')]], + shiftRight: ['Shift+Right', [0x1b, ...splitChars('[1;2C')]], + shiftLeft: ['Shift+Left', [0x1b, ...splitChars('[1;2D')]], + delete: ['Backspace', [0x7f]], + backspace: ['Backspace', [0x7f]] } module.exports.compileKeybindings = function(bindings, commands) { + // The "commands" array is an optional argument - if not given, the resulting + // handler function will simply return the keybinding array for whichever + // matches the inputted keypress. Too bad this feature isn't used anywhere. + // Thanks, old me. + const handlers = bindings.map(binding => { const [ keys, command, ...args] = binding @@ -29,12 +36,13 @@ module.exports.compileKeybindings = function(bindings, commands) { if (typeof item === 'number') { return [item] } else if (simpleKeybindings.hasOwnProperty(item)) { - return simpleKeybindings[item] + return simpleKeybindings[item][1] } else if (typeof item === 'string' && item.length === 1) { return [item.charCodeAt(0)] } else { - // Error - console.warn('Invalid keybinding part', item, 'in keybinding', bindings) + console.warn( + 'Invalid keybinding part', item, 'in keybinding', bindings + ) failed = true return [] } @@ -46,19 +54,51 @@ module.exports.compileKeybindings = function(bindings, commands) { const buffer = Buffer.from(bufferParts) - return function(inputData) { + return async function(inputData) { if (buffer.equals(inputData)) { - commands[command](...args) - return true + if (commands) { + const result = await commands[command](...args) + return typeof result === 'undefined' ? true : result + } else { + return keybinding + } } } }).filter(Boolean) - return function(inputData) { + return async function(inputData) { for (const handler of handlers) { - if (handler(inputData)) { - break + const result = await handler(inputData) + if (typeof result !== 'undefined') { + return result } } } } + +module.exports.getComboForCommand = function(command, bindings) { + const binding = bindings.find(kb => kb[1] === command) + if (binding) { + return binding[0] + } else { + return null + } +} + +module.exports.stringifyCombo = function(combo) { + const stringifiedItems = combo.map(item => { + if (typeof item === 'string') { + if (item.length === 1) { + return item.toUpperCase() + } else if (simpleKeybindings.hasOwnProperty(item)) { + return simpleKeybindings[item][0] + } else { + return item + } + } else { + return JSON.stringify(item) + } + }) + + return stringifiedItems.join('+') +} diff --git a/src/play.js b/src/play.js index 2a5cbdd..ff9e76a 100755 --- a/src/play.js +++ b/src/play.js @@ -11,7 +11,6 @@ const commandExists = require('./command-exists') const startLoopPlay = require('./loop-play') const processArgv = require('./process-argv') const promisifyProcess = require('./promisify-process') -const { compileKeybindings } = require('./keybinder') const processSmartPlaylist = require('./smart-playlist') const { @@ -19,6 +18,10 @@ const { updatePlaylistFormat, collapseGrouplike, filterGrouplikeByProperty, isTrack } = require('./playlist-utils') +const { + compileKeybindings, getComboForCommand, stringifyCombo +} = require('./keybinder') + const readFile = promisify(fs.readFile) const writeFile = promisify(fs.writeFile) @@ -401,6 +404,20 @@ async function main(args) { '-list-tracks': util => util.alias('-list-all'), 'L': util => util.alias('-list-all'), + '-list-keybindings': function() { + console.log('Keybindings:') + + for (const [ combo, command, ...args ] of keybindings) { + console.log(`${stringifyCombo(combo)}: ${command}${ + args ? ' ' + args.join(' ') : ''}`) + } + + shouldPlay = false + }, + + '-show-keybindings': util => util.alias('-list-keybindings'), + '-keybindings': util => util.alias('-list-keybindings'), + '-play': function(util) { // --play (alias: -p) // Forces the playlist to actually play. @@ -625,6 +642,12 @@ async function main(args) { console.warn("If you're piping into http-music, this is normal.") } + const trackInfoCombo = stringifyCombo(getComboForCommand( + 'showTrackInfo', keybindings + )) + + const trackInfoString = `(Press ${trackInfoCombo} for track info!)` + const commands = { 'doNothing': function() {}, @@ -662,7 +685,7 @@ async function main(args) { 'skipBack': function() { clearConsoleLine() - console.log("Skipping backwards. (Press I for track info!") + console.log("Skipping backwards.", trackInfoString) playController.skipBack() }, @@ -670,8 +693,7 @@ async function main(args) { 'skipAhead': function() { clearConsoleLine() console.log( - "Skipping the track that's currently playing. " + - "(Press I for track info!)" + "Skipping the track that's currently playing.", trackInfoString ) playController.skip() -- cgit 1.3.0-6-gf8a5