wmiirc-rumai

git clone git://oldgit.suckless.org/wmiirc-rumai/
Log | Files | Refs | README | LICENSE

commit fe7dc60a030abc3d89529e5ebbd4fc54702e8471
parent 5ac820de9478040764656498e2675501b22182a2
Author: Suraj N. Kurapati <sunaku@gmail.com>
Date:   Thu, 31 Aug 2006 07:06:41 -0700

[project @ 9d1835a975265153368b9142eb993d0b8e0292d8]

[project @ 23]
up  IxpFile class is more general now. Wmii derives from it.
up  ruby-ized wmiirc where necessary; remember, too many abstractions will slow stuff down

Diffstat:
wmii.rb | 97+++++++++++++++++++++++++++++++++++++++----------------------------------------
wmiirc | 261++++++++++++++++++++++++++++++++++++++-----------------------------------------
2 files changed, 175 insertions(+), 183 deletions(-)

diff --git a/wmii.rb b/wmii.rb @@ -24,47 +24,46 @@ require 'ixp' require 'find' require 'singleton' -class Wmii - include Singleton - SELECTION_TAG = 'SEL' - DETACHED_TAG = 'status' +# Encapsulates access to a file in the IXP file system +class IxpFile + attr_reader :path + def initialize aPath + @path = aPath - ## - # IXP file system - # - - def initialize - begin - @cl = IXP::Client.new - rescue Errno::ECONNREFUSED - retry + unless defined? @@ixp + begin + @@ixp = IXP::Client.new + rescue Errno::ECONNREFUSED + retry + end end end - # Creates the given WM path. + # Creates a file at the given path and returns it. def create aPath begin - @cl.create aPath + @@ixp.create aPath + IxpFile.new aPath rescue IXP::IXPException => e puts "#{e.backtrace.first}: #{e}" end end - # Deletes the given WM path. + # Deletes the given path. def remove aPath begin - @cl.remove aPath + @@ixp.remove aPath rescue IXP::IXPException => e puts "#{e.backtrace.first}: #{e}" end end - # Writes the given content to the given WM path. + # Writes the given content to the given path. def write aPath, aContent begin - @cl.open(aPath) do |f| + @@ixp.open(aPath) do |f| f.write aContent.to_s end rescue IXP::IXPException => e @@ -72,10 +71,10 @@ class Wmii end end - # Reads from the given WM path and returns the content. If the path is a directory, then the names of all files in that directory are returned. + # Reads from the given path and returns the content. If the path is a directory, then the names of all files in that directory are returned. def read aPath begin - @cl.open(aPath) do |f| + @@ixp.open(aPath) do |f| if f.respond_to? :next # read file-names from directory names = '' @@ -93,6 +92,29 @@ class Wmii end end + def method_missing aMeth, *aArgs + if aMeth.to_s =~ /=$/ + write "#{@path}/#{$`}", *aArgs + + elsif content = read("#{@path}/#{aMeth}") + content + + else + super + end + end +end + +class Wmii < IxpFile + SELECTION_TAG = 'SEL' + DETACHED_TAG = 'status' + + attr_reader :config + + def initialize + super "/" + @config = IxpFile.new('/def') + end ## # WM state access @@ -339,35 +361,12 @@ class Wmii ## - # Subclasses + # subclasses # - # Encapsulates access to a file in the IXP file system - class IxpFile - attr_reader :wm, :path - - def initialize aPath - @wm = Wmii.instance - @path = aPath - @subordinateClass = nil - end - - def method_missing aMeth, *aArgs - if aMeth.to_s =~ /=$/ - @wm.write "#{@path}/#{$`}", *aArgs - else - if content = @wm.read("#{@path}/#{aMeth}") - content - else - super - end - end - end - end - class Container < IxpFile def indices - if list = @wm.read(@path) + if list = read(@path) # go in reverse order to accomodate destructive procedures list.split.grep(/^\d+$/).reverse else @@ -403,7 +402,7 @@ class Wmii def focus! ['select', 'view'].each do |cmd| - return if @wm.write "#{@path}/../ctl", "#{cmd} #{File.basename @path}" + return if write "#{@path}/../ctl", "#{cmd} #{File.basename @path}" end end end @@ -412,11 +411,11 @@ class Wmii TAG_DELIMITER = "+" def tags - @wm.read("#{@path}/tags").split(TAG_DELIMITER) + read("#{@path}/tags").split(TAG_DELIMITER) end def tags= *aTags - @wm.write "#{@path}/tags", aTags.flatten.uniq.join(TAG_DELIMITER) + write "#{@path}/tags", aTags.flatten.uniq.join(TAG_DELIMITER) end # Do stuff (the given block) with this client's tags. diff --git a/wmiirc b/wmiirc @@ -21,14 +21,20 @@ $: << File.dirname(__FILE__) require 'wmii' -WM = Wmii.instance ## # WM STARTUP # -# terminate other running wmiirc's - sleep 1 until WM.write('/event', "Start wmiirc\n") +WM = Wmii.new + +# terminate existing wmiirc processes + WM.event = "Start wmiirc\n" + +PROGRAM_MENU = WM.find_programs(*ENV['PATH'].split(':')).join("\n") +ACTION_MENU = WM.find_programs('/home/sun/dry/apps/wmii/etc/wmii-3', '~/.wmii-3').join("\n") + +# system 'xsetroot -solid "#333333"' ## @@ -44,41 +50,30 @@ ENV['WMII_NORMCOLORS']='#222222 #eeeeee #666666' # WM CONFIGURATION # -WM.write '/def/border', 2 -WM.write '/def/font', ENV['WMII_FONT'] -WM.write '/def/selcolors', ENV['WMII_SELCOLORS'] -WM.write '/def/normcolors', ENV['WMII_NORMCOLORS'] -WM.write '/def/colmode', 'default' -WM.write '/def/colwidth', 0 - - -## -# TAGGING RULES -# - -WM.write '/def/rules', <<EOF -/QEMU.*/ -> ~ -/jEdit.*/ -> code -/Buddy List.*/ -> chat -/XChat.*/ -> chat -/.*thunderbird.*/ -> mail -/Gimp.*/ -> gimp -/MPlayer.*/ -> ~ -/xconsole.*/ -> ~ -/alsamixer.*/ -> ~ -/.*/ -> ! -/.*/ -> 1 -EOF - - -## -# MISC CONFIGURATION -# - -# system 'xsetroot -solid "#333333"' - -PROGRAM_MENU = WM.find_programs(*ENV['PATH'].split(':')).join("\n") -ACTION_MENU = WM.find_programs('/home/sun/dry/apps/wmii/etc/wmii-3', '~/.wmii-3').join("\n") +WM.config.instance_eval do + border = 2 + + font = ENV['WMII_FONT'] + selcolors = ENV['WMII_SELCOLORS'] + normcolors = ENV['WMII_NORMCOLORS'] + + colmode = 'default' + colwidth = 0 + + rules = <<-EOS.gsub(/^\s+/, '') + /QEMU.*/ -> ~ + /jEdit.*/ -> code + /Buddy List.*/ -> chat + /XChat.*/ -> chat + /.*thunderbird.*/ -> mail + /Gimp.*/ -> gimp + /MPlayer.*/ -> ~ + /xconsole.*/ -> ~ + /alsamixer.*/ -> ~ + /.*/ -> ! + /.*/ -> 1 + EOS +end ## @@ -91,86 +86,86 @@ DOWN='n' LEFT='h' RIGHT='s' -SELECT="#{MODKEY}-Control-" -SEND="#{SELECT}m," -SWAP="#{SELECT}w," -LAYOUT="#{SELECT}z," -MENU="#{SELECT}" -PROGRAM="#{SELECT}" -GROUP="#{SELECT}g," +FOCUS="#{MODKEY}-Control-" +SEND="#{FOCUS}m," +SWAP="#{FOCUS}w," +LAYOUT="#{FOCUS}z," +MENU="#{FOCUS}" +PROGRAM="#{FOCUS}" +GROUP="#{FOCUS}g," SHORTCUTS = { - "#{SELECT}#{LEFT}" => lambda do + "#{FOCUS}#{LEFT}" => lambda do WM.write '/view/ctl', 'select prev' end, - "#{SELECT}#{RIGHT}" => lambda do - WM.write '/view/ctl', 'select next' + "#{FOCUS}#{RIGHT}" => lambda do + WM.write '/view/ctl', 'select next' end, - "#{SELECT}#{DOWN}" => lambda do - WM.write '/view/sel/ctl', 'select next' + "#{FOCUS}#{DOWN}" => lambda do + WM.write '/view/sel/ctl', 'select next' end, - "#{SELECT}#{UP}" => lambda do - WM.write '/view/sel/ctl', 'select prev' + "#{FOCUS}#{UP}" => lambda do + WM.write '/view/sel/ctl', 'select prev' end, - "#{SELECT}space" => lambda do - WM.write '/view/ctl', 'select toggle' + "#{FOCUS}space" => lambda do + WM.write '/view/ctl', 'select toggle' end, - "#{SELECT}comma" => lambda do - WM.cycle_view :left + "#{FOCUS}comma" => lambda do + WM.cycle_view :left end, - "#{SELECT}period" => lambda do - WM.cycle_view :right + "#{FOCUS}period" => lambda do + WM.cycle_view :right end, "#{LAYOUT}w" => lambda do - WM.write '/view/sel/mode', 'default' + WM.write '/view/sel/mode', 'default' end, "#{LAYOUT}v" => lambda do - WM.write '/view/sel/mode', 'stack' + WM.write '/view/sel/mode', 'stack' end, "#{LAYOUT}m" => lambda do - WM.write '/view/sel/mode', 'max' + WM.write '/view/sel/mode', 'max' end, "#{LAYOUT}z" => lambda do - WM.write '/view/0/sel/geom', '0 0 east south' + WM.write '/view/0/sel/geom', '0 0 east south' end, "#{LAYOUT}t" => lambda do - WM.apply_tiling_layout + WM.apply_tiling_layout end, "#{LAYOUT}g" => lambda do - WM.apply_grid_layout + WM.apply_grid_layout end, "#{GROUP}g" => lambda do - WM.current_client.invert_selection! + WM.current_client.invert_selection! end, "#{GROUP}a" => lambda do - WM.current_view.select! + WM.current_view.select! end, "#{GROUP}i" => lambda do - WM.current_view.invert_selection! + WM.current_view.invert_selection! end, "#{GROUP}n" => lambda do - WM.select_none + WM.select_none end, @@ -193,10 +188,10 @@ SHORTCUTS = { "#{MENU}a" => lambda do # prepare a list of menu choices choices = WM.read('/client').split.inject([]) do |acc, id| - tags = WM.read("/client/#{id}/tags") - name = WM.read("/client/#{id}/name").downcase + tags = WM.read("/client/#{id}/tags") + name = WM.read("/client/#{id}/name").downcase - acc << format("%d. [%s] %s", id, tags, name) + acc << format("%d. [%s] %s", id, tags, name) end @@ -204,7 +199,7 @@ SHORTCUTS = { target = WM.show_menu(choices.join("\n")) unless target.empty? - WM.focus_client target.scan(/\d+/).first + WM.focus_client target.scan(/\d+/).first end end, @@ -216,25 +211,25 @@ SHORTCUTS = { "#{SEND}#{LEFT}" => lambda do WM.selected_clients.each do |c| - c.ctl = 'sendto prev' + c.ctl = 'sendto prev' end end, "#{SEND}#{RIGHT}" => lambda do WM.selected_clients.each do |c| - c.ctl = 'sendto next' + c.ctl = 'sendto next' end end, "#{SEND}space" => lambda do WM.selected_clients.each do |c| - c.ctl = 'sendto toggle' + c.ctl = 'sendto toggle' end end, "#{SEND}Delete" => lambda do WM.selected_clients.each do |c| - c.ctl = 'kill' + c.ctl = 'kill' end end, @@ -245,31 +240,31 @@ SHORTCUTS = { target = WM.show_menu(choices.join("\n")) WM.selected_clients.each do |c| - c.with_tags do - case target - when /^\+/ - push $' - - when /^\-/ - delete $' - - else - clear - push target - end - end + c.with_tags do + case target + when /^\+/ + push $' + + when /^\-/ + delete $' + + else + clear + push target + end + end end end, "#{SEND}d" => lambda do # WM.with_selection do - WM.detach_current_client + WM.detach_current_client # end end, "#{SEND}Shift-d" => lambda do # WM.with_selection do - WM.attach_last_client + WM.attach_last_client # end end, @@ -290,56 +285,56 @@ SHORTCUTS = { 10.times do |i| k = (i - 1) % 10 # associate '1' with the leftmost label, instead of '0' - SHORTCUTS["#{SELECT}#{i}"] = lambda do - WM.focus_view(WM.read('/tags').split[k] || i) + SHORTCUTS["#{FOCUS}#{i}"] = lambda do + WM.focus_view(WM.read('/tags').split[k] || i) end SHORTCUTS["#{SEND}#{i}"] = lambda do - WM.write '/view/sel/sel/tags', (WM.read('/tags').split[k] || i) + WM.write '/view/sel/sel/tags', (WM.read('/tags').split[k] || i) end SHORTCUTS["#{LAYOUT}#{i}"] = lambda do - WM.apply_grid_layout i + WM.apply_grid_layout i end # shortcuts for adding and removing tags of a client SHORTCUTS["#{SEND}equal,#{i}"] = SHORTCUTS["#{SEND}Shift-equal,#{i}"] = lambda do - WM.selected_clients.each do |c| - c.with_tags do - push(WM.tags[k] || i) - end - end + WM.selected_clients.each do |c| + c.with_tags do + push(WM.tags[k] || i) + end + end end SHORTCUTS["#{SEND}minus,#{i}"] = lambda do - WM.selected_clients.each do |c| - c.with_tags do - delete(WM.tags[k] || i) - end - end + WM.selected_clients.each do |c| + c.with_tags do + delete(WM.tags[k] || i) + end + end end SHORTCUTS["#{SEND}Shift-minus"] = lambda do - WM.selected_clients.each do |c| - c.with_tags do - delete WM.current_view.name - end - end + WM.selected_clients.each do |c| + c.with_tags do + delete WM.current_view.name + end + end end end ('a'..'z').each do |char| SHORTCUTS["#{MENU}v,#{char}"] = lambda do - if view = WM.tags.select {|t| t =~ /^#{char}/i}.first - WM.focus_view view - end + if view = WM.tags.select {|t| t =~ /^#{char}/i}.first + WM.focus_view view + end end end -WM.write '/def/grabmod', MODKEY -WM.write '/def/keys', SHORTCUTS.keys.join("\n") +WM.config.grabmod = MODKEY +WM.config.keys = SHORTCUTS.keys.join("\n") ## @@ -348,14 +343,12 @@ WM.write '/def/keys', SHORTCUTS.keys.join("\n") # display time and system status in the bar Thread.new do - status = Wmii::IxpFile.new("/bar/status") - WM.create status.path - + status = WM.create("/bar/status") status.colors = ENV['WMII_NORMCOLORS'] loop do - status.data = Time.now.to_s << " " << `uptime`.scan(/\d+\.\d+/).join(' ') - sleep 5 + status.data = Time.now.to_s << " " << `uptime`.scan(/\d+\.\d+/).join(' ') + sleep 5 end end @@ -366,25 +359,25 @@ WM.write '/def/keys', SHORTCUTS.keys.join("\n") begin IO.popen('wmiir read /event') do |io| while event = io.readline.chomp - type, arg = event.split($;, 2) + type, arg = event.split($;, 2) - p event, type, arg if $DEBUG + p event, type, arg if $DEBUG - case type - when 'Start' - exit if arg == 'wmiirc' + case type + when 'Start' + exit if arg == 'wmiirc' - when 'BarClick' - view, button = arg.split - WM.focus_view view + when 'BarClick' + view, button = arg.split + WM.focus_view view - when 'ClientClick' - client, button = arg.split - Wmii::Client.new(WM, "/client/#{client}").invert_selection! + when 'ClientClick' + client, button = arg.split + Wmii::Client.new("/client/#{client}").invert_selection! - when 'Key' - SHORTCUTS[arg].call - end + when 'Key' + SHORTCUTS[arg].call + end end end rescue EOFError