onilog

A strange HLWM configuration

29 January 2012 0:00 AM (guile | hlwm | scheme)

Heh, I only realized later that I'd posted snippets from my strange herbstluftwm config without explaining it. So you get lispy commands instead of bashy ones.

First, I'll say something to those people who don't know herbstluftwm, or its configuration method.

herbstluftwm uses a special program to send commands to the window manager while it's running. And the only configuration you can do is actually calling that program multiple times during startup. This may sound limiting in the way that I'm saying it, but it really isn't.

herbstluftwm calls the ~~/.config/herbstluftwm/autostart~ file. This file should contain some shell-executable code and should be executable by you. This means that it can be pretty much anything as long as it sends the right commands to the window manager.

By default a nice bash script is provided, as a starting point if you will. Now, as I'm almost certainly crazy (even just for trying this), I have replaced that original bash script with a guile script. Guile is the official GNU Extension Language and is an implementation of scheme, which is a lisp dialect. Since using emacs I have come to find lisp very interesting, and I've heard good things about guile, so I've always wanted to work with it more. Since I'm not really writing much at the moment, I'm looking for other ways to use it, like this one.

It wasn't all that hard, guile has some very nice and easy process management functions, and all I needed to do, really, was call the herbstclient program over and over again. So I wrote a function for that:

(define (hc command)
  "Calls the herbstclient program to execute a command"
  (system (string-append "herbstclient " command)))

This basically just calls the herbstclient program and appends the string command to it.

Then, there are some functions to help with setting up all the settings:

(define (keybind modkey key command)
  "Binds a keyboard key to a command, also prints it for testing
purposes"
  (display (string-append "keybind " modkey "-" key " " command "\n"))
  (hc (string-append "keybind " modkey "-" key " " command)))

(define (mousebind modkey button command)
  "Binds a mouse button to a command"
  (hc (string-append "mousebind " modkey "-" button " " command)))

(define (add-tag name)
  "Create a new tag"
  (hc (string-append "add " name)))

(define (set variable value)
  "Set the value of a variable"
  (hc (string-append "set " variable " " value)))

(define (unrule)
  "Clear all rules from memory"
  (hc "unrule -F"))

(define (rule spec)
  "Add a new rule"
  (hc (string-append "rule " spec)))

(define modkey "Mod4")

(define (create-tag name)
  (add-tag name)
  (keybind modkey name (string-append "use " name))
  (keybind modkey
           (string-append "Shift-" name)
           (string-append "move "  name)))

(define (dmenu-command fn nb nf)
  (string-append "dmenu_run -fn '" fn "' -nb '" nb "' -nf '" nf "'"))

(define (set-layout layout)
  (display (string-append "set_layout " layout "\n"))
  (hc (string-append "set_layout " layout)))

I've given them some docstrings, they should be fairly self explanatory that way. For the ones that don't have a docstring: create-tag creates a new tag (desktop) to be used, dmenu-command as a function I use to more easily change the values dmenu uses, set-layout sets a certain layout to be used and prints this for testing purposes.

This makes it easy to do many things, although having to do everything with strings is probably not very effici��nt. I'm still looking into creating a guile extension for herbstluftwm, but I have very little experience with IPCs, guile and X programming, so I'm not going very fast with that.

I hope that explains the lispy config snippets in my last post.

No responses

Leave a Reply