Tuesday, August 16, 2011

Toggle Airport power from emacs using shell commands

I can usually work for relatively long periods of time without needing the internet, or needing it only sporadically, and mostly while using emacs to edit various kinds of text files.  While I'm doing this, I usually turn off power to the Airport wireless radio on my MacBook Pro to save battery power, then turn it on only when I need it.

Using emacs trains you not to use the mouse unless absolutely necessary, and the small bit of time and effort required to turn the Airport off and on from the menu bar, added up over time, was sort of bothering me.  So, given sufficient desire to procrastinate, I found a way to toggle power to my Airport wireless radio from within emacs.

The first step is to write a shell script to do the toggling (see below).  After a bit of searching, I found the "networksetup" command in the discussion attached to this Macworld hint.  The trick is to use

networksetup -getairportpower en1 | cut -d : -f 2

to get the status and then

networksetup -setairportpower en1 Off

to turn it off, or "On" to turn it back on.

The second step was to insert it into my .emacs.el as a custom function with a key binding.  This was pretty straightforward and the code is in the comments in the shell script below.  The only potential sticky point is to make sure to declare the function as interactive so that it can be bound to a key.


# toggle-airport
# Toggles OS X airport power on or off.  dan.t.swain@gmail.com 8/14/11
# I built this to be used within emacs.  I bound it to C-c a with the
# following in my .emacs.el (obviously you need to change the path
# for your own use):
#  (defun dts-toggle-airport ()
#    (interactive)
#    (shell-command "~/bin/toggle-airport")
#    )
#  (global-set-key (kbd "\C-c a") 'dts-toggle-airport)
# Commands gleaned from the following mac hints discussion (near the bottom):
#   http://hints.macworld.com/article.php?story=20070728102702656

# get the current status, this will look like "AirPort Power (en1): Off"
#  so by cutting at the ':' and taking everything after that
#  we get " On" or " Off"
CURRENT_STATUS=`networksetup -getairportpower en1 | cut -d : -f 2`

# determine the new status from the old status - note the leading whitespace
if [[ "$CURRENT_STATUS" == " On" ]]

# set the new power status
networksetup -setairportpower en1 $NEW_STATUS
# display the results by querying the device again
networksetup -getairportpower en1