[228] in BarnOwl Developers

home help back first fref pref prev next nref lref last post

[D-O-H] r404 - in trunk: . conf.asedeno conf.asedeno/owl conf.asedeno/owl/modules

daemon@ATHENA.MIT.EDU (asedeno@darkmatter.mit.edu)
Thu Oct 29 18:03:54 2009

Resent-From: nelhage@mit.edu
Resent-To: barnowl-dev-mtg@charon.mit.edu
To: dirty-owl-hackers@mit.edu
From: asedeno@darkmatter.mit.edu
Reply-to: dirty-owl-hackers@MIT.EDU
Date: Wed, 25 Oct 2006 18:59:36 -0400 (EDT)

Author: asedeno
Date: 2006-10-25 18:59:35 -0400 (Wed, 25 Oct 2006)
New Revision: 404

Added:
   trunk/conf.asedeno/
   trunk/conf.asedeno/README
   trunk/conf.asedeno/owl/
   trunk/conf.asedeno/owl/modules/
   trunk/conf.asedeno/owl/modules/ColorUtils.pl
   trunk/conf.asedeno/owl/modules/PageView.pl
   trunk/conf.asedeno/owl/modules/VT-asedeno.pl
   trunk/conf.asedeno/owl/modules/thread_example_1.pl
   trunk/conf.asedeno/owl/owlconf.pl
   trunk/conf.asedeno/owlconf
Log:
Committing my owlconf system, and some modules.



Added: trunk/conf.asedeno/README
===================================================================
--- trunk/conf.asedeno/README	2006-10-25 06:44:24 UTC (rev 403)
+++ trunk/conf.asedeno/README	2006-10-25 22:59:35 UTC (rev 404)
@@ -0,0 +1,5 @@
+owlconf = ~/.owlconf
+owl = ~/.owl
+
+owl/owlconf.pl is the heart of my "module" system, and it has plenty
+of comments in line.

