And then there's this funny thing nobody would want to implement in shell
script :)...

Working set inference using a biased Markov model with exponential decay

I normally have around a dozen open views/tags at a time, so even switching
to the Nth one with ALT+N becomes relatively difficult: counting past the 5th
view or so requires some thinking. A possible solution
can be found on wmii's wiki: a
key binding that jumps to the first view starting with the pressed letter.
But that won't work very well unless you name your views carefully.

Fortunately, the transitions between views aren't random: they're often
predictable, since I tend to stay within a given working set. I came up with
a way to discover it automagically.

My first idea was modelling the situation with a first-order Markov process:
I assume the probability of jumping to a view given the whole jump history is

where is the Nth view I jumped to, and is the set of
possible destination views. In other words, the view I'm going to jump to depends on which one I'm currently at.
The probabilities are updated incrementally as follows: when I've already jumped N times from
view , I assign

and increase the probability for the view I just chose with

Favoring the last choice

I modified the basic model to favor recent choices (so it forgets decisions distant in the past),
introducing exponential decay and a bias factor for the choice I just made:

would mean that only the last choice is remembered (all others get probability zero), and
is the normal Markov process. seems reasonable.

Favoring the view I came from

Another refinement consists in biasing for the view I just came from. This is
totally outside the Markov model, and I implemented it separately, by
assigning a configurable probability to that view before the candidate
destinations are sorted.

View intellisort in action

At the end of the day, the list of tags I get with Mod1+t is sorted in such
way that the one I want to go to comes normally first, and Mod4+letter takes
me to the view I want. I don't know how useful the later will be in practice,
though, as it overlaps functionally with Mod1+r (which takes me to the view
from which I jumped to the current one). All in all, this was most probably
way overdone, but it was fun. Try to write that in shell script someday ;)

Some other goodies

Mod4-space

switch keyboard mode (raw/normal)

Mod1-r

return to the view I came from (GOOD!)

Mod4-letter

jump to view starting with letter, uses intellisort

Mod4-comma,Mod4-period

jump to previous/next view within namespace

and many more...

Got Nil - chris (2006-06-22 (Thr) 04:15:53)

Hi,

wmii-ruby just rocks. Thx, for the great work. I really appreciate it.
There's one (minor) issue, though. On one machine the logfile gets filled with "DEBUG -- : Got nil". Any hints how to debug this?

Matt 2006-06-22 (Thr) 09:46:29

mfp 2006-06-22 (Thr) 10:30:21

Matt: good catch! fixing it... but I'm not sure about doing it exactly that way: I dislike having to rely on NilClass#to_i returning 0.

Wael: I'm working on a way to simplify updates & allow people to publish/exchange extensions easily. This is a fairly interesting problem actually (how to manage sw distribution&deployment, API changes and backwards compatibility in a situation very given to breakage).

Wael Nasreddine 2006-06-23 (Fri) 04:04:49

Mauricio I thought of a way to do the extension you said, the file has Two important sections, the bar and the plugins (internal plugins), So instead of filling the wmiirc script with such code, we can create two subdirectories ~/.wmii-3/plugins and ~/.wmii-3/bar, wmiirc script will include all files in those 2 folders, So updating it would be much much easier...

Also I agree with Tom, we should split the wmiirc file into config file and WMII module...

mfp 2006-06-26 (Mon) 04:43:45

Tom, Wael: I implemented the new configuration system over the weekend, you should be receiving an email with the details. To sum up, there are now three parts to ruby-wmii:

the main wmiirc, with the core and standard bindings/bar applets. It can be overwritten safely on upgrade.

wmiirc-config.rb: contains the user settings, preserved on upgrade

~/.wmii-3/plugins: third party plugins with other bindings/actions and bar applets

Wael: I uploaded a copy of my darcs repository to

http://eigenclass.org/repos/ruby-wmii/

As for the crash: the last version uses wmiisetsid to launch external programs; ruby-wmii 0.2.1 didn't and I think that's the culprit of your crash.

Nathan 2006-06-30 (Fri) 16:52:54

[mfp: reformatted]

Just trying out the new goodies now (from darcs). Thanks for writing it :-). Here's a few quick points/questions so far:

I think wmiirc needs to set ENV["WMII_FONT"] as well, or wmiimenu will just use fixed all the time.

What's with the two modkey thing? Is it the only way to get enough keys for the mod-letter switching? I disabled it for now (although I liked it) since I need mod1 in some apps (I use mod4 for wm functions.)

I don't get the raw/normal mode setup... what's the point? (meaning, what am I missing here? :-) )

Maybe the volume/mpd/dict etc. bits could be removed from the main wmiirc and made into plugins? It would simplify and shorten the main script, which would make it easier to get started figuring the whole thing out... (you know, for people like me right now)

Anyway, thanks for the great script. I'm sure I'll have more comments sometime, and maybe a plugin or two...

Nathan 2006-06-30 (Fri) 16:56:33

Argh. I've got to get into the habit of using * for lists... sorry about that.

[mfp: np, the benevolent cens^H^H^H^Heditor reformatted it :)]

mfp 2006-07-01 (Sat) 01:11:11

You're very right about WMII_FONT, I'm fixing that.
As for MODKEY2, all MODKEY2+letter combinations are taken by the letter-jump-x bindings, leaving few simple sequences free. Note that you could change the key_subs to e.g.

:MODKEY => Mod4, :MODKEY2 => Mod3

and assign Mod3 to the "Menu" key with

xmodmap -e "add mod3 = Menu"

if you absolutely want Mod1 to remain free for other apps. OTOH, if only a few Mod1+x bindings interfere with your apps', raw mode might prove useful: it's just a pass-through mode where nothing (but the sequence to get back to normal mode) is captured by wmii.
You can also set something like

key_subs :MODKEY => "Control-t"

which would turn C-t into a sort of WM command prefix.

Anyway, that's just the default configuration and you can rebind everything to your hearts' content in wmiirc-config.rb :)

There's one important practical reason to keep wmiirc's support code and the default configuration in a single file: this way upgrading involves overwriting a single file, and you get both the core upgrades and the fixes to the default actions/applets at once.
But you're right, it makes the script harder to read... One solution would be providing better documentation so that there's no need to read wmiirc just to figure how to configure the thing (I'm thinking of adding some mechanism to document plugins). Another would be providing an installation script that copies the standard plugin under ~/.wmii-3/plugins.
Hmmm actually I think I'll do that too :)

Celti 2006-07-01 (Sat) 01:18:03

I rather love the modal setup. If I'm using an app with keybindings that conflict with wmii, M2-Space and I'm free to use the app without worrying about making keybindings that don't conflict with a seldom-used application.

I still want an x86 version of the space-cadet keyboard, though. There will never be enough easily-accessible shortcuts to satisfy me.

Nathan 2006-07-01 (Sat) 12:11:10

Ok, now the modal thing makes sense... I think that will work nicely. Thanks.

Oh, and you've got a typo on the last line of use_binding that prevents key overriding from working...

on_key(*keys, &block)

should be:

on_key(*actual_keys, &block)

mfp 2006-07-02 (Sun) 01:21:40

Thanks, committed.
I also moved the standard plugin to a separate file and wrote install.rb.