wmii: auto-tagging
September 1st, 2006
Lately I’ve been playing with wmii, the window manager. The ruby-addons for wmii by mfp open up the base wmii quite a bit. Once I got used to this dynamic window manager, I can’t imagine going back to WIMP.
I started to poke around in the ruby-wmii config files, because I was curious about how whenever I opened Firefox, the client was automatically tagged with “web”. Since I was constantly tagging my other apps with names using MODKEY-ctrl-T, I decided I wanted some of them to auto-tag like the browsers do.
After initially just copying the existing code that tags the browsers, I finally worked out a way to get it to tag things the way I want them.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# *** excerpt of wmiirc-config.rb *** # first, I commented out this orginal tagger # {{{ Tag all browser instances as 'web' in addition to the current tag # browsers = %w[Firefox Konqueror] # browser_re = /^#{browsers.join("|")}/ # on_createclient(condition{|c| browser_re =~ read("/client/#{c}/class")}) do |cid| # write("/client/#{cid}/tags", normalize(read("/client/#{cid}/tags") + "+web")) # end ############################################# # here's the stuff I added # these are tags for particular apps that I want to have # new tags - note, they won't get appended to their current tag tag_for_apps = { "irc" => "Xchat", "gaim" => "Gaim", "web" => "Firefox", "4-jedit" => "jedit" } # these are terminals that I've given specific titles to # so they can be tagged tag_for_named_terms = { "2-consoles" => "console:", "3-logs" => "log:", "1-terms" => "term:" } # now when a new client comes up, check for an autotag on_createclient do |cid| LOGGER.info "checking for autotag on class: #{read("/client/#{cid}/class")} " + "and name: #{read("/client/#{cid}/name")} " # if this client is a terminal, check the 'name' if /terminal/ =~ read("/client/#{cid}/class") tag_for_named_terms.each do |tfn| names_re = /#{tfn[1]}/ if names_re =~ read("/client/#{cid}/name") write("/client/#{cid}/tags", tfn[0]) LOGGER.info " ... autotag'd #{tfn[1]} with #{tfn[0]}!" end end # not a terminal, so go by the 'class' else tag_for_apps.each do |tfa| apps_re = /#{tfa[1]}/ if apps_re =~ read("/client/#{cid}/class") write("/client/#{cid}/tags", tfa[0]) LOGGER.info " ... autotag'd #{tfa[1]} with #{tfa[0]}!" end end end end |
Notice, for terminals, I check for certain terminal window titles. I changed my gnome-terminal script a bit, so now it looks like this:
#!/bin/sh
# set working dir
wd="/home/jason/dev/rails_app"
gnome-terminal --working-directory=$wd --hide-menubar -e "mongrel_rails start" -t "log: web server" \
--window --working-directory=$wd --hide-menubar -e "tail -f log/development.log" -t "log: dev log" \
--window --working-directory=$wd --hide-menubar -e "script/console" -t "console: rails irb" \
--window --working-directory=$wd --hide-menubar -e "mysql -u root --password=mysecret myapp_development" -t "console: mysql" \
--window --working-directory=$wd --hide-menubar -t "term: approot"
For some of my tag names, I stick a number in the front – that’s just to force them into order so I can easily MODKEY-n over to them.
I’d like to work the auto-tagger out into a plugin, but after poking around some of the existing plugins I gave up. I have no idea how to check for on_createclient from within a plugin, and I’m pretty confused about how those long-winded option get passed to plugins. If anyone has any hints, I’d love to hear them.
4 Responses to “wmii: auto-tagging”
Sorry, comments are closed for this article.


September 4th, 2006 at 10:32 AM
What’s the advantage of this over the built-in wmii rules? Maybe I don’t get something, but it looks to me like what you’ve written is basically the same functionality-wise as this, earlier on in the wmiirc-config.rb:
rules <<eof />EOF
When I start firefox, nicotine, etc. or open new windows within them, they are “auto-tagged”, i.e. they pop up in a view with no other tags than what I’ve specified there.
September 4th, 2006 at 10:42 AM
and the thing I’ve pasted looks like this with linebreaks:
I apologise for the comment spammage, I really have no experience with making comments on blogs ;)
September 5th, 2006 at 03:40 AM
Um. I guess I didn’t realize you could do that. When I looked at the default ‘rules’ I just got the impression they were mainly there for sending certain apps to the floating layer. I saw the section for tagging Firefox/Konquerer with ‘web’ and assumed that was the way to do it.
In retrospect, I guess the only advantage to using my example is if for some reason you want a little more control, as with the way I ‘title’ my terminal windows and then tag them by parts of their titles.
September 5th, 2006 at 07:24 PM The functionality provided by tag_for_apps is equivalent to the rules moskvax showed. However, the one thing the code in the default wmiirc-config.rb (with the on_createclient callback) does that rule matching can’t is adding a tag without replacing the current one. For instance, whereas would tag firefox as “net” unconditionally,
# {{{ Tag all browser instances as 'web' in addition to the current tag browsers = %w[Firefox Konqueror] browser_re = /^#{browsers.join("|")}/ on_createclient(condition{|c| browser_re =~ read("/client/#{c}/class")}) do |cid| write("/client/#{cid}/tags", normalize(read("/client/#{cid}/tags") + "+web")) endmerely retags it as <current_tag>+web. The point of this is ensuring that all browser windows are visible in the “web” view (so that I can close them easilyI often have a dozen tags at a time and going through each one to close old windows would be painful), while letting each window remain in the view where it was created originally.
Here’s another use case: when I’m hacking rcov, I often want to have both a browser window and the console where I’m hacking visible at a time. If my browsers went to “web” automatically, I’d have to pull one by going to the web view and retagging it as +rcov. With the above code, it’s tagged as rcov+web and I don’t need to retag.
As for how to wrap it up as a plugin: atm. only bindings and bar applets can be imported selectively withfrom "me@foo.com" do use_binding "bar" use_bar_applet "baz" endThis means that right now your snippet would have to be added to wmiirc-config.rb directly. However, I’ll probably implement “generalized plugins”, which would allow any code to be evaluated in the WMII::Configuration context. I’ll also try to improve the documentation.