Added: trunk/conf.asedeno/owl/modules/ColorUtils.pl
===================================================================
--- trunk/conf.asedeno/owl/modules/ColorUtils.pl	2006-10-25 06:44:24 UTC (rev 403)
+++ trunk/conf.asedeno/owl/modules/ColorUtils.pl	2006-10-25 22:59:35 UTC (rev 404)
@@ -0,0 +1,604 @@
+# Colors module.
+package ARS_Color;
+
+################################################################################
+#Run this on start and reload. Adds styles, sets style to start.
+################################################################################
+sub onStart
+{
+    bindings_Color();
+    load();
+}
+
+push @::onStartSubs, \&onStart;
+
+
+################################################################################
+# Help information
+################################################################################
+sub moduleHelp()
+{
+    my @helpmsgArray = <<END_OF_HELP ;
+Module: ColorUtils (package: ARS_Color)
+
+  Module keys:
+    C-d (0-9)     Change the color for this sender or class (or instance if 
+		   -c message) to
+                  0 - Black              1 - Red
+                  2 - Green              3 - Yellow
+                  4 - Blue               5 - Magenta
+                  6 - Cyan               7 - White
+		  8 - (reset)            9 - (reset)
+
+    C-d b         Toggle bold for this sender or class (or instance if
+		   -c message). Bold support only matters for styles that
+		   support it, such as VT-asedeno.
+    C-d u         Unset the color for this sender or class (or instance if
+		   -c message).
+    C-d d         Reset color for this sender or class to the color specified
+                   when colors were last loaded. This will reset the instance
+		   color instead if -c message, or if reseting the class color
+		   would be a no-op.
+
+    M-C-d (0-9)   These keybindings work like their counterparts above, but
+    M-C-d b        for instances of a class. Class+Instance settings override
+    M-C-d u        specific class settings.
+    M-C-d d       
+    
+    C-d l         (Re)Load color information from ~/.owl/colormap
+    C-d s         Save color information to ~/.owl/colormap
+
+END_OF_HELP
+
+    return @helpmsgArray;
+}
+push @::onModuleHelp, \&moduleHelp;
+
+################################################################################
+## Color state.
+################################################################################
+#our %colors = ();
+#our %cSaved = ();
+#our %bolds = ();
+#our %bSaved = ();
+
+our %currentColorMap = ();
+our %savedColorMap = ();
+our %currentBoldMap = ();
+our %savedBoldMap = ();
+our %mode2Protocol = ('zephyr' => 'zephyr',
+		      'zephyr-personal' => 'zephyr',
+		      'aim' => 'aim',
+		      'loopback' => 'loopback');
+
+################################################################################
+## Loading function
+################################################################################
+sub createFilters
+{
+    # Prepare the color filters.
+    my @colorList = ('black','red','green','yellow',
+		     'blue','magenta','cyan','white');
+    foreach my $color (@colorList)
+    {
+	my $str = "filter $color -c $color ( ";
+
+	#######################################################################
+	my $mode = 'zephyr';
+	{
+	    $str .= ' ( type ^'.$mode2Protocol{$mode}.'$ and ( ';
+	    foreach my $c (sort keys %{ $currentColorMap{$mode} })
+	    {
+		$c =~ s/([+*])/\\\1/g;
+		my $strClass = '';
+		if ($currentColorMap{$mode}{$c}{'*'} eq $color)
+		{
+		    $strClass .= ' ( class ^'.$c.'(.d)*$ ';
+		    my $strInst = '';
+		    
+		    foreach my $i (sort keys %{ $currentColorMap{$mode}{$c} })
+		    {
+			next if (($i eq '*') || ($currentColorMap{$mode}{$c}{$i} eq $color));
+			$i =~ s/([+*])/\\\1/g;
+			$strInst .= ' and ' if ($strInst ne "");
+			$strInst .= ' ( not instance ^'.$i.'(.d)*$ ) ';
+		    }
+		    
+		    $strClass .= ' and ( '.$strInst.' ) ' if ($strInst ne "");
+		    $strClass .= ' ) ';
+		}
+		else
+		{
+		    my $strInst = '';
+		    foreach my $i (sort keys %{ $currentColorMap{$mode}{$c} })
+		    {
+			next if (($i eq '*') || ($currentColorMap{$mode}{$c}{$i} ne $color));
+			$i =~ s/([+*])/\\\1/g;
+			$strInst .= ' or ' if ($strInst ne "");
+			$strInst .= ' ( instance ^'.$i.'(.d)*$ ) ';
+		    }
+		    $strClass = '( class ^'.$c.'(.d)*$ and ( '.$strInst.' ) ) '  if ($strInst ne "");
+		}
+		$str .= ' '.$strClass.' or ' if ($strClass ne "");
+	    }
+	    $str .= ' false ) ) or ';
+	}
+	#######################################################################
+	$mode = 'zephyr-personal';
+	{
+	    my $zpStr .= ' ( type ^'.$mode2Protocol{$mode}.'$ and ( ( class ^message$ and instance ^personal$ ) or class ^login$ ) and ( ';
+	    my $count = 0;
+	    foreach my $sender (sort keys %{ $currentColorMap{$mode} })
+	    {
+		next if ($currentColorMap{$mode}{$sender} ne $color);
+		$sender =~ s/([+*])/\\\1/g;
+		$count++;
+		$zpStr .= ' sender ^'.$sender.'$ or recipient ^'.$sender.'$ or ';
+	    }
+	    $zpStr .= ' false ) ) or ';
+	    $str .= $zpStr if ($count);
+	}
+	#######################################################################
+	$mode = 'aim';
+	{
+	    my $aimStr .= ' ( type ^'.$mode2Protocol{$mode}.'$ and ( ';
+	    my $count = 0;
+	    foreach my $sender (sort keys %{ $currentColorMap{$mode} })
+	    {
+		next if ($currentColorMap{$mode}{$sender} ne $color);
+		$sender =~ s/([+*])/\\\1/g;
+		$count++;
+		$aimStr .= ' sender ^'.$sender.'$ or recipient ^'.$sender.'$ or ';
+	    }
+	    $aimStr .= ' false ) ) or ';
+	    $str .= $aimStr if ($count);
+	}
+	#######################################################################
+	$mode = 'loopback';
+	{
+	    $str .= ' ( type ^'.$mode2Protocol{$mode}.'$ ) or ' if ($currentColorMap{$mode} eq $color);
+	}
+	#######################################################################
+	$str .= " false ) ";
+	$str =~ s/or\s+false//g;
+	owl::command($str);
+    }
+}
+
+sub bindings_Color
+{
+    # sender/class coloring (also works on -c message)
+    owl::command('bindkey recv "C-d 0" command perl ARS_Color::setBlack(0)');
+    owl::command('bindkey recv "C-d 1" command perl ARS_Color::setRed(0)');
+    owl::command('bindkey recv "C-d 2" command perl ARS_Color::setGreen(0)');
+    owl::command('bindkey recv "C-d 3" command perl ARS_Color::setYellow(0)');
+    owl::command('bindkey recv "C-d 4" command perl ARS_Color::setBlue(0)');
+    owl::command('bindkey recv "C-d 5" command perl ARS_Color::setMagenta(0)');
+    owl::command('bindkey recv "C-d 6" command perl ARS_Color::setCyan(0)');
+    owl::command('bindkey recv "C-d 7" command perl ARS_Color::setWhite(0)');
+    owl::command('bindkey recv "C-d 8" command perl ARS_Color::reset(0)');
+    owl::command('bindkey recv "C-d 9" command perl ARS_Color::reset(0)');
+    owl::command('bindkey recv "C-d d" command perl ARS_Color::reset(0)');
+    owl::command('bindkey recv "C-d u" command perl ARS_Color::setUndef(0)');
+    owl::command('bindkey recv "C-d C-d" command perl ARS_Color::reset(0)');
+
+    # instance coloring
+    owl::command('bindkey recv "M-C-d 0" command perl ARS_Color::setBlack(1)');
+    owl::command('bindkey recv "M-C-d 1" command perl ARS_Color::setRed(1)');
+    owl::command('bindkey recv "M-C-d 2" command perl ARS_Color::setGreen(1)');
+    owl::command('bindkey recv "M-C-d 3" command perl ARS_Color::setYellow(1)');
+    owl::command('bindkey recv "M-C-d 4" command perl ARS_Color::setBlue(1)');
+    owl::command('bindkey recv "M-C-d 5" command perl ARS_Color::setMagenta(1)');
+    owl::command('bindkey recv "M-C-d 6" command perl ARS_Color::setCyan(1)');
+    owl::command('bindkey recv "M-C-d 7" command perl ARS_Color::setWhite(1)');
+    owl::command('bindkey recv "M-C-d 8" command perl ARS_Color::reset(1)');
+    owl::command('bindkey recv "M-C-d 9" command perl ARS_Color::reset(1)');
+    owl::command('bindkey recv "M-C-d d" command perl ARS_Color::reset(1)');
+    owl::command('bindkey recv "M-C-d u" command perl ARS_Color::setUndef(1)');
+    owl::command('bindkey recv "M-C-d d" command perl ARS_Color::reset(1)');
+    owl::command('bindkey recv "M-C-d M-C-u" command perl ARS_Color::setUndef(1)');
+    owl::command('bindkey recv "M-C-d M-C-d" command perl ARS_Color::reset(1)');
+
+    # bold toggling
+    owl::command('bindkey recv "C-d b" command perl ARS_Color::toggleBold()');
+    owl::command('bindkey recv "C-d C-b" command perl ARS_Color::toggleBold()');
+    owl::command('bindkey recv "M-C-d b" command perl ARS_Color::toggleBold(1)');
+    owl::command('bindkey recv "M-C-d M-C-b" command perl ARS_Color::toggleBold(1)');
+
+    # save/load
+    owl::command('bindkey recv "C-d s" command perl ARS_Color::save()');
+    owl::command('bindkey recv "C-d l" command perl ARS_Color::load()');
+}
+
+################################################################################
+## Color toggling functions
+################################################################################
+sub isZPersonal
+{
+    # Return 1 for things that would qualify a zephyr as personal.
+    $m = shift;
+    return 1 if ($m->recipient ne "" and $m->recipient !~ /^@/);
+    return 1 if lc($m->class) eq "login";
+    return 0;
+}
+
+sub setBlack {setColor('black',shift)}
+sub setRed {setColor('red',shift)}
+sub setGreen {setColor('green',shift)}
+sub setYellow {setColor('yellow',shift)}
+sub setBlue {setColor('blue',shift)}
+sub setMagenta {setColor('magenta',shift)}
+sub setCyan {setColor('cyan',shift)}
+sub setWhite {setColor('white',shift)}
+sub setUndef 
+{
+    my $bInst = shift;
+    my $m = owl::getcurmsg();
+    my $type = lc($m->type);
+    if ($type eq 'zephyr')
+    {
+	if (isZPersonal($m))
+	{
+	    my $sender = lc((lc($m->direction) eq 'in') ? $m->sender : $m->recipient);
+	    delete $currentColorMap{'zephyr-personal'}{$sender};
+	    delete $currentBoldMap{'zephyr-personal'}{$sender};
+	}
+	else
+	{
+	    my $class = lc($m->class);
+	    my $instance = ($bInst || ($class eq 'message')) ? lc($m->instance) : '*';
+	    
+	    if ($instance eq '*')
+	    {
+		$currentColorMap{$type}{$class}{$instance} = default;
+	    }
+	    else
+	    {
+		delete $currentColorMap{$type}{$class}{$instance};
+	    }
+	    delete $currentBoldMap{$type}{$class}{$instance};
+	}
+    }
+    elsif ($type eq 'aim')
+    {
+	my $sender = (lc($m->direction) eq 'in') ? $m->sender : $m->recipient;
+	delete $currentColorMap{$type}{$sender};
+	delete $currentBoldMap{$type}{$sender};
+    }
+    elsif ($type eq 'loopback')
+    {
+	delete $currentColorMap{$type};
+	delete $currentBoldMap{$type};
+    }
+
+    refreshView();
+}
+
+sub setColor
+{
+    my $color = shift;
+    my $bInst = shift;
+    my $m = owl::getcurmsg();
+
+    my $type = lc($m->type);
+    if ($type eq 'zephyr')
+    {
+	if (isZPersonal($m))
+	{
+	    my $sender = lc((lc($m->direction) eq 'in') ? $m->sender : $m->recipient);
+	    $currentColorMap{'zephyr-personal'}{$sender} = $color;
+	}
+	else
+	{
+	    my $class = lc($m->class);
+	    my $instance = ($bInst || ($class eq 'message')) ? lc($m->instance) : '*';
+	    $currentColorMap{$type}{$class}{$instance} = $color;
+	}
+    }
+    elsif ($type eq 'aim')
+    {
+	my $sender = lc((lc($m->direction) eq 'in') ? $m->sender : $m->recipient);
+	$currentColorMap{$type}{$sender} = $color;
+    }
+    elsif ($type eq 'loopback')
+    {
+	$currentColorMap{$type} = $color;
+    }
+
+    refreshView();
+}
+
+sub reset
+{
+    my $bInst = shift;
+    my $m = owl::getcurmsg();
+    my $type = lc($m->type);
+    if ($type eq 'zephyr')
+    {
+	if (isZPersonal($m))
+	{
+	    my $sender = lc((lc($m->direction) eq 'in') ? $m->sender : $m->recipient);
+	    if (my $oldColor = $savedColorMap{'zephyr-personal'}{$sender})
+	    {
+		$currentColorMap{'zephyr-personal'}{$sender} = $oldColor;
+	    }
+	    else
+	    {
+		delete $currentColorMap{'zephyr-personal'}{$sender};
+	    }
+	    $currentBoldMap{'zephyr-personal'}{$sender} = $savedBoldMap{'zephyr-personal'}{$sender};
+	}
+	else
+	{
+	    my $class = lc($m->class);
+	    $instance = lc($m->instance);
+	    $instance = 
+		($bInst 
+		 || ($class eq 'message')
+		 || (($savedColorMap{$type}{$class}{'*'} eq $currentColorMap{$type}{$class}{'*'})
+		     && ($savedBoldMap{$type}{$class}{'*'} eq $currentBoldMap{$type}{$class}{'*'})
+		     && ($savedColorMap{$type}{$class}{$instance} ne $currentColorMap{$type}{$class}{$instance}
+			 || $savedBoldMap{$type}{$class}{$instance} ne $currentBoldMap{$type}{$class}{$instance}))
+		     )
+		? $instance
+		: '*';
+
+	    if(my $oldColor = $savedColorMap{$type}{$class}{$instance})
+	    {
+		$currentColorMap{$type}{$class}{$instance} = $oldColor;
+	    }
+	    else
+	    {
+		delete $currentColorMap{$type}{$class}{$instance};
+	    }
+	    $currentBoldMap{$type}{$class}{$instance} = $savedBoldMap{$type}{$class}{$instance};
+	}
+    }
+    elsif ($type eq 'aim')
+    {
+	my $sender = lc((lc($m->direction) eq 'in') ? $m->sender : $m->recipient);
+	if (my $oldColor = $savedColorMap{$type}{$sender})
+	{
+	    $currentColorMap{$type}{$sender} = $oldColor;
+	}
+	else
+	{
+	    delete $currentColorMap{$type}{$sender};
+	}
+	$currentBoldMap{$type}{$sender} = $savedBoldMap{$type}{$sender};
+    }
+    elsif ($type eq 'loopback')
+    {
+
+	if (my $oldColor = $savedColorMap{$type})
+	{
+	    $savedColorMap{$type} = $oldColor; 
+	}
+	else
+	{
+	    delete $savedColorMap{$type} 
+	}
+	$currentBoldMap{$type} = $savedBoldMap{$type};
+    }
+
+    refreshView();
+}
+
+sub toggleBold
+{
+    my $bInst = shift;
+    my $m = owl::getcurmsg();
+    my $type = lc($m->type);
+
+    if ($type eq 'zephyr')
+    {
+	if (isZPersonal($m))
+	{
+#	    my $sender = (lc($m->direction) eq 'in') ? $m->sender : $m->recipient;
+#	    $currentBoldMap{'zephyr-personal'}{$sender} = $currentBoldMap{'zephyr-personal'}{$sender} ? 0 : 1;
+	}
+	else
+	{
+	    my $class = lc($m->class);
+	    my $instance = ($bInst || ($class eq 'message')) ? lc($m->instance) : '*';
+	    
+	    $currentBoldMap{$type}{$class}{$instance} = (($currentBoldMap{$type}{$class}{$instance}) ? 0 : 1);
+	}
+    }
+    elsif ($type eq 'aim')
+    {
+	my $sender = (lc($m->direction) eq 'in') ? $m->sender : $m->recipient;
+	$currentBoldMap{$type}{$sender} = $currentBoldMap{$type}{$sender} ? 0 : 1;
+    }
+    elsif ($type eq 'loopback')
+    {
+	$currentBoldMap{$type} = $currentBoldMap{$type} ? 0 : 1;
+    }
+
+
+#    owl::command('view -s VT');
+    refreshView();
+}
+
+sub refreshView()
+{
+    createFilters();
+    my $filter = owl::command("getview");
+    my $style = owl::command("getstyle");
+
+    owl::command("view -f $filter ".($style?"-s $style":""));
+}
+
+################################################################################
+## Bold testing
+################################################################################
+sub isBold($)
+{
+    my $m = shift;
+    
+    my $type = lc($m->type);
+
+    if ($type eq 'zephyr')
+    {
+	if (isZPersonal($m))
+	{
+	    my $sender = (lc($m->direction) eq 'in') ? $m->sender : $m->recipient;
+	    return $currentBoldMap{'zephyr-personal'}{$sender};
+	}
+	else
+	{
+	    my $c = undef;
+	    my $class = lc($m->class);
+	    
+	    do
+	    {
+		my $instance = lc($m->instance);
+		do
+		{
+		    $c = $currentBoldMap{$type}{$class}{$instance};
+		    $instance =~ s/(.*)\.d$/$1/ei;
+		} while (($c eq undef) && $instance =~ /\.d$/i);
+		
+		if ($c eq undef)
+		{
+		    $c = $currentBoldMap{$type}{$class}{$instance} || $currentBoldMap{$type}{$class}{'*'};
+		}
+		$class =~ s/(.*)\.d$/$1/ei;
+		
+	    } while (($c eq undef) && $class =~ /\.d$/i);
+	    
+	    if ($c eq undef)
+	    {
+		$c = $currentBoldMap{$type}{$class}{$instance} || $currentBoldMap{$type}{$class}{'*'};
+	    }
+	    
+	    return $c ? 1 : 0;
+	}
+    }
+    elsif ($type eq 'aim')
+    {
+	my $sender = (lc($m->direction) eq 'in') ? $m->sender : $m->recipient;
+	return $currentBoldMap{$type}{$sender};
+	
+    }
+    elsif ($type eq 'loopback')
+    {
+	return $currentBoldMap{$type};
+    }
+}
+
+################################################################################
+## Saving/Loading functions
+################################################################################
+sub save
+{
+    open(COLORS, ">$ENV{HOME}/.owl/colormap");
+
+    my $type = 'zephyr';
+    print COLORS "MODE: $type\n";
+    foreach my $c (sort keys %{ $currentColorMap{$type} })
+    {
+
+	foreach my $i (sort keys %{ $currentColorMap{$type}{$c} })
+	{
+	    if ($i eq '*'
+		|| !(($currentBoldMap{$type}{$c}{$i} eq $currentBoldMap{$type}{$c}{'*'} || !$currentBoldMap{$type}{$c}{$i})
+		     && ($currentColorMap{$type}{$c}{$i} eq $currentColorMap{$type}{$c}{'*'} || !$currentColorMap{$type}{$c}{$i})))
+	    {
+		print COLORS "$c,$i,".($currentBoldMap{$type}{$c}{$i}?'b':'').($currentColorMap{$type}{$c}{$i} ? $currentColorMap{$type}{$c}{$i} : 'default')."\n";
+	    }
+        }
+    } 
+
+    $type = 'zephyr-personal';
+    print COLORS "MODE: $type\n";
+    foreach my $s (sort keys %{ $currentColorMap{$type} })
+    {
+	print COLORS "$s,".($currentBoldMap{$type}{$s}?'b':'').($currentColorMap{$type}{$s} ? $currentColorMap{$type}{$s} : 'default')."\n";
+    }
+
+    $type = 'aim';
+    print COLORS "MODE: $type\n";
+    foreach my $s (sort keys %{ $currentColorMap{$type} })
+    {
+	print COLORS "$s,".($currentBoldMap{$type}{$s}?'b':'').($currentColorMap{$type}{$s} ? $currentColorMap{$type}{$s} : 'default')."\n";
+    }
+
+    $type = 'loopback';
+    print COLORS "MODE: $type\n";
+    print COLORS ($currentBoldMap{$type}{$s}?'b':'').($currentColorMap{$type}{$s} ? $currentColorMap{$type}{$s} : 'default')."\n";
+
+    close(COLORS);
+    load();
+}
+
+sub load
+{
+    %currentColorMap = ();
+    %savedColorMap = ();
+    %currentBoldMap = ();
+    %savedBoldMap = ();
+
+    # Parse the color file.
+    open(COLORS, "<$ENV{HOME}/.owl/colormap");
+
+    my $mode = "zephyr";
+
+    while (chomp(my $line = <COLORS>))
+    {
+	if ($line =~ /^MODE: (.*)$/)
+	{
+	    if (lc($1) eq "zephyr") 
+	    { 
+		$mode = 'zephyr';
+	    }
+	    elsif (lc($1) eq "zephyr-personal")
+	    {
+		$mode = 'zephyr-personal';
+	    }
+	    elsif (lc($1) eq "aim") 
+	    {
+		$mode = 'aim';
+	    }
+	    elsif (lc($1) eq "loopback") 
+	    {
+		$mode = 'loopback';
+	    }
+	    else 
+	    {
+		$mode = 'zephyr';
+	    }
+	}
+	elsif ($mode eq 'zephyr' && $line =~ /^(.+),(.+),(b?)(black|red|green|yellow|blue|magenta|cyan|white|default)$/i)
+	{
+	    $currentColorMap{$mode}{lc($1)}{lc($2)} = lc($4);
+	    $savedColorMap{$mode}{lc($1)}{lc($2)}   = lc($4);
+	    $currentBoldMap{$mode}{lc($1)}{lc($2)}  = $3 ? 1 : 0;
+	    $savedBoldMap{$mode}{lc($1)}{lc($2)}    = $3 ? 1 : 0;
+	}
+	elsif ($mode eq 'zephyr-personal' && $line =~ /^(.+),(b?)(black|red|green|yellow|blue|magenta|cyan|white|default)$/i)
+	{
+	    $currentColorMap{$mode}{lc($1)} = lc($3);
+	    $savedColorMap{$mode}{lc($1)}   = lc($3);
+	    $currentBoldMap{$mode}{lc($1)}  = $2 ? 1 : 0;
+	    $savedBoldMap{$mode}{lc($1)}    = $2 ? 1 : 0;
+	}
+	elsif ($mode eq 'aim' && $line =~ /^(.+),(b?)(black|red|green|yellow|blue|magenta|cyan|white|default)$/i)
+	{
+	    $currentColorMap{$mode}{lc($1)} = lc($3);
+	    $savedColorMap{$mode}{lc($1)}   = lc($3);
+	    $currentBoldMap{$mode}{lc($1)}  = $2 ? 1 : 0;
+	    $savedBoldMap{$mode}{lc($1)}    = $2 ? 1 : 0;
+	}
+	elsif ($mode eq 'loopback' && $line =~ /^(b?)(black|red|green|yellow|blue|magenta|cyan|white|default)$/i)
+	{
+	    $currentColorMap{$mode} = lc($2);
+	    $savedColorMap{$mode}   = lc($2);
+	    $currentBoldMap{$mode}  = $1 ? 1 : 0;
+	    $savedBoldMap{$mode}    = $1 ? 1 : 0;
+	}
+
+    }
+    close(COLORS);
+    refreshView();
+}

