Skip to content

Instantly share code, notes, and snippets.

@sennah911
Last active August 19, 2019 19:46
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save sennah911/10012494 to your computer and use it in GitHub Desktop.
Save sennah911/10012494 to your computer and use it in GitHub Desktop.
My config file for Phoenix (https://github.com/sdegutis/Phoenix)
// This is my attempt at making Phoenix as vim-like as possible. A good chunk
// of the code comes from https://gist.github.com/teetrinkers/9435065
//
// Command mode is activated with shift-ctrl-alt-command-space
// When we are in command mode, we can do things like:
// "h" to move current window to the left side of the screen
// "mh" to move the current window a nudge
// "mH" moves the window all the way to the left
// "34m" moves the window to the imaginary grid position 3:4
// "10mh" to move the current window 10 nudges
// "4gk" to grow the window 4 times from the top side
// "2389g" set the current window to span the imaginary grids located at 2:3 and 8:9
// "pq" set the window to preset q position/size (there are also "pA", "pd", "pC" and so on...)
// "sl" to shrink the window from the right side
// "." to repeat last command
// "q[a-z]" starts recording of temporary macros
// "q" then stops it
// "@[a-z]" plays back specified register
// "shift-2" executes the macro
// and lots lots more...
//
//
// Find me at https://github.com/sennah911
var mNone = [],
mCmd = ['cmd'],
mShift = ['shift'],
nudgePixels = 10,
largeGridNum = 10;
smallGridNum = 40;
menuHeight = 20;
padding = 0,
previousSizes = {};
// Remembers hotkey bindings.
var keys = [];
function bind(key, mods, callback) {
keys.push(api.bind(key, mods, callback));
}
// ############################################################################
// Modal activation - curtesy of teetrinkers
// ############################################################################
// Modal activator
// This hotkey enables/disables all other hotkey
api.bind('space', ['cmd','shift','alt','ctrl'], function() {
if (!active) {
enableKeys();
} else {
disableKeys();
}
});
api.bind('n', ['cmd','shift','alt','ctrl'], function() {
Window.focusedWindow().focusNextWindowOnSameScreen();
});
var buffer = "";
var lastBuffer = "";
var macros = {};
var isRecording = false;
var recordingToRegister = "";
var showingOverlay = false;
function interperateKeystroke(key) {
api.alert(key);
if (key != ".") {
buffer += key;
}
if (isRecording && key !== "q") {
macros[recordingToRegister] += key;
}
var command = parser.parse(buffer);
if(command.description in commands) {
lastBuffer = buffer;
commands[command.description](command.value);
}
}
function interperateKeystrokes(keys) {
for (var i = 0; i < keys.length; i++) {
var c = keys.charAt(i);
interperateKeystroke(c);
}
lastBuffer = keys;
}
bind('.', mNone, function() { interperateKeystrokes(lastBuffer) });
bind('3', mShift, function() {
showingOverlay = !showingOverlay;
api.overlay(showingOverlay, "/Users/hannesremahl/Desktop/grid.png");
});
bind('escape', mNone, function() {
if (buffer === "") {
disableKeys();
} else {
buffer = "";
}
});
// All of vim is not needed, but keeping it like this for now...
var opTest = new RegExp('\(\.\*\?\)\(S\|s\|f\|m\|c\|d\|y\|~\|g~\|gu\|gU\|!\|=\|gg\|g\\?\|>\|<\|zf\|g@\)$');
var motions = ['g', 'H', 'J', 'K', 'L', 'n', 'p[a-z\|A-Z]', '@@', '@[a-z]', 'q', 'q[a-z]', 'h', '%', 'l','0','\\$','\\^','g_','\\|','\(?:\'\|`\)\(\?\:[a-z]\)','\(?:F\|t\|T\)\(\?\:.\)',';',',','k','j','\\+','-','_','(?:[1-9]+[0-9]*|)G','e','E','w','W','b','B','ge','gE','\\(','\\)','\\{','\\}','\\]\\]','\\]\\[','\\[\\[','\\[\\]','(?:\\?|\\/)(?:\\S+)\\n'];
var motionTest = new RegExp('\(\.\*\?\)\(' + motions.join('\|') + '\)\$');
var positions = {
'a': [0, 0, 0.4, 1],
'A': [0, 0, 0.6, 1],
'd': [0.6, 0, 0.4, 1],
'D': [0.4, 0, 0.6, 1],
'x': [0, 0.6, 1, 0.4],
'X': [0, 0.4, 1, 0.6],
'w': [0, 0, 1, 0.4],
'W': [0, 0, 1, 0.6],
'q': [0, 0, 0.4, 0.6],
'Q': [0, 0, 0.6, 0.6],
'e': [0.6, 0, 0.4, 0.6],
'E': [0.4, 0, 0.6, 0.6],
'c': [0.6, 0.6, 0.4, 0.4],
'C': [0.4, 0.4, 0.6, 0.4],
'z': [0, 0.6, 0.4, 0.4],
'Z': [0, 0.6, 0.6, 0.4],
'f': [0, 0, 1, 1]
}
var commands = {
'{count}{motion}': function(commandValue) {
var count = commandValue[0];
var motion = commandValue[1];
if (motion === "g") {
var countStr = ('000000000' + count).substr(-4);
var thousands = parseInt(countStr.charAt(0));
var hundreds = parseInt(countStr.charAt(1));
var tens = parseInt(countStr.charAt(2));
var ones = parseInt(countStr.charAt(3));
Window.focusedWindow().toGrid(thousands/10, hundreds/10, (tens+1-thousands)/10, (ones+1-hundreds)/10);
buffer = "";
} else {
while(count--) {
commands['{motion}']([motion]);
}
}
},
'{motion}': function(commandValue) {
var motion = commandValue[0];
if (motion === "h") {
Window.focusedWindow().toGrid(0, 0, 0.5, 1);
buffer = "";
} else if (motion === "j") {
Window.focusedWindow().toGrid(0, 0.5, 1, 0.5);
buffer = "";
} else if (motion === "k") {
Window.focusedWindow().toGrid(0, 0, 1, 0.5);
buffer = "";
} else if (motion === "l") {
Window.focusedWindow().toGrid(0.5, 0, 0.5, 1);
buffer = "";
} else if (motion.charAt(0) === "q") {
if (!isRecording && motion.length == 2) {
api.alert("recording to register " + motion.charAt(1));
recordingToRegister = motion.charAt(1);
macros[recordingToRegister] = "";
isRecording = true;
buffer = "";
} else if (isRecording && motion.length == 1) {
api.alert("Stopped recording to register " + recordingToRegister);
isRecording = false;
api.alert(macros[recordingToRegister]);
recordingToRegister = "";
buffer = "";
}
} else if (motion.charAt(0) == "@") {
if (motion === "@@") {
//todo
} else {
buffer = "";
interperateKeystrokes(macros[motion.charAt(1)]);
}
} else if (motion.charAt(0) === "p") {
//move to position
var position = positions[motion.charAt(1)];
Window.focusedWindow().toGrid(position[0], position[1], position[2], position[3]);
buffer = "";
} else if (motion === "n") {
Window.focusedWindow().focusNextWindowOnSameScreen();
buffer = "";
}
},
'{count}{operator}': function(commandValue) {
count = commandValue[0];
operator = commandValue[1];
if (operator === "m") {
//Moving to grid
var countStr = ('000000000' + count).substr(-2);
var tens = parseInt(countStr.charAt(0));
var ones = parseInt(countStr.charAt(1));
var win = Window.focusedWindow();
var frame = win.frame();
var screenFrame = win.screen().frameWithoutDockOrMenu();
frame.x = tens * screenFrame.width / largeGridNum;
frame.y = ones * screenFrame.height / largeGridNum + menuHeight;
win.setFrame(frame);
buffer = "";
}
},
'{count}{operator}{motion}': function(commandValue) {
count = commandValue[0];
operator = commandValue[1];
motion = commandValue[2];
if (operator === "S") {
// Split with count %
count /= 100.0;
if (motion === "h") {
Window.focusedWindow().splitLeft(count);
} else if (motion === "j") {
Window.focusedWindow().splitDown(count);
} else if (motion === "k") {
Window.focusedWindow().splitUp(count);
} else if (motion === "l") {
Window.focusedWindow().splitRight(count);
}
buffer = "";
} else {
while(count--) {
commands['{operator}{motion}']([operator, motion]);
}
}
},
'{operator}{count}{motion}': function(commandValue) {
operator = commandValue[0];
count = commandValue[1];
motion = commandValue[2];
while(count--) {
commands['{operator}{motion}']([operator, motion]);
}
},
'{operator}{motion}': function(commandValue) {
operator = commandValue[0];
motion = commandValue[1];
if (operator === "m") {
if (motion === "h") {
Window.focusedWindow().nudgeLeft( 5 );
buffer = "";
} else if (motion === "j") {
Window.focusedWindow().nudgeDown( 5 );
buffer = "";
} else if (motion === "k") {
Window.focusedWindow().nudgeUp( 5 );
buffer = "";
} else if (motion === "l") {
Window.focusedWindow().nudgeRight( 5 );
buffer = "";
} else if (motion === "H") {
Window.focusedWindow().pushLeft();
buffer = "";
} else if (motion === "J") {
Window.focusedWindow().pushDown();
buffer = "";
} else if (motion === "K") {
Window.focusedWindow().pushUp();
buffer = "";
} else if (motion === "L") {
Window.focusedWindow().pushRight();
buffer = "";
}
} else if (operator === ">") {
if (motion === "h") {
Window.focusedWindow().growLeft();
buffer = "";
} else if (motion === "j") {
Window.focusedWindow().growBottom();
buffer = "";
} else if (motion === "k") {
Window.focusedWindow().growTop();
buffer = "";
} else if (motion === "l") {
Window.focusedWindow().growRight();
buffer = "";
}
} else if (operator === "<") {
if (motion === "h") {
Window.focusedWindow().shrinkLeft();
buffer = "";
} else if (motion === "j") {
Window.focusedWindow().shrinkBottom();
buffer = "";
} else if (motion === "k") {
Window.focusedWindow().shrinkTop();
buffer = "";
} else if (motion === "l") {
Window.focusedWindow().shrinkRight();
buffer = "";
}
} else if (operator === "f") {
if (motion === "h") {
Window.focusedWindow().focusWindowLeft();
buffer = "";
} else if (motion === "j") {
Window.focusedWindow().focusWindowDown();
buffer = "";
} else if (motion === "k") {
Window.focusedWindow().focusWindowUp();
buffer = "";
} else if (motion === "l") {
Window.focusedWindow().focusWindowRight();
buffer = "";
}
} else if (operator === "s") {
if (motion === "h") {
Window.focusedWindow().splitLeft(0.5);
buffer = "";
} else if (motion === "j") {
Window.focusedWindow().splitDown(0.5);
buffer = "";
} else if (motion === "k") {
Window.focusedWindow().splitUp(0.5);
buffer = "";
} else if (motion === "l") {
Window.focusedWindow().splitRight(0.5);
buffer = "";
}
}
}
};
// These keys end Phoenix mode. bind('escape', [], function() { disableKeys(); }); bind('return', [], function() { disableKeys(); });
// Bind all the keys
bind("`", mNone, function() { interperateKeystroke("`"); });
bind('1', mNone, function() { interperateKeystroke("1"); });
bind('2', mNone, function() { interperateKeystroke("2"); });
bind('3', mNone, function() { interperateKeystroke("3"); });
bind('4', mNone, function() { interperateKeystroke("4"); });
bind('5', mNone, function() { interperateKeystroke("5"); });
bind('6', mNone, function() { interperateKeystroke("6"); });
bind('7', mNone, function() { interperateKeystroke("7"); });
bind('8', mNone, function() { interperateKeystroke("8"); });
bind('9', mNone, function() { interperateKeystroke("9"); });
bind('0', mNone, function() { interperateKeystroke("0"); });
bind('-', mNone, function() { interperateKeystroke("-"); });
bind('=', mNone, function() { interperateKeystroke("="); });
bind('q', mNone, function() { interperateKeystroke("q"); });
bind('w', mNone, function() { interperateKeystroke("w"); });
bind('e', mNone, function() { interperateKeystroke("e"); });
bind('r', mNone, function() { interperateKeystroke("r"); });
bind('t', mNone, function() { interperateKeystroke("t"); });
bind('y', mNone, function() { interperateKeystroke("y"); });
bind('u', mNone, function() { interperateKeystroke("u"); });
bind('i', mNone, function() { interperateKeystroke("i"); });
bind('o', mNone, function() { interperateKeystroke("o"); });
bind('p', mNone, function() { interperateKeystroke("p"); });
bind('[', mNone, function() { interperateKeystroke("["); });
bind(']', mNone, function() { interperateKeystroke("]"); });
bind("\\", mNone, function() { interperateKeystroke("\\"); });
bind('a', mNone, function() { interperateKeystroke("a"); });
bind('s', mNone, function() { interperateKeystroke("s"); });
bind('d', mNone, function() { interperateKeystroke("d"); });
bind('f', mNone, function() { interperateKeystroke("f"); });
bind('g', mNone, function() { interperateKeystroke("g"); });
bind('h', mNone, function() { interperateKeystroke("h"); });
bind('j', mNone, function() { interperateKeystroke("j"); });
bind('k', mNone, function() { interperateKeystroke("k"); });
bind('l', mNone, function() { interperateKeystroke("l"); });
bind(';', mNone, function() { interperateKeystroke(";"); });
bind("'", mNone, function() { interperateKeystroke("'"); });
bind('z', mNone, function() { interperateKeystroke("z"); });
bind('x', mNone, function() { interperateKeystroke("x"); });
bind('c', mNone, function() { interperateKeystroke("c"); });
bind('v', mNone, function() { interperateKeystroke("v"); });
bind('b', mNone, function() { interperateKeystroke("b"); });
bind('n', mNone, function() { interperateKeystroke("n"); });
bind('m', mNone, function() { interperateKeystroke("m"); });
bind(',', mNone, function() { interperateKeystroke(","); });
bind('.', mNone, function() { interperateKeystroke("."); });
bind('/', mNone, function() { interperateKeystroke("/"); });
bind("`", mShift, function() { interperateKeystroke("~"); });
bind('1', mShift, function() { interperateKeystroke("!"); });
bind('2', mShift, function() { interperateKeystroke("@"); });
bind('3', mShift, function() { interperateKeystroke("#"); });
bind('4', mShift, function() { interperateKeystroke("$"); });
bind('5', mShift, function() { interperateKeystroke("%"); });
bind('6', mShift, function() { interperateKeystroke("^"); });
bind('7', mShift, function() { interperateKeystroke("&"); });
bind('8', mShift, function() { interperateKeystroke("*"); });
bind('9', mShift, function() { interperateKeystroke("("); });
bind('0', mShift, function() { interperateKeystroke(")"); });
bind('_', mShift, function() { interperateKeystroke("_"); });
bind('+', mShift, function() { interperateKeystroke("+"); });
bind('q', mShift, function() { interperateKeystroke("Q"); });
bind('w', mShift, function() { interperateKeystroke("W"); });
bind('e', mShift, function() { interperateKeystroke("E"); });
bind('r', mShift, function() { interperateKeystroke("R"); });
bind('t', mShift, function() { interperateKeystroke("T"); });
bind('y', mShift, function() { interperateKeystroke("Y"); });
bind('u', mShift, function() { interperateKeystroke("U"); });
bind('i', mShift, function() { interperateKeystroke("I"); });
bind('o', mShift, function() { interperateKeystroke("O"); });
bind('p', mShift, function() { interperateKeystroke("P"); });
bind('[', mShift, function() { interperateKeystroke("{"); });
bind(']', mShift, function() { interperateKeystroke("}"); });
bind("\\", mShift, function() { interperateKeystroke("|"); });
bind('a', mShift, function() { interperateKeystroke("A"); });
bind('s', mShift, function() { interperateKeystroke("S"); });
bind('d', mShift, function() { interperateKeystroke("D"); });
bind('f', mShift, function() { interperateKeystroke("F"); });
bind('g', mShift, function() { interperateKeystroke("G"); });
bind('h', mShift, function() { interperateKeystroke("H"); });
bind('j', mShift, function() { interperateKeystroke("J"); });
bind('k', mShift, function() { interperateKeystroke("K"); });
bind('l', mShift, function() { interperateKeystroke("L"); });
bind(';', mShift, function() { interperateKeystroke(":"); });
bind("'", mShift, function() { interperateKeystroke('"'); });
bind('z', mShift, function() { interperateKeystroke("Z"); });
bind('x', mShift, function() { interperateKeystroke("X"); });
bind('c', mShift, function() { interperateKeystroke("C"); });
bind('v', mShift, function() { interperateKeystroke("V"); });
bind('b', mShift, function() { interperateKeystroke("B"); });
bind('n', mShift, function() { interperateKeystroke("N"); });
bind('m', mShift, function() { interperateKeystroke("M"); });
bind(',', mShift, function() { interperateKeystroke("<"); });
bind('.', mShift, function() { interperateKeystroke(">"); });
bind('/', mShift, function() { interperateKeystroke("?"); });
// ############################################################################
// Helpers - mostly curtesy of teetrinkers
// ############################################################################
// Disables all remembered keys.
function disableKeys() {
active = false;
_(keys).each(function(key) {
key.disable();
});
api.alert("done", 0.5);
mode = "normal";
count = 0;
api.setTint([0,1],[0,1],[0,1]);
api.overlay(false, "/Users/hannesremahl/Desktop/grid.png");
//args = new Array("-v", "victoria", "Off");
//api.runCommand("/usr/bin/say", args);
}
// Enables all remembered keys.
function enableKeys() {
active = true;
_(keys).each(function(key) {
key.enable();
});
api.alert("Phoenix", 0.5);
api.setTint([0, 1], [0, 1], [0, 0.4]);
api.overlay(showingOverlay, "/Users/hannesremahl/Desktop/grid.png");
//args = new Array("-v", "victoria", "On");
//api.runCommand("/usr/bin/say", args);
}
function windowToGrid(window, x, y, width, height) {
var screen = window.screen().frameWithoutDockOrMenu();
window.setFrame({
x: Math.round( x * screen.width ) + padding + screen.x,
y: Math.round( y * screen.height ) + padding + screen.y,
width: Math.round( width * screen.width ) - ( 2 * padding ),
height: Math.round( height * screen.height ) - ( 2 * padding )
});
window.focusWindow();
return window;
}
function toGrid(x, y, width, height) {
windowToGrid(Window.focusedWindow(), x, y, width, height);
}
Window.prototype.toGrid = function(x, y, width, height) {
windowToGrid(this, x, y, width, height);
};
// Convenience method, doing exactly what it says. Returns the window
// instance.
Window.prototype.toFullScreen = function() {
return this.toGrid( 0, 0, 1, 1 );
};
Window.prototype.focusNextWindowOnSameScreen = function() {
var currentWindow = Window.focusedWindow();
var windows = currentWindow.otherWindowsOnSameScreen();
windows.push(currentWindow);
windows = _.chain(windows).sortBy(function(window) { return window.hash()}).value();
windows[(_.indexOf(windows, currentWindow) + 1) % windows.length].focusWindow();
};
// Convenience method, pushing the window to the top half of the screen.
// Returns the window instance.
Window.prototype.toN = function() {
return this.toGrid( 0, 0, 1, 0.5 );
};
// Convenience method, pushing the window to the right half of the screen.
// Returns the window instance.
Window.prototype.toE = function() {
return this.toGrid( 0.5, 0, 0.5, 1 );
};
// Convenience method, pushing the window to the bottom half of the screen.
// Returns the window instance.
Window.prototype.toS = function() {
return this.toGrid( 0, 0.5, 1, 0.5 );
};
// Convenience method, pushing the window to the left half of the screen.
// Returns the window instance.
Window.prototype.toW = function() {
return this.toGrid( 0, 0, 0.5, 1 );
};
// Stores the window position and size, then makes the window full screen.
// Should the window be full screen already, its original position and size
// is restored. Returns the window instance.
Window.prototype.toggleFullscreen = function() {
if ( previousSizes[ this ] ) {
this.setFrame( previousSizes[ this ] );
delete previousSizes[ this ];
}
else {
previousSizes[ this ] = this.frame();
this.toFullScreen();
}
return this;
};
Window.prototype.pushLeft = function() {
var win = this,
frame = win.frame();
frame.x = 0;
win.setFrame(frame);
}
Window.prototype.pushDown = function() {
var win = this,
screen = win.screen().frameWithoutDockOrMenu();
win.nudgeDown(screen.height);
}
Window.prototype.pushUp = function() {
var win = this,
frame = win.frame();
frame.y = 0;
win.setFrame(frame);
}
Window.prototype.pushRight = function() {
var win = this,
screen = win.screen().frameWithoutDockOrMenu();
win.nudgeRight(screen.width);
}
Window.prototype.splitLeft = function(amount) {
var win = this,
frame = win.frame();
amount = 1 - amount;
frame.width *= amount;
frame.x = win.frame().x;
win.setFrame(frame);
}
Window.prototype.splitRight = function(amount) {
var win = this,
frame = win.frame();
amount = 1 - amount;
frame.width *= amount;
win.setFrame(frame);
}
Window.prototype.splitDown = function(amount) {
var win = this,
frame = win.frame();
amount = 1 - amount;
var newy = frame.y + (frame.height - frame.height * amount);
frame.height *= amount;
frame.y = newy;
win.setFrame(frame);
}
Window.prototype.splitUp = function(amount) {
var win = this,
frame = win.frame();
amount = 1 - amount;
frame.height *= amount;
win.setFrame(frame);
}
Window.prototype.splitRight = function(amount) {
var win = this,
frame = win.frame();
amount = 1 - amount;
var newx = frame.x + (frame.width - frame.width * amount);
frame.width *= amount;
frame.x = newx;
win.setFrame(frame);
}
// Move the currently focussed window left by [`nudgePixel`] pixels.
Window.prototype.nudgeLeft = function( factor ) {
var win = this,
frame = win.frame(),
pixels = win.screen().frameIncludingDockAndMenu().width / smallGridNum;
if (frame.x >= pixels) {
frame.x -= pixels;
} else {
frame.x = 0;
}
win.setFrame( frame );
};
// Move the currently focussed window right by [`nudgePixel`] pixels.
Window.prototype.nudgeRight = function( factor ) {
var win = this,
frame = win.frame(),
maxLeft = win.screen().frameIncludingDockAndMenu().width - frame.width,
pixels = win.screen().frameIncludingDockAndMenu().width / smallGridNum;
if (frame.x < maxLeft - pixels) {
frame.x += pixels;
} else {
frame.x = maxLeft;
}
win.setFrame( frame );
};
// Move the currently focussed window left by [`nudgePixel`] pixels.
Window.prototype.nudgeUp = function( factor ) {
var win = this,
frame = win.frame(),
pixels = win.screen().frameIncludingDockAndMenu().height / smallGridNum;
if (frame.y >= pixels) {
frame.y -= pixels;
} else {
frame.y = 0;
}
win.setFrame( frame );
};
// Move the currently focussed window right by [`nudgePixel`] pixels.
Window.prototype.nudgeDown = function( factor ) {
var win = this,
frame = win.frame(),
maxTop = win.screen().frameIncludingDockAndMenu().height - frame.height,
pixels = win.screen().frameIncludingDockAndMenu().height / smallGridNum;
if (frame.y < maxTop - pixels) {
frame.y += pixels;
} else {
frame.y = maxTop;
}
win.setFrame( frame );
};
// #### Functions for growing / shrinking the focussed window.
Window.prototype.growTop = function() {
this.nudgeUp(6);
var win = this,
frame = win.frame(),
screenFrame = win.screen().frameIncludingDockAndMenu(),
pixels = win.screen().frameIncludingDockAndMenu().height / smallGridNum;
if (frame.height < screenFrame.height - pixels) {
frame.height += pixels;
} else {
frame.height = screenFrame.height;
}
win.setFrame(frame);
};
Window.prototype.growBottom = function() {
var win = this,
frame = win.frame(),
screenFrame = win.screen().frameIncludingDockAndMenu(),
pixels = win.screen().frameIncludingDockAndMenu().height / smallGridNum;
if (frame.height < screenFrame.height - pixels) {
frame.height += pixels;
} else {
frame.height = screenFrame.height;
}
win.setFrame(frame);
};
Window.prototype.growLeft = function() {
this.nudgeLeft(6);
var win = this,
frame = win.frame(),
screenFrame = win.screen().frameIncludingDockAndMenu(),
pixels = win.screen().frameIncludingDockAndMenu().width / smallGridNum;
if (frame.width < screenFrame.width - pixels) {
frame.width += pixels;
} else {
frame.width = screenFrame.width;
}
win.setFrame(frame);
};
Window.prototype.growRight = function() {
var win = this,
frame = win.frame(),
screenFrame = win.screen().frameIncludingDockAndMenu(),
pixels = win.screen().frameIncludingDockAndMenu().width / smallGridNum;
if (frame.width < screenFrame.width - pixels) {
frame.width += pixels;
} else {
frame.width = screenFrame.width;
}
win.setFrame(frame);
};
Window.prototype.shrinkTop = function() {
var win = this,
frame = win.frame(),
screenFrame = win.screen().frameWithoutDockOrMenu(),
pixels = win.screen().frameIncludingDockAndMenu().height / smallGridNum;
if (frame.height >= pixels * 2) {
frame.height -= pixels;
} else {
frame.height = pixels;
}
win.setFrame(frame);
this.nudgeDown(6);
};
Window.prototype.shrinkBottom = function() {
var win = this,
frame = win.frame(),
screenFrame = win.screen().frameWithoutDockOrMenu(),
pixels = win.screen().frameIncludingDockAndMenu().height / smallGridNum;
if (frame.height >= pixels * 2) {
frame.height -= pixels;
} else {
frame.height = pixels;
}
win.setFrame(frame);
};
Window.prototype.shrinkLeft = function() {
var win = this,
frame = win.frame(),
screenFrame = win.screen().frameIncludingDockAndMenu(),
pixels = win.screen().frameIncludingDockAndMenu().width / smallGridNum;
if (frame.width >= pixels * 2) {
frame.width -= pixels;
} else {
frame.width = pixels;
}
win.setFrame(frame);
this.nudgeRight(6);
};
Window.prototype.shrinkRight = function() {
var win = this,
frame = win.frame(),
screenFrame = win.screen().frameIncludingDockAndMenu(),
pixels = win.screen().frameIncludingDockAndMenu().width / smallGridNum;
if (frame.width >= pixels * 2) {
frame.width -= pixels;
} else {
frame.width = pixels;
}
win.setFrame(frame);
};
// ### Helper methods `App`
//
// Finds the window with a certain title. Expects a string, returns a window
// instance or `undefined`. If there are several windows with the same title,
// the first found instance is returned.
App.findByTitle = function( title ) {
return _( this.runningApps() ).find( function( app ) {
if ( app.title() === title ) {
app.show();
return true;
}
});
};
// Finds the window whose title matches a regex pattern. Expects a string
// (the pattern), returns a window instance or `undefined`. If there are
// several matching windows, the first found instance is returned.
App.prototype.findWindowMatchingTitle = function( title ) {
var regexp = new RegExp( title );
return _( this.visibleWindows() ).find( function( win ) {
return regexp.test( win.title() );
});
};
// Finds the window whose title doesn't match a regex pattern. Expects a
// string (the pattern), returns a window instance or `undefined`. If there
// are several matching windows, the first found instance is returned.
App.prototype.findWindowNotMatchingTitle = function( title ) {
var regexp = new RegExp( title );
return _( this.visibleWindows() ).find( function( win ) {
return !regexp.test( win.title() );
});
};
// Returns the first visible window of the app or `undefined`.
App.prototype.firstWindow = function() {
return this.visibleWindows()[ 0 ];
};
// ############################################################################
// Init
// ############################################################################
// Initially disable all hotkeys
disableKeys();
// ############################################################################
// The following code comes from https://github.com/itsjoesullivan/js-vim-command
// ############################################################################
var Parser = function() {};
/** Parse a command
input: string of text
output: object containing the interpreted string and an array with each element
*/
Parser.prototype.parse = function(command) {
var motion = this.getLastMotion(command);
var prefix = command;
var command = {
description: '',
value: []
};
var next;
while(prefix.length) {
next = this.getLastCount(prefix) || this.getLastMotion(prefix) || this.getLastOperator(prefix);
if(!next) break
prefix = next.prefix;
command.description = next.description + command.description;
command.value.unshift(next.value);
command.prefix = next.prefix;
}
return command.description.length ? command : false;
var x = this.getLastCount(command) || this.getLastMotion(command) || this.getLastOperator(command);
/*
{count}
{count}{op}{motion}
{op}{count}{motion}
{count}{op}{count}{motion}
{motion}
{
*/
};
//Test for operator
/** Determines whether command is an operator, returning it if so */
Parser.prototype.getLastOperator = function(command) {
var op = opTest.exec(command)
if(!op) return;
return {
description: '{operator}',
value: op[2],
prefix: op[1]
};
};
/** Get motions, of which there are a variety
h l 0 ^ g_ | (f|F|t|T){char} ; , k j - + _ G
word motions:
e E w W b B ge gE
text object motions:
( ) { } ]] [] [[ []
*/
Parser.prototype.getLastMotion = function(command) {
var motion = motionTest.exec(command);
if(!motion) return;
return {
description: '{motion}',
value: motion[2],
prefix: motion[1]
}
};
var countTest = /(.*?)([0-9]+[0-9]*)$/
Parser.prototype.getLastCount = function(command) {
var countResult = countTest.exec(command);
if(!countResult) return;
return {
description: '{count}',
value: parseInt(countResult[2]),
prefix: countResult[1]
};
};
parser = new Parser();
@jasonm23
Copy link

Could you link to the grid.png?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment