# 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.