diff --git a/app/scripts/comp/auto-type/auto-type-runner.js b/app/scripts/comp/auto-type/auto-type-runner.js index 33736854..06a60ece 100644 --- a/app/scripts/comp/auto-type/auto-type-runner.js +++ b/app/scripts/comp/auto-type/auto-type-runner.js @@ -128,7 +128,11 @@ AutoTypeRunner.prototype.tryParseCommand = function(op) { case 'clearfield': // {CLEARFIELD} op.type = 'group'; - op.value = [{ type: 'key', value: 'a', mod: { '^': true } }, { type: 'key', value: 'bs' }]; + op.value = [ + { type: 'key', value: 'end' }, + { type: 'key', value: 'home', mod: { '+': true } }, + { type: 'key', value: 'bs' } + ]; return true; case 'vkey': // {VKEY 10} {VKEY 0x1F} @@ -310,10 +314,14 @@ AutoTypeRunner.prototype.run = function(callback) { mod: {}, activeMod: {} }; - this.emitNext(this.ops); + this.emitNext(); }; -AutoTypeRunner.prototype.emitNext = function() { +AutoTypeRunner.prototype.emitNext = function(err) { + if (err) { + this.emitterState.callback(err); + return; + } this.resetEmitterMod(this.emitterState.mod); if (this.emitterState.opIx >= this.emitterState.ops.length) { var state = this.emitterState.stack.pop(); diff --git a/app/scripts/comp/auto-type/emitter-impl/auto-type-emitter-impl-darwin.js b/app/scripts/comp/auto-type/emitter-impl/auto-type-emitter-impl-darwin.js index 66d74b8e..8dc9984b 100644 --- a/app/scripts/comp/auto-type/emitter-impl/auto-type-emitter-impl-darwin.js +++ b/app/scripts/comp/auto-type/emitter-impl/auto-type-emitter-impl-darwin.js @@ -1,21 +1,77 @@ 'use strict'; +var Launcher = require('../../launcher'); + +var spawn = Launcher.req('child_process').spawn; + +var KeyMap = { + tab: 48, enter: 36, space: 49, + up: 126, down: 125, left: 123, right: 124, home: 115, end: 119, pgup: 116, pgdn: 121, + ins: 114, del: 117, bs: 51, esc: 53, + win: 55, rwin: 55, + f1: 122, f2: 120, f3: 99, f4: 118, f5: 96, f6: 97, f7: 98, f8: 100, f9: 101, + f10: 109, f11: 103, f12: 111, f13: 105, f14: 107, f15: 113, f16: 106, + add: 69, subtract: 78, multiply: 67, divide: 75, + n0: 82, n1: 83, n2: 84, n3: 85, n4: 86, + n5: 87, n6: 88, n7: 89, n8: 91, n9: 92 +}; + +var ModMap = { + '^': 'command', + '+': 'shift', + '%': 'option', + '^^': 'control' +}; + var AutoTypeEmitterImpl = function() { + this.mod = {}; }; AutoTypeEmitterImpl.prototype.setMod = function(mod, enabled) { + if (enabled) { + this.mod[mod] = true; + } else { + delete this.mod[mod]; + } }; AutoTypeEmitterImpl.prototype.text = function(text, callback) { - callback(); + if (!text) { + return callback(); + } + text = text.replace(/"/g, '\\"'); + this.runScript('keystroke "' + text + '"'+ this.modString(), callback); }; AutoTypeEmitterImpl.prototype.key = function(key, callback) { - callback(); + if (typeof key !== 'number') { + if (!KeyMap[key]) { + return callback('Bad key: ' + key); + } + key = KeyMap[key]; + } + this.runScript('key code ' + key + this.modString(), callback); }; AutoTypeEmitterImpl.prototype.waitComplete = function(callback) { callback(); }; +AutoTypeEmitterImpl.prototype.modString = function() { + var keys = Object.keys(this.mod); + if (!keys.length) { + return ''; + } + return ' using {' + keys.map(AutoTypeEmitterImpl.prototype.mapMod).join(', ') + '}'; +}; + +AutoTypeEmitterImpl.prototype.mapMod = function(mod) { + return ModMap[mod] + ' down'; +}; + +AutoTypeEmitterImpl.prototype.runScript = function(script, callback) { + var ps = spawn('osascript', ['-e', 'tell application "System Events" to ' + script]); + ps.on('close', function(code) { callback(code ? 'Exit code ' + code : undefined); }); +}; + module.exports = AutoTypeEmitterImpl;