Last active
March 7, 2017 21:36
-
-
Save davidkuster/de9f745679a4b8f167ad to your computer and use it in GitHub Desktop.
Slate JS config
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 javascript config | |
// global configs | |
slate.log("-- setting up global configs --"); | |
slate.configAll({ | |
defaultToCurrentScreen: false, | |
orderScreensLeftToRight: true, | |
checkDefaultsOnLoad: true, | |
nudgePercentOf: "screenSize", | |
windowHintsBackgroundColor : "50;53;58;1.0", | |
windowHintsFontColor: "255.0;255.0;255.0;1.0", // Red;Green;Blue;Alpha - R/G/B are numbers between 0.0 and 255.0 and Alpha is a number between 0.0 and 1.0 | |
windowHintsShowIcons: false, | |
windowHintsIgnoreHiddenWindows: false, | |
windowHintsSpread: false, | |
windowHintsDuration: 5 | |
}); | |
// screen references | |
var leftScreenRef = "0"; | |
var middleScreenRef = "1"; | |
var rightScreenRef = "2"; | |
// slate operations | |
slate.log("-- setting up operations --"); | |
// generic operations | |
var hint = slate.operation("hint", { | |
"characters": "QWERTYUIOPASDFGHJKLZXCVBNM" | |
}); | |
var nudgeDownAndRight = slate.operation("nudge", { | |
"x" : "+2%", | |
"y" : "+2%" | |
}); | |
// 0,0 for x,y = top left corner of screen. x = width, y = height. | |
// all offsets need to be % values between 0-1: "0", "0.1", "0.85", "1", etc | |
// (width & height offsets should never be 0) | |
var buildOpParameters = function(screen, xPlacementOffset, yPlacementOffset, widthOffset, heightOffset) { | |
return { | |
"screen": screen, | |
"x" : "screenOriginX + (screenSizeX * " + xPlacementOffset + ")", | |
"y" : "screenOriginY + (screenSizeY * " + yPlacementOffset + ")", | |
"width" : "screenSizeX * " + widthOffset, | |
"height" : "screenSizeY * " + heightOffset | |
}; | |
}; | |
// operation to maximize a window to full screen | |
var fullScreenOp = function(screen) { | |
return slate.operation("move", buildOpParameters(screen, "0", "0", "1", "1")); | |
}; | |
// operation to center a window on the screen, at 80% width and 80% height | |
var centerScreenOp = function(screen) { | |
return slate.operation("move", buildOpParameters(screen, "0.1", "0.1", "0.8", "0.8")); | |
}; | |
// operation to place a window in the top left corner of the given screen | |
// (currently only used in conjunction with the stackMultipleWindows function) | |
var topLeftScreenOp = function(screen) { | |
return slate.operation("corner", { | |
"screen": screen, | |
"direction": "top-left" | |
}); | |
}; | |
// operation to place a window 30% below the upper left corner, sized to 80% width, 40% height | |
// (currently only used with the stackMultipleWindows function) | |
var customSizedScreenOp = function(screen) { | |
return slate.operation("move", buildOpParameters(screen, "0", "0.3", "0.8", "0.4")); | |
}; | |
// operation to place a window to 85% width, full height, right-justified on the given screen | |
// (currently only used for the triple monitor layout) | |
var right85ScreenOp = function(screen) { | |
return slate.operation("move", buildOpParameters(screen, "0.15", "0", "0.85", "1")); | |
}; | |
// operation to place a window to 85% width, full height, left-justified on the given screen | |
var left85ScreenOp = function(screen) { | |
return slate.operation("move", buildOpParameters(screen, "0", "0", "0.85", "1")); | |
}; | |
// operation to place a window to just under 60% height, full width, top-justified on the given screen | |
var top60ScreenOp = function(screen) { | |
return slate.operation("move", buildOpParameters(screen, "0", "0", "1", "0.549")); | |
// back height off from 0.55 just a bit for some visual separation | |
}; | |
// operation to place a window 100% width, 55% height on the given screen | |
// (intended for use on vertically-oriented monitors) | |
var fullWidthCenterHeightScreenOp = function(screen) { | |
return slate.operation("move", buildOpParameters(screen, "0", "0.225", "1", "0.55")); | |
}; | |
// operation to place a window 100% width, 45% height, bottom-justified | |
var bottom45ScreenOp = function(screen) { | |
return slate.operation("move", buildOpParameters(screen, "0", "0.55", "1", "0.45")); | |
}; | |
// operation to place a window in the top left corner of the given screen, 60% width, 45% height | |
var top55Left60CornerScreenOp = function(screen) { | |
return slate.operation("move", buildOpParameters(screen, "0", "0", "0.6", "0.55")); | |
}; | |
// operation to place a window in the top right corner of the given screen, 60% width, 45% height | |
var top55Right60CornerScreenOp = function(screen) { | |
return slate.operation("move", buildOpParameters(screen, "0.4", "0", "0.6", "0.55")); | |
}; | |
// operation to place a window in the bottom left corner of the given screen, 60% width, 45% height | |
var bottom45Left60CornerScreenOp = function(screen) { | |
return slate.operation("move", buildOpParameters(screen, "0", "0.55", "0.6", "0.45")); | |
}; | |
// operation to place a window in the bottom right corner of the given screen, 60% width, 45% height | |
var bottom45Right60CornerScreenOp = function(screen) { | |
return slate.operation("move", buildOpParameters(screen, "0.4", "0.55", "0.6", "0.45")); | |
}; | |
// operation to place a window in the bottom left corner of the given screen, 50% width, 50% height | |
var bottomLeftCornerScreenOp = function(screen) { | |
return slate.operation("move", buildOpParameters(screen, "0", "0.5", "0.5", "0.5")); | |
}; | |
// operation to place a window in the bottom right corner of the given screen, 50% width, 50% height | |
var bottomRightCornerScreenOp = function(screen) { | |
return slate.operation("move", buildOpParameters(screen, "0.5", "0.5", "0.5", "0.5")); | |
}; | |
// operation to place a window in the top left corner of the given screen, 50% width, 50% height | |
var topLeftCornerScreenOp = function(screen) { | |
return slate.operation("move", buildOpParameters(screen, "0", "0", "0.5", "0.5")); | |
}; | |
// operation to place a window in the top right corner of the given screen, 50% width, 50% height | |
var topRightCornerScreenOp = function(screen) { | |
return slate.operation("move", buildOpParameters(screen, "0.5", "0", "0.5", "0.5")); | |
}; | |
// operation to place a window on the right half of the screen, full height | |
var rightHalfScreenOp = function(screen) { | |
return slate.operation("move", buildOpParameters(screen, "0.5", "0", "0.5", "100")); | |
}; | |
// operation to place a window on the left half of the screen, full height | |
var leftHalfScreenOp = function(screen) { | |
return slate.operation("move", buildOpParameters(screen, "0", "0", "0.5", "100")); | |
}; | |
// utility method to focus on the given app | |
// (currently only used in conjunction with window-specific focus bindings below) | |
var focusAppOp = function(appName) { | |
var focus = slate.operation("focus", { | |
"app": appName | |
}); | |
return focus; | |
}; | |
// utility method to focus on the given window title, once an app has received focus | |
// (currently only used in conjunction with window-specific focus bindings below) | |
// needs to be cleaned up - with the exclusion of /shelved/ & /reference/ this is too specific to sublime... | |
var focusWinOp = function(win, titleMatcher) { | |
win.app().eachWindow(function(w) { | |
var title = w.title(); | |
if (title !== undefined && title.match(titleMatcher) && (! title.match(/shelved/)) && (! title.match(/reference/))) { | |
w.focus(); | |
return; | |
} | |
}); | |
}; | |
/** | |
* Pseudo-operation function. | |
* | |
* @param win - Slate Window object. See https://github.com/jigish/slate/wiki/Window-Object | |
* @param startPosOperation - Slate Operation function. See https://github.com/jigish/slate/wiki/Operations#move | |
*/ | |
var stackMultipleWindows = function(win, startPosOperation) { | |
var winNum = 0; | |
win.app().eachWindow(function(w) { | |
w.doOperation(startPosOperation); | |
for (i=0; i < winNum; i++) { | |
w.doOperation(nudgeDownAndRight); | |
} | |
w.focus(); | |
winNum++; | |
}); | |
}; | |
// app-specific operations | |
var sublimeTextOp = function(win) { | |
var title = win.title(); | |
// put shelved code in the right monitor | |
if (title !== undefined && title.match(/shelved/)) { | |
win.move({ | |
"screen": rightScreenRef, | |
"x": "screenOriginX + 100", | |
"y": "screenOriginY + 60", | |
"width": 1200, | |
"height": 800 | |
}); | |
} | |
else if (title !== undefined && title.match(/reference/)) { | |
win.doOperation(bottom45ScreenOp(leftScreenRef)); | |
} | |
else if (title !== undefined && title.match(/notes/)) { | |
//win.doOperation(fullWidthCenterHeightScreenOp(rightScreenRef)); | |
win.doOperation(fullWidthCenterHeightScreenOp(rightScreenRef)); | |
} | |
else if (title !== undefined && title.match(/Public API Design/)) { | |
win.doOperation(bottom45ScreenOp(middleScreenRef)); | |
} | |
else { | |
// default to full screen in the left monitor | |
win.doOperation(fullScreenOp(middleScreenRef)); | |
} | |
}; | |
var commandCenterOp = function(win) { | |
win.move({ | |
"screen": rightScreenRef, | |
"x": "screenOriginX", | |
"y": "screenOriginY + 181", | |
"width": "1080", | |
"height": "550" | |
}); | |
}; | |
var mailOp = function(win) { | |
win.move(buildOpParameters(middleScreenRef, "0.85", "0", "0.85", "1")); | |
}; | |
var slackOp = function(win) { | |
win.move(buildOpParameters(leftScreenRef, "0", "0.20", "0.6", "0.80")); | |
}; | |
var pomelloOp = function(win) { | |
// function(screen, xPlacementOffset, yPlacementOffset, widthOffset, heightOffset) { | |
win.move(buildOpParameters(rightScreenRef, "0.5", "0", "0.4", "0.1")); | |
}; | |
var finderOp = function(win) { | |
var title = win.title(); | |
var winNum = 0; | |
win.app().eachWindow(function(w) { | |
if (winNum === 0) { | |
w.doOperation(topRightCornerScreenOp(rightScreenRef)); | |
} | |
else if (winNum == 1) { | |
w.doOperation(topLeftCornerScreenOp(rightScreenRef)); | |
} | |
else { | |
w.doOperation(bottomRightCornerScreenOp(leftScreenRef)); | |
} | |
winNum++; | |
}); | |
}; | |
// layouts | |
slate.log("-- setting up layouts --"); | |
var tripleMonitorLayout = slate.layout("triple_monitor", { | |
/*"_after_": { | |
"operations" : [ slate.operation("focus", { | |
"app": "Safari" | |
})], | |
"ignore-fail": true | |
},*/ | |
// idea was to focus Safari only on desktop 1, but this will actually switch to desktop 1 | |
// regardless of which desktop the layout is run on. which presents an interesting idea... | |
// it may be possible to write a function which applies the layout for desktop 1, then | |
// focuses an app on desktop 2, does the layout there, then repeat for desktops 3 & 4... | |
// desktop 1 | |
"Mail": { | |
"operations": [ function(win) { | |
mailOp(win); | |
}], | |
"ignore-fail": true, | |
"repeat": true | |
}, | |
"Calendar": { | |
"operations": [ bottomRightCornerScreenOp(rightScreenRef) ] | |
}, | |
"Safari": { | |
"operations": [ | |
centerScreenOp(middleScreenRef), | |
leftHalfScreenOp(middleScreenRef), | |
rightHalfScreenOp(middleScreenRef) | |
], | |
"ignore-fail": true, | |
"main-first": false | |
}, | |
"Messages": { | |
"operations": [ top55Left60CornerScreenOp(leftScreenRef) ] | |
}, | |
"Slack": { | |
"operations": [ function(win) { | |
slackOp(win); | |
}], | |
"ignore-fail": true | |
}, | |
"Pomello": { | |
"operations": [ function(win) { | |
pomelloOp(win); | |
}], | |
"ignore-fail": true | |
}, | |
// desktop 2 | |
"Firefox": { | |
//"operations": [ fullWidthCenterHeightScreenOp(rightScreenRef) ], | |
"operations": [ leftHalfScreenOp(rightScreenRef) ], | |
"ignore-fail": true, | |
"main-first": true | |
}, | |
"iTerm": { | |
"operations": [ rightHalfScreenOp(leftScreenRef), bottomRightCornerScreenOp(leftScreenRef), topRightCornerScreenOp(leftScreenRef) ], | |
"ignore-fail": true, | |
"repeat": true | |
}, | |
"Terminal": { | |
"operations": [ topLeftCornerScreenOp(leftScreenRef) ] | |
}, | |
"Kitematic (Beta)": { | |
"operations": [ bottom45ScreenOp(middleScreenRef) ] | |
}, | |
"Sublime Text 2": { | |
// set specific locations for sublime windows | |
"operations": [ function(win) { | |
sublimeTextOp(win); | |
}], | |
"ignore-fail": true, | |
"repeat": true | |
}, | |
"IntelliJ IDEA": { | |
"operations": [ fullScreenOp(middleScreenRef) ], | |
"repeat": true | |
}, | |
"Dash": { | |
//"operations": [ fullWidthCenterHeightScreenOp(rightScreenRef) ] | |
"operations": [ rightHalfScreenOp(rightScreenRef) ] | |
}, | |
"GrailsCommandCenter": { | |
// put GrailsCommandCenter in a custom spot, so not using a reusable operation | |
"operations": [ function(win) { | |
commandCenterOp(win); | |
}], | |
"ignore-fail": true | |
}, | |
// desktop 3 | |
"Aqua Data Studio": { | |
"operations": [ left85ScreenOp(leftScreenRef) ] | |
}, | |
"Oracle SQL Developer": { | |
"operations": [ left85ScreenOp(leftScreenRef) ] | |
}, | |
"VMware Fusion": { | |
"operations": [ bottom45ScreenOp(rightScreenRef) ], | |
"repeat": true | |
}, | |
"Google Chrome": { | |
"operations": [ bottom45ScreenOp(rightScreenRef), top60ScreenOp(rightScreenRef), centerScreenOp(middleScreenRef) ], | |
"ignore-fail": true | |
}, | |
// desktop 4 | |
"Evernote": { | |
"operations": [ fullWidthCenterHeightScreenOp(rightScreenRef) ] | |
}, | |
"Chromium": { | |
"operations": [ centerScreenOp(middleScreenRef), rightHalfScreenOp(rightScreenRef) ], | |
"repeat": true | |
}, | |
"PowerPoint": { | |
"operations": [ function(win) { | |
stackMultipleWindows(win, topLeftScreenOp(middleScreenRef)); | |
}], | |
"ignore-fail": true | |
}, | |
"iTunes": { | |
"operations": [ centerScreenOp(middleScreenRef) ] | |
}, | |
"Numbers": { | |
"operations": [ fullScreenOp(leftScreenRef) ] | |
}, | |
"Photos": { | |
"operations": [ bottom45ScreenOp(rightScreenRef) ] | |
}, | |
// desktop 5 | |
"OmniGraffle 6": { | |
// put the first window in the upper left corner of the middle screen, | |
// then nudge down any additional windows | |
"operations": [ function(win) { | |
stackMultipleWindows(win, topLeftScreenOp(middleScreenRef)); | |
}], | |
"ignore-fail": true | |
}, | |
"Notability": { | |
"operations": [ top60ScreenOp(rightScreenRef) ], | |
"ignore-fail": true | |
}, | |
// multiple desktops | |
"Finder": { | |
"operations": [ function(win) { | |
finderOp(win); | |
}], | |
"ignore-fail": true | |
}, | |
"TextEdit": { | |
"operations": [ bottom45Left60CornerScreenOp(leftScreenRef) ] | |
}, | |
"Preview": { | |
// put the first window in the upper left corner of the middle screen, | |
// then nudge down any additional windows | |
"operations": [ function(win) { | |
stackMultipleWindows(win, customSizedScreenOp(leftScreenRef)); | |
}], | |
"ignore-fail": true | |
} | |
}); | |
// key bindings | |
slate.log("-- setting up bindings --"); | |
// bind the layout to super+tilde key combo | |
slate.bind("`:alt", slate.operation("layout", { "name": tripleMonitorLayout })); | |
// bind super + escape to window hints for quickly changing focus (as opposed to alt+tab) | |
//slate.bind("esc:alt", hint); | |
slate.bind("space:alt", hint); | |
// use super + pseudo-arrow key approach to move windows around (across all 3 screens) | |
slate.bind("i:alt", top60ScreenOp(middleScreenRef)); | |
slate.bind("l:alt", fullWidthCenterHeightScreenOp(rightScreenRef)); | |
slate.bind("o:alt", top60ScreenOp(rightScreenRef)); | |
slate.bind("u:alt", top60ScreenOp(leftScreenRef)); | |
slate.bind(",:alt", bottom45ScreenOp(middleScreenRef)); | |
slate.bind("m:alt", bottom45ScreenOp(leftScreenRef)); | |
slate.bind(".:alt", bottom45ScreenOp(rightScreenRef)); | |
slate.bind("k:alt", centerScreenOp(middleScreenRef)); | |
slate.bind("j:alt", fullWidthCenterHeightScreenOp(leftScreenRef)); | |
// use super + ctrl + pseudo-arrow key to move windows around on the current screen | |
slate.bind("i:alt,ctrl", function(win) { fullScreenOp(win.screen().id()).run(); }); | |
slate.bind("l:alt,ctrl", function(win) { rightHalfScreenOp(win.screen().id()).run(); }); | |
slate.bind("o:alt,ctrl", function(win) { topRightCornerScreenOp(win.screen().id()).run(); }); | |
slate.bind("u:alt,ctrl", function(win) { topLeftCornerScreenOp(win.screen().id()).run(); }); | |
slate.bind(",:alt,ctrl", function(win) { bottom45ScreenOp(win.screen().id()).run(); }); | |
slate.bind("m:alt,ctrl", function(win) { bottomLeftCornerScreenOp(win.screen().id()).run(); }); | |
slate.bind(".:alt,ctrl", function(win) { bottomRightCornerScreenOp(win.screen().id()).run(); }); | |
slate.bind("k:alt,ctrl", function(win) { centerScreenOp(win.screen().id()).run(); }); | |
slate.bind("j:alt,ctrl", function(win) { leftHalfScreenOp(win.screen().id()).run(); }); | |
// window-specific focus bindings (for commonly used windows) | |
// bind super+p to find Profile Service sublime window | |
slate.bind("p:alt", function(win) { | |
focusAppOp("Sublime Text 2").run(); | |
focusWinOp(win, /Profile Service/); | |
}); | |
// bind super+n to find Northstar (all projects) sublime window | |
slate.bind("n:alt", function(win) { | |
focusAppOp("Sublime Text 2").run(); | |
focusWinOp(win, /Northstar \(all projects\)/); | |
}); | |
// bind super+e to find IntelliJ (mnemonic: IDE - the "e") | |
slate.bind("e:alt", function(win) { | |
focusAppOp("IntelliJ IDEA").run(); | |
}); | |
// bind super+d to find Dash | |
slate.bind("d:alt", function(win) { | |
focusAppOp("Dash").run(); | |
}); | |
// the end | |
slate.log("-- slate.js finished load --"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment