Skip to content

Instantly share code, notes, and snippets.

@muppetjones
Last active August 29, 2015 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save muppetjones/868e9a292e533410f866 to your computer and use it in GitHub Desktop.
Save muppetjones/868e9a292e533410f866 to your computer and use it in GitHub Desktop.
Slate js Rotating App Focus
// 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