Stumpwm shutdown nag


I use Stumpwm as my pri­mary win­dow man­ager on my desk­top at home. Stumpwm is actu­ally a pretty neat win­dow manager: it’s tiled, pro­vides facil­i­ties for group and be con­trolled com­pletely from the key­board, no mouse nec­es­sary, but it’s chief advan­tage to me is that it’s writ­ten and con­fig­ured with Common Lisp, which make it much eas­ier for me to script and mod­i­fy. I can arbi­trar­ily load pro­grams, libraries, and code into the Stumpwm run­time in real­time while it is still run­ning just to see if and how it works. This actu­ally makes it much more deeply mod­i­fi­able than most other win­dows man­agers (or indeed, pro­grams of any sort,) and I’ve taken advan­tage of this from time to time.

One of my more peren­nial prob­lems is a sort of insom­nia that I have. I’ve found how­ev­er, that if I limit my com­puter usage in the evening and spend a cou­ple hours away from it before going to bed, it becomes much less of an issue. This presents a bit of a dis­ci­pline prob­lem how­ever with me hav­ing to remem­ber and be will­ing to do so every night. That’s a pain so I fig­ured why the hell not write a pro­gram that helps me with this? Stumpwm seemed like a nat­ural place to put it.

So, what I was think­ing was to make a script which would be trig­gered at a cer­tain time in the evening and would shut­down the com­put­er. This is pretty sim­ple and could be done with a sim­ple cron­job but it has the issue that it’s also a lit­tle abrupt. It wold only take a few nights of me loos­ing work to it for me to turn it off. So what about a pro­gram which launches at a cer­tain moment and then nags me until I turn off the com­put­er? This is much bet­ter because it would allow me to fin­ish what­ever I’m doing but would still encour­age me to turn off the machine.

I set­tled on a script which would, at the spec­i­fied time, launch a prompts telling me it was time to shut­down the com­pute and giv­ing me the option to snooze. If I press the snooze it will go away, but pop up again in a few minutes. Each time I press the snooze, the snoze gets shorter which makes the pro­gram more annoy­ing and imprac­ti­cal to just keep snooz­ing. The pro­gram locks down my input while prompt­ing me and the only option other than snooze is imme­di­ate shut­down. Because the pro­gram runs as part of the win­dow man­ager, I can’t shut it down using usual process man­age­ment tools like ps and kill.

To make the pro­gram start at only cer­tain times, I used the cl-cron library and loaded it into Stumpwm using this code in my .stumpwmrc:

(require 'cl-cron)
(use-package 'cl-cron)

(start-cron)

Stumpwm has a few func­tions for cre­at­ing prompts and ask­ing for input but it does­n’t really have a sim­ple y/n prompt. For­tu­nate­ly, this was sim­ple to write:

(defun y-n-prompt (prompt &optional (y-answer "OK") (n-answer "OK") wrong-char)
  "Asks user a yes or no question and returns a boolean based on user response."
  (message (if wrong-char "~A (type \"Y\" or \"N\")" "~A (y/n)") prompt)
  (let ((input (read-one-char (current-screen))))
    (case input
      (#\y (stumpwm::echo y-answer) t)
      (#\Y (stumpwm::echo y-answer) t)
      (#\n (stumpwm::echo n-answer) nil)
      (#\N (stumpwm::echo n-answer) nil)
      (t (y-n-prompt prompt y-answer n-answer t)))))

Now I can actu­ally write the nag func­tion. The logic is pretty simple: ini­ti­ate a y/n prompt ask­ing the using if he wants to shut­down the com­puter just yet. If the user answers yes, shut every­thing down, oth­er­wise wait a lit­tle while and relaunch. Here’s the code:

(defun night-time (&optional (snooze 900) (speedup-rate 1/3))
  "Bedtime nag. Asks user to shutdown computer with increasing frequency."
  (if (y-n-prompt "Time for bed. Shutdown now?" 
	      "Shutting Down" 
	      (format nil "Snoozing for ~A:~A minutes" 
		      (floor (/ snooze 60)) 
		      (round (mod snooze 60))))
      (stumpwm::quit)
    (progn
      (sleep snooze)
      (night-time (- snooze (* snooze speedup-rate))
	      speedup-rate))))

Pretty sim­ple right? Notice that it reduces the snooze time with each iter­a­tion. Any­way, all I have to do is add it to cl-cron:

(make-cron-job 'night-time
           :minute 0
           :hour 22)

Now it will run at ten every night. Prob­lem solved.

I actu­ally have a cou­ple of tricks in my .stump­wmrc so I’ll prob­a­bly give it a home on this site at one point, prob­a­bly after my .emacs has got­ten it’s place.

    Last update: 20/11/2011

    blog comments powered by Disqus