john chesley

fresh stuff

destinations

favorites

nocterm.rb

using a computer at night when it's dark can be quite a strain on the eyes. i tend to do this a lot, and whether programming or chatting with friends in europe, i've found the program Nocturne to be a sight for sore eyes, as it were.

Nocturne is simple app for switching a computer to night vision mode. It has a few tricks up its sleeve: color correction, window shadow toggling, and background removal. --blacktree.com

my only problem was with my Terminal windows. they're already normally light-colored text on a dark background, so naturally when the screen gets Nocturned, using a terminal would blast my eyes out!

i started playing around with applescript to see if i could do anything about it. i was able to get applescript to change the colors of the terminal, but i got tangled up in applescript's verbose syntax when i tried to go through each open Terminal window and change all the colors.

that's where appscript comes in. using appscript you can do anything you can do in applescript in your choice of ruby, python, or objective-c. i chose ruby for this project, since i'm a little more familiar with it than with python or obj-c. it's a pretty small script:


#!/usr/bin/ruby

# nocterm.rb: change the terminal colors for night-vision mode
# may 25, 2009
# john chesley <john@cheslicious.com>
# update may 28, 2009: added support for toggling emacs color-theme
# uses emacsclient, so put (server-start) in your .emacs if it's not there

require 'appscript'
include Appscript

# themes to toggle in Terminal and emacs
term_noc_theme = "Nocturne"
term_normal_theme = "Pro"
emacs_noc_theme = "jsc-light"
emacs_normal_theme = "charcoal-black"
emacs_colors = emacs_normal_theme

term = app('Terminal')

# 1.upto() because windows[0] and windows[1] represent the same window
1.upto(term.windows.count) {|x|
  window = term.windows[x]
  w_name = window.name.get
  if (w_name.grep(/Visor/) == []) then
    puts "#{x}: " + window.current_settings.name.get

    if window.current_settings.name.get == term_noc_theme then
      term_colors = term.settings_sets[term_normal_theme]
      emacs_colors = emacs_normal_theme
    else
      term_colors = term.settings_sets[term_noc_theme]
      emacs_colors = emacs_noc_theme
    end
 
    # apply new settings
    window.tabs.current_settings.set(term_colors)
    term.default_settings.set(term_colors)

 end
}
system("emacsclient -e \\(color-theme-#{emacs_colors}\\)")
app("Finder").startup_disk.folders["Applications"].application_files["Nocturne.app"].open

download: nocterm.rb - right click and save as nocterm.rb

in Terminal.app's preferences I set up the two themes I would use, one for normal use and one for use with Nocturne, and for each of Terminal's windows i toggle between the two each time the script runs. we also toggle the default settings for new Terminal windows and tabs.

the script takes advantage of the fact that if Nocturne is running and you open it again, night vision mode activates. open it again and night vision mode deactivates.

since i'm also using visor, which keeps some extra hidden windows around that aren't terminal windows (the pref window and about window), we have to ignore those or we'll toss errors all over the floor.

now, using quicksilver, i've tied a keyboard shortcut to run the script nocterm.rb, so with a single keystroke i can toggle between night- and day- modes on my macbook.

update: may 28, 2009 - updated nocterm.rb to use emacsclient to execute a lisp function call to toggle the current emacs color-theme :)

bugs/feature requests

there's a few things i wish it could do...