rumai 3.2.2 → 3.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. data/CREDITS +27 -5
  2. data/bin/rumai +12 -37
  3. data/lib/rumai/inochi.rb +8 -17
  4. data/lib/rumai/irb.rb +21 -0
  5. data/man.html +914 -0
  6. data/man/man1/rumai.1.gz +0 -0
  7. metadata +19 -94
  8. data/HISTORY +0 -350
  9. data/INSTALL +0 -33
  10. data/MANUAL +0 -26
  11. data/README +0 -92
  12. data/USAGE +0 -297
  13. data/doc/ann.xml +0 -61
  14. data/doc/api/IO.html +0 -119
  15. data/doc/api/Integer.html +0 -171
  16. data/doc/api/Rumai.html +0 -1540
  17. data/doc/api/Rumai/Area.html +0 -1485
  18. data/doc/api/Rumai/Chain.html +0 -301
  19. data/doc/api/Rumai/Client.html +0 -2451
  20. data/doc/api/Rumai/ClientContainer.html +0 -301
  21. data/doc/api/Rumai/ExportInstanceMethods.html +0 -103
  22. data/doc/api/Rumai/IXP.html +0 -94
  23. data/doc/api/Rumai/IXP/Agent.html +0 -1625
  24. data/doc/api/Rumai/IXP/Agent/FidStream.html +0 -959
  25. data/doc/api/Rumai/IXP/Agent/RangedPool.html +0 -381
  26. data/doc/api/Rumai/IXP/Error.html +0 -110
  27. data/doc/api/Rumai/IXP/Fcall.html +0 -503
  28. data/doc/api/Rumai/IXP/Qid.html +0 -207
  29. data/doc/api/Rumai/IXP/Rattach.html +0 -148
  30. data/doc/api/Rumai/IXP/Rauth.html +0 -148
  31. data/doc/api/Rumai/IXP/Rclunk.html +0 -148
  32. data/doc/api/Rumai/IXP/Rcreate.html +0 -148
  33. data/doc/api/Rumai/IXP/Rerror.html +0 -148
  34. data/doc/api/Rumai/IXP/Rflush.html +0 -148
  35. data/doc/api/Rumai/IXP/Ropen.html +0 -148
  36. data/doc/api/Rumai/IXP/Rread.html +0 -148
  37. data/doc/api/Rumai/IXP/Rremove.html +0 -148
  38. data/doc/api/Rumai/IXP/Rstat.html +0 -148
  39. data/doc/api/Rumai/IXP/Rversion.html +0 -148
  40. data/doc/api/Rumai/IXP/Rwalk.html +0 -148
  41. data/doc/api/Rumai/IXP/Rwrite.html +0 -148
  42. data/doc/api/Rumai/IXP/Rwstat.html +0 -148
  43. data/doc/api/Rumai/IXP/Stat.html +0 -335
  44. data/doc/api/Rumai/IXP/Stream.html +0 -194
  45. data/doc/api/Rumai/IXP/Struct.html +0 -586
  46. data/doc/api/Rumai/IXP/Struct/ClassField.html +0 -242
  47. data/doc/api/Rumai/IXP/Struct/Field.html +0 -782
  48. data/doc/api/Rumai/IXP/Struct/Field/CounteeField.html +0 -227
  49. data/doc/api/Rumai/IXP/Struct/Field/CounterField.html +0 -153
  50. data/doc/api/Rumai/IXP/Struct/Integer8Field.html +0 -242
  51. data/doc/api/Rumai/IXP/Struct/StringField.html +0 -206
  52. data/doc/api/Rumai/IXP/Tattach.html +0 -148
  53. data/doc/api/Rumai/IXP/Tauth.html +0 -148
  54. data/doc/api/Rumai/IXP/Tclunk.html +0 -148
  55. data/doc/api/Rumai/IXP/Tcreate.html +0 -148
  56. data/doc/api/Rumai/IXP/Terror.html +0 -231
  57. data/doc/api/Rumai/IXP/Tflush.html +0 -148
  58. data/doc/api/Rumai/IXP/Topen.html +0 -240
  59. data/doc/api/Rumai/IXP/Tread.html +0 -148
  60. data/doc/api/Rumai/IXP/Tremove.html +0 -148
  61. data/doc/api/Rumai/IXP/Tstat.html +0 -148
  62. data/doc/api/Rumai/IXP/Tversion.html +0 -162
  63. data/doc/api/Rumai/IXP/Twalk.html +0 -148
  64. data/doc/api/Rumai/IXP/Twrite.html +0 -148
  65. data/doc/api/Rumai/IXP/Twstat.html +0 -148
  66. data/doc/api/Rumai/Node.html +0 -1406
  67. data/doc/api/Rumai/View.html +0 -1587
  68. data/doc/api/Rumai/WidgetImpl.html +0 -333
  69. data/doc/api/Rumai/WidgetNode.html +0 -246
  70. data/doc/api/String.html +0 -258
  71. data/doc/api/StringIO.html +0 -119
  72. data/doc/api/Time.html +0 -247
  73. data/doc/api/_index.html +0 -581
  74. data/doc/api/class_list.html +0 -36
  75. data/doc/api/css/common.css +0 -1
  76. data/doc/api/css/full_list.css +0 -50
  77. data/doc/api/css/style.css +0 -273
  78. data/doc/api/file.LICENSE.html +0 -73
  79. data/doc/api/file_list.html +0 -38
  80. data/doc/api/frames.html +0 -13
  81. data/doc/api/index.html +0 -73
  82. data/doc/api/js/app.js +0 -111
  83. data/doc/api/js/full_list.js +0 -117
  84. data/doc/api/js/jquery.js +0 -19
  85. data/doc/api/method_list.html +0 -1491
  86. data/doc/api/top-level-namespace.html +0 -89
  87. data/doc/index.html +0 -2655
  88. data/inochi.opts +0 -31
  89. data/test/rumai/ixp/message_test.rb +0 -245
  90. data/test/runner +0 -25
  91. data/test/test_helper.rb +0 -1
data/CREDITS CHANGED
@@ -1,5 +1,27 @@
1
- - Christoph Blank <http://textmode.at>
2
- - ghedamat <http://github.com/ghedamat>
3
- - Gigamo <http://github.com/gigamo>
4
- - Michael Andrus <http://github.com/centyx>
5
- - Simon Hafner <http://github.com/Tass>
1
+ %#----------------------------------------------------------------------------
2
+ ## AUTHORS
3
+ %#----------------------------------------------------------------------------
4
+
5
+ Suraj N. Kurapati
6
+
7
+ %#----------------------------------------------------------------------------
8
+ ## CREDITS
9
+ %#----------------------------------------------------------------------------
10
+
11
+ Christoph Blank,
12
+ Simon Hafner,
13
+ Michael Andrus,
14
+ Nathan Neff,
15
+ [Gigamo],
16
+ [ghedamat]
17
+
18
+ %# XXX: only link to these contributors because they do not have real names
19
+ [Gigamo]: http://github.com/gigamo
20
+ [ghedamat]: http://github.com/ghedamat
21
+
22
+ %#----------------------------------------------------------------------------
23
+ ## LICENSE
24
+ %#----------------------------------------------------------------------------
25
+
26
+ %# See the file named "LICENSE".
27
+ %< "LICENSE"
data/bin/rumai CHANGED
@@ -17,25 +17,20 @@
17
17
  # -v, --version : Show version number and exit.
18
18
  #
19
19
 
20
- $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
21
20
  require 'rumai'
22
21
 
23
22
  # parse command line
24
23
  if ARGV.delete('-h') or ARGV.delete('--help')
25
- puts
26
- puts Rumai.inspect
27
- puts Rumai::TAGLINE
28
- puts
29
- puts
30
- puts File.read(__FILE__)[/^#(\r?\n)(.*?)\1\1/m, 2].gsub(/^# ?/, '')
31
- puts
32
- puts
33
- puts 'Read the user manual for more information:'
34
- puts
35
- puts " #{Rumai::INSTDIR}/doc/index.html"
36
- puts
37
- puts " #{Rumai::WEBSITE}"
38
- puts
24
+ # try to display UNIX version of help manual
25
+ man_path = File.join(Rumai::INSTDIR, 'man')
26
+ unless system 'man', '-M', man_path, '-a', 'rumai'
27
+ # try to display HTML version of help manual
28
+ man_html = man_path + '.html'
29
+ unless %w[$BROWSER open start].any? {|b| system "#{b} #{man_html}" }
30
+ # no luck; direct user to project website
31
+ puts "See #{Rumai::WEBSITE}"
32
+ end
33
+ end
39
34
  exit
40
35
  elsif ARGV.delete('-v') or ARGV.delete('--version')
41
36
  puts Rumai::VERSION
@@ -43,27 +38,7 @@ elsif ARGV.delete('-v') or ARGV.delete('--version')
43
38
  end
44
39
 
45
40
  # start IRB session
46
- require 'irb'
47
- require 'irb/completion' # enable TAB-completion
48
-
49
- module IRB
50
- ##
51
- # Starts an IRB session *inside* the given object.
52
- #
53
- # This code was adapted from a snippet on Massimiliano Mirra's website:
54
- # http://www.therubymine.com/articles/2007/01/29/programmare-dallinterno
55
- #
56
- def self.start_session context
57
- IRB.setup nil
58
-
59
- env = IRB::WorkSpace.new(context)
60
- irb = IRB::Irb.new(env)
61
- IRB.conf[:MAIN_CONTEXT] = irb.context
62
-
63
- catch :IRB_EXIT do
64
- irb.eval_input
65
- end
66
- end
67
- end
41
+ require 'rumai/irb'
42
+ require 'irb/completion'
68
43
 
69
44
  IRB.start_session Rumai
data/lib/rumai/inochi.rb CHANGED
@@ -18,12 +18,12 @@ module Rumai
18
18
  ##
19
19
  # Number of this release of this project.
20
20
  #
21
- VERSION = "3.2.2"
21
+ VERSION = "3.2.3"
22
22
 
23
23
  ##
24
24
  # Date of this release of this project.
25
25
  #
26
- RELDATE = "2010-04-01"
26
+ RELDATE = "2010-04-28"
27
27
 
28
28
  ##
29
29
  # Description of this release of this project.
@@ -74,30 +74,21 @@ module Rumai
74
74
  # }
75
75
  #
76
76
  DEVTIME = {
77
- "inochi" => [ "~> 2" ], # for managing this project
77
+ "inochi" => [ ">= 3.0.0", "< 4" ],
78
78
  "dfect" => [ "~> 2" ], # for unit testing
79
79
  }
80
80
 
81
- ##
82
- # Loads the correct version (as defined by the {RUNTIME} or {DEVTIME}
83
- # constant in this module) of the given gem or the gem that contains
84
- # the given library.
85
- #
86
- def self.require gem_name_or_library
87
- # prepare the correct version of the gem for loading
88
- if respond_to? :gem
89
- gem_name = gem_name_or_library.to_s.sub(%r{/.*$}, '')
90
- if gem_version = RUNTIME[gem_name] || DEVTIME[gem_name]
81
+ # establish gem version dependencies
82
+ if respond_to? :gem
83
+ [RUNTIME, DEVTIME].each do |deps|
84
+ deps.each do |gem_name, gem_version|
91
85
  begin
92
- gem gem_name, *gem_version
86
+ gem gem_name, *Array(gem_version)
93
87
  rescue LoadError => error
94
88
  warn "#{self.inspect}: #{error}"
95
89
  end
96
90
  end
97
91
  end
98
-
99
- # do the loading
100
- super
101
92
  end
102
93
 
103
94
  end
data/lib/rumai/irb.rb ADDED
@@ -0,0 +1,21 @@
1
+ require 'irb'
2
+
3
+ module IRB
4
+ ##
5
+ # Starts an IRB session *inside* the given object.
6
+ #
7
+ # This code was adapted from a snippet on Massimiliano Mirra's website:
8
+ # http://www.therubymine.com/articles/2007/01/29/programmare-dallinterno
9
+ #
10
+ def self.start_session context
11
+ IRB.setup nil
12
+
13
+ env = IRB::WorkSpace.new(context)
14
+ irb = IRB::Irb.new(env)
15
+ IRB.conf[:MAIN_CONTEXT] = irb.context
16
+
17
+ catch :IRB_EXIT do
18
+ irb.eval_input
19
+ end
20
+ end
21
+ end
data/man.html ADDED
@@ -0,0 +1,914 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv='content-type' value='text/html;charset=utf8'>
5
+ <meta name='generator' value='Ronn/v0.5'>
6
+ <title>rumai(1) - Ruby interface to the wmii window manager</title>
7
+ <style type='text/css'>
8
+ body {margin:0}
9
+ #man, #man code, #man pre, #man tt, #man kbd, #man samp {
10
+ font-family:consolas,monospace;
11
+ font-size:16px;
12
+ line-height:1.3;
13
+ color:#343331;
14
+ background:#fff; }
15
+ #man { max-width:87ex; margin:0 3ex 1ex 1ex; text-align:justify; }
16
+ #man div.man-navigation {
17
+ position:fixed;
18
+ top:0;
19
+ left:91ex;
20
+ height:100%;
21
+ width:100%;
22
+ padding:1ex 0 0 2ex;
23
+ border-left:0.5ex solid #DCDCDC;
24
+ background-color: #F5F5F5;
25
+ }
26
+ #man div.man-navigation a { display:block; margin-bottom:1.5ex }
27
+ #man h1, #man h2, #man h3 { color:#232221;clear:left }
28
+ #man h1 { font-size:28px; margin:15px 0 30px 0; text-align:center }
29
+ #man h2 { font-size:18px; margin-bottom:0; margin-top:10px; line-height:1.3; }
30
+ #man h3 { font-size:16px; margin:0 0 0 4ex; }
31
+ #man p, #man ul, #man ol, #man dl, #man pre { margin:0 0 18px 0; }
32
+ #man pre {
33
+ color:#333231;
34
+ background:#edeceb;
35
+ padding:5px 7px;
36
+ margin:0px 0 20px 0;
37
+ border-left:2ex solid #ddd}
38
+ #man pre + h2, #man pre + h3 {
39
+ margin-top:22px;
40
+ }
41
+ #man h2 + pre, #man h3 + pre {
42
+ margin-top:5px;
43
+ }
44
+ #man > p, #man > ul, #man > ol, #man > dl, #man > pre { margin-left:8ex; }
45
+ #man dt { margin:0; clear:left }
46
+ #man dt.flush { float:left; width:8ex }
47
+ #man dd { margin:0 0 0 9ex }
48
+ #man code, #man strong, #man b { font-weight:bold; color:#131211; }
49
+ #man pre code { font-weight:normal; color:#232221; background:inherit }
50
+ #man em, var, u {
51
+ font-style:normal; color:#333231; border-bottom:1px solid #999; }
52
+ #man h1.man-title { display:none; }
53
+ #man ol.man, #man ol.man li { margin:2px 0 10px 0; padding:0;
54
+ float:left; width:33%; list-style-type:none;
55
+ text-transform:uppercase; font-size:18px; color:#999;
56
+ letter-spacing:1px;}
57
+ #man ol.man { width:100%; }
58
+ #man ol.man li.tl { text-align:left }
59
+ #man ol.man li.tc { text-align:center;letter-spacing:4px }
60
+ #man ol.man li.tr { text-align:right; float: right }
61
+ #man ol.man a { color:#999 }
62
+ #man ol.man a:hover { color:#333231 }
63
+ #man img { display:block; margin:auto }
64
+ </style>
65
+ <style type='text/css' media='print'>
66
+ #man { max-width:none }
67
+ #man div.man-navigation { display:none }
68
+ #man a[href]:not([href^="#"]):not([data-bare-link]):after {
69
+ content:" " attr(href);
70
+ }
71
+ </style>
72
+ </head>
73
+ <body>
74
+ <div id='man'>
75
+
76
+ <div class='man-navigation'><a href='#NAME'>NAME</a> <a href='#SYNOPSIS'>SYNOPSIS</a> <a href='#DESCRIPTION'>DESCRIPTION</a> <a href='#OPTIONS'>OPTIONS</a> <a href='#EXAMPLES'>EXAMPLES</a> <a href='#HACKING'>HACKING</a> <a href='#VERSIONS'>VERSIONS</a> <a href='#AUTHORS'>AUTHORS</a> <a href='#CREDITS'>CREDITS</a> <a href='#LICENSE'>LICENSE</a> <a href='#SEE-ALSO'>SEE ALSO</a></div>
77
+
78
+ <h1 class='man-title'>rumai(1)</h1>
79
+
80
+ <ol class='head man'>
81
+ <li class='tl'>rumai(1)</li>
82
+ <li class='tc'>Version 3.2.3</li>
83
+ <li class='tr'>rumai(1)</li>
84
+ </ol>
85
+
86
+ <h2 id='NAME'>NAME</h2>
87
+ <p><code>rumai</code> - Ruby interface to the wmii window manager</p>
88
+
89
+ <p>Rumai is a pure <a href="http://ruby-lang.org">Ruby</a> interface to the <a href="http://wmii.suckless.org">wmii</a> window manager. Its name is a
90
+ portmanteau of "<em>Ru</em>by" and "w<em>mi</em>i" (which I pronounce as "vim eye").</p>
91
+
92
+ <h3 id="Features">Features</h3>
93
+
94
+ <ul>
95
+ <li><p>Provides an interactive shell for live experimentation.</p></li>
96
+ <li><p>Arranges clients, columns, views, and tags dynamically.</p></li>
97
+ <li><p>Talks directly to wmii's <a href="http://libs.suckless.org/libixp">IXP filesystem interface</a>.</p></li>
98
+ <li><p>Includes a pure Ruby client for the <a href="http://cm.bell-labs.com/magic/man2html/5/intro">9P2000 protocol</a>.</p></li>
99
+ <li><p>Powers <a href="http://github.com/sunaku/wmiirc">my personal</a> wmiirc and
100
+ <a href="http://github.com/sunaku/wmiirc/network">many others</a> like it.</p></li>
101
+ </ul>
102
+
103
+
104
+ <h3 id="Resources">Resources</h3>
105
+
106
+ <dl>
107
+ <dt>Issue tracker (report bugs, request features, get help)</dt><dd><p><a href="http://github.com/sunaku/rumai/issues" data-bare-link="true">http://github.com/sunaku/rumai/issues</a></p></dd>
108
+ <dt>Source code (browse online or obtain with <a href="http://git-scm.com">Git</a>)</dt><dd><p><a href="http://github.com/sunaku/rumai" data-bare-link="true">http://github.com/sunaku/rumai</a></p></dd>
109
+ <dt>API documentation</dt><dd><p><a href="http://snk.tuxfamily.org/lib/rumai/api/" data-bare-link="true">http://snk.tuxfamily.org/lib/rumai/api/</a></p></dd>
110
+ <dt>Announcements feed</dt><dd><p><a href="http://snk.tuxfamily.org/lib/rumai/ann.xml" data-bare-link="true">http://snk.tuxfamily.org/lib/rumai/ann.xml</a></p></dd>
111
+ <dt>Official website</dt><dd><p><a href="http://snk.tuxfamily.org/lib/ember/" data-bare-link="true">http://snk.tuxfamily.org/lib/ember/</a></p></dd>
112
+ </dl>
113
+
114
+
115
+ <h3 id="Setup">Setup</h3>
116
+
117
+ <p>Prerequisites:</p>
118
+
119
+ <ul>
120
+ <li><p><a href="http://ruby-lang.org">Ruby</a> 1.8.6 or newer.</p></li>
121
+ <li><p><a href="http://rubygems.org">RubyGems</a> 1.3.6 or newer.</p></li>
122
+ <li><p><a href="http://wmii.suckless.org">wmii</a> 3.9 or newer.</p></li>
123
+ </ul>
124
+
125
+
126
+ <p>Installing:</p>
127
+
128
+ <pre><code>gem install rumai
129
+ </code></pre>
130
+
131
+ <p>Upgrading:</p>
132
+
133
+ <pre><code>gem update rumai
134
+ </code></pre>
135
+
136
+ <p>Removing:</p>
137
+
138
+ <pre><code>gem uninstall rumai
139
+ </code></pre>
140
+
141
+ <h2 id="SYNOPSIS">SYNOPSIS</h2>
142
+
143
+ <p><code>rumai</code> [<var>OPTIONS</var>] [<var>IRB_OPTIONS</var>]</p>
144
+
145
+ <h2 id="DESCRIPTION">DESCRIPTION</h2>
146
+
147
+ <p>Starts an interactive Ruby shell (IRB) session by passing the given
148
+ <var>IRB_OPTIONS</var> to irb(1). This puts you at a command prompt as follows:</p>
149
+
150
+ <pre><code>irb(Rumai):001:0&gt;
151
+ </code></pre>
152
+
153
+ <p>The <code>irb(Rumai)</code> token in the command prompt indicates that commands will be
154
+ evaluated <em>inside</em> the <code>Rumai</code> module. As a result, you can omit the "Rumai"
155
+ prefix from your commands if you wish.</p>
156
+
157
+ <p>For example, to get the currently selected client, you can type <code>curr_client</code>
158
+ instead of <code>Rumai.curr_client</code> at the prompt. Both commands achieve the same
159
+ effect.</p>
160
+
161
+ <p>The next thing to notice is that <em>TAB completion</em> is enabled. So you can type
162
+ part of a command and press the TAB key to see a list of possible completions.</p>
163
+
164
+ <h2 id="OPTIONS">OPTIONS</h2>
165
+
166
+ <dl>
167
+ <dt><code>-h</code>, <code>--help</code></dt><dd><p>Display this manual and exit.</p></dd>
168
+ <dt><code>-v</code>, <code>--version</code></dt><dd><p>Print version number and exit.</p></dd>
169
+ </dl>
170
+
171
+
172
+ <h2 id="EXAMPLES">EXAMPLES</h2>
173
+
174
+ <p>Now that you know how to start the interactive shell (see <strong>DESCRIPTION</strong>
175
+ above) let us walk through a series of examples that highlight the main
176
+ features of Rumai. You can follow along by copying &amp; pasting the presented
177
+ commands into the interactive shell.</p>
178
+
179
+ <h3 id="Automated-client-arrangement">Automated client arrangement</h3>
180
+
181
+ <p>Launch a few terminals so that we have something to work with:</p>
182
+
183
+ <pre><code>colors = %w[ red green blue black orange brown gray navy gold ]
184
+ colors.each {|c| system "xterm -bg #{c} -title #{c} -e sh -c read &amp;" }
185
+ </code></pre>
186
+
187
+ <p>Arrange all clients in a grid:</p>
188
+
189
+ <pre><code>curr_view.arrange_in_grid
190
+ </code></pre>
191
+
192
+ <p>Arrange all clients in a diamond shape:</p>
193
+
194
+ <pre><code>curr_view.arrange_in_diamond
195
+ </code></pre>
196
+
197
+ <p>Arrange all clients like LarsWM does:</p>
198
+
199
+ <pre><code>curr_view.arrange_as_larswm
200
+ </code></pre>
201
+
202
+ <p>Close the terminals we launched earlier:</p>
203
+
204
+ <pre><code>terms = curr_view.clients.select {|c| colors.include? c.label.read }
205
+ terms.each {|c| c.kill }
206
+ </code></pre>
207
+
208
+ <h3 id="Multiple-client-grouping">Multiple client grouping</h3>
209
+
210
+ <p>Launch a few terminals so that we have something to work with:</p>
211
+
212
+ <pre><code>colors = %w[ red green blue black orange brown gray navy gold ]
213
+ colors.each {|c| system "xterm -bg #{c} -title #{c} -e sh -c read &amp;" }
214
+ </code></pre>
215
+
216
+ <p>Add the red, green, and blue terminals into the "grouping":</p>
217
+
218
+ <pre><code>terms = curr_view.clients.select do |c|
219
+ %w[red green blue].include? c.label.read
220
+ end
221
+ terms.each {|c| c.group }
222
+ </code></pre>
223
+
224
+ <p>You should now see a new button labelled as "@" on the left-hand side of
225
+ wmii's bar, indicating that there is now a new view labelled "@" in wmii.
226
+ Let us inspect what clients this mysterious view contains:</p>
227
+
228
+ <pre><code>v = View.new "@"
229
+ puts v.clients.map {|c| c.label.read }
230
+ </code></pre>
231
+
232
+ <p>Aha! The mysterious view contains the red, green, and blue clients we
233
+ recently "grouped". Thus, by adding a client to the "grouping", we are
234
+ simply tagging the client with the "@" token.</p>
235
+
236
+ <p>Now that we have put some clients into the "grouping", let us move all
237
+ clients in the grouping to the floating area in the current view:</p>
238
+
239
+ <pre><code>grouping.each {|c| c.send "toggle" }
240
+ </code></pre>
241
+
242
+ <p>Neat! Let us bring them back into the managed area:</p>
243
+
244
+ <pre><code>grouping.each {|c| c.send "toggle" }
245
+ </code></pre>
246
+
247
+ <p>Close the terminals we launched earlier:</p>
248
+
249
+ <pre><code>terms = curr_view.clients.select {|c| colors.include? c.label.read }
250
+ terms.each {|c| c.kill }
251
+ </code></pre>
252
+
253
+ <p>In summary, you can select multiple clients (by adding them to the
254
+ "grouping") and perform operations on them. This is useful when you want
255
+ to do something with a group of clients but do not want to manually focus
256
+ one, perform the action, focus the next one, and so on.</p>
257
+
258
+ <p>Another important aspect is that selected clients stay selected until they
259
+ are unselected. This allows you to continue performing tasks on the
260
+ selection without having to reselect the same clients after every
261
+ operation.</p>
262
+
263
+ <h3 id="Easy-column-manipulation">Easy column manipulation</h3>
264
+
265
+ <p>Launch a few terminals so that we have something to work with:</p>
266
+
267
+ <pre><code>colors = %w[ red green blue black orange brown gray navy gold ]
268
+ colors.each {|c| system "xterm -bg #{c} -title #{c} -e sh -c read &amp;" }
269
+ </code></pre>
270
+
271
+ <p>You can insert a group of clients to the top, bottom, or after the
272
+ currently focused client of <em>any</em> column using Array-like methods.</p>
273
+
274
+ <p>Give each client its own column (one client per column):</p>
275
+
276
+ <pre><code>curr_view.each_column {|c| c.length = 1 }
277
+ </code></pre>
278
+
279
+ <p>Put (at most) three clients in every column:</p>
280
+
281
+ <pre><code>curr_view.each_column {|c| c.length = 3 }
282
+ </code></pre>
283
+
284
+ <p>Move the red, green, and blue clients into the floating area:</p>
285
+
286
+ <pre><code>rgb = %w[red green blue]
287
+ terms = curr_view.clients.select {|c| rgb.include? c.label.read }
288
+ curr_view.areas[0].push terms
289
+ </code></pre>
290
+
291
+ <p>Slurp all floating clients into the last column:</p>
292
+
293
+ <pre><code>list = curr_view.areas
294
+ a, b = list.first, list.last
295
+ b.concat a
296
+ </code></pre>
297
+
298
+ <p>Set the last column's layout to stacking mode:</p>
299
+
300
+ <pre><code>b.layout = 'stack'
301
+ </code></pre>
302
+
303
+ <p>Move the red, green, and blue clients to the top of the second column:</p>
304
+
305
+ <pre><code>curr_view.areas[2].unshift terms
306
+ </code></pre>
307
+
308
+ <p>Move the red, green, and blue clients to the bottom of the third column:</p>
309
+
310
+ <pre><code>curr_view.areas[3].push terms
311
+ </code></pre>
312
+
313
+ <p>Close the terminals we launched earlier:</p>
314
+
315
+ <pre><code>terms = curr_view.clients.select {|c| colors.include? c.label.read }
316
+ terms.each {|c| c.kill }
317
+ </code></pre>
318
+
319
+ <h3 id="Easy-client-manipulation">Easy client manipulation</h3>
320
+
321
+ <p>Launch a few terminals so that we have something to work with:</p>
322
+
323
+ <pre><code>colors = %w[ red green blue black orange brown gray navy gold ]
324
+ colors.each {|c| system "xterm -bg #{c} -title #{c} -e sh -c read &amp;" }
325
+ </code></pre>
326
+
327
+ <p>Obtain a reference to the red client:</p>
328
+
329
+ <pre><code>red = curr_view.clients.find {|c| c.label.read == "red" }
330
+ </code></pre>
331
+
332
+ <p>Show the red client's current tags:</p>
333
+
334
+ <pre><code>red.tags
335
+ </code></pre>
336
+
337
+ <p>Add the "foo" and "bar" tags to the red client:</p>
338
+
339
+ <pre><code>red.tag "foo", "bar"
340
+ </code></pre>
341
+
342
+ <p>Remove the "bar" tag from the red client:</p>
343
+
344
+ <pre><code>red.untag "bar"
345
+ </code></pre>
346
+
347
+ <p>Do complex operations on the red client's tags:</p>
348
+
349
+ <pre><code>red.with_tags { concat %w[a b c]; push 'z'; delete 'c' }
350
+ </code></pre>
351
+
352
+ <p>Focus the next client after the red client:</p>
353
+
354
+ <pre><code>red.next.focus
355
+ curr_client == red.next #=&gt; true
356
+ </code></pre>
357
+
358
+ <p>Notice that by focusing a client, we make it the current client.</p>
359
+
360
+ <p>Focus the red client on a different view:</p>
361
+
362
+ <pre><code>orig = curr_view
363
+ v = red.views.last
364
+ red.focus v
365
+ </code></pre>
366
+
367
+ <p>Return to the original view:</p>
368
+
369
+ <pre><code>orig.focus
370
+ </code></pre>
371
+
372
+ <p>Send the red client to the last column:</p>
373
+
374
+ <pre><code>red.send curr_view.areas.last
375
+ </code></pre>
376
+
377
+ <p>Close the terminals we launched earlier:</p>
378
+
379
+ <pre><code>terms = curr_view.clients.select {|c| colors.include? c.label.read }
380
+ terms.each {|c| c.kill }
381
+ </code></pre>
382
+
383
+ <h3 id="Traversing-the-file-system">Traversing the file system</h3>
384
+
385
+ <p>Show the root node of wmii's IXP file system:</p>
386
+
387
+ <pre><code>fs
388
+ </code></pre>
389
+
390
+ <p>Show the names of all files at the root level:</p>
391
+
392
+ <pre><code>fs.entries
393
+ </code></pre>
394
+
395
+ <p>Show the parent of the root node:</p>
396
+
397
+ <pre><code>fs.parent
398
+ </code></pre>
399
+
400
+ <p>Show the children of the root node:</p>
401
+
402
+ <pre><code>fs.children
403
+ </code></pre>
404
+
405
+ <p>Navigate into to the <code>/lbar/</code> directory:</p>
406
+
407
+ <pre><code>n1 = fs.lbar
408
+ n2 = fs['lbar']
409
+ n1 == n2 #=&gt; true
410
+ left_bar = n1
411
+ </code></pre>
412
+
413
+ <p>Notice that you can traverse the file system hierarchy by simply calling
414
+ methods on node objects. Alternatively, you can traverse by specifying an
415
+ arbitrary sub-path (relative path) using the <code>[]</code> operator on a node.</p>
416
+
417
+ <p>Create a new temporary button:</p>
418
+
419
+ <pre><code>b = left_bar.rumai_example # path of new button
420
+ b.exist? #=&gt; false
421
+ b.create
422
+ b.exist? #=&gt; true
423
+ </code></pre>
424
+
425
+ <p>You should now see an empty button on the left-hand side of the wmii bar.</p>
426
+
427
+ <p>Color the button black-on-white and label it as "hello world":</p>
428
+
429
+ <pre><code>content = "#000000 #ffffff #000000 hello world"
430
+ b.write content
431
+ b.read == content #=&gt; true
432
+ </code></pre>
433
+
434
+ <p>Remove the temporary button:</p>
435
+
436
+ <pre><code>b.remove
437
+ b.exist? #=&gt; false
438
+ </code></pre>
439
+
440
+ <h2 id="HACKING">HACKING</h2>
441
+
442
+ <p>This section is meant for people who want to develop Rumai's source code.</p>
443
+
444
+ <h3 id="Prerequisites">Prerequisites</h3>
445
+
446
+ <p>Install Ruby libraries necessary for development:</p>
447
+
448
+ <pre><code>gem install rumai --development
449
+ </code></pre>
450
+
451
+ <h3 id="Infrastructure">Infrastructure</h3>
452
+
453
+ <p><a href="http://snk.tuxfamily.org/lib/inochi/">Inochi</a> serves as the project infrastructure for Rumai. It handles tasks
454
+ such as building this help manual and API documentation, and packaging,
455
+ announcing, and publishing new releases. See its help manual and list of
456
+ tasks to get started:</p>
457
+
458
+ <pre><code>inochi --help # display help manual
459
+ inochi --tasks # list available tasks
460
+ </code></pre>
461
+
462
+ <h3 id="-LOAD_PATH-setup">$LOAD_PATH setup</h3>
463
+
464
+ <p>Ensure that the <code>lib/</code> directory is listed in Ruby's <code>$LOAD_PATH</code> before you
465
+ use any libraries therein or run any executables in the <code>bin/</code> directory.</p>
466
+
467
+ <p>This can be achieved by passing an option to Ruby:</p>
468
+
469
+ <pre><code>ruby -Ilib bin/rumai
470
+ irb -Ilib -r rumai
471
+ </code></pre>
472
+
473
+ <p>Or by setting the <code>$RUBYLIB</code> environment variable:</p>
474
+
475
+ <pre><code>export RUBYLIB=lib # bash, ksh, zsh
476
+ setenv RUBYLIB lib # csh
477
+ set -x RUBYLIB lib # fish
478
+
479
+ ruby bin/rumai
480
+ irb -r rumai
481
+ </code></pre>
482
+
483
+ <p>Or by installing the <a href="http://github.com/chneukirchen/rup">ruby-wrapper</a> tool.</p>
484
+
485
+ <h3 id="RubyGems-setup">RubyGems setup</h3>
486
+
487
+ <p>If you use Ruby 1.8 or older, then ensure that RubyGems is activated before
488
+ you use any libraries in the <code>lib/</code> directory or run any executables in the
489
+ <code>bin/</code> directory.</p>
490
+
491
+ <p>This can be achieved by passing an option to Ruby:</p>
492
+
493
+ <pre><code>ruby -rubygems bin/rumai
494
+ irb -rubygems -r rumai
495
+ </code></pre>
496
+
497
+ <p>Or by setting the <code>$RUBYOPT</code> environment variable:</p>
498
+
499
+ <pre><code>export RUBYOPT=-rubygems # bash, ksh, zsh
500
+ setenv RUBYOPT -rubygems # csh
501
+ set -x RUBYOPT -rubygems # fish
502
+ </code></pre>
503
+
504
+ <h3 id="Running-tests">Running tests</h3>
505
+
506
+ <p>Simply execute the included test runner, which sets up Ruby's <code>$LOAD_PATH</code> for
507
+ testing, loads the included <code>test/test_helper.rb</code> file, and then evaluates all
508
+ <code>test/**/*_test.rb</code> files:</p>
509
+
510
+ <pre><code>test/runner
511
+ </code></pre>
512
+
513
+ <p>Its exit status will indicate whether all tests have passed. It may also
514
+ print additional pass/fail information depending on the testing library used
515
+ in the <code>test/test_helper.rb</code> file.</p>
516
+
517
+ <h3 id="Contributing">Contributing</h3>
518
+
519
+ <p>Fork this project on GitHub (see <strong>Resources</strong> above) and send a pull request.</p>
520
+
521
+ <h2 id="VERSIONS">VERSIONS</h2>
522
+
523
+ <p>This section contains release notes of current and past releases.</p>
524
+
525
+ <h3 id="Version-3-2-3-2010-04-28-">Version 3.2.3 (2010-04-28)</h3>
526
+
527
+ <p>This release adds a UNIX manual page and requires wmii 3.9 or newer.</p>
528
+
529
+ <p>Bug fixes:</p>
530
+
531
+ <ul>
532
+ <li><p><code>Rumai::Area#unshift</code> needs wmii 3.9 or newer.
533
+ The help manual has been corrected accordingly.</p>
534
+
535
+ <p>Thanks to <a href="http://github.com/ghedamat">ghedamat</a> for reporting <a href="http://github.com/sunaku/wmiirc/issues/8">this issue</a>.</p></li>
536
+ </ul>
537
+
538
+
539
+ <p>Housekeeping:</p>
540
+
541
+ <ul>
542
+ <li><p>Upgrade to Inochi 3.0.0. Run <code>rumai --help</code> to see the UNIX manual page!</p></li>
543
+ <li><p>Move IRB session creation code from rumai(1) into <code>rumai/irb</code> sub-library.</p></li>
544
+ </ul>
545
+
546
+
547
+ <h3 id="Version-3-2-2-2010-04-01-">Version 3.2.2 (2010-04-01)</h3>
548
+
549
+ <p>This release fixes some warnings that appeared during installation and
550
+ performs some minor housekeeping.</p>
551
+
552
+ <p>Bug fixes:</p>
553
+
554
+ <dl>
555
+ <dt>Warnings of the following form appeared during gem installation:</dt><dd><p></p>
556
+
557
+ <pre><code>Unrecognized directive '...' in lib/rumai/inochi.yaml
558
+ </code></pre>
559
+
560
+ <p>Thanks to <a href="http://github.com/ghedamat">ghedamat</a> for reporting this.</p></dd>
561
+ </dl>
562
+
563
+
564
+ <p>Housekeeping:</p>
565
+
566
+ <ul>
567
+ <li>Upgrade to Inochi 2.0.0-rc2 for managing this project.</li>
568
+ </ul>
569
+
570
+
571
+ <h3 id="Version-3-2-1-2010-03-22-">Version 3.2.1 (2010-03-22)</h3>
572
+
573
+ <p>This release improves multi-threading support in Rumai's pure-Ruby
574
+ implementation of the <a href="http://libs.suckless.org/libixp">IXP file-system interface</a>.</p>
575
+
576
+ <p>Thank you:</p>
577
+
578
+ <ul>
579
+ <li><a href="http://github.com/gigamo">Gigamo</a> reported the issue of status bar applets not refreshing
580
+ according to their prescribed schedule (this is particularly noticable
581
+ in the clock applet) and verified my fix for the problem.</li>
582
+ </ul>
583
+
584
+
585
+ <p>Bug fixes:</p>
586
+
587
+ <ul>
588
+ <li>Perform a blocking I/O read to recieve a 9P2000 message in
589
+ <code>Rumai::IXP::Agent#recv</code> only if recieve buffer is empty. This gives
590
+ other threads a chance to check the recieve buffer for their response.
591
+ instead of being blocked by us as we greedily hold on to the 9P2000
592
+ message stream until our expected response arrives.</li>
593
+ </ul>
594
+
595
+
596
+ <p>Housekeeping:</p>
597
+
598
+ <ul>
599
+ <li>Upgrade to Inochi 2.0.0-rc1 and Dfect 2.0.0.</li>
600
+ </ul>
601
+
602
+
603
+ <h3 id="Version-3-2-0-2009-11-17-">Version 3.2.0 (2009-11-17)</h3>
604
+
605
+ <p>This release adds a new automated view arrangement, simplifies the IXP
606
+ transport layer, and cleans up the code and API documentation.</p>
607
+
608
+ <p>New features:</p>
609
+
610
+ <ul>
611
+ <li><p>Add <code>Rumai::View#arrange_in_stacks</code> automated view arrangement.</p></li>
612
+ <li><p>Convert <code>:stack</code> and <code>:max</code> arguments into wmii 3.9 syntax in
613
+ <code>Rumai::Area#layout=</code>.</p></li>
614
+ </ul>
615
+
616
+
617
+ <p>Bug fixes:</p>
618
+
619
+ <ul>
620
+ <li>Rewrote IXP transport layer (<code>Rumai::IXP::Agent</code>) to <em>not</em> use a
621
+ background thread, according to <a href="http://www.x.org/releases/X11R7.5/doc/libxcb/tutorial/#requestsreplies">the XCB cookie approach</a>.</li>
622
+ </ul>
623
+
624
+
625
+ <p>Housekeeping:</p>
626
+
627
+ <ul>
628
+ <li><p>Clean up some code and API docs.</p></li>
629
+ <li><p>Reduce amount of string concatenation in <code>Struct#to_9p</code>.</p></li>
630
+ </ul>
631
+
632
+
633
+ <h3 id="Version-3-1-1-2009-11-16-">Version 3.1.1 (2009-11-16)</h3>
634
+
635
+ <p>This release fixes bugs in automated view arrangements and updates the user
636
+ manual.</p>
637
+
638
+ <p>Thank you:</p>
639
+
640
+ <ul>
641
+ <li>Nathan Neff reported the client ordering bug in automated view
642
+ arrangements.</li>
643
+ </ul>
644
+
645
+
646
+ <p>Bug fixes:</p>
647
+
648
+ <ul>
649
+ <li><p>The relative order of clients was not being preserved during view
650
+ arrangements.</p></li>
651
+ <li><p>Focus on the current view was lost after automated view arrangement was
652
+ applied if the current view was not the first view on which the initially
653
+ focused (before the automated arrangement was applied) client appeared.</p></li>
654
+ </ul>
655
+
656
+
657
+ <h3 id="Version-3-1-0-2009-10-02-">Version 3.1.0 (2009-10-02)</h3>
658
+
659
+ <p>This release adds new methods, fixes some bugs, and revises the manual.</p>
660
+
661
+ <p>New features:</p>
662
+
663
+ <ul>
664
+ <li><p>Add <code>Client#float</code> methods to manipulate floating status.</p></li>
665
+ <li><p>Add <code>Client#manage</code> methods to manipulate managed status.</p></li>
666
+ <li><p>The <code>Client#tags=</code> method now accepts '~' and '!' tag prefixes.</p></li>
667
+ </ul>
668
+
669
+
670
+ <p>Bug fixes:</p>
671
+
672
+ <ul>
673
+ <li><p>There is no <code>View#move_focus</code> method, only <code>View#select</code>.</p></li>
674
+ <li><p>Assertion failure in test suite because all files in <code>/rbar</code>
675
+ (inside wmii's IXP filesystem) contain an automatic color header when
676
+ read.</p></li>
677
+ </ul>
678
+
679
+
680
+ <p>Housekeeping:</p>
681
+
682
+ <ul>
683
+ <li><p>Use simpler Copyright reminder at the top of every file.</p></li>
684
+ <li><p>Open source is for fun, so <a href="http://loiclemeur.com/english/2009/03/never-criticize-your-competitors.html">be
685
+ nice</a>:
686
+ speak of "related works" instead of "competitors".</p></li>
687
+ </ul>
688
+
689
+
690
+ <h3 id="Version-3-0-0-2009-05-11-">Version 3.0.0 (2009-05-11)</h3>
691
+
692
+ <p>This release revises method names, adds new methods, and fixes a bug.</p>
693
+
694
+ <p>Incompatible changes:</p>
695
+
696
+ <ul>
697
+ <li><p>Rename <code>#toggle_</code> methods to use <code>!</code> suffix in their names.</p></li>
698
+ <li><p>Rename <code>#float</code> methods to <code>#floating</code>.</p></li>
699
+ <li><p>Rename <code>View#floater</code> method to <code>View#floating_area</code>.</p></li>
700
+ </ul>
701
+
702
+
703
+ <p>New features:</p>
704
+
705
+ <ul>
706
+ <li><p>Add <code>Client#stick</code> methods to manipulate sticky status.</p></li>
707
+ <li><p>Add <code>Client#fullscreen</code> methods to manipulate fullscreen status.</p></li>
708
+ <li><p>Add <code>Client#slay</code> method which is a forceful version of <code>#kill</code>.</p></li>
709
+ <li><p>Add <code>View#select</code> method to move focus relatively inside a view.</p></li>
710
+ <li><p>Add <code>Area::floating</code> method for symmetry with <code>Area::curr</code>.</p></li>
711
+ <li><p>Add <code>View#managed_area</code> aliases for <code>View#column</code> methods.</p></li>
712
+ </ul>
713
+
714
+
715
+ <p>Bug fixes:</p>
716
+
717
+ <ul>
718
+ <li><p>Fix error when unzooming clients from temporary view.</p></li>
719
+ <li><p>Fix code that launches temporary terminals in the Tutorial.</p>
720
+
721
+ <p>Use the <code>/bin/sh</code> version of the <strong>read</strong> command for portability.</p></li>
722
+ </ul>
723
+
724
+
725
+ <p>Housekeeping:</p>
726
+
727
+ <ul>
728
+ <li><p>Use <code>Client#send</code> instead of <code>#swap</code> in automated arrangements because
729
+ it causes less traffic on /event/.</p></li>
730
+ <li><p>Add old release notes from blog to user manual.</p></li>
731
+ </ul>
732
+
733
+
734
+ <h3 id="Version-2-1-0-2009-05-09-">Version 2.1.0 (2009-05-09)</h3>
735
+
736
+ <p>This release improves client arrangement, fixes several bugs, and cleans up
737
+ the code.</p>
738
+
739
+ <p>Thank you:</p>
740
+
741
+ <ul>
742
+ <li>Simon Hafner reported several bugs.</li>
743
+ <li>Michael Andrus verified bug fixes.</li>
744
+ </ul>
745
+
746
+
747
+ <p>New features:</p>
748
+
749
+ <ul>
750
+ <li><p>Focus is now restored on the initially focused client after applying
751
+ automated client arrangements.</p></li>
752
+ <li><p>The push(), insert(), and unshift() instance methods of the
753
+ <code>Rumai::Area</code> class now preserve the order of inserted clients.</p></li>
754
+ <li><p>The <code>Rumai::View#arrange_in_grid()</code> method now accepts 1 as a parameter.
755
+ This invocation causes every column to contain at most 1 client.</p></li>
756
+ </ul>
757
+
758
+
759
+ <p>Bug fixes:</p>
760
+
761
+ <ul>
762
+ <li><p>Fix error caused by focusing the top/bottom client in the destination
763
+ area before sending new clients into that area.</p></li>
764
+ <li><p>Fix error when importing clients into an empty area.</p></li>
765
+ </ul>
766
+
767
+
768
+ <p>Housekeeping:</p>
769
+
770
+ <ul>
771
+ <li><p>Use snake_case instead of camelCase for variable names.</p></li>
772
+ <li><p>Add copyright notice at the top of every file.</p></li>
773
+ <li><p>Plenty of code formatting and beautification.</p></li>
774
+ </ul>
775
+
776
+
777
+ <h3 id="Version-2-0-2-2009-02-26-">Version 2.0.2 (2009-02-26)</h3>
778
+
779
+ <p>This release fixes a connection bug.</p>
780
+
781
+ <p>Thank you:</p>
782
+
783
+ <ul>
784
+ <li>Simon Hafner reported and helped debug the <code>$DISPLAY</code> bug.</li>
785
+ </ul>
786
+
787
+
788
+ <p>Bug fixes:</p>
789
+
790
+ <ul>
791
+ <li>wmii omits the fractional portion of <code>$DISPLAY</code> in its socket file path.
792
+ Rumai was trying to connect with the entire <code>$DISPLAY</code> value (including
793
+ the fractional portion) and thus could not find wmii's socket file.</li>
794
+ </ul>
795
+
796
+
797
+ <h3 id="Version-2-0-1-2009-01-25-">Version 2.0.1 (2009-01-25)</h3>
798
+
799
+ <p>This release simplifies project administrivia using <a href="http://snk.tuxfamily.org/lib/inochi/">Inochi</a>, improves the unit tests, and revises the user
800
+ manual.</p>
801
+
802
+ <p>Bug fixes:</p>
803
+
804
+ <ul>
805
+ <li>The rumai/ixp/message library's unit test failed if
806
+ <code>/rbar/status</code> did not already exist in wmii.</li>
807
+ </ul>
808
+
809
+
810
+ <p>Housekeeping:</p>
811
+
812
+ <ul>
813
+ <li><p>Store IXP socket address in <code>Rumai::IXP_SOCK_ADDR</code>.</p></li>
814
+ <li><p>Added missing test cases for (TR)create and (TR)remove messages in the
815
+ unit test for the rumai/ixp/message library.</p></li>
816
+ </ul>
817
+
818
+
819
+ <h3 id="Version-2-0-0-2008-02-04-">Version 2.0.0 (2008-02-04)</h3>
820
+
821
+ <p>This release adds support for wmii 3.6, improves the performance of the IXP
822
+ library, and fixes some bugs.</p>
823
+
824
+ <p>Thank you:</p>
825
+
826
+ <ul>
827
+ <li>Christoph Blank tested Rumai 1.0.0 under wmii 3.6 and reported bugs.</li>
828
+ </ul>
829
+
830
+
831
+ <p>Incompatible changes:</p>
832
+
833
+ <ul>
834
+ <li><p>wmii version 3.6 or newer is now required.</p></li>
835
+ <li><p>The <code>Rumai::IXP::Agent::FidStream#read_partial</code> method has been replaced
836
+ by <code>Rumai::IXP::Agent::FidStream#read(true)</code> for efficiency.</p></li>
837
+ <li><p>The <code>Rumai::IXP::Agent::FidStream#write</code> method no longer writes to
838
+ the beginning of the stream. Instead, it writes to the current position
839
+ in the stream.</p></li>
840
+ <li><p>The <code>Rumai::View#floating_area</code> method has been renamed to
841
+ <code>Rumai::View#floater</code> for brevity.</p></li>
842
+ </ul>
843
+
844
+
845
+ <p>New features:</p>
846
+
847
+ <ul>
848
+ <li><p>Added several more methods (such as rewind, pos=, eof?, and so on) from
849
+ Ruby's IO class to the <code>Rumai::IXP::Agent::FidStream</code> class.</p></li>
850
+ <li><p>Added the <code>Rumai::Client#kill</code> method to simplify client termination.</p></li>
851
+ </ul>
852
+
853
+
854
+ <p>Bug fixes:</p>
855
+
856
+ <ul>
857
+ <li>Fixed a race condition in <code>Rumai::Agent#talk</code> which would cause Rumai to
858
+ hang when multiple threads used it.</li>
859
+ </ul>
860
+
861
+
862
+ <h3 id="Version-1-0-0-2008-01-26-">Version 1.0.0 (2008-01-26)</h3>
863
+
864
+ <p>This is the first release of Rumai, the evolution of
865
+ <a href="http://article.gmane.org/gmane.comp.window-managers.wmii/1704">wmii-irb</a>,
866
+ which lets you manipulate the <a href="http://wmii.suckless.org">wmii</a> window manager through <a href="http://ruby-lang.org">Ruby</a>. Enjoy!</p>
867
+
868
+ <h2 id="AUTHORS">AUTHORS</h2>
869
+
870
+ <p>Suraj N. Kurapati</p>
871
+
872
+ <h2 id="CREDITS">CREDITS</h2>
873
+
874
+ <p>Christoph Blank,
875
+ Simon Hafner,
876
+ Michael Andrus,
877
+ Nathan Neff,
878
+ <a href="http://github.com/gigamo">Gigamo</a>,
879
+ <a href="http://github.com/ghedamat">ghedamat</a></p>
880
+
881
+ <h2 id="LICENSE">LICENSE</h2>
882
+
883
+ <p>(the ISC license)</p>
884
+
885
+ <p>Copyright 2006 Suraj N. Kurapati <a href="&#x6d;&#97;&#105;&#108;&#x74;&#x6f;&#58;&#x73;&#117;&#110;&#97;&#x6b;&#117;&#64;&#103;&#109;&#97;&#105;&#x6c;&#46;&#x63;&#x6f;&#109;" data-bare-link="true">&#115;&#x75;&#110;&#x61;&#107;&#117;&#x40;&#x67;&#x6d;&#x61;&#x69;&#x6c;&#46;&#x63;&#x6f;&#109;</a></p>
886
+
887
+ <p>Permission to use, copy, modify, and/or distribute this software for any
888
+ purpose with or without fee is hereby granted, provided that the above
889
+ copyright notice and this permission notice appear in all copies.</p>
890
+
891
+ <p>THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
892
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
893
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
894
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
895
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
896
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
897
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.</p>
898
+
899
+ <h2 id="SEE-ALSO">SEE ALSO</h2>
900
+
901
+ <p>irb(1),
902
+ wmiir(1),
903
+ wmii(1)</p>
904
+
905
+
906
+ <ol class='foot man'>
907
+ <li class='tl'></li>
908
+ <li class='tc'>April 2010</li>
909
+ <li class='tr'>rumai(1)</li>
910
+ </ol>
911
+
912
+ </div>
913
+ </body>
914
+ </html>