rumai 2.1.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. data/CREDITS +1 -0
  2. data/doc/api/classes/Integer.html +5 -5
  3. data/doc/api/classes/Rumai.html +178 -215
  4. data/doc/api/classes/Rumai/Area.html +194 -126
  5. data/doc/api/classes/Rumai/Chain.html +21 -21
  6. data/doc/api/classes/Rumai/Client.html +506 -142
  7. data/doc/api/classes/Rumai/ClientContainer.html +22 -22
  8. data/doc/api/classes/Rumai/IXP/Agent.html +55 -55
  9. data/doc/api/classes/Rumai/IXP/Agent/FidStream.html +30 -30
  10. data/doc/api/classes/Rumai/IXP/Agent/MODES.html +5 -5
  11. data/doc/api/classes/Rumai/IXP/Fcall.html +25 -25
  12. data/doc/api/classes/Rumai/IXP/Stat.html +5 -5
  13. data/doc/api/classes/Rumai/IXP/Stream.html +5 -5
  14. data/doc/api/classes/Rumai/IXP/Struct.html +20 -20
  15. data/doc/api/classes/Rumai/IXP/Struct/Field.html +30 -30
  16. data/doc/api/classes/Rumai/IXP/Struct/Field/CounteeField.html +10 -10
  17. data/doc/api/classes/Rumai/IXP/Struct/Field/CounterField.html +5 -5
  18. data/doc/api/classes/Rumai/IXP/Terror.html +5 -5
  19. data/doc/api/classes/Rumai/Node.html +45 -45
  20. data/doc/api/classes/Rumai/View.html +226 -125
  21. data/doc/api/classes/Rumai/WidgetImpl.html +1 -1
  22. data/doc/api/classes/String.html +10 -10
  23. data/doc/api/classes/Time.html +10 -10
  24. data/doc/api/created.rid +1 -1
  25. data/doc/api/files/CREDITS.html +4 -1
  26. data/doc/api/files/lib/rumai/fs_rb.html +1 -1
  27. data/doc/api/files/lib/rumai/wm_rb.html +1 -1
  28. data/doc/api/files/lib/rumai_rb.html +1 -1
  29. data/doc/api/panel/search_index.js +1 -1
  30. data/doc/history.erb +63 -0
  31. data/doc/index.erb +2 -2
  32. data/doc/index.xhtml +215 -67
  33. data/doc/intro.erb +4 -1
  34. data/doc/usage.erb +1 -1
  35. data/lib/rumai.rb +2 -2
  36. data/lib/rumai/wm.rb +200 -130
  37. metadata +2 -2
data/doc/intro.erb CHANGED
@@ -10,8 +10,11 @@
10
10
  %|chapter "Introduction"
11
11
  %|project
12
12
  <%= $project %> is a [Ruby](<%= ruby_url %>) interface to the [wmii](<%= wmii_url %>) window manager.
13
+
13
14
  * It excels at dynamic arrangement of clients, columns, views, and tags.
14
- * It provides an <%= xref 'shell', 'interactive shell' %> for live entertainment.
15
+
16
+ * It provides an <%= xref 'shell', 'interactive shell' %> for live entertainment and experimentation.
17
+
15
18
  * It contains a pure Ruby client for the [9P2000 protocol](<%= p9p_url %>) on which wmii's [IXP file-system interface](<%= wmii_ixp_url %>) is built.
16
19
 
17
20
  These features distinguish <%= $project %> from the competition:
data/doc/usage.erb CHANGED
@@ -59,7 +59,7 @@
59
59
 
60
60
  <code>
61
61
  colors = %w[ red green blue black orange brown gray navy gold ]
62
- colors.each {|c| system "xterm -bg #{c} -title #{c} -e read &" }
62
+ colors.each {|c| system "xterm -bg #{c} -title #{c} -e sh -c read &" }
63
63
  </code>
64
64
  }.gsub(/^\s+/, '')
65
65
 
data/lib/rumai.rb CHANGED
@@ -8,8 +8,8 @@ gem 'inochi', '~> 1'
8
8
  require 'inochi'
9
9
 
10
10
  Inochi.init :Rumai,
11
- :version => '2.1.0',
12
- :release => '2009-05-09',
11
+ :version => '3.0.0',
12
+ :release => '2009-05-11',
13
13
  :website => 'http://snk.tuxfamily.org/lib/rumai/',
14
14
  :tagline => 'Ruby interface to the wmii window manager',
15
15
  :develop => {
data/lib/rumai/wm.rb CHANGED
@@ -15,67 +15,11 @@ class Object #:nodoc:
15
15
  end
16
16
 
17
17
  module Rumai
18
- # access to global WM state
19
-
20
- ROOT = Node.new '/'
21
-
22
- # Returns the root of IXP file system hierarchy.
23
- def fs
24
- ROOT
25
- end
26
-
27
- # Returns the current set of tags.
28
- def tags
29
- fs.tag.entries.sort - %w[sel]
30
- end
31
-
32
- # Returns the current set of views.
33
- def views
34
- tags.map! {|t| View.new t }
35
- end
36
-
37
- module ClientContainer
38
- # see definition below!
39
- end
40
-
41
- include ClientContainer
42
-
43
- # Returns the IDs of the current set of clients.
44
- def client_ids
45
- fs.client.entries - %w[sel]
46
- end
47
-
48
- # Returns the name of the currently focused tag.
49
- def curr_tag
50
- curr_view.id
51
- end
52
-
53
- # Returns the name of the next tag.
54
- def next_tag
55
- next_view.id
56
- end
57
-
58
- # Returns the name of the previous tag.
59
- def prev_tag
60
- prev_view.id
61
- end
62
-
63
-
64
- # multiple client grouping: allows you to group a set of clients
65
- # together and perform operations on all of them simultaneously.
66
-
67
- GROUPING_TAG = '@'
68
-
69
- # Returns a list of all grouped clients in
70
- # the currently focused view. If there are
71
- # no grouped clients, then the currently
72
- # focused client is returned in the list.
73
- def grouping
74
- list = curr_view.clients.select {|c| c.group? }
75
- list << curr_client if list.empty? and curr_client.exist?
76
- list
77
- end
78
-
18
+ IXP_FS_ROOT = Node.new('/')
19
+ FOCUSED_WIDGET_ID = 'sel'.freeze
20
+ FLOATING_AREA_ID = '~'.freeze
21
+ CLIENT_GROUPING_TAG = '@'.freeze
22
+ CLIENT_STICKY_TAG = '/./'.freeze
79
23
 
80
24
  # abstraction of WM components
81
25
 
@@ -118,7 +62,7 @@ module Rumai
118
62
  ##
119
63
  # The basic building block of the WM hierarchy.
120
64
  #
121
- # NOTE: Inheritors must have a 'current' class method.
65
+ # NOTE: Inheritors must define a 'curr' class method.
122
66
  # NOTE: Inheritors must override the 'focus' method.
123
67
  #
124
68
  module WidgetImpl #:nodoc:
@@ -147,11 +91,11 @@ module Rumai
147
91
  def initialize id, path_prefix
148
92
  super "#{path_prefix}/#{id}"
149
93
 
150
- if id.to_s == 'sel' and ctl.exist?
94
+ if id == FOCUSED_WIDGET_ID and ctl.exist?
151
95
  @id = ctl.read.split.first
152
- @path = File.join(File.dirname(@path), @id)
96
+ super "#{path_prefix}/#{@id}"
153
97
  else
154
- @id = File.basename(@path)
98
+ @id = id.to_s
155
99
  end
156
100
  end
157
101
  end
@@ -168,7 +112,7 @@ module Rumai
168
112
  # Returns the currently focused client.
169
113
  #
170
114
  def self.curr
171
- new :sel
115
+ new FOCUSED_WIDGET_ID
172
116
  end
173
117
 
174
118
  include Chain
@@ -187,7 +131,7 @@ module Rumai
187
131
  #
188
132
  def focus view = nil
189
133
  if exist? and not focus?
190
- Array(view || self.views).each do |v|
134
+ (view ? [view] : self.views).each do |v|
191
135
  if a = self.area(v) and a.exist?
192
136
  v.focus
193
137
  a.focus
@@ -200,9 +144,7 @@ module Rumai
200
144
  distance = (src - dst).abs
201
145
  direction = src < dst ? :down : :up
202
146
 
203
- distance.times do
204
- v.ctl.write "select #{direction}"
205
- end
147
+ distance.times { v.move_focus direction }
206
148
 
207
149
  break
208
150
  end
@@ -218,6 +160,8 @@ module Rumai
218
160
  view.ctl.write "send #{@id} #{dst}"
219
161
  end
220
162
 
163
+ alias move send
164
+
221
165
  ##
222
166
  # Swaps this client with the given destination within the given view.
223
167
  #
@@ -233,6 +177,77 @@ module Rumai
233
177
  ctl.write :kill
234
178
  end
235
179
 
180
+ ##
181
+ # Terminates this client forcefully.
182
+ #
183
+ def slay
184
+ ctl.write :slay
185
+ end
186
+
187
+ ##
188
+ # Maximizes this client to occupy the entire screen on the current view.
189
+ #
190
+ def fullscreen
191
+ ctl.write 'Fullscreen on'
192
+ end
193
+
194
+ ##
195
+ # Restores this client back to its original size on the current view.
196
+ #
197
+ def unfullscreen
198
+ ctl.write 'Fullscreen off'
199
+ end
200
+
201
+ ##
202
+ # Toggles the fullscreen status of this client on the current view.
203
+ #
204
+ def fullscreen!
205
+ ctl.write 'Fullscreen toggle'
206
+ end
207
+
208
+ ##
209
+ # Checks if this client is currently fullscreen on the current view.
210
+ #
211
+ def fullscreen?
212
+ #
213
+ # If the client's dimensions match those of the
214
+ # floating area, then we know it is fullscreen.
215
+ #
216
+ View.curr.manifest =~ /^# #{FLOATING_AREA_ID} (\d+) (\d+)\n.*^#{FLOATING_AREA_ID} #{@id} \d+ \d+ \1 \2 /m
217
+ end
218
+
219
+ ##
220
+ # Checks if this client is sticky (appears in all views).
221
+ #
222
+ def stick?
223
+ tags.include? CLIENT_STICKY_TAG
224
+ end
225
+
226
+ ##
227
+ # Makes this client sticky (appears in all views).
228
+ #
229
+ def stick
230
+ tag CLIENT_STICKY_TAG
231
+ end
232
+
233
+ ##
234
+ # Makes this client unsticky (does not appear in all views).
235
+ #
236
+ def unstick
237
+ untag CLIENT_STICKY_TAG
238
+ end
239
+
240
+ ##
241
+ # Toggles the stickyness of this client.
242
+ #
243
+ def stick!
244
+ if stick?
245
+ unstick
246
+ else
247
+ stick
248
+ end
249
+ end
250
+
236
251
  # WM hierarchy
237
252
 
238
253
  ##
@@ -304,7 +319,7 @@ module Rumai
304
319
  # Checks if this client is included in the current grouping.
305
320
  #
306
321
  def group?
307
- tags.include? GROUPING_TAG
322
+ tags.include? CLIENT_GROUPING_TAG
308
323
  end
309
324
 
310
325
  ##
@@ -312,7 +327,7 @@ module Rumai
312
327
  #
313
328
  def group
314
329
  with_tags do
315
- push GROUPING_TAG
330
+ push CLIENT_GROUPING_TAG
316
331
  end
317
332
  end
318
333
 
@@ -320,13 +335,13 @@ module Rumai
320
335
  # Removes this client to the current grouping.
321
336
  #
322
337
  def ungroup
323
- untag GROUPING_TAG
338
+ untag CLIENT_GROUPING_TAG
324
339
  end
325
340
 
326
341
  ##
327
342
  # Toggles the presence of this client in the current grouping.
328
343
  #
329
- def toggle_group
344
+ def group!
330
345
  if group?
331
346
  ungroup
332
347
  else
@@ -336,10 +351,13 @@ module Rumai
336
351
 
337
352
  private
338
353
 
354
+ ##
355
+ # Returns the wmii ID of the given area.
356
+ #
339
357
  def area_to_id area_or_id
340
358
  if area_or_id.respond_to? :id
341
359
  id = area_or_id.id
342
- id == '~' ? :toggle : id
360
+ id == FLOATING_AREA_ID ? :toggle : id
343
361
  else
344
362
  area_or_id
345
363
  end
@@ -365,7 +383,7 @@ module Rumai
365
383
  end
366
384
 
367
385
  # multiple client grouping
368
- %w[group ungroup toggle_group].each do |meth|
386
+ %w[group ungroup group!].each do |meth|
369
387
  define_method meth do
370
388
  clients.each do |c|
371
389
  c.__send__ meth
@@ -399,17 +417,19 @@ module Rumai
399
417
  ##
400
418
  # Checks if this area is the floating area.
401
419
  #
402
- def float?
403
- @id == '~'
420
+ def floating?
421
+ @id == FLOATING_AREA_ID
404
422
  end
405
423
 
406
424
  ##
407
425
  # Checks if this is a managed area (a column).
408
426
  #
409
427
  def column?
410
- not float?
428
+ not floating?
411
429
  end
412
430
 
431
+ alias managed? column?
432
+
413
433
  include WidgetImpl
414
434
 
415
435
  ##
@@ -419,6 +439,13 @@ module Rumai
419
439
  View.curr.area_of_client Client.curr
420
440
  end
421
441
 
442
+ ##
443
+ # Returns the floating area in the given view.
444
+ #
445
+ def self.floating view = View.curr
446
+ new FLOATING_AREA_ID, view
447
+ end
448
+
422
449
  include Chain
423
450
 
424
451
  ##
@@ -487,11 +514,10 @@ module Rumai
487
514
 
488
515
  insert clients
489
516
 
490
- # adjust the order of clients in this
491
- # area to reflect the tail-wise insertion
517
+ # move inserted clients to bottom
492
518
  clients.each_with_index do |c, i|
493
519
  until c.id == self.client_ids[-i.succ]
494
- c.swap :down
520
+ c.send :down
495
521
  end
496
522
  end
497
523
  end
@@ -520,11 +546,10 @@ module Rumai
520
546
 
521
547
  insert clients
522
548
 
523
- # adjust the order of clients in this
524
- # area to reflect the head-wise insertion
549
+ # move inserted clients to top
525
550
  clients.each_with_index do |c, i|
526
551
  until c.id == self.client_ids[i]
527
- c.swap :up
552
+ c.send :up
528
553
  end
529
554
  end
530
555
  end
@@ -601,14 +626,14 @@ module Rumai
601
626
  # Returns the currently focused view.
602
627
  #
603
628
  def self.curr
604
- new :sel
629
+ new FOCUSED_WIDGET_ID
605
630
  end
606
631
 
607
632
  ##
608
633
  # Focuses this view.
609
634
  #
610
635
  def focus
611
- Rumai.fs.ctl.write "view #{@id}"
636
+ IXP_FS_ROOT.ctl.write "view #{@id}"
612
637
  end
613
638
 
614
639
  include Chain
@@ -643,12 +668,21 @@ module Rumai
643
668
  super view_id, '/tag'
644
669
  end
645
670
 
646
- ##
647
- # Returns the manifest of all areas and clients in this view.
648
- #
649
- def manifest
650
- index.read || ''
651
- end
671
+ # WM operations
672
+
673
+ ##
674
+ # Returns the manifest of all areas and clients in this view.
675
+ #
676
+ def manifest
677
+ index.read || ''
678
+ end
679
+
680
+ ##
681
+ # Moves the focus from the current client in the given direction.
682
+ #
683
+ def select direction
684
+ ctl.write "select #{direction}"
685
+ end
652
686
 
653
687
  # WM hierarchy
654
688
 
@@ -673,9 +707,7 @@ module Rumai
673
707
  # Returns the IDs of all areas in this view.
674
708
  #
675
709
  def area_ids
676
- ids = manifest.scan(/^# (\d+)/).flatten
677
- ids.unshift '~' # the floating area
678
- ids
710
+ manifest.scan(/^# (\d+)/).flatten.unshift(FLOATING_AREA_ID)
679
711
  end
680
712
 
681
713
  ##
@@ -688,8 +720,8 @@ module Rumai
688
720
  ##
689
721
  # Returns the floating area of this view.
690
722
  #
691
- def floater
692
- areas.first
723
+ def floating_area
724
+ Area.floating self
693
725
  end
694
726
 
695
727
  ##
@@ -699,6 +731,8 @@ module Rumai
699
731
  areas[1..-1]
700
732
  end
701
733
 
734
+ alias managed_areas columns
735
+
702
736
  ##
703
737
  # Resiliently iterates through possibly destructive changes to
704
738
  # each column. That is, if the given block creates new
@@ -719,6 +753,8 @@ module Rumai
719
753
  end
720
754
  end
721
755
 
756
+ alias each_managed_area each_column
757
+
722
758
  # visual arrangement of clients
723
759
 
724
760
  ##
@@ -731,17 +767,23 @@ module Rumai
731
767
  #
732
768
  def arrange_as_larswm
733
769
  maintain_focus do
734
- float, main, *extra = areas
735
-
736
770
  # keep only one client in the primary column
771
+ main = Area.new(1, self)
737
772
  main.length = 1
773
+ main.layout = :default
774
+
775
+ # collapse remaining areas into secondary column
776
+ extra = columns[1..-1]
738
777
 
739
778
  if extra.length > 1
740
- # collapse remaining areas into secondary column
741
779
  extra.reverse.each_cons(2) do |src, dst|
742
780
  dst.concat src
743
781
  end
744
782
  end
783
+
784
+ if dock = extra.first
785
+ dock.layout = :default
786
+ end
745
787
  end
746
788
  end
747
789
 
@@ -823,7 +865,7 @@ module Rumai
823
865
  # before the given block was executed.
824
866
  #
825
867
  def maintain_focus
826
- c = Rumai.curr_client
868
+ c = Client.curr
827
869
  yield
828
870
  c.focus
829
871
  end
@@ -836,47 +878,75 @@ module Rumai
836
878
  end
837
879
  end
838
880
 
839
- # shortcuts for interactive WM manipulation (via IRB)
840
-
841
- # provide easy access to container state information
842
- [Client, Area, View].each {|c| c.extend ExportInstanceMethods }
881
+ # access to global WM state
843
882
 
844
- def curr_client
845
- Client.curr
883
+ ##
884
+ # Returns the root of IXP file system hierarchy.
885
+ #
886
+ def fs
887
+ IXP_FS_ROOT
846
888
  end
847
889
 
848
- def next_client
849
- curr_client.next
890
+ ##
891
+ # Returns the current set of tags.
892
+ #
893
+ def tags
894
+ ary = IXP_FS_ROOT.tag.entries.sort
895
+ ary.delete FOCUSED_WIDGET_ID
896
+ ary
850
897
  end
851
898
 
852
- def prev_client
853
- curr_client.prev
899
+ ##
900
+ # Returns the current set of views.
901
+ #
902
+ def views
903
+ tags.map! {|t| View.new t }
854
904
  end
855
905
 
856
- def curr_area
857
- Area.curr
858
- end
906
+ include ClientContainer
859
907
 
860
- def next_area
861
- curr_area.next
862
- end
908
+ ##
909
+ # Returns the IDs of the current set of clients.
910
+ #
911
+ def client_ids
912
+ ary = IXP_FS_ROOT.client.entries
913
+ ary.delete FOCUSED_WIDGET_ID
914
+ ary
915
+ end
863
916
 
864
- def prev_area
865
- curr_area.prev
866
- end
917
+ def curr_client ; Client.curr ; end
918
+ def next_client ; curr_client.next ; end
919
+ def prev_client ; curr_client.prev ; end
867
920
 
868
- def curr_view
869
- View.curr
870
- end
921
+ def curr_area ; Area.curr ; end
922
+ def next_area ; curr_area.next ; end
923
+ def prev_area ; curr_area.prev ; end
871
924
 
872
- def next_view
873
- curr_view.next
874
- end
925
+ def curr_view ; View.curr ; end
926
+ def next_view ; curr_view.next ; end
927
+ def prev_view ; curr_view.prev ; end
875
928
 
876
- def prev_view
877
- curr_view.prev
929
+ def curr_tag ; curr_view.id ; end
930
+ def next_tag ; next_view.id ; end
931
+ def prev_tag ; prev_view.id ; end
932
+
933
+ ##
934
+ # Returns a list of all grouped clients in
935
+ # the currently focused view. If there are
936
+ # no grouped clients, then the currently
937
+ # focused client is returned in the list.
938
+ #
939
+ def grouping
940
+ list = curr_view.clients.select {|c| c.group? }
941
+ list << curr_client if list.empty? and curr_client.exist?
942
+ list
878
943
  end
879
944
 
945
+ # shortcuts for interactive WM manipulation (via IRB)
946
+
947
+ # provide easy access to container state information
948
+ [Client, Area, View].each {|c| c.extend ExportInstanceMethods }
949
+
880
950
  def focus_client id
881
951
  Client.focus id
882
952
  end
@@ -890,5 +960,5 @@ module Rumai
890
960
  end
891
961
 
892
962
  # provide easy access to this module's instance methods
893
- module_function(*instance_methods)
963
+ module_function(*instance_methods(false))
894
964
  end