Automating save-build-refresh on os x

This blog is powered by Pelican. When I first started out, I was composing in vim, switching over to a terminal to build, and finally to my browser to preview the result. Clearly this becomes tedious pretty quickly.

I was already familiar with tools to watch folders for changes and trigger actions, and I recently discovered that I could use a bit of applescript to refresh my browser, saving precious seconds and make the workflow feel more natural.

I already have a makefile for the actual build step. It's a fairly trivial command but this file saves me rembmering it:

$ cat Makefile
html:
    pelican . -s settings.py -o ../output_folder

Along with this i use a python script calling the MacFSEvents library. This lets me watch a folder for changes, and exectue a function as a reaction. My setup is pretty much straight from the docs:

import re
from fsevents import Observer, Stream

# ignore vim swap files
swp_regex = re.compile(r"\.sw.$|~$")

def callback(event):
    if not swp_regex.search(event.name):
        # uses subprocess to call 'make html'
        pelican_build()

if __name__ == '__main__':

    observer = Observer()
    observer.start()

    stream = Stream(callback, ".", file_events=True)
    observer.schedule(stream)

    # trap ctrl-c and exit gracefully
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()

This was my setup as of this morning. The new addition, is a second function called by the callback: reload_browser()

url_identifier = 'localhost'
brower = 'Google Chrome'

reload_string = """
tell application "%s"
    set windowList to every window
    repeat with aWindow in windowList
        set tabList to every tab of aWindow
        repeat with atab in tabList
            if (URL of atab contains "%s") then
                tell atab to reload
            end if
        end repeat
    end repeat
end tell """ % (brower, url_identifier)

def reload_browser():
    pipe = subprocess.Popen(['osascript'],
        stdout = subprocess.PIPE,
        stdin = subprocess.PIPE,
        stderr = sys.stderr
    )
    pipe.communicate(reload_string)

The apple script looks through all my tabs for urls matching a given string, and reloads them. So now all i need to do is save the source file i'm editing, and look over to see my browser reloading. Beautiful!

Comments !