Added: trunk/conf.asedeno/owl/modules/PageView.pl
===================================================================
--- trunk/conf.asedeno/owl/modules/PageView.pl	2006-10-25 06:44:24 UTC (rev 403)
+++ trunk/conf.asedeno/owl/modules/PageView.pl	2006-10-25 22:59:35 UTC (rev 404)
@@ -0,0 +1,74 @@
+# Colors module.
+package ARS_Pages;
+
+################################################################################
+#Run this on start and reload. Adds styles, sets style to start.
+################################################################################
+sub onStart
+{
+    bindings_Pages();
+}
+
+push @::onStartSubs, \&onStart;
+
+
+################################################################################
+# Help information
+################################################################################
+sub moduleHelp()
+{
+    my @helpmsgArray = <<END_OF_HELP ;
+Module: PageView (package: ARS_Pages)
+
+  Module keys:
+    M-(0-9)   Bind the current view to page n.
+   (0-9)      Switch to page n.
+END_OF_HELP
+
+    return @helpmsgArray;
+}
+push @::onModuleHelp, \&moduleHelp;
+
+sub bindings_Pages
+{
+    # sender/class coloring (also works on -c message)
+    owl::command('bindkey recv "M-0" command perl ARS_Pages::savePage(0)');
+    owl::command('bindkey recv "M-1" command perl ARS_Pages::savePage(1)');
+    owl::command('bindkey recv "M-2" command perl ARS_Pages::savePage(2)');
+    owl::command('bindkey recv "M-3" command perl ARS_Pages::savePage(3)');
+    owl::command('bindkey recv "M-4" command perl ARS_Pages::savePage(4)');
+    owl::command('bindkey recv "M-5" command perl ARS_Pages::savePage(5)');
+    owl::command('bindkey recv "M-6" command perl ARS_Pages::savePage(6)');
+    owl::command('bindkey recv "M-7" command perl ARS_Pages::savePage(7)');
+    owl::command('bindkey recv "M-8" command perl ARS_Pages::savePage(8)');
+    owl::command('bindkey recv "M-9" command perl ARS_Pages::savePage(9)');
+
+    owl::command('bindkey recv "0" command perl ARS_Pages::loadPage(0)');
+    owl::command('bindkey recv "1" command perl ARS_Pages::loadPage(1)');
+    owl::command('bindkey recv "2" command perl ARS_Pages::loadPage(2)');
+    owl::command('bindkey recv "3" command perl ARS_Pages::loadPage(3)');
+    owl::command('bindkey recv "4" command perl ARS_Pages::loadPage(4)');
+    owl::command('bindkey recv "5" command perl ARS_Pages::loadPage(5)');
+    owl::command('bindkey recv "6" command perl ARS_Pages::loadPage(6)');
+    owl::command('bindkey recv "7" command perl ARS_Pages::loadPage(7)');
+    owl::command('bindkey recv "8" command perl ARS_Pages::loadPage(8)');
+    owl::command('bindkey recv "9" command perl ARS_Pages::loadPage(9)');
+}
+
+our %pages;
+
+sub savePage
+{
+    my $pgnum = shift;
+    $pages{$pgnum}{'filter'} = owl::command("getview");
+    $pages{$pgnum}{'style'} = owl::command("getstyle");
+}
+
+sub loadPage
+{
+    my $pgnum = shift;
+    my $filter = $pages{$pgnum}{'filter'};
+    my $style = $pages{$pgnum}{'style'};
+    return if ($filter eq undef);
+    owl::command("view -f $filter ".($style?"-s $style":""));
+}

