commit 12086db40e2a7c528a03ed5990a79f065193d325
parent 2c0eb8e1439d1a6af7ffdeaaedb60fd5a1dffd45
Author: Suraj N. Kurapati <sunaku@gmail.com>
Date: Sat, 26 Jan 2008 19:18:47 -0800
upgrade to Rumai
Diffstat:
README | | | 29 | +++-------------------------- |
wmiirc | | | 200 | ++++++++++++++++++++++++++++++++++++++++++------------------------------------- |
wmiirc-config.rb | | | 135 | ++++++++++++++++++++++++++++++++++++++++--------------------------------------- |
3 files changed, 178 insertions(+), 186 deletions(-)
diff --git a/README b/README
@@ -2,7 +2,7 @@ wmiirc: wmii configuration in Ruby
==================================
This is my wmii configuration in Ruby [1]. It currently only works with
-wmii-snap20070516, and I will work on upgrading it to wmii-3.6 soon.
+wmii-snap20070516, but I will work on upgrading it to wmii-3.6 soon.
If you have any questions or suggestions, e-mail me at <SNK at GNA dot ORG>.
@@ -14,30 +14,7 @@ Cheers.
Setup instructions
------------------
-# obtain my wmii configuration
+1. Install the Rumai library: http://rumai.rubyforge.org
- darcs get http://rassmalog.rubyforge.org/blog/pub/code/wmiirc/
- chmod +x wmiirc
+2. Adjust the $: (load path) variable at the top of the wmiirc file.
-# obtain wmii-irb (which is a requirement for my wmii configuration)
-
- darcs get http://rassmalog.rubyforge.org/blog/pub/code/wmii-irb/
- cd wmii-irb
-
-# satisfy dependencies for wmii-irb
-
- svn co svn://svn.gna.org/svn/rubyixp/trunk ruby-ixp
-
-# view API reference for wmii-irb
-
- rdoc *.rb
- firefox doc/index.html &
-
-# customize my wmii configuration
-
- cd ..
- vim wmiirc-config.rb
-
-# apply the new configuration
-
- wmiirc
diff --git a/wmiirc b/wmiirc
@@ -6,148 +6,162 @@
# See the file named LICENSE for details.
# load the wmii-irb library
- $: << File.join(File.dirname(__FILE__), 'wmii-irb')
- require 'wm'
+$: << '/home/sun/src/rumai/lib'
+require 'rumai'
+include Rumai
- include Wmii
# create a logger to aid debugging
- require 'logger'
+require 'logger'
+LOG = Logger.new(__FILE__ + '.log', 5)
- LOG = Logger.new(__FILE__ + '.log', 5)
+unless $DEBUG
+ class << LOG
+ alias write << # emulate IO.write
+ end
# capture standard output in logger
- unless $DEBUG
- class << LOG
- alias write << # emulate IO.write
- end
+ $stdout = $stderr = LOG
+end
- $stdout = $stderr = LOG
- end
LOG.info "birth"
begin
+ ##
+ #
# Miniature DSL to ease configuration.
+ #
+ ##
- class Handler < Hash
- # When a block is given, registers a handler for the given key.
- # Otherwise, executes all registered handlers for the given key.
- def handle aKey, *aArgs, &aBlock
- if block_given?
- (self[aKey] ||= []) << aBlock
-
- elsif key? aKey
- self[aKey].each do |block|
- block.call(*aArgs)
- end
+ class Handler < Hash
+ def initialize
+ super {|h,k| h[k] = [] }
+ end
+
+ # When a block is given, registers a handler for the given key.
+ # Otherwise, executes all registered handlers for the given key.
+ def handle aKey, *aArgs, &aBlock
+ if block_given?
+ self[aKey] << aBlock
+
+ elsif key? aKey
+ self[aKey].each do |block|
+ block.call(*aArgs)
end
end
end
+ end
- EVENTS = Handler.new
- ACTIONS = Handler.new
- KEYS = Handler.new
+ EVENTS = Handler.new
+ ACTIONS = Handler.new
+ KEYS = Handler.new
- def event *a, &b
- EVENTS.handle(*a, &b)
- end
+ def event *a, &b
+ EVENTS.handle(*a, &b)
+ end
- def action *a, &b
- ACTIONS.handle(*a, &b)
- end
+ def action *a, &b
+ ACTIONS.handle(*a, &b)
+ end
+
+ def key *a, &b
+ KEYS.handle a.map {|k| k.flatten.join('-') rescue k }.join(','), &b
+ end
- def key *a, &b
- a.map! { |x| x.respond_to?(:flatten) ? x.flatten.join('-') : x }
- KEYS.handle a.join(','), &b
- end
+ ##
+ #
# Utility functions
+ #
+ ##
- # Shows a menu with the given items and returns the chosen
- # item. If nothing was chosen, then *nil* is returned.
- def show_menu aChoices, aPrompt = nil
- cmd = "dmenu -b -fn #{WMII_FONT.inspect} " <<
- %w[-nf -nb -sf -sb].zip(
- Color::NORMAL.split[0,2] + Color::FOCUSED.split[0,2]
- ).flatten.map {|s| s.inspect}.join(' ')
+ # Shows a menu with the given items and returns the chosen
+ # item. If nothing was chosen, then *nil* is returned.
+ def show_menu aChoices, aPrompt = nil
+ cmd = "dmenu -b -fn #{WMII_FONT.inspect} " <<
+ %w[-nf -nb -sf -sb].zip(
+ Color::NORMAL.split[0,2] + Color::FOCUSED.split[0,2]
+ ).flatten.map {|s| s.inspect}.join(' ')
- cmd << " -p #{aPrompt.to_s.inspect}" if aPrompt
+ cmd << " -p #{aPrompt.to_s.inspect}" if aPrompt
- IO.popen cmd, 'r+' do |menu|
- menu.puts aChoices
- menu.close_write
+ IO.popen cmd, 'r+' do |menu|
+ menu.puts aChoices
+ menu.close_write
- choice = menu.read
- choice unless choice.empty?
- end
+ choice = menu.read
+ choice unless choice.empty?
end
+ end
- require 'pathname'
+ require 'pathname'
- # Returns the names of programs present in the given directories.
- def find_programs *aDirs
- aDirs.flatten.map do |d|
- Pathname.new(d).expand_path.children rescue []
- end.flatten.map do |f|
- f.basename.to_s if f.file? and f.executable?
- end.compact.uniq.sort
- end
+ # Returns the names of programs present in the given directories.
+ def find_programs *aDirs
+ aDirs.flatten.map do |d|
+ Pathname.new(d).expand_path.children rescue []
+ end.flatten.map do |f|
+ f.basename.to_s if f.file? and f.executable?
+ end.compact.uniq.sort
+ end
# terminate existing instances of this program
- fs.event << 'Start wmiirc'
+ fs.event.write 'Start wmiirc'
- event :Start do |arg|
- exit if arg == 'wmiirc'
- end
+ event :Start do |arg|
+ exit if arg == 'wmiirc'
+ end
# load user's configuration file
- load File.join(File.dirname(__FILE__), 'wmiirc-config.rb')
+ load File.join(File.dirname(__FILE__), 'wmiirc-config.rb')
- # Tag bar setup
- fs.lbar.clear
+ # populate lbar with buttons for every tag
+ bar = fs.lbar
+ bar.clear
- tags.each do |tag|
- color = (tag == current_tag) ? Color::FOCUSED : Color::NORMAL
+ tags.each do |tag|
+ color = (tag == curr_tag) ? Color::FOCUSED : Color::NORMAL
- bar = fs.lbar[tag]
- bar.create
- bar.write "#{color} #{tag}"
- end
+ btn = bar[tag]
+ btn.create
+ btn.write "#{color} #{tag}"
+ end
- # Keygrab setup
- fs.keys = KEYS.keys.join("\n")
+ # enable keyboard shortcuts
+ fs.keys.write KEYS.keys.join("\n")
- event :Key do |*args|
- key(*args)
- end
+ event :Key do |*args|
+ key(*args)
+ end
- # Event loop
- fs.event.open do |bus|
- loop do
- bus.read.split("\n").each do |event|
- type, parms = event.split(' ', 2)
+ # the main event loop
+ fs.event.each_line do |line|
+ line.split("\n").each do |event|
+ type, parms = event.split(' ', 2)
- args = parms.split(' ') rescue []
- event type.to_sym, *args
- end
- end
- end
+ args = parms.split(' ') rescue []
+ event type.to_sym, *args
+ end
+ end
rescue => e
LOG.error e
# allow the user to rescue themselves
- system 'xterm &'
+ system 'xterm &'
- IO.popen('xmessage -file - -buttons recover:0,ignore:1', 'w') do |f|
- f.puts e.inspect, e.backtrace
- end
+ IO.popen('xmessage -file - -buttons recover:0,ignore:1', 'w') do |f|
+ f.puts e.inspect, e.backtrace
+ end
- if $?.exitstatus == 0
- system $0 + ' &'
- end
+ if $?.exitstatus == 0
+ system $0 + ' &'
+ end
+
+rescue SystemExit
+ # ignore it
rescue Exception => e
LOG.fatal e
diff --git a/wmiirc-config.rb b/wmiirc-config.rb
@@ -51,7 +51,7 @@ WMII_FONT = '-*-bitstream vera sans mono-medium-r-*-*-16-*-*-*-*-*-*-*'
################################################################################
# WM Configuration
-fs.ctl = <<EOF
+fs.ctl.write <<EOF
grabmod #{Key::MOD}
border 2
font #{WMII_FONT}
@@ -60,12 +60,12 @@ normcolors #{Color::NORMAL}
EOF
# Column Rules
-fs.colrules = <<EOF
+fs.colrules.write <<EOF
/./ -> 50+50
EOF
# Tagging Rules
-fs.tagrules = <<EOF
+fs.tagrules.write <<EOF
/.*notes.*/ -> note
/Buddy List.*/ -> chat
/XChat.*/ -> chat
@@ -94,19 +94,22 @@ EOF
end
event :FocusTag do |tag|
- fs.lbar[tag] << "#{Color::FOCUSED} #{tag}"
+ fs.lbar[tag].write "#{Color::FOCUSED} #{tag}"
end
event :UnfocusTag do |tag|
- fs.lbar[tag] << "#{Color::NORMAL} #{tag}"
+ btn = fs.lbar[tag]
+ btn.write "#{Color::NORMAL} #{tag}" if btn.exist?
end
event :UrgentTag do |tag|
- fs.lbar[tag] << "*#{tag}"
+ btn = fs.lbar[tag]
+ btn.write "*#{tag}" if btn.exist?
end
event :NotUrgentTag do |tag|
- fs.lbar[tag] << tag
+ btn = fs.lbar[tag]
+ btn.write tag if btn.exist?
end
event :LeftBarClick do |button, viewId|
@@ -116,13 +119,13 @@ EOF
when Mouse::MIDDLE
# add the grouping onto the clicked view
- grouped_clients.each do |c|
+ grouping.each do |c|
c.tag viewId
end
when Mouse::SECONDARY
# remove the grouping from the clicked view
- grouped_clients.each do |c|
+ grouping.each do |c|
c.untag viewId
end
end
@@ -132,7 +135,7 @@ EOF
case button.to_i
when Mouse::SECONDARY
# toggle the clicked client's grouping
- Client.toggle_grouping clientId
+ Client.toggle_group clientId
end
end
@@ -145,7 +148,7 @@ EOF
end
action :kill do
- fs.ctl = 'quit'
+ fs.ctl.write 'quit'
end
action :quit do
@@ -161,15 +164,13 @@ EOF
# gnome-panel refuses to die by other means
system 'killall -s TERM gnome-panel'
- fs.event.open do |f|
- clients.each do |c|
- if c.exist?
+ clients.each do |c|
+ while c.exist?
+ begin
c.focus
- c.ctl = :kill
-
- # wait until the client is dead
- until f.read =~ /DestroyClient #{c.id}/
- end
+ c.ctl.write :kill
+ rescue IXP::Error
+ # ignore and retry
end
end
end
@@ -209,61 +210,61 @@ EOF
# focus client at left
key Key::FOCUS + Key::LEFT do
- current_view.ctl = 'select left'
+ curr_view.ctl.write 'select left' rescue nil
end
# focus client at right
key Key::FOCUS + Key::RIGHT do
- current_view.ctl = 'select right'
+ curr_view.ctl.write 'select right' rescue nil
end
# focus client below
key Key::FOCUS + Key::DOWN do
- current_view.ctl = 'select down'
+ curr_view.ctl.write 'select down'
end
# focus client above
key Key::FOCUS + Key::UP do
- current_view.ctl = 'select up'
+ curr_view.ctl.write 'select up'
end
# toggle focus between floating area and the columns
key Key::FOCUS + 'space' do
- current_view.ctl = 'select toggle'
+ curr_view.ctl.write 'select toggle'
end
# apply equal-spacing layout to current column
key Key::ARRANGE + 'w' do
- current_area.layout = :default
+ curr_area.layout = :default
end
# apply equal-spacing layout to all columns
key Key::ARRANGE + 'Shift-w' do
- current_view.columns.each do |a|
+ curr_view.columns.each do |a|
a.layout = :default
end
end
# apply stacked layout to currently focused column
key Key::ARRANGE + 'v' do
- current_area.layout = :stack
+ curr_area.layout = :stack
end
# apply stacked layout to all columns in current view
key Key::ARRANGE + 'Shift-v' do
- current_view.columns.each do |a|
+ curr_view.columns.each do |a|
a.layout = :stack
end
end
# apply maximized layout to currently focused column
key Key::ARRANGE + 'm' do
- current_area.layout = :max
+ curr_area.layout = :max
end
# apply maximized layout to all columns in current view
key Key::ARRANGE + 'Shift-m' do
- current_view.columns.each do |a|
+ curr_view.columns.each do |a|
a.layout = :max
end
end
@@ -282,61 +283,61 @@ EOF
# sending / moving
key Key::SEND + Key::LEFT do
- grouped_clients.each do |c|
+ grouping.each do |c|
c.send :left
end
end
key Key::SEND + Key::RIGHT do
- grouped_clients.each do |c|
+ grouping.each do |c|
c.send :right
end
end
key Key::SEND + Key::DOWN do
- grouped_clients.each do |c|
+ grouping.each do |c|
c.send :down
end
end
key Key::SEND + Key::UP do
- grouped_clients.each do |c|
+ grouping.each do |c|
c.send :up
end
end
# send all grouped clients from managed to floating area (or vice versa)
key Key::SEND + 'space' do
- grouped_clients.each do |c|
+ grouping.each do |c|
c.send :toggle
end
end
# close all grouped clients
key Key::SEND + 'Delete' do
- grouped_clients.each do |c|
- c.ctl = 'kill'
+ grouping.each do |c|
+ c.ctl.write 'kill'
end
end
# swap the currently focused client with the one to its left
key Key::SWAP + Key::LEFT do
- current_client.swap :left
+ curr_client.swap :left
end
# swap the currently focused client with the one to its right
key Key::SWAP + Key::RIGHT do
- current_client.swap :right
+ curr_client.swap :right
end
# swap the currently focused client with the one below it
key Key::SWAP + Key::DOWN do
- current_client.swap :down
+ curr_client.swap :down
end
# swap the currently focused client with the one above it
key Key::SWAP + Key::UP do
- current_client.swap :up
+ curr_client.swap :up
end
# Changes the tag (according to a menu choice) of each grouped client and
@@ -346,7 +347,7 @@ EOF
choices = tags.map {|t| [t, "+#{t}", "-#{t}"]}.flatten
if target = show_menu(choices, 'tag as:')
- grouped_clients.each do |c|
+ grouping.each do |c|
case target
when /^\+/
c.tag $'
@@ -366,10 +367,10 @@ EOF
# Sends grouped clients to temporary view.
key Key::PREFIX + 'b' do
- src = current_tag
+ src = curr_tag
dst = src + '~' + src.object_id.abs.to_s
- grouped_clients.each do |c|
+ grouping.each do |c|
c.tag dst
end
@@ -380,12 +381,12 @@ EOF
# Sends grouped clients back to their original view.
key Key::PREFIX + 'Shift-b' do
- src = current_tag
+ src = curr_tag
if src =~ /~\d+$/
dst = $`
- grouped_clients.each do |c|
+ grouping.each do |c|
c.with_tags do
delete src
push dst if empty?
@@ -401,76 +402,76 @@ EOF
# include/exclude the currently focused client from the grouping
key Key::GROUP + 'g' do
- current_client.toggle_grouping
+ curr_client.toggle_group
end
# include all clients in the currently focused view into the grouping
key Key::GROUP + 'v' do
- current_view.group
+ curr_view.group
end
# exclude all clients in the currently focused view from the grouping
key Key::GROUP + 'Shift-v' do
- current_view.ungroup
+ curr_view.ungroup
end
# include all clients in the currently focused area into the grouping
key Key::GROUP + 'c' do
- current_area.group
+ curr_area.group
end
# exclude all clients in the currently focused column from the grouping
key Key::GROUP + 'Shift-c' do
- current_area.ungroup
+ curr_area.ungroup
end
# include all clients in the floating area into the grouping
key Key::GROUP + 'f' do
- current_view.floating_area.group
+ curr_view.floating_area.group
end
# exclude all clients in the currently focused column from the grouping
key Key::GROUP + 'Shift-f' do
- current_view.floating_area.ungroup
+ curr_view.floating_area.ungroup
end
# include all clients in the managed areas into the grouping
key Key::GROUP + 'a' do
- current_view.columns.each do |c|
+ curr_view.columns.each do |c|
c.group
end
end
# exclude all clients in the managed areas from the grouping
key Key::GROUP + 'Shift-a' do
- current_view.columns.each do |c|
+ curr_view.columns.each do |c|
c.ungroup
end
end
# invert the grouping in the currently focused view
key Key::GROUP + 'i' do
- current_view.toggle_grouping
+ curr_view.toggle_group
end
# exclude all clients everywhere from the grouping
key Key::GROUP + 'n' do
- ungroup_all
+ Rumai.ungroup
end
# visual arrangement
key Key::ARRANGE + 't' do
- current_view.arrange_as_larswm
+ curr_view.arrange_as_larswm
end
key Key::ARRANGE + 'g' do
- current_view.arrange_in_grid
+ curr_view.arrange_in_grid
end
key Key::ARRANGE + 'd' do
- current_view.arrange_in_diamond
+ curr_view.arrange_in_diamond
end
@@ -520,7 +521,7 @@ EOF
# Open a new terminal and set its working directory
# to be the same as the currently focused terminal.
key Key::EXECUTE + 'x' do
- c = current_client
+ c = curr_client
d = File.expand_path(c.label.read.sub(/^.*?:\s+/, '')) rescue nil
d = ENV['HOME'] unless File.directory? d.to_s
@@ -572,9 +573,9 @@ EOF
# Detach the current grouping from the current view.
key Key::PREFIX + 'd' do
- grouped_clients.each do |c|
+ grouping.each do |c|
c.with_tags do
- delete current_tag
+ delete curr_tag
push DETACHED_TAG
end
end
@@ -587,7 +588,7 @@ EOF
if v.exist? and c = v.clients.last
c.with_tags do
delete DETACHED_TAG
- push current_tag
+ push curr_tag
end
end
end
@@ -603,19 +604,19 @@ EOF
# send current grouping to {i}'th view
key Key::SEND + i.to_s do
- grouped_clients.each do |c|
+ grouping.each do |c|
c.tags = tags[i - 1] || i
end
end
# swap current client with the primary client in {i}'th column
key Key::SWAP + i.to_s do
- current_view.ctl = "swap sel #{i+1}" # XXX: +1 b/c floating area is column 1: until John-Galt fixes this!
+ curr_view.ctl.write "swap sel #{i+1}" # XXX: +1 b/c floating area is column 1: until John-Galt fixes this!
end
# apply grid layout with {i} clients per column
key Key::ARRANGE + i.to_s do
- current_view.arrange_in_grid i
+ curr_view.arrange_in_grid i
end
end