Online Package Tracking
While waiting for my books I couldn’t help but remember something that made me laugh a little while ago, and I realized how true it was.
It’s official part deux, and a little scheming along the way.
Got my state EMT-B license in the mail to go along with my national license today. Now I can actually start working. Ideally I’d like a part time or full time gig at the agency I did my ride time with, but if need be I can give the local fire dept. or maybe the hospitals or something a try. Re-read the hell out of that pediatrics chapter in the meantime, now I’m just eager to to get to work (and get paid).
And as long as there’s actually some kind of job in my future, I’m using a bit of cash I’ve managed to save to feed my lust for books which has been starved for far too long. Specifically, “The x Schemer” series, as I’ve been wanting to get these for quite some time now.
The Little Schemer for recursion and Scheme in general,
The Seasoned Schemer for functional programming and more details on Scheme,
and The Reasoned Schemer for its blend of functional and logic programming.
Eventually I intend to go through my entire TAoCP set again, this time rewriting all of the examples and problems in Scheme.
Man, I need to get laid.
A really cool StumpWM config for MPD
[ Update: Last I checked, this was included with the StumpWM sources under /contrib ]
Alas, it would seem I poorly reinvented a wheel. Piss poorly, compared to this. I was looking at the change history for StumpWM’s Wiki which led me to http://appart.kicks-ass.net/patzy/files/mpd.lisp.
Unlike my extremely primitive couple of functions, this is essentially a complete MPD client that just happens to use StumpWM as its UI, written by someone with obviously far more Lisp experience than I. I reproduce its current contents below:
;;; MPD client & formatters for stumpwm
;;;
;;; Copyright 2007 Morgan Veyret.
;;;
;;; This module is free software; you can redistribute it and/or modify
;;; it under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 2, or (at your option)
;;; any later version.
;;;
;;; This module is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with this software; see the file COPYING. If not, write to
;;; the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
;;; Boston, MA 02111-1307 USA
;;;
;;; USAGE:
;;;
;;; Put:
;;;
;;; (load "/path/to/mpd.lisp")
;;;
;;; In your ~/.stumpwmrc
;;;
;;; Then you can use "%m" in your mode line format.
;;; You can also use the various commands defined at the end of the file
;;;
;;; NOTES:
;;; see http://mpd.wikia.com/wiki/Protocol_Reference for full protocol
(in-package :stumpwm)
;;mpd client
(defparameter *mpd-socket* nil)
(defparameter *mpd-server* "localhost")
(defparameter *mpd-port* 6600)
(defun mpd-send (command)
"Send command to stream ending with newline"
(with-mpd-connection
(ext:write-char-sequence
(concatenate 'string command (string #\Newline))
*mpd-socket*)))
(defun mpd-termination-p (str)
(or (mpd-error-p str)
(mpd-ok-p str)))
(defun mpd-error-p (str)
(when (>= (length str) 3)
(equal (subseq str 0 3) "ACK")))
(defun mpd-ok-p (str)
(equal str "OK"))
(defun mpd-tokenize (str)
(let ((pos (position #\: str)))
(list (read-from-string (concatenate 'string
":"
(subseq str 0 pos)))
(subseq str (+ pos 2)))))
(defun assoc-value (name list)
(cadr (assoc name list)))
(defun mpd-receive ()
"Returns a list containing all data sent by mpd."
(with-mpd-connection
(loop for i = (read-line *mpd-socket*)
when (mpd-error-p i)
do (message "Error sent back by mpd: ~a" i)
until (mpd-termination-p i)
collect (mpd-tokenize i))))
(defun mpd-connect ()
"Connect to mpd server"
(setf *mpd-socket*
(handler-case (socket:socket-connect *mpd-port* *mpd-server*
:element-type 'character)
((or system::simple-os-error error)
(err)
(format t "Error connecting to mpd: ~a~%" err))))
(when *mpd-socket*
(read-line *mpd-socket*)))
(defun mpd-disconnect ()
"Disconnect from mpd server"
(with-mpd-connection
(close *mpd-socket*)
(setf *mpd-socket* nil)))
(defun mpd-send-command (cmd)
(mpd-send cmd)
(mpd-receive))
(defmacro with-mpd-connection (&body body)
`(if *mpd-socket*
(handler-case (progn ,@body)
(error (c) (progn
(message "Error with mpd connection: ~a" c)
(setf *mpd-socket* nil))))
(message "Error: not connected to mpd~%")))
;;mpd formatter
(dolist (a '((#\m fmt-mpd-status)))
(push a *screen-mode-line-formatters*))
(defparameter *mpd-current-song* nil)
(defparameter *mpd-status* nil)
(defun mpd-update-current-song ()
(setf *mpd-current-song* (mpd-send-command "currentsong")))
(defun mpd-update-status ()
(setf *mpd-status* (mpd-send-command "status")))
(defun format-mpd-current-song (current-song)
(let ((artist (assoc-value :artist current-song))
(album (assoc-value :album current-song))
(title (assoc-value :title current-song))
(file (assoc-value :file current-song)))
(if (or (null artist)
(null album)
(null title))
(format nil "~a" file)
(format nil "~a (~a): ~a"
artist
album
title))))
(defun format-mpd-status (status)
(let ((mpd-state (assoc-value :state status)))
(cond
((equal mpd-state "play")
(format nil "Playing [~a;~a] (~a%)"
(if (equal (assoc-value :random *mpd-status*)
"0")
"_"
"S")
(if (equal (assoc-value :repeat *mpd-status*)
"0")
"_"
"R")
(assoc-value :volume *mpd-status*)))
((equal mpd-state "pause")
(format nil "Paused [~a;~a]"
(if (equal (assoc-value :random *mpd-status*)
"0")
"_"
"S")
(if (equal (assoc-value :repeat *mpd-status*)
"0")
"_"
"R")))
((equal mpd-state "stop")
(format nil "Stopped [~a;~a]"
(if (equal (assoc-value :random *mpd-status*)
"0")
"_"
"S")
(if (equal (assoc-value :repeat *mpd-status*)
"0")
"_"
"R"))))))
;;FIXME: update status based on last current song time
;;FIXME: this means updating status on commands calls
(defun fmt-mpd-status (ml)
(declare (ignore ml))
(if *mpd-socket*
(with-mpd-connection
(mpd-update-status)
(if (equal "stop" (assoc-value :state *mpd-status*))
(format nil "~a"
(format-mpd-status *mpd-status*))
(progn (mpd-update-current-song)
(format nil "~a: ~a"
(format-mpd-status *mpd-status*)
(format-mpd-current-song *mpd-current-song*)))))
"Not connected"))
;;mpd commands
(defparameter *mpd-volume-step* 5)
(define-stumpwm-command "mpd-select-song-in-playlist" ()
(let ((status (mpd-send-command "status")))
(labels ((pick (options)
(let ((selection
(select-from-menu (current-screen) options
"Play song in playlist"
(if (equal
(assoc-value :state status)
"play")
(parse-integer
(assoc-value :song status))
0))))
(cond
((null selection)
(throw 'stumpwm::error "Abort."))
(t selection)))))
(let* ((response (mpd-send-command "playlistinfo"))
(result (mapcar #'cadr (remove-if (lambda (item)
(not (equal :file
(first item))))
response))))
(let* ((choice (pick result))
(song-number (position choice result)))
(mpd-send-command (format nil "play ~d" song-number)))))))
(define-stumpwm-command "mpd-connect" ()
(message "~a" (mpd-connect)))
(define-stumpwm-command "mpd-disconnect" ()
(mpd-disconnect))
(define-stumpwm-command "mpd-send-command" ((cmd :rest "Send mpd: "))
(mpd-send cmd)
(mpd-receive))
(define-stumpwm-command "mpd-toggle-pause" ()
(let ((status (mpd-send-command "status")))
(cond
((equal (assoc-value :state status)
"play") (mpd-send-command "pause 1"))
((equal (assoc-value :state status)
"pause") (mpd-send-command "pause 0")))))
(define-stumpwm-command "mpd-toggle-random" ()
(let ((status (mpd-send-command "status")))
(cond
((equal (assoc-value :random status) "0") (mpd-send-command "random 1"))
((equal (assoc-value :random status) "1") (mpd-send-command "random 0")))))
(define-stumpwm-command "mpd-toggle-repeat" ()
(let ((status (mpd-send-command "status")))
(cond
((equal (assoc-value :repeat status) "0") (mpd-send-command "repeat 1"))
((equal (assoc-value :repeat status) "1") (mpd-send-command "repeat 0")))))
(define-stumpwm-command "mpd-play" ()
(mpd-send-command "play"))
(define-stumpwm-command "mpd-stop" ()
(mpd-send-command "stop"))
(define-stumpwm-command "mpd-next" ()
(mpd-send-command "next"))
(define-stumpwm-command "mpd-prev" ()
(mpd-send-command "previous"))
(define-stumpwm-command "mpd-set-volume" ((vol :rest "Set volume to: "))
(mpd-send-command (format nil "setvol ~a" vol)))
(define-stumpwm-command "mpd-volume-up" ()
(let* ((status (mpd-send-command "status"))
(vol (read-from-string (assoc-value :volume status))))
(mpd-send-command (format nil "setvol ~a" (+ vol *mpd-volume-step*)))))
(define-stumpwm-command "mpd-volume-down" ()
(let* ((status (mpd-send-command "status"))
(vol (read-from-string (assoc-value :volume status))))
(mpd-send-command (format nil "setvol ~a" (- vol *mpd-volume-step*)))))
(define-stumpwm-command "mpd-clear" ()
(mpd-send-command "clear"))
(define-stumpwm-command "mpd-update" ()
(message "~a" (mpd-send-command "update")))
(define-stumpwm-command "mpd-current-song" ()
(message "~a" (format-mpd-current-song (mpd-send-command "currentsong"))))
(define-stumpwm-command "mpd-playlist" ()
(let* ((response (mpd-send-command "playlistinfo"))
(result (mapcar #'cadr (remove-if (lambda (item)
(not (equal :file
(first item))))
response))))
(if (< (length result) 80)
(message "Current playlist (~a): ~%^7*~{~a~%~}"
(length result)
result)
(message "~a files in playlist" (length result)))))
(define-stumpwm-command "mpd-add-file" ((file :rest "Add file to playlist: "))
(mpd-send-command (format nil "add \"~a\"" file)))
(define-stumpwm-command "mpd-search-and-add-artist"
((what :rest "Search & add artist to playlist: "))
(let* ((response (mpd-send-command (format nil "search artist \"~a\"" what)))
(result (mapcar #'cadr (remove-if (lambda (item)
(not (equal :file
(first item))))
response))))
(loop for i in result
do (mpd-send-command (format nil "add \"~a\"" i)))
(if (< (length result) 80)
(message "Added ~a files: ~%^7*~{~a~%~}"
(length result)
result)
(message "~a files added" (length result)))))
(define-stumpwm-command "mpd-search-artist" ((what :rest "Search artist: "))
(mpd-send-command (format nil "search artist \"~a\"" what)))
(define-stumpwm-command "mpd-search-file" ((what :rest "Search file: "))
(mpd-send-command (format nil "search file \"~a\"" what)))
(define-stumpwm-command "mpd-search-title" ((what :rest "Search title: "))
(mpd-send-command (format nil "search title \"~a\"" what)))
(define-stumpwm-command "mpd-search-album" ((what :rest "Search album: "))
(mpd-send-command (format nil "search album \"~a\"" what)))
(define-stumpwm-command "mpd-search-genre" ((what :rest "Search genre: "))
(mpd-send-command (format nil "search genre \"~a\"" what)))
;;Key map
;;FIXME: maybe some inferior mode would be a good idea (see resize in user.lisp)
(setf *mpd-search-map*
(let ((m (make-sparse-keymap)))
(define-key m (kbd "a") "mpd-search-artist")
(define-key m (kbd "A") "mpd-search-album")
(define-key m (kbd "t") "mpd-search-title")
(define-key m (kbd "f") "mpd-search-file")
(define-key m (kbd "g") "mpd-search-genre")
m))
(setf *mpd-map*
(let ((m (make-sparse-keymap)))
(define-key m (kbd "SPC") "mpd-toggle-pause")
(define-key m (kbd "s") "mpd-toggle-random")
(define-key m (kbd "r") "mpd-toggle-repeat")
(define-key m (kbd "p") "mpd-play")
(define-key m (kbd "o") "mpd-stop")
(define-key m (kbd "m") "mpd-next")
(define-key m (kbd "l") "mpd-prev")
(define-key m (kbd "c") "mpd-clear")
(define-key m (kbd "u") "mpd-update")
(define-key m (kbd "a") "mpd-search-and-add-artist")
(define-key m (kbd "q") "mpd-select-song-in-playlist")
(define-key m (kbd "z") "mpd-playlist")
(define-key m (kbd "v") "mpd-set-volume")
(define-key m (kbd "e") "mpd-volume-up")
(define-key m (kbd "d") "mpd-volume-down")
(define-key m (kbd "S") *mpd-search-map*)
m))
It’s official.
Mail came. Got the usual congratulations letter, the diploma-ish thing, couple papers trying to sell me something or another, an arm patch (what in the world would I use that on other than a work uniform that likely has something similar anyway?), and most importantly, the actual card that says I’m an NREMT-B with the # needed to verify it, that lets me get the state license to actually work, which I’ll probably go have laminated tomorrow.
It’ll be job huntin’ time soon now. I better get a haircut while I’m out tomorrow too.
Scheme vs. Common Lisp
Poking around online as I do, I happened to come across this choice quote:
“Most newcomers eventually (and independently) decide the same thing: Scheme is a better language, but Common Lisp is the right choice for production work. CL has more libraries, and the implementations are somewhat more compatible than Scheme implementations, particularly with respect to macros. ” — http://steve-yegge.blogspot.com/2006/04/lisp-is-not-acceptable-lisp.html
It’s disturbing how true that is. That was precisely my conclusion when I was just getting started (which I still am, but anyway…). Any way you look at it, CL reeks of decades of crust, especially if you’ve written a few lines of Scheme. But… how do you open a network socket in scheme? I asked this question in #Scheme on Freenode last night, and this was the reply:
Prael | Does slib or such have anything for network sockets? offby1 | Prael: slib won't, but your favorite scheme probably does (and it's sure to be non-portable).
That just doesn’t work for me. Or most anyone else, I figure. I like to write code for specs, or failing that, at least de-facto standards. In Common Lisp the answer’s pretty simple: (asdf:install ’sockets-package-of-choosing). I’m not even quite sure what a good one would be, both occasions I’ve had to use sockets other than my simple StumpWM config it was simply a matter of (asdf:install ‘cl-irc) and (asdf:install ‘cl-audioscrobbler).
As it stands, Common Lisp is my “get shit done” language and Scheme is my “fun” language.
And yes, I’m aware that the new R6RS Scheme does have things like libraries. But the new standard as a whole failed to do anything other than turn it into an ugly hack chock full of arbitrarily bolted on shit that completely violates the spirit of Scheme and would only have justification to exist if Common Lisp wasn’t around, and I have no intention of ever using it. Even those that bothered to comment their approval votes often contain phrases such as “compromise” and “good enough” and “not perfect, but…”. I’m sorry but if that’s what I wanted, I already have Common Lisp. I’ll stick to R5RS, thank you.
.stumpwmrc 0.6
; -*-lisp-*- ;;; 0.6 ;; 2008/01/11 ;; Renamed (mpc) to (mpd-command). ;; Wrote that custom (current-song-info), and changed its name to (mpd-info). ;; It uses CL-PPCRE but we don't need to :use it, StumpWM already does. ;; And neither of them are likely portable, though it would be trivial to make them so if anyone cared. ;; Would have done it sooner but I was too busy passing my NREMT-B license exam. (in-package :stumpwm) ;;; Internal variable definitions. (defparameter FOREGROUND-COLOR "green") (defparameter BACKGROUND-COLOR "black") (defparameter BORDER-COLOR FOREGROUND-COLOR) (setf *format-time-string-default* "%a %b %e %k:%M") (defparameter MPD-HOST "127.0.0.1") (defparameter MPD-PORT 2100) (defparameter MPD-PASS "") ;;; Internal function definitions. ;; Found at: ;; http://en.wikipedia.org/wiki/User:Gwern/.stumpwmrc (defun cat (&rest strings) "A shortcut for (concatenate 'string foo bar)." (apply 'concatenate 'string strings)) ;;; My MPD "client". It's pretty clunky, but it works. ;; These are used by mpd-info. (defvar artist-scanner (cl-ppcre:create-scanner "^Artist:\\s(.*)")) (defvar title-scanner (cl-ppcre:create-scanner "^Title:\\s(.*)")) ;; Returns "(Artist - Title)" (defun mpd-info (host port pass) "Return current song information from MPD." (with-open-stream (socket (socket:socket-connect port host)) ; Likely unportable from CLISP. (format socket "password ~a~%" pass) (format socket "currentsong~%") (cat (loop :for line = (read-line socket nil nil) :while line :do (if (cl-ppcre:scan artist-scanner line) (return (subseq (cl-ppcre:scan-to-strings artist-scanner line) 8)))) " - " (loop :for line = (read-line socket nil nil) :while line :do (if (cl-ppcre:scan title-scanner line) (return (subseq (cl-ppcre:scan-to-strings title-scanner line) 7))))))) ;; This sends our vol up/down and prev/next song and pause/unpause commands. (defun mpd-command (host port pass command) "Pass commands to MPD." (with-open-stream (socket (socket:socket-connect port host :timeout 1)) ; Likely unportable from CLISP. (format socket "password ~a~%" pass) (format socket "~a~%" command))) ;;; Theme. ;; Window border colors. (set-focus-color FOREGROUND-COLOR) (set-unfocus-color BACKGROUND-COLOR) ;; Input box colors. (set-fg-color FOREGROUND-COLOR) (set-bg-color BACKGROUND-COLOR) (set-border-color BORDER-COLOR) ;; Modeline colors. (setf *mode-line-foreground-color* FOREGROUND-COLOR) (setf *mode-line-background-color* BACKGROUND-COLOR) (setf *mode-line-border-color* BORDER-COLOR) ;; Background. (run-shell-command (cat "xsetroot -solid " BACKGROUND-COLOR)) ;;; Init stuff. ;; Make frames 1-indexed. ;; See: http://lists.gnu.org/archive/html/stumpwm-devel/2006-08/msg00002.html ;; Found at: http://en.wikipedia.org/wiki/User:Gwern/.stumpwmrc (setf *frame-number-map* "1234567890") ; Still doesn't seem to work. ;; Rename the first group to Browse and create the other groups. ;; Found at: http://en.wikipedia.org/wiki/User:Gwern/.stumpwmrc (setf (group-name (first (screen-groups (current-screen)))) "Browse") (run-commands "gnewbg Edit" "gnewbg Term" "gnewbg Comms" "gnewbg Misc") ;; Change the prefix key ;; keycode 115 = F20 in ~/.xmodmaprc, 115 being the left "windows" key. (set-prefix-key (kbd "F20")) ;; Set up X cursor and colors. (run-shell-command (cat "xsetroot -cursor_name left_ptr -fg " BACKGROUND-COLOR ; Cursor body " -bg " BORDER-COLOR)) ; Cursor outline ;; Keep the X cursor out of the way. Even when I want it. (run-with-timer 5 5 'banish-pointer) ;; Configure and start the modeline. Colors are handled above. (setf *mode-line-border-width* 1) (setf *mode-line-pad-x* 1) (setf *mode-line-pad-y* 1) (setf *mode-line-position* :bottom) (setf *mode-line-timeout* 10) ; Update every 10 seconds if nothing else has triggered it already. (setf *screen-mode-line-format* (list "(%n %w) (" ; Current group and frames `(:eval (format-time-string)) ") (" ; Just a spacer `(:eval (mpd-info MPD-HOST MPD-PORT MPD-PASS)) ; Defined above ")")) ;; Switch mode-line on only if needed. Found at: ;; http://hcl-club.lu/svn/development/lisp/.stumpwmrc (if (not (head-mode-line (current-head))) (toggle-mode-line (current-screen) (current-head))) ;; Found this tidbit browsing the source. Defaults to :ignore (setf *mouse-focus-policy* :click) ; I'm fucking lame. ;;; Keyboard shortcuts. ;; Fluxbox-style Alt-F# virtual desktop (group in StumpWM-speak) switching. Modified from: ;; http://hcl-club.lu/svn/development/lisp/.stumpwmrc (dotimes (i 13) (unless (eq i 0) ; F0 is non-existant and will error. (define-key *top-map* (kbd (format nil "M-F~a" i)) (format nil "gselect ~a" i)))) ;; Applications. (define-key *root-map* (kbd "b") "exec firefox ") (define-key *root-map* (kbd "e") "exec xemacs ") (define-key *root-map* (kbd "c") (cat "exec urxvt -fg " FOREGROUND-COLOR " -bg " BACKGROUND-COLOR " -pr " FOREGROUND-COLOR " +sb ")) ;; Audio controls, uses un-numlocked keypad. ;; Some keys duplicated, not sure which I prefer yet. (define-key *top-map* (kbd "KP_Up") "mpc-volume-up") (define-key *top-map* (kbd "KP_Add") "mpc-volume-up") ; Redundant (define-key *top-map* (kbd "KP_Down") "mpc-volume-down") (define-key *top-map* (kbd "KP_Subtract") "mpc-volume-down") ; Redundant (define-key *top-map* (kbd "KP_Left") "mpc-song-prev") (define-key *top-map* (kbd "KP_Right") "mpc-song-next") (define-key *top-map* (kbd "Num_Lock") "mpc-pause") ; The light indicates play/pause(define-stumpwm-command "mpc-volume-up" () "Increase MPD playback volume." (mpd-command MPD-HOST MPD-PORT MPD-PASS "volume +5")) (define-stumpwm-command "mpc-volume-down" () "Decrease MPD playback volume." (mpd-command MPD-HOST MPD-PORT MPD-PASS "volume -5")) (define-stumpwm-command "mpc-song-next" () "Switches MPD playback to next song." (mpd-command MPD-HOST MPD-PORT MPD-PASS "next")) (define-stumpwm-command "mpc-song-prev" () "Switches MPD playback to previous song." (mpd-command MPD-HOST MPD-PORT MPD-PASS "previous")) (define-stumpwm-command "mpc-pause" () "Pause/unpause MPD" (mpd-command MPD-HOST MPD-PORT MPD-PASS "pause"))
The coin landed. Guess those kids live afterall.
EMT-Basic Application Summary:
Application Confirmation ID: xxxxxxxxxx
Application Created: 11/15/2007 4:14:00 PM (CST)
Exam Date: 1/10/2008 (CST)
Results Date: 1/11/2008 (CST)
Examination Scored
Congratulations on passing the NREMT cognitive examination. Your passing result on the cognitive examination will remain valid for a one year period from the date of the examination, 1/10/2008(provided you meet all current requirements for National EMS Certification.
Please allow 2 weeks for the NREMT to mail out results letters.
The coin’s flipped. Expect to land in a couple days.
I havn’t a damn clue if I passed, and I won’t for at least a couple days.
I did all the read & signin stuff, and was told to come back in 20 minutes. The test took that damn long to load. And when it finally finished? I clicked through the usual instructions explaining such vastly complicated concepts such as how to click “next”, the last of which produced nothing but the iconic hourglass pointer. For another 5-10 minutes. Then it finally loaded the first question.
The exam kept asking a bunch of children-related questions, which likely means I was totally bombing in that area. Poor kids. And a *lot* of the questions were of the two or three of these are damn well technically correct but pick the “best” one and hell no you can’t get more detail sort. I hate that, so much. And all of the questions were situational. It would have been nice if the workbook we had was in this format, but it was more concerned with definitions and acronyms and order of steps and etc…, which the exam asked precisely zero of (if it had, I’d already know I passed).
But then again, a lot of the questions did seem fairly obvious as well, and quite a few seemed likely to be considered “difficult” (that test throws some really weird shit at you) which is supposed to happen when you’re answering correctly… so I don’t know. I’ll find out in a couple days and if I need to retest, so be it. At least I’ll know what’s coming and can adjust my study accordingly.
But for now, other than rereading the hell out of that pediatric chapter, I’m giving it a break before I get stressed out. I think I’ll write a CL package for MusicPD access or something.
“The time has come,” the walrus said…
In about half an hour I’ll be on my way to take my NREMT-Basic license examination. I don’t think I’ve never been so nervous before a test, and I don’t know why. Maybe it’s because they apparently confiscate your wallet, keys, cell phone, watch, take your fingerprints, video record the session… sounds like jail. Maybe I’m just afraid I’ll fail, given the class finished over a month ago and we’re just now getting to test, a long time to forget things. It costs $70 *per attempt*. Maybe it’s all the coffee, I’m not usually a day person. But I have been reviewing a lot these past couple days, and I certainly wouldn’t feel uncomfortable at an actual emergency, I actually found the required hospital and ambulance observation times more fun than worrying and wish I were working already. Getting *paid* to do that? Hell yeah, sign me up (and probably demand a haircut, but I’ll live). And regardless, anytime something important such as this comes up, I always seem to pass. State HS final, driving, VoTech (hell, I went to nationals), the entrance exam for college, never had to retake anything. And if I somehow manage to fail, hell I have the $70 to study my ass off and try again. But still, I’m nervous as hell. Wish me luck. Time to jump in the shower and get my ass out the door.
.stumpwmrc 0.5
; -*-lisp-*-
;;; 0.5
;; 2008/01/09
;; Moved all the audio commands to un-numlocked keypad. Who uses those keys anyway?
;; Don't need the prefix key this way either, much more efficient.
;; Added Fluxbox-style alt-F# virtual desktop (group in StumpWM speak) switch. Modified from:
;; http://hcl-club.lu/svn/development/lisp/.stumpwmrc
;; Replaced call to (mode-line) with something more intelligent. Found at:
;; http://hcl-club.lu/svn/development/lisp/.stumpwmrc
(in-package :stumpwm)
;;; Internal variable definitions.
(defparameter FOREGROUND-COLOR "green")
(defparameter BACKGROUND-COLOR "black")
(defparameter BORDER-COLOR FOREGROUND-COLOR)
(setf *format-time-string-default* "%a %b %e %k:%M")
(defparameter MPD-HOST "127.0.0.1")
(defparameter MPD-PORT 2100)
(defparameter MPD-PASS "")
;;; Internal function definitions.
;; Found at:
;; http://en.wikipedia.org/wiki/User:Gwern/.stumpwmrc
(defun cat (&rest strings) "A shortcut for (concatenate 'string foo bar)."
(apply 'concatenate 'string strings))
;; My MPD "client".
(defun mpc (host port pass command) "Pass commands to MPD."
(with-open-stream (socket (socket:socket-connect port host :timeout 1))
(format socket "password ~a~%" pass)
(format socket "~a~%" command)))
;; To be replaced.
(defun current-song-info () "Return current song information from MPD."
(run-shell-command "mpc | head -n 1 | tr -d '\\n'" t))
;;; Theme.
;; Window border colors.
(set-focus-color FOREGROUND-COLOR)
(set-unfocus-color BACKGROUND-COLOR)
;; Input box colors.
(set-fg-color FOREGROUND-COLOR)
(set-bg-color BACKGROUND-COLOR)
(set-border-color BORDER-COLOR)
;; Modeline colors.
(setf *mode-line-foreground-color* FOREGROUND-COLOR)
(setf *mode-line-background-color* BACKGROUND-COLOR)
(setf *mode-line-border-color* BORDER-COLOR)
;; Background.
(run-shell-command (cat "xsetroot -solid " BACKGROUND-COLOR))
;;; Init stuff.
;; Make frames 1-indexed.
;; See: http://lists.gnu.org/archive/html/stumpwm-devel/2006-08/msg00002.html
;; Found at: http://en.wikipedia.org/wiki/User:Gwern/.stumpwmrc
(setf *frame-number-map* "1234567890") ; Still doesn't seem to work.
;; Rename the first group to Browse and create the other groups.
;; Found at: http://en.wikipedia.org/wiki/User:Gwern/.stumpwmrc
(setf (group-name (first (screen-groups (current-screen)))) "Browse")
(run-commands "gnewbg Edit" "gnewbg Term" "gnewbg Comms" "gnewbg Misc")
;; Change the prefix key
;; keycode 115 = F20 in ~/.xmodmap, 115 being the left "windows" key.
(set-prefix-key (kbd "F20"))
;; Set up X cursor and colors.
(run-shell-command (cat "xsetroot -cursor_name left_ptr -fg " BACKGROUND-COLOR ; Cursor body
" -bg " BORDER-COLOR)) ; Cursor outline
;; Keep the X cursor out of the way.
(run-with-timer 5 5 'banish-pointer)
;; Configure and start the modeline. Colors are handled above.
(setf *mode-line-border-width* 1)
(setf *mode-line-pad-x* 1)
(setf *mode-line-pad-y* 1)
(setf *mode-line-position* :bottom)
(setf *mode-line-timeout* 10) ; Update every 10 seconds if nothing else has triggered it already.
(setf *screen-mode-line-format* (list "(%n %w) (" ; Current group and frames
`(:eval (format-time-string))
") (" ; Just a spacer
`(:eval (current-song-info)) ; Defined above
")"))
;; Switch mode-line on only if needed. Found at:
;; http://hcl-club.lu/svn/development/lisp/.stumpwmrc
(if (not (head-mode-line (current-head)))
(toggle-mode-line (current-screen) (current-head)))
;; Found this tidbit browsing the source. Defaults to :ignore
(setf *mouse-focus-policy* :click) ; I'm fucking lame.
;;; Keyboard shortcuts.
;; Fluxbox-style Alt-F# virtual desktop (group in StumpWM-speak) switching. Modified from:
;; http://hcl-club.lu/svn/development/lisp/.stumpwmrc
(dotimes (i 13)
(unless (eq i 0)
(define-key *top-map* (kbd (format nil "M-F~a" i)) (format nil "gselect ~a" i))))
;; Applications.
(define-key *root-map* (kbd "b") "exec firefox ")
(define-key *root-map* (kbd "e") "exec xemacs ")
(define-key *root-map* (kbd "c") (cat "exec urxvt -fg " FOREGROUND-COLOR
" -bg " BACKGROUND-COLOR
" -pr " FOREGROUND-COLOR
" +sb "))
;; Audio controls, uses un-numlocked keypad.
;; Some keys duplicated, not sure which I prefer yet.
(define-key *top-map* (kbd "KP_Up") "mpc-volume-up")
(define-key *top-map* (kbd "KP_Down") "mpc-volume-down")
(define-key *top-map* (kbd "KP_Add") "mpc-volume-up") ; Redundant
(define-key *top-map* (kbd "KP_Subtract") "mpc-volume-down") ; Redundant
(define-key *top-map* (kbd "KP_Left") "mpc-song-prev")
(define-key *top-map* (kbd "KP_Right") "mpc-song-next")
(define-key *top-map* (kbd "Num_Lock") "mpc-pause") ; The light indicates play/pause
(define-key *top-map* (kbd "KP_Enter") "mpc-status")
(define-key *top-map* (kbd "KP_Insert") "mpc-status") ; Redundant
(define-stumpwm-command "mpc-status" () "Shows current MPD status and song info. MPC's default output."
(run-shell-command "mpc" t))
(define-stumpwm-command "mpc-volume-up" () "Increase MPD playback volume."
(mpc MPD-HOST MPD-PORT MPD-PASS "volume +10"))
(define-stumpwm-command "mpc-volume-down" () "Decrease MPD playback volume."
(mpc MPD-HOST MPD-PORT MPD-PASS "volume -10"))
(define-stumpwm-command "mpc-song-next" () "Switches MPD playback to next song."
(mpc MPD-HOST MPD-PORT MPD-PASS "next"))
(define-stumpwm-command "mpc-song-prev" () "Switches MPD playback to previous song."
(mpc MPD-HOST MPD-PORT MPD-PASS "previous"))
(define-stumpwm-command "mpc-pause" () "Pause/unpause MPD"
(mpc MPD-HOST MPD-PORT MPD-PASS "pause"))
-
Recent
-
Links
-
Archives
- October 2009 (1)
- August 2009 (1)
- July 2009 (3)
- April 2009 (2)
- March 2009 (1)
- December 2008 (1)
- November 2008 (1)
- September 2008 (1)
- July 2008 (5)
- June 2008 (8)
- April 2008 (3)
- March 2008 (5)
-
Categories
-
RSS
Entries RSS
Comments RSS