Scripting your Mac: Basic Motion

If you’re just joining us, you may want to start at the beginning with hello world.

While that was fun, it’s not the most useful. Let’s start moving things around. Also, I’m going to make a point of explaining what’s going on from now on.

To move windows at your command, we’ll again need the mjolnir.hotkey rock. As you probably noticed, mjolnir.hotkey.bind() allows you to attach functions to key press and release events. This is how we’ll be triggering the window changes we want to make.

We’ll also need the mjolnir.window rock to give us access to the windows we want to control. We’ll be focusing on moving the currently active window, so we’ll access its window object with mjolnir.window.focusedwindow(). Then we’ll want to change it’s position on the screen, which is available as the rect object from mjolnir.window:frame(). Then we can fiddle with the x & y positions and save using mjolnir.window:setframe()!

So let’s begin by installing our dependencies:

luarocks install mjolnir.hotkey
luarocks install mjolnir.alert

Let’s begin with a tiny use case, just moving a window a bit to the left. Users of vi and nethack know that the only appropriate key bindings for this must use the H key. I’ll be assuming that you also don’t mind a bit of key mashing, so I’ll use Cmd+Alt+Ctrl as our mode. Here goes:

local hotkey = require "mjolnir.hotkey"
local window = require "mjolnir.window"

hotkey.bind({"cmd", "alt", "ctrl"}, "H", function()
  local win = window.focusedwindow()
  local f = win:frame()

  f.x = f.x - 10
  win:setframe(f)
end)

Seems simple enough right? The only thing to remember is that the origin of this Cartesian plane is in the upper left corner of the screen. So making x smaller means left, larger means right. And for y smaller means up, larger means down.

So let’s extend this control to the full nethack motion:

y k u
h l
b j n
local hotkey = require "mjolnir.hotkey"
local window = require "mjolnir.window"

-- Basic movement
-- y up-left
-- k up
-- u up-right
-- h leftgg
-- l right
-- b down-left
-- j down
-- n down-right

hotkey.bind({"cmd", "alt", "ctrl"}, "Y", function()
  local win = window.focusedwindow()
  local f = win:frame()

  f.x = f.x - 10
  f.y = f.y - 10
  win:setframe(f)
end)

hotkey.bind({"cmd", "alt", "ctrl"}, "K", function()
  local win = window.focusedwindow()
  local f = win:frame()

  f.y = f.y - 10
  win:setframe(f)
end)

hotkey.bind({"cmd", "alt", "ctrl"}, "U", function()
  local win = window.focusedwindow()
  local f = win:frame()

  f.x = f.x + 10
  f.y = f.y - 10
  win:setframe(f)
end)

hotkey.bind({"cmd", "alt", "ctrl"}, "H", function()
  local win = window.focusedwindow()
  local f = win:frame()

  f.x = f.x - 10
  win:setframe(f)
end)

hotkey.bind({"cmd", "alt", "ctrl"}, "L", function()
  local win = window.focusedwindow()
  local f = win:frame()

  f.x = f.x + 10
  win:setframe(f)
end)

hotkey.bind({"cmd", "alt", "ctrl"}, "B", function()
  local win = window.focusedwindow()
  local f = win:frame()

  f.x = f.x - 10
  f.y = f.y + 10
  win:setframe(f)
end)

hotkey.bind({"cmd", "alt", "ctrl"}, "J", function()
  local win = window.focusedwindow()
  local f = win:frame()

  f.y = f.y + 10
  win:setframe(f)
end)

hotkey.bind({"cmd", "alt", "ctrl"}, "N", function()
  local win = window.focusedwindow()
  local f = win:frame()

  f.x = f.x + 10
  f.y = f.y + 10
  win:setframe(f)
end)

Remember to reload your config!

And there you have it, basic motion for all cardinal and ordinal directions. With that under our belt, we’re ready to handle tiling motions.

Scripting your Mac: Getting started

I’m switching from Spectacle to Mjolnir mostly as an excuse to learn Lua. I’ve noticed that introductory documentation is a little sparing, so I figure I may as well start writing some.

If you’ve never programmed in Lua before, you may want to run through Learn Lua in Y minutes before you begin.

We’re going to work our way through building a subset of common tiling window managers like Spectacle and SizeUp.

First let’s build the traditional “Hello World!”.

We’ll need to install Mjolnir first, so download the latest release, move it into your Applications folder, and fire it up.

This example will need a couple libraries to work, so we’ll need to install the mjolnir.hotkey and mjolnir.alert rocks:

luarocks install mjolnir.hotkey
luarocks install mjolnir.alert

Then in your config (usually ~/.mjolnir/init.lua) file enter:

local hotkey = require "mjolnir.hotkey"
local alert = require "mjolnir.alert"

hotkey.bind({"cmd", "alt", "ctrl"}, "H", function()
  alert.show("Hello World!")
end)

Reload your config and press Cmd+Alt+Ctrl+H. You should see a bubble in the middle of the screen with the text “Hello World!”

Now that we understand the basic parts, we’re ready to move onto basic motion.

12% combined

The USDA standards for processed, packaged “Salisbury steak” require a minimum content of 65% meat, of which up to 25% can be pork, except if defatted beef or pork is used, the limit is 12% combined. No more than 30% may be fat. Meat byproducts are not permitted; however, beef heart meat is allowed. Extender (bread crumbs, flour, oat flakes, etc.) content is limited to 12%, except isolated soy protein at 6.8% is considered equivalent to 12% of the others.

Wikipedia, Salisbury steak.

Page 2 of 10