Last active
August 29, 2015 14:10
-
-
Save muppetjones/868e9a292e533410f866 to your computer and use it in GitHub Desktop.
Slate js Rotating App Focus
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// slate_rotateApp.js | |
// Stephen J. Bush | |
// This snippet for slate js allows switching between a group of apps with a single keystroke. | |
// FIXED: Binding failed if an app in the list is not open. | |
// FIXED: Window object undefined for some apps or if window minimized. | |
// UPDATE: [12.05.14] Rotate now returns to the last used app in the group before rotating. | |
// NOTE: This only works when using the key binding as the 'windowFocused' event does not reliably trigger. | |
// TODO: Rotate between open windows for each app. | |
/* | |
* App lookup hash and list | |
* | |
* User must define appHash -- assign programs to groups | |
* > "group name": ["programs in group"] | |
* AppList both updates appHash AND creates a reverse lookup of appHash | |
* > expects a hash in the format described above | |
* > restructures appHash to add additional info for app rotation function | |
*/ | |
var appHash = { | |
'browser': ['Firefox', 'Google Chrome'], | |
'editor': ['Eclipse', 'TextWrangler', 'RStudio', 'texmaker'], | |
'office': ['Microsoft Word', 'Microsoft PowerPoint', 'Microsoft Excel'], | |
'terminal': ['iTerm', 'Terminal'], | |
}; | |
var appList = (function(hash) { | |
var list = {}; | |
for (var group in hash) | |
{ | |
alist = hash[group]; | |
// restructure the app hash | |
// -- put app list into a 'list' element | |
// -- create an undef_count variable to handle when the window object is undefined | |
// -- create a last_used element, default to first element | |
hash[group] = {'list': alist}; | |
hash[group]['undef_count'] = 0; | |
hash[group]['last_used'] = alist['0']; | |
// create the reverse lookup | |
for (var i in alist) | |
{ | |
list[alist[i]] = group; | |
} | |
} | |
return list; | |
})(appHash); | |
/* | |
* Generic Rotating App Focus | |
* Arguments | |
* win (window object) slate-generated; passed from binding | |
* appList (array of strings) list of app names to rotate between | |
*/ | |
var rotateFocus2 = function(win, group) | |
{ | |
// required for some apps (e.g., texmaker) | |
// unknown why, but some apps will pass an undefined window object | |
// - in case one of the apps in the group is one such window, | |
// we have an 'undef_count' to prevent getting stuck on that app | |
if (! win) | |
{ | |
win = slate.window(); | |
++appHash[group]['undef_count']; | |
} | |
// Get app name and index within list | |
// NOTE: an undefined window will have appIndex == -1 | |
var appName = win.app().name(); | |
var appList = appHash[group]['list']; | |
var appIndex = appList.indexOf(appName); | |
var nextIndex; | |
// If the current app is NOT a part of this group AND we're not on an undefined window | |
// Then we want to go to the last used app from the group | |
if (appIndex == -1 && appHash[group]['undef_count'] < 1) | |
{ | |
// if not already focused on one of these groups, use last focused | |
nextIndex = appList.indexOf(appHash[group]['last_used']); | |
} | |
// Otherwise, we want to go to the next app | |
// (This also means we did NOT have an undefined window, so reset the count | |
else | |
{ | |
// Focus on next app within list (or first) | |
nextIndex = (1 + appIndex) % appList.length; | |
appHash[group]['undef_count'] = 0; | |
} | |
// Finally, we know which app should be next, so switch | |
var success = win.doOperation(slate.operation("focus", {"app": appList[nextIndex]})); | |
// Unfortunately, if the app is not open, it will fail. | |
// If this happens, just try the next app in the list until we've tried 'em all. | |
var n = 0; | |
while (! success) | |
{ | |
if (n++ >= appList.length) | |
{ | |
break; | |
} | |
nextIndex = (1 + nextIndex) % appList.length; | |
success = win.doOperation(slate.operation("focus", {"app": appList[nextIndex]})); | |
} | |
// If we made it to a new window, mark it as the last used | |
if (success) | |
{ | |
appHash[group]['last_used'] = appList[nextIndex]; | |
} | |
return success; | |
}; | |
/* | |
* Group functions for app rotation | |
*/ | |
var rotateEditor = function(win) { | |
rotateFocus(win, 'editor'); | |
} | |
var rotateTerminal = function(win) { | |
rotateFocus(win, 'terminal'); | |
} | |
var rotateBrowser = function(win) { | |
rotateFocus(win, 'browser'); | |
} | |
var rotateOffice = function(win) { | |
rotateFocus(win, 'office'); | |
} | |
////////////////////////// | |
// Binding Examples | |
var hyper_keystroke = ":ctrl,shift,alt,cmd"; | |
slate.bind("b" + hyper_keystroke, rotateBrowser); | |
slate.bind("e" + hyper_keystroke, rotateEditor); | |
slate.bind("o" + hyper_keystroke, rotateOffice); | |
slate.bind("t" + hyper_keystroke, rotateTerminal); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment