rumai 2.1.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
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