Added: trunk/conf.asedeno/owl/modules/VT-asedeno.pl
===================================================================
--- trunk/conf.asedeno/owl/modules/VT-asedeno.pl	2006-10-25 06:44:24 UTC (rev 403)
+++ trunk/conf.asedeno/owl/modules/VT-asedeno.pl	2006-10-25 22:59:35 UTC (rev 404)
@@ -0,0 +1,578 @@
+package VT_asedeno;
+
+################################################################################
+#Run this on start and reload. Adds styles, sets style to start.
+################################################################################
+sub onStart
+{
+    bindings_VT();
+    owl::set("-q default_style VT");
+    owl::command("VT");
+}
+
+push @::onStartSubs, \&onStart;
+
+################################################################################
+# Help information
+################################################################################
+sub moduleHelp()
+{
+    my @helpmsgArray = <<END_OF_HELP ;
+Module: VT-asedeno (package: VT_asedeno)
+
+  Module commands:
+    VT            Switch to VT style
+    VT-zsigs      Toggle for displaying zsigs
+    VT-hosts      Toggle for displaying .MIT.EDU in zephyr hostnames
+    VT-ctrl       Toggle for dealing with control characters.
+
+  Module keys:
+    C-s C-v       VT
+    C-s C-z       VT-zsigs
+    C-s C-h       VT-hosts
+    
+END_OF_HELP
+
+    return @helpmsgArray;
+}
+push @::onModuleHelp, \&moduleHelp;
+
+
+################################################################################
+# Branching point for various formatting functions in this style.
+################################################################################
+sub style_VT($)
+{
+    my $m = shift;
+
+    if ($m->is_zephyr)
+    {	
+	return format_VT($m);
+    }
+    elsif ($m->is_admin)
+    {
+	return "\@bold(OWL ADMIN):\t".$m->body;    
+    }
+    elsif ($m->is_aim)
+    {
+	return format_VT_AIM($m);
+    }
+    else 
+    { 
+	return "Unexpected message type: ";    
+    }
+}
+
+################################################################################
+# A place to keep my options all together, with default values.
+################################################################################
+our %VT_Options = 
+    ("zsigs" => 0,
+     "showControl" => 0,
+     "stripMitEdu" => 1,
+     "narrowMode" => 100);
+
+sub bindings_VT
+{
+    # Style definition
+    owl::command("style VT perl VT_asedeno::style_VT");
+
+    # Command aliases
+    owl::command("alias VT view -s VT");
+    owl::command("alias VT-zsigs perl VT_asedeno::VT_toggle_sigs()");
+    owl::command("alias VT-hosts perl VT_asedeno::VT_toggle_host_strip()");
+    owl::command("alias VT-ctrl perl VT_asedeno::VT_toggle_control()");
+
+    # Keybinding
+    owl::command('bindkey recv "C-s C-v" command VT');
+    owl::command('bindkey recv "C-s C-z" command VT-zsigs');
+    owl::command('bindkey recv "C-s C-h" command VT-hosts');
+}
+
+#Turn zsigs on or off
+sub VT_toggle_sigs
+{
+    $VT_Options{"zsigs"} = !($VT_Options{"zsigs"});
+#    owl::command('VT');
+    refreshView();
+}
+
+#Toggle stripping of MIT.EDU from hosts
+sub VT_toggle_host_strip
+{
+    $VT_Options{"stripMitEdu"} = !($VT_Options{"stripMitEdu"});
+#    owl::command('VT');
+    refreshView();
+}
+
+#Toggle literal backspace display method
+sub VT_toggle_control
+{
+    $VT_Options{"showControl"} = !($VT_Options{"showControl"});
+#    owl::command('VT');
+    refreshView();
+}
+
+sub refreshView()
+{
+    my $filter = owl::command("getview");
+    my $style = owl::command("getstyle");
+    owl::command("view -f $filter ".($style?"-s $style":""));
+}
+
+
+################################################################################
+# Functions to format zephyrs.
+# header for large screens (>narrowMode cols):
+#  username___.HH:MM.class[instance]___.A. (width: 38)
+################################################################################
+sub format_VT($)
+{
+    my $m = shift;
+
+    # Extract time from message
+    my ($time) = $m->time =~ /(\d\d:\d\d)/;
+   
+    # Deal with PING messages, assuming owl's rxping variable is true.
+    if ($m->is_ping)
+    {
+	return("\@bold(PING) from \@bold(".$m->pretty_sender.")\n");
+    }
+
+    # Deal with login/logout messages
+    elsif ($m->is_loginout)
+    {
+        return sprintf('@b(%-10.10s) %s @b(%s) at %s %s',
+		       $m->pretty_sender,
+		       $time,
+		       uc($m->login),
+		       uc($m->host),
+		       $m->login_tty);
+    }
+
+    # Extract destination from message
+    my $dest;
+    
+    if ($m->is_personal)
+    {
+	# Special casing personal zephyrs. Yes, we could use personals as a
+	# case of -c message, but I want the consistency of case on display.
+	$dest = '[personal]';
+    }
+    elsif (lc($m->instance) eq 'personal')
+    {
+	# Since personal is the default instance, strip it and just use the
+	# class name.
+	$dest = class_display_name($m);
+    }
+    elsif (lc($m->class) eq 'message')
+    {
+	# Since message is the default class, strip it and just use the
+	# instance name, in square brackets.
+	$dest = '['.$m->instance.']';
+    }
+    else
+    {
+	# If the defaults aren't being used, show both class and instance.
+	$dest = class_display_name($m).'['.$m->instance.']';
+    }
+    
+    # Extract user/authentication information from the message.
+    my $user = $m->pretty_sender;
+
+    my $auth = (($m->auth =~ /YES/) 
+		? '+'
+		: '-');
+    
+    # I'm assuming I'll never see echoes of outbound non-personal zephyrs,
+    # so these must be personals. For outbound personals, set username as
+    # the recipient with '->' prepended, set auth to '>' to indicate
+    # outbound.
+    if (lc($m->direction) eq 'out')
+    {
+	$user = "->".$m->recipient;
+	$user =~ s/\@ATHENA\.MIT\.EDU//;
+	$dest = '[personal]';
+	$auth = '>';
+    }
+
+    my ($body, $hostSep) = format_body($m);
+   
+    my $zVT = "";
+    my $cols = owl::getnumcols();
+    if ($cols < $VT_Options{"narrowMode"})
+    {
+	#This formats the zephyr for smaller screens.
+
+	$cols -= 3;
+	if ($cols < 50)
+	{
+	    #         1
+	    #1234567890123456789
+	    #_username_ HH:MM A
+	    my $wDest = $cols - 19;
+	    my $fmt = "%-10.10s %5s $auth %-".$wDest.".".$wDest."s\n %s";
+	    $zVT = sprintf($fmt,
+			   $user,
+			   $time,
+			   $dest,
+			   $body);
+	}
+	else
+	{
+	    # Prepare the hostname.
+	    my $hostStr = uc($m->host);
+	    $hostStr =~ s/\.MIT\.EDU$// if $VT_Options{"stripMitEdu"};
+
+	    my $rest  = $cols - 50;
+	    
+	    my $wDest = 16 + (($rest <= 14) ? $rest : 14 );
+	    $rest -= $wDest - 16;
+	    
+	    my $wUser = 10 + (($rest <= 2) ? $rest : 2);
+	    $rest -= $wUser - 10;
+	    
+	    my $wHost = 14 + (($rest <= 10) ? $rest : 10);
+	    $rest -= $wHost - 14;
+	    
+	    $wDest += $rest;
+	    
+	    my $fmt =  "%-".$wUser.".".$wUser."s %5s $auth %-".$wDest.".".$wDest."s %".$wHost."s\n %s";
+	    
+	    $zVT = sprintf($fmt,
+			   $user,
+			   $time,
+			   $dest,
+			   $hostSep.' '.$hostStr,
+			   $body);
+	}
+    }
+    else
+    {
+	# This formats the zephyr for larger screens.
+	$zVT = sprintf("%-10.10s %5s %-18.18s $auth%s",
+		       $user,
+		       $time,
+		       $dest,
+		       $body);
+    }
+    
+    if (($m->is_personal || lc($m->direction) eq 'out') ||
+	ARS_Color::isBold($m))
+    {
+	return boldify($zVT);
+    }
+    return $zVT;
+}
+
+################################################################################
+# Functions to format AIM messages.
+################################################################################
+sub format_VT_AIM($)
+{
+    my $m = shift;
+
+    # Extract time from message
+    my ($time) = $m->time =~ /(\d\d:\d\d)/;
+   
+    # Deal with login/logout messages
+    if ($m->is_login())
+    {
+	return sprintf("\@b(%-10.10s) %s \@b(%s)",
+		       "AIM LOGIN",
+		       $time,
+		       $m->sender);
+    }
+
+    if ($m->is_logout())
+    {
+	return sprintf("\@b(%-10.10s) %s \@b(%s)",
+		       "AIM LOGOUT",
+		       $time,
+		       $m->sender);
+    }
+
+    # Extract destination from message
+    my $dest = $m->recipient;
+    
+    # Extract user/authentication information from the message.
+    my $user = $m->sender;
+
+    my $dir = (lc($m->direction) eq 'out') ? '>' : '<';
+    
+    my ($body, $hostSep) = format_body($m);
+    
+    # Now build the message.
+    my $zVT = "";
+    if (owl::getnumcols() < $VT_Options{"narrowMode"})
+    {
+	$zVT = sprintf("From: %-16.16s To: %-16.16s %5s\n %s",
+		       $user,
+		       $dest,
+		       $time,
+		       $body);
+    }
+    else
+    {
+	$zVT = sprintf("%-10.10s %5s %-18.18s $dir%s",
+		       $user,
+		       $time,
+		       $dest,
+		       $body);
+    }
+    return boldify($zVT);
+}
+
+################################################################################
+# Universal body formatter.
+################################################################################
+sub format_body
+{
+    my $m = shift;
+    my $cols = owl::getnumcols();          # actual number of columns 
+    my $width = $cols - 3;                 # max usable width
+    my $hwidth = ($cols < $VT_Options{"narrowMode"}) ? 2 : 38;   # body header width / body indent
+    my $bwidth = $width - $hwidth;         # body width
+    my $zsindent = ($cols < $VT_Options{"narrowMode"}) ? 1 : 18; # zsig indent width (zephyrs only)
+    my $zsbwidth = $width - $zsindent;     # zsig body width (zephyrs only)
+
+    my $strlen = 0;
+    my $body = "";
+    my $hostAlone = 0;
+    
+    # Zephyrs only: This shows me if there are literal backspaces in the
+    # zephyr body or zsig.
+    my $hostSep = ($m->body =~ /\cH/ || $m->zsig =~ /\cH/) ? "!#" : "##";
+
+    my $rawBody = $m->body;
+
+    # Deal with literal backspaces by interpreting them or revealing them.
+    if ($VT_Options{"showControl"})
+    {
+	$rawBody =~ s/[\cH]/^H/g;
+    }
+    else
+    {
+	1 while $rawBody =~ s/[^\cH]\cH//g;
+	$rawBody =~ s/[\cH]//g;
+    }
+
+    # This cleans up other peoples formatting. I can see what they meant, but it
+    # doesn't muck with my display. Sorry about the painful regexp.
+    # Basically, double up the '@'s in these formatting messages such that they
+    # no longer work. Also, fix backspace issues.
+    $rawBody =~ s/\@font\(fixed\)$//; # GAIM is broken.
+    $rawBody =~ s/([^@]|^)(\@(?:b|bold|i|italic|l|left|r|right|c|center|huge|large|medium|small|beep|color)([\(\<\{\[]))/\1\@\2/gi;
+
+    
+    # This is a really dumb formatting test. If the message has any newlines 
+    # followed by whitespace followed by non whitespace, I'll assume the sender
+    # knows what they're doing and format the message as they desire.
+    if ($rawBody =~ /\n[ \t]+\S.*\n/)
+    {
+	# Strip multiple and trailing newlines, then get an array of lines.
+	$rawBody =~ s/\n+/\n/g;
+	$rawBody =~ s/\n*$//g;
+	my @lines = split (/\n/, $rawBody);
+	
+	# build the body, taking into account the desired indenting.
+	my $line = shift @lines;
+	$body .= " $line";
+	$strlen = length($line);
+
+	foreach $line (@lines)    
+	{
+	    $body .= "\n";
+	    $body .= " " x ($hwidth - 1);
+	    $body .= " $line";
+	    $strlen = length($line);
+	}
+    }
+    # If the formatting does not pass the above test, I'm rewrapping the entire
+    # message to my liking.
+    else
+    {
+	# Strip leading whitespace and then get an array of 'words'
+	$rawBody =~ s/^\s*//; 
+	my @words = split (/\s+/,$rawBody);
+	
+	# -1 to take into account the leading space. It makes the loop nicer,
+	# and is a useful space anyways.
+	$strlen = -1;
+	foreach my $word (@words)
+	{
+	    #Strip extra control characters, and take note.
+	    $hostSep = '!#' if ($word =~ /[[:cntrl:]]/);
+	    if (!$VT_Options{'showControl'})
+	    {
+		$word =~ s/[[:cntrl:]]//g;
+	    }
+	    if (($strlen + length($word) + 1) < $bwidth)
+	    {
+		$body .= " $word";
+		$strlen += 1 + length($word);
+	    }	
+	    else		
+	    {	
+		# There is a small bug here, but it doesn't bother me. If
+		# someone types in a 'word' that is larger than the 
+		# 'max width' it will be on a line by itself.
+		# Since owl can scroll sideways, I can look at what was said, 
+		# and it won't affect the rest of the display... I hope.
+		# I could instead break the 'word' if this becomes a problem 
+		# one day.
+
+		$body .= "\n";
+		$body .= " " x $hwidth;
+		$body .= "$word";
+		$strlen = length($word);
+	    }
+
+	    # Since '@@' is displayed as '@', we should take that into
+	    # account when figuring out how long this word is.
+	    my @count = split(/\@\@/, $word);
+	    if ($#count == -1)
+	    {
+		$strlen -= length($word) / 2;
+	    }
+	    elsif ($#count)
+	    {
+		$strlen -= $#count;
+	    }
+	}
+    }
+
+    if ($m->is_zephyr)
+    {
+	# Now that the body is done, we deal with formatting the zsig, if desired.
+	if ($VT_Options{"zsigs"} && $m->zsig ne "")
+	{
+	    $hostAlone = 0;
+	    $body .= "\n";
+	    $body .= " " x $zsindent;
+	    $body .= "--";
+	    
+	    my $sig = $m->zsig;
+	    
+	    $sig =~ s/.\cH//g;
+	    # Kill leading whitespace
+	    $sig =~ s/^\s*//;
+	    
+	    # You've seen this regexp before. 
+	    $sig =~ s/([^@]|^)(\@(?:b|bold|i|italic|l|left|r|right|c|center|huge|large|medium|small|beep|color)([\(\<\{\[]))/\1\@\2/gi;
+	    
+	    # Unlike zephyr bodies, I'm unwrapping zsigs no matter what.
+	    my @words = split (/\s+/, $sig);
+	    
+	    $strlen = 2; #takes into account the '--' we've put in.
+	    
+	    foreach my $word (@words)
+	    {
+		$hostSep = '!#' if ($word =~ /[[:cntrl:]]/);
+		if (!$VT_Options{'showControl'})
+		{
+		    $word =~ s/[[:cntrl:]]//go;
+		}
+		if (($strlen + length($word) + 1) < $zsbwidth)
+		{
+		    $body .= " $word";
+		    $strlen += 1 + length($word);
+		}
+		else
+		{
+		    $body .= "\n";
+		    $body .= " " x $zsindent;
+		    # The three extra spaces keep the zsig body lined up.
+		    # Remember the '-- '?
+		    $body .= "   $word";
+		    $strlen = 3 + length($word);
+		}
+		# And again with the '@@' => '@' processing.
+		my @count = split(/\@\@/, $word);
+		if ($#count == -1)
+		{
+		    $strlen -= length($word) / 2;
+		}
+		elsif ($#count)
+		{
+		    $strlen -= $#count;
+		}
+	    }
+	}
+	
+	# Finally append the hostname. If it will fit on the last line of the
+	# zephyr, that's great, if not it gets a line of its own. The hostname is
+	# right justified. This only happens in the large screen formatting style.
+	if ($cols >= $VT_Options{"narrowMode"})
+	{
+	    my $hostwidth = (!($VT_Options{"zsigs"} && $m->zsig ne "")
+			     ? $bwidth 
+			     : $zsbwidth);
+	    
+	    my $hostStr = uc($m->host);
+	    $hostStr =~ s/\.MIT\.EDU$// if $VT_Options{"stripMitEdu"};
+	    
+	    if ($hostAlone || (($strlen + 5 + length($hostStr)) >= $hostwidth))
+	    {
+		$body .= "\n";
+		$body .= sprintf("%".($width - 1)."s",
+				 " $hostSep $hostStr");
+	    }
+	    else
+	    {
+		$body .= " " x ($hostwidth - $strlen - 5 - length($hostStr));
+		$body .= " $hostSep $hostStr";
+	    }
+	}
+    }
+    return ($body, $hostSep);
+}
+
+
+################################################################################
+# Random helper functions
+################################################################################
+
+# This takes a zephyr to be displayed and modifies it to be displayed entirely
+# in bold. Point being that owl doesn't count the bold colors as separate
+# colors, but I want them treated as such. This in conjunction with 
+# ARS_Color::isbold() grants me those colors in the VT style.
+sub boldify($)
+{
+    $_ = shift;
+    if (!( /\)/ ))
+    {
+	return '@b('.$_.')';
+    }
+    elsif (!( /\>/ ))
+    {
+	return '@b<'.$_.'>';
+    }
+    elsif (!( /\}/ ))
+    {
+	return '@b{'.$_.'}';
+    }
+    elsif (!( /\]/ ))
+    {
+	return '@b['.$_.']';
+    }
+    else
+    {
+	my $txt = "\@b($_";
+	$txt =~ s/\)/\)\@b\[\)\]\@b\(/g;
+	return $txt.')';
+    }
+}
+
+# Quick hack for abbreviations.
+sub class_display_name
+{
+    my $m = shift;
+    my $class = lc($m->class);
+    if ($class eq 'dirty-owl-hackers')
+    {
+	return 'doh';
+    }
+
+    return $class;
+}

Added: trunk/conf.asedeno/owl/modules/thread_example_1.pl
===================================================================
--- trunk/conf.asedeno/owl/modules/thread_example_1.pl	2006-10-25 06:44:24 UTC (rev 403)
+++ trunk/conf.asedeno/owl/modules/thread_example_1.pl	2006-10-25 22:59:35 UTC (rev 404)
@@ -0,0 +1,16 @@
+package thread_example_1;
+use threads;
+use Thread::Queue;
+
+sub onStart
+{
+    threads->new(sub {
+	my $i = 0;
+	while ($i++ < 10)
+	{
+	    $::queue->enqueue($i);
+	    sleep(5);
+	}
+    })->detach();
+}
+push @::onStartSubs, \&onStart;

Added: trunk/conf.asedeno/owl/owlconf.pl
===================================================================
--- trunk/conf.asedeno/owl/owlconf.pl	2006-10-25 06:44:24 UTC (rev 403)
+++ trunk/conf.asedeno/owl/owlconf.pl	2006-10-25 22:59:35 UTC (rev 404)
@@ -0,0 +1,209 @@
+################################################################################
+###
+### [LEGACY]
+### The owlconf config file
+###
+### This file is interpreted by the perl interpreter.
+### If you wish to execute an owl command use the
+### function owl::command().  i.e.
+###
+###      owl::command("set zsigproc /mit/kretch/bin/getzsig");
+###
+### will set the owl variable zsigproc.  Subroutines created with
+### the names below will be executed at the specified times:
+###
+###     subroutine name    properties
+###     ---------------    ----------
+###     owl::startup()     run when owl first starts
+###     owl::shutdown()    run when owl exits
+###     owl::format_msg()  run to format messages when using the perl style.
+###                        The return value is used to display the message on
+###                        the screen.
+###     owl::receive_msg() run when a message is received, and after it has
+###                        been added to the message list.
+###
+### The following variables will be set each time a message is recevied:
+###     $owl::class, $owl::instance, $owl::recipient,
+###     $owl::sender, $owl::opcode, $owl::zsig,
+###     $owl::msg, $owl::time, $owl::host, @owl::fields
+###
+################################################################################
+### asedeno's owlconf
+### 
+### This is now a modules-based owlconf file.
+### on [re]load, .pl files in ~/.owl/modules are sourced. These files should
+### be in their own packages so as to play nice with other files. Code that
+### should run on startup should be in a function, the reference of which
+### should be pushed onto @::onStartSubs.
+###
+### In general, modules designed for this system should make use of message
+### objects, and not use the legacy variables listed above. For styles, the
+### message will be passed as an argument by owl. The message is a hash that
+### has keys such as class, instance, msg, etc. For more information, see
+### perlwrap.pm in the the owl source, or docs if they've been written.
+###
+### I recommend you not run this owlconf out of my locker, since I frequently
+### change it and the revisions can be substantial. Instead, copy it to
+### ~/.owl/owlconf.pl and set your ~/.owlconf to source it, or just put it at
+### ~/.owlconf.
+###
+################################################################################
+
+################################################################################
+# Module Event Queue and Mainloop hook.  
+#
+# This is a prototype. I need to figure out how to do more clever things with
+# this. For now, it simply takes any scalars that have been enqueued and
+# outputs them using aperl. We're going to need real message injection into
+# owl to make this really useful. We're also probably going to want to enqueue
+# functions, I think.
+################################################################################
+
+use threads;
+use Thread::Queue;
+
+our $queue;
+$queue =  new Thread::Queue if ($queue == undef);
+
+sub owl::mainloop_hook
+{
+    if ($queue->pending)
+    {
+	my $qobj = $queue->dequeue_nb();
+	owl::command("aperl $qobj");
+    }
+    return;
+}
+
+################################################################################
+# Startup and Shutdown code
+################################################################################
+sub owl::startup
+{
+# Modern versions of owl provides a great place to have startup stuff.
+# Put things in ~/.owl/startup
+
+# At this point I use owl::startup to pull in some hooks for reloading and
+# to set up keybindings specific to this file.
+
+    onStart();
+}
+
+# Arrays of function pointers to be called at specific times.
+@onStartSubs = undef;
+@onReceiveMsg = undef;
+@onModuleHelp = undef;
+
+#Run this on start and reload. Adds modules and runs their startup functions.
+sub onStart
+{
+    reload_init();
+
+    owl::command('alias modhelp perl moduleHelp()');
+    owl::command('bindkey recv "F2" command modhelp');
+    owl::command('bindkey recv "C-s C-d" command view -s default');
+    owl::command('bindkey recv "C-s C-b" command view -s basic');
+    owl::command('bindkey recv HOME command first');
+    owl::command('bindkey recv END  command last');
+    owl::command('bindkey edit DC  command edit:delete-next-char');
+
+    @onStartSubs = ();
+    @onReceiveMsg = ();
+    @onModuleHelp = ();
+
+    loadModules();
+    foreach (@onStartSubs)
+    {
+	&$_();
+    }
+
+    # Hook ourselves into owl's main loop.
+    owl::command(qq/set -q perl_mainloop_hook "owl::mainloop_hook"/);
+}
+################################################################################
+# Reload Code, taken from /afs/sipb/user/jdaniel/project/owl/perl
+################################################################################
+sub reload_hook (@) 
+{
+    # Redefine this function in your .owlconf and include in it any
+    # code you want to happen on a reload.  I suggest you create
+    # load_filters() and run it from here and owl::startup()
+    # because owl::command() must be in a sub
+    onStart();
+    return 1;
+}
+
+sub reload 
+{
+    if (do "$ENV{HOME}/.owlconf" && reload_hook(@_)) 
+    {
+        return "owlconf reloaded";
+    } 
+    else
+    {
+        return "$ENV{HOME}/.owlconf load attempted, but error encountered:\n$@";
+    }
+}
+
+sub reload_init () 
+{
+    owl::command('alias reload perl reload');
+    owl::command('bindkey global "C-x C-r" command reload');
+}
+
+################################################################################
+# Loads modules from ~/.owl/modules
+################################################################################
+
+sub loadModules ()
+{
+    opendir(MODULES, "$ENV{HOME}/.owl/modules");
+    # source ./modules/*.pl
+    my @modules = grep(/\.pl$/, readdir(MODULES));
+    foreach my $mod (@modules)
+    {
+	
+	do "$ENV{HOME}/.owl/modules/$mod";
+    }
+    closedir(MODULES);
+}
+
+################################################################################
+# Hooks into receive_msg()
+################################################################################
+
+sub owl::receive_msg
+{
+    my $m = shift;
+    foreach (@onReceiveMsg)
+    {
+	&$_($m);
+    }
+}
+
+################################################################################
+# Module help system.
+################################################################################
+
+sub moduleHelp()
+{
+    my @helpmsgArray = <<END_OF_HELP ;
+OWLCONF MODULE HELP
+
+  Core module keys:
+    F2            Bring up this help menu
+    C-s C-d       Switch to default style
+    C-s C-b       Switch to basic style
+    HOME , END    Move to first, last message  (same as < , >)
+
+END_OF_HELP
+
+    my $helpmsg = join("\n", @helpmsgArray);
+    
+    foreach (@onModuleHelp)
+    {
+	$helpmsg .= join("\n", &$_());
+    }
+    owl::command(qq/pperl "$helpmsg"/);
+}
+

Added: trunk/conf.asedeno/owlconf
===================================================================
--- trunk/conf.asedeno/owlconf	2006-10-25 06:44:24 UTC (rev 403)
+++ trunk/conf.asedeno/owlconf	2006-10-25 22:59:35 UTC (rev 404)
@@ -0,0 +1,2 @@
+# Load my owlconf out of ~/.owl
+do "$ENV{HOME}/.owl/owlconf.pl";


home help back first fref pref prev next nref lref last post