canis 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +45 -0
  3. data/CHANGES +52 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +24 -0
  7. data/Rakefile +2 -0
  8. data/canis.gemspec +25 -0
  9. data/examples/alpmenu.rb +46 -0
  10. data/examples/app.sample +19 -0
  11. data/examples/appemail.rb +191 -0
  12. data/examples/atree.rb +105 -0
  13. data/examples/bline.rb +181 -0
  14. data/examples/common/devel.rb +319 -0
  15. data/examples/common/file.rb +93 -0
  16. data/examples/data/README.markdown +9 -0
  17. data/examples/data/brew.txt +38 -0
  18. data/examples/data/color.2 +37 -0
  19. data/examples/data/gemlist.txt +59 -0
  20. data/examples/data/lotr.txt +12 -0
  21. data/examples/data/ports.txt +136 -0
  22. data/examples/data/table.txt +37 -0
  23. data/examples/data/tasks.csv +88 -0
  24. data/examples/data/tasks.txt +27 -0
  25. data/examples/data/todo.txt +16 -0
  26. data/examples/data/todocsv.csv +28 -0
  27. data/examples/data/unix1.txt +21 -0
  28. data/examples/data/unix2.txt +11 -0
  29. data/examples/dbdemo.rb +506 -0
  30. data/examples/dirtree.rb +177 -0
  31. data/examples/newtabbedwindow.rb +100 -0
  32. data/examples/newtesttabp.rb +92 -0
  33. data/examples/tabular.rb +212 -0
  34. data/examples/tasks.rb +179 -0
  35. data/examples/term2.rb +88 -0
  36. data/examples/testbuttons.rb +307 -0
  37. data/examples/testcombo.rb +102 -0
  38. data/examples/testdb.rb +182 -0
  39. data/examples/testfields.rb +208 -0
  40. data/examples/testflowlayout.rb +43 -0
  41. data/examples/testkeypress.rb +98 -0
  42. data/examples/testlistbox.rb +187 -0
  43. data/examples/testlistbox1.rb +199 -0
  44. data/examples/testmessagebox.rb +144 -0
  45. data/examples/testprogress.rb +116 -0
  46. data/examples/testree.rb +107 -0
  47. data/examples/testsplitlayout.rb +53 -0
  48. data/examples/testsplitlayout1.rb +49 -0
  49. data/examples/teststacklayout.rb +48 -0
  50. data/examples/testwsshortcuts.rb +68 -0
  51. data/examples/testwsshortcuts2.rb +129 -0
  52. data/lib/canis.rb +16 -0
  53. data/lib/canis/core/docs/index.txt +104 -0
  54. data/lib/canis/core/docs/list.txt +16 -0
  55. data/lib/canis/core/docs/style_help.yml +34 -0
  56. data/lib/canis/core/docs/tabbedpane.txt +15 -0
  57. data/lib/canis/core/docs/table.txt +31 -0
  58. data/lib/canis/core/docs/textpad.txt +48 -0
  59. data/lib/canis/core/docs/tree.txt +23 -0
  60. data/lib/canis/core/include/.DS_Store +0 -0
  61. data/lib/canis/core/include/action.rb +83 -0
  62. data/lib/canis/core/include/actionmanager.rb +49 -0
  63. data/lib/canis/core/include/appmethods.rb +179 -0
  64. data/lib/canis/core/include/bordertitle.rb +49 -0
  65. data/lib/canis/core/include/canisparser.rb +100 -0
  66. data/lib/canis/core/include/colorparser.rb +437 -0
  67. data/lib/canis/core/include/defaultfilerenderer.rb +64 -0
  68. data/lib/canis/core/include/io.rb +320 -0
  69. data/lib/canis/core/include/layouts/SplitLayout.rb +161 -0
  70. data/lib/canis/core/include/layouts/abstractlayout.rb +213 -0
  71. data/lib/canis/core/include/layouts/flowlayout.rb +104 -0
  72. data/lib/canis/core/include/layouts/stacklayout.rb +109 -0
  73. data/lib/canis/core/include/listbindings.rb +89 -0
  74. data/lib/canis/core/include/listeditable.rb +319 -0
  75. data/lib/canis/core/include/listoperations.rb +61 -0
  76. data/lib/canis/core/include/listselectionmodel.rb +388 -0
  77. data/lib/canis/core/include/multibuffer.rb +173 -0
  78. data/lib/canis/core/include/ractionevent.rb +73 -0
  79. data/lib/canis/core/include/rchangeevent.rb +27 -0
  80. data/lib/canis/core/include/rhistory.rb +95 -0
  81. data/lib/canis/core/include/rinputdataevent.rb +47 -0
  82. data/lib/canis/core/include/textdocument.rb +111 -0
  83. data/lib/canis/core/include/vieditable.rb +175 -0
  84. data/lib/canis/core/include/widgetmenu.rb +66 -0
  85. data/lib/canis/core/system/colormap.rb +165 -0
  86. data/lib/canis/core/system/keydefs.rb +32 -0
  87. data/lib/canis/core/system/ncurses.rb +237 -0
  88. data/lib/canis/core/system/panel.rb +129 -0
  89. data/lib/canis/core/system/window.rb +1081 -0
  90. data/lib/canis/core/util/ansiparser.rb +119 -0
  91. data/lib/canis/core/util/app.rb +696 -0
  92. data/lib/canis/core/util/basestack.rb +412 -0
  93. data/lib/canis/core/util/defaultcolorparser.rb +84 -0
  94. data/lib/canis/core/util/extras/README +5 -0
  95. data/lib/canis/core/util/extras/bottomline.rb +1815 -0
  96. data/lib/canis/core/util/extras/padreader.rb +192 -0
  97. data/lib/canis/core/util/focusmanager.rb +31 -0
  98. data/lib/canis/core/util/helpmanager.rb +160 -0
  99. data/lib/canis/core/util/oldwidgetshortcuts.rb +304 -0
  100. data/lib/canis/core/util/promptmenu.rb +235 -0
  101. data/lib/canis/core/util/rcommandwindow.rb +933 -0
  102. data/lib/canis/core/util/rdialogs.rb +520 -0
  103. data/lib/canis/core/util/textutils.rb +74 -0
  104. data/lib/canis/core/util/viewer.rb +238 -0
  105. data/lib/canis/core/util/widgetshortcuts.rb +508 -0
  106. data/lib/canis/core/widgets/applicationheader.rb +103 -0
  107. data/lib/canis/core/widgets/box.rb +58 -0
  108. data/lib/canis/core/widgets/divider.rb +310 -0
  109. data/lib/canis/core/widgets/extras/README.md +12 -0
  110. data/lib/canis/core/widgets/extras/rtextarea.rb +960 -0
  111. data/lib/canis/core/widgets/extras/stackflow.rb +474 -0
  112. data/lib/canis/core/widgets/keylabelprinter.rb +194 -0
  113. data/lib/canis/core/widgets/listbox.rb +326 -0
  114. data/lib/canis/core/widgets/listfooter.rb +86 -0
  115. data/lib/canis/core/widgets/rcombo.rb +210 -0
  116. data/lib/canis/core/widgets/rcontainer.rb +415 -0
  117. data/lib/canis/core/widgets/rlink.rb +30 -0
  118. data/lib/canis/core/widgets/rmenu.rb +970 -0
  119. data/lib/canis/core/widgets/rmenulink.rb +30 -0
  120. data/lib/canis/core/widgets/rmessagebox.rb +400 -0
  121. data/lib/canis/core/widgets/rprogress.rb +118 -0
  122. data/lib/canis/core/widgets/rtabbedpane.rb +631 -0
  123. data/lib/canis/core/widgets/rtabbedwindow.rb +70 -0
  124. data/lib/canis/core/widgets/rwidget.rb +3634 -0
  125. data/lib/canis/core/widgets/scrollbar.rb +147 -0
  126. data/lib/canis/core/widgets/statusline.rb +113 -0
  127. data/lib/canis/core/widgets/table.rb +1072 -0
  128. data/lib/canis/core/widgets/tabular.rb +264 -0
  129. data/lib/canis/core/widgets/textpad.rb +1674 -0
  130. data/lib/canis/core/widgets/tree.rb +690 -0
  131. data/lib/canis/core/widgets/tree/treecellrenderer.rb +150 -0
  132. data/lib/canis/core/widgets/tree/treemodel.rb +432 -0
  133. data/lib/canis/version.rb +3 -0
  134. metadata +229 -0
data/examples/atree.rb ADDED
@@ -0,0 +1,105 @@
1
+ require 'canis/core/util/app'
2
+
3
+ App.new do
4
+ var = Variable.new
5
+ header = app_header "canis #{Canis::VERSION}", :text_center => "Tree Demo", :text_right =>"New Improved!", :color => :black, :bgcolor => :white, :attr => :bold
6
+ message "Press Enter to expand/collapse"
7
+
8
+ @form.bind_key(FFI::NCurses::KEY_F3) {
9
+ require 'canis/core/util/viewer'
10
+ Canis::Viewer.view("canis14.log", :close_key => KEY_ENTER, :title => "<Enter> to close")
11
+ }
12
+
13
+ ww = FFI::NCurses.COLS-0
14
+ flow :width => ww , :margin_top => 1, :height => FFI::NCurses.LINES-2 do
15
+ stack :margin_top => 0, :width_pc => "30" do
16
+ tm = nil
17
+ atree = tree :height => 10, :title => '[ ruby way ]' do
18
+ root "root" do
19
+ branch "hello" do
20
+ leaf "ruby"
21
+ end
22
+ branch "goodbye" do
23
+ leaf "java"
24
+ leaf "verbosity"
25
+ end
26
+ end
27
+ end
28
+ found=atree.get_node_for_path "goodbye"
29
+ atree.set_expanded_state(atree.root, true)
30
+ atree.set_expanded_state(found,true)
31
+
32
+ # using a Hash
33
+ model = { :ruby => [ "jruby", {:mri => %W[ 1.8.6 1.8.7]}, {:yarv => %W[1.9.1 1.9.2]}, "rubinius", "macruby" ], :python => %W[ cpython jython laden-swallow ] }
34
+ tree :data => model, :title => "[ Hash ]"
35
+
36
+ end # stack
37
+ stack :margin_top => 0, :width_pc => "30" do
38
+
39
+ # using an Array, these would be expanded on selection, using an event
40
+ tree :data => Dir.glob("*"), :title=> "[ Array ]" do
41
+ command do |node|
42
+ # insert dir entries unless done so already
43
+ if node.children && !node.children.empty?
44
+ else
45
+ f = node.user_object
46
+ if File.directory? f
47
+ l = Dir.glob(f + "/*")
48
+ node.add(l) if l
49
+ end
50
+ end
51
+ end
52
+ bind :ENTER_ROW do |t|
53
+ # now ENTER_ROW comes from TEXTpad and gives an event
54
+ var.value = t.text
55
+ end
56
+ end
57
+
58
+ # long way ISO 9001 certifed, SEI CMM 5 compliant
59
+ #
60
+ root = TreeNode.new "ROOT"
61
+ subroot = TreeNode.new "subroot"
62
+ leaf1 = TreeNode.new "leaf 1"
63
+ leaf2 = TreeNode.new "leaf 2"
64
+ model = DefaultTreeModel.new root
65
+ #model.insert_node_into(subroot, root, 0) # BLEAH JAVA !!
66
+
67
+ # slightly better, since we return self in ruby
68
+ root << subroot
69
+ subroot << leaf1 << leaf2
70
+ leaf1 << "leaf11"
71
+ leaf1 << "leaf12"
72
+
73
+ # more rubyish way
74
+ root.add "blocky", true do
75
+ add "block2"
76
+ add "block3" do
77
+ add "block31"
78
+ end
79
+ end
80
+
81
+ tree :data => model, :title => "[ legacy way ]"
82
+
83
+ end
84
+ #stack :margin_top => 2 do
85
+ stack :margin_top => 0, :width_pc => "40", :height => :expand do
86
+ # using height_pc as 100 was causing prefresh to fail if file lines went beyond 31
87
+ # tput lines gives 32 so only when file length exceeded was it actually writing beyond screen
88
+ t = textview :suppress_borders => true, :height_pc => 90, :color => :green, :bgcolor => :black
89
+ var.command do |filename|
90
+ filename = filename.value
91
+ if File.directory? filename
92
+ lines = Dir.entries(filename )
93
+ t.set_content lines
94
+ elsif File.exist? filename
95
+ # next line bombs on "invalid byte sequence on UTF-8" on split.
96
+ lines = File.open(filename,'r').read.split("\n")
97
+ # next line bombs on binary files. normally we would check file type using +file+ command
98
+ t.set_content lines
99
+ else
100
+ alert " #{filename} does not appear to be a file "
101
+ end
102
+ end
103
+ end
104
+ end # flow
105
+ end # app
data/examples/bline.rb ADDED
@@ -0,0 +1,181 @@
1
+ require 'canis/core/util/app'
2
+ require 'canis/core/util/rcommandwindow'
3
+ require 'fileutils'
4
+ require 'pathname'
5
+ require 'canis/core/include/defaultfilerenderer'
6
+ require './common/devel.rb'
7
+
8
+ # this will go into top namespace so will conflict with other apps!
9
+ def testnumberedmenu
10
+ list1 = %w{ ruby perl python erlang rake java lisp scheme chicken }
11
+ list1[0] = %w{ ruby ruby1.9 ruby1.8.x jruby rubinius ROR }
12
+ list1[5] = %w{ java groovy grails }
13
+ str = numbered_menu list1, { :title => "Languages: ", :prompt => "Select :" }
14
+ $log.debug "17 We got #{str.class} "
15
+ message "We got #{str} "
16
+ end
17
+ def testdisplay_list
18
+ # scrollable filterable list
19
+ text = Dir.glob "*.rb"
20
+ $log.debug "DDD got #{text.size} "
21
+ str = display_list text, :title => "Select a file"
22
+ #$log.debug "23 We got #{str} : #{str.class} , #{str.list[str.current_index]} "
23
+ $log.debug "23 We got #{str} "
24
+ #file = str.list[str.current_index]
25
+ file = str
26
+ #message "We got #{str.list[str.current_index]} "
27
+ show file if file
28
+ end
29
+ def testdisplay_text
30
+ #str = display_text_interactive File.read($0), :title => "#{$0}"
31
+ str = display_text $0, :title => "#{$0}"
32
+ end
33
+ def testdir
34
+ # this behaves like vim's file selector, it fills in values
35
+ str = rb_gets("File? ", Pathname) do |q|
36
+ #q.completion_proc = Proc.new {|str| Dir.glob(str +"*").collect { |f| File.directory?(f) ? f+"/" : f } }
37
+ q.help_text = "Enter start of filename and tab to get completion"
38
+ end
39
+ message "We got #{str} "
40
+ show str
41
+ end
42
+ # if components have some commands, can we find a way of passing the command to them
43
+ # method_missing gave a stack overflow.
44
+ def execute_this(meth, *args)
45
+ alert " #{meth} not found ! "
46
+ $log.debug "app email got #{meth} " if $log.debug?
47
+ cc = @form.get_current_field
48
+ [cc].each do |c|
49
+ if c.respond_to?(meth, true)
50
+ c.send(meth, *args)
51
+ return true
52
+ end
53
+ end
54
+ false
55
+ end
56
+
57
+ App.new do
58
+ @startdir ||= File.expand_path("..")
59
+ def show file
60
+ w = @form.by_name["tv"]
61
+ if File.directory? file
62
+ lines = Dir.entries(file)
63
+ w.text lines
64
+ w.title "[ #{file} ]"
65
+ elsif File.exists? file
66
+ lines = File.open(file,'r').readlines
67
+ w.text lines
68
+ w.title "[ #{file} ]"
69
+ end
70
+ end
71
+ def testchoosedir
72
+ # list filters as you type
73
+ $log.debug "called CHOOSE " if $log.debug?
74
+ str = choose_file :title => "Select a file",
75
+ :recursive => true,
76
+ :dirs => true,
77
+ :directory => @startdir,
78
+ :help_text => "Enter pattern, use UP DOWN to traverse, Backspace to delete, ENTER to select. Esc-Esc to quit"
79
+ if str
80
+ message "We got #{str} "
81
+ show str
82
+ end
83
+ end
84
+ def testchoosefile
85
+ # list filters as you type a pattern
86
+ glob = "**/*.rb"
87
+ str = choose_file glob, :title => "Select a file",
88
+ :directory => @startdir,
89
+ :help_text => "Enter pattern, use UP DOWN to traverse, Backspace to delete, ENTER to select. Esc-Esc to quit"
90
+ if str and str != ""
91
+ message "We got #{str} "
92
+ show str
93
+ end
94
+ end
95
+ ht = 24
96
+ borderattrib = :reverse
97
+ @header = app_header "canis #{Canis::VERSION}", :text_center => "rCommandline Test",
98
+ :text_right =>"Press :", :color => :white, :bgcolor => 236
99
+ message "Press F10 (or qq) to exit, F1 Help, : for Menu "
100
+
101
+
102
+
103
+ # commands that can be mapped to or executed using M-x
104
+ # however, commands of components aren't yet accessible.
105
+ def get_commands
106
+ %w{ testchoosedir testchoosefile testnumberedmenu testdisplay_list testdisplay_text testdir }
107
+ end
108
+ def help_text
109
+ <<-eos
110
+ rCommandLine HELP
111
+
112
+ These are some features for either getting filenames from user
113
+ at the bottom of the window like vim and others do, or filtering
114
+ from a list (like ControlP plugin). Or seeing a file at bottom
115
+ of screen for a quick preview.
116
+
117
+ : - Command mode
118
+ F1 - Help
119
+ F10 - Quit application
120
+ qq - Quit application
121
+ = - file selection (interface like Ctrl-P, very minimal)
122
+
123
+ Some commands for using bottom of screen as vim and emacs do.
124
+ These may be selected by pressing ':'
125
+
126
+ testchoosedir - filter directory list as you type
127
+ '>' to step into a dir, '<' to go up.
128
+ testchoosefile - filter file list as you type
129
+ ENTER to select, C-c or Esc-Esc to quit
130
+ testdir - vim style, tabbing completes matching files
131
+ testnumberedmenu - use menu indexes to select options
132
+ testdisplaylist - display a list at bottom of screen
133
+ Press <ENTER> to select, arrow keys to traverse,
134
+ and characters to filter list.
135
+ testdisplaytext - display text at bottom (current file contents)
136
+ Press <ENTER> when done.
137
+
138
+ The file/dir selection options are very minimally functional. Improvements
139
+ and thorough testing are required. I've only tested them out gingerly.
140
+
141
+ testchoosedir and file were earlier like Emacs/memacs with TAB completion
142
+ but have now moved to the much faster and friendlier ControlP plugin like
143
+ 'filter as you type' format.
144
+
145
+ -----------------------------------------------------------------------
146
+ :n or Alt-n for general help.
147
+ eos
148
+ end
149
+
150
+ #install_help_text help_text
151
+
152
+ def app_menu
153
+ @curdir ||= Dir.pwd
154
+ Dir.chdir(@curdir) if Dir.pwd != @curdir
155
+ require 'canis/core/util/promptmenu'
156
+ menu = PromptMenu.new self do
157
+ item :c, :testchoosedir
158
+ item :f, :testchoosefile
159
+ item :d, :testdir
160
+ item :n, :testnumberedmenu
161
+ item :l, :testdisplay_list
162
+ item :t, :testdisplay_text
163
+ end
164
+ menu.display_new :title => "Menu"
165
+ end
166
+ @form.bind_key(?:, "App Menu") { app_menu; }
167
+ @form.bind_key(?=, "Choose File") {
168
+ @curdir ||= Dir.pwd
169
+ Dir.chdir(@curdir) if Dir.pwd != @curdir
170
+ #testdisplay_list;
171
+ testchoosefile;
172
+ }
173
+
174
+ stack :margin_top => 1, :margin_left => 0, :width => :expand , :height => FFI::NCurses.LINES-2 do
175
+ tv = textview :height_pc => 100, :width_pc => 100, :name => "tv", :suppress_borders => true
176
+ tv.renderer ruby_renderer
177
+ end # stack
178
+
179
+ sl = status_line :row => Ncurses.LINES-1
180
+ testdisplay_list
181
+ end # app
@@ -0,0 +1,319 @@
1
+ # ----------------------------------------------------------------------------- #
2
+ # File: devel.rb
3
+ # Description: Some routines for development time
4
+ # Author: j kepler http://github.com/mare-imbrium/canis/
5
+ # Date: 2014-06-02 - 20:26
6
+ # License: MIT
7
+ # Last update: 2014-07-10 18:33
8
+ # ----------------------------------------------------------------------------- #
9
+ # devel.rb Copyright (C) 2012-2014 j kepler
10
+ require 'canis/core/include/appmethods'
11
+ require 'canis/core/util/rcommandwindow'
12
+ module Canis
13
+ module Devel
14
+ def devel_bindings
15
+ form = @form
16
+ raise "Form not set in Canis::Devel" unless form
17
+ #alert "executing devel_bindings "
18
+ form.bind_key(FFI::NCurses::KEY_F3,'view log') {
19
+ view("canis14.log", :close_key => 'q', :title => "<q> to close")
20
+ }
21
+ form.bind_key([?\\,?\\,?l],'view log') {
22
+ view("canis14.log", :close_key => 'q', :title => "<q> to close")
23
+ }
24
+ form.bind_key([?\\,?\\,?x],'view current') {
25
+ code_browse $0
26
+ }
27
+ form.bind_key([?\\,?\\,?c],'run command') {
28
+ shell_output
29
+ }
30
+ form.bind_key([?\\,?\\,?o],'choose file') {
31
+ choose_file_and_view
32
+ }
33
+ form.bind_key([?\\,?g,?f],'change global fore color') {
34
+ ret = get_string "Enter a foreground color (number)", :default => "255"
35
+ if ret
36
+ $def_fg_color = ret.to_i
37
+ form.repaint_all_widgets
38
+ end
39
+ }
40
+ form.bind_key([?\\,?g,?b],'change global bg color') {
41
+ ret = get_string "Enter a background color (number)", :default => "0"
42
+ if ret
43
+ $def_bg_color = ret.to_i
44
+ form.repaint_all_widgets
45
+ end
46
+ }
47
+ form.bind_key([?\\,?f,?f],'change forms fore color') {
48
+ }
49
+ form.bind_key([?\\,?f,?b],'change forms bg color') {
50
+ }
51
+ end
52
+ # a quick dirty code formatter,
53
+ # TODO : parse it at least like a help file, with a content_type :code or :ruby
54
+ # TODO : provide key 'gf' to open other files under cursor
55
+ # @param [String] file name to browse
56
+ def code_browse path
57
+ dr = ruby_renderer
58
+ view(path, :close_key => 'q', :title => $0) do |t|
59
+ t.renderer dr
60
+ t.bind_key([?\\,?\\,?o],'choose file') {
61
+ str = choose_file "**/*"
62
+ if str and str != ""
63
+ t.add_content str
64
+ t.buffer_last
65
+ else
66
+ alert "nothing chosen"
67
+ end
68
+ }
69
+ end
70
+ end
71
+ # this should be available to view also.
72
+ def choose_file_and_view glob=nil, startdir="."
73
+ glob ||= "**/*.rb"
74
+ str = choose_file glob, :title => "Select a file",
75
+ :directory => startdir,
76
+ :help_text => "Enter pattern, use UP DOWN to traverse, Backspace to delete, ENTER to select. Esc-Esc to quit"
77
+ if str and str != ""
78
+ code_browse str
79
+ end
80
+ end
81
+ def ruby_renderer
82
+ require 'canis/core/include/defaultfilerenderer'
83
+ dr = DefaultFileRenderer.new
84
+ dr.insert_mapping /^\s*## /, [:red, :black]
85
+ dr.insert_mapping /^\s*#/, [:blue, :black]
86
+ dr.insert_mapping /^\s*(class|module)/, [:cyan, :black, BOLD]
87
+ dr.insert_mapping /^\s*(def|function)/, [:yellow, :black, FFI::NCurses::A_BOLD]
88
+ dr.insert_mapping /^\s*(require|load)/, [:green, :black]
89
+ dr.insert_mapping /^\s*(end|if |elsif|else|begin|rescue|ensure|include|extend|while|unless|case |when )/, [:magenta, :black]
90
+ return dr
91
+ end
92
+ def directory_renderer obj
93
+ #DirectoryRenderer.new obj
94
+ LongDirectoryRenderer.new obj
95
+ end
96
+
97
+ # the issue with a generic directory renderer is that it does not have
98
+ # the full path, the dir name that is.
99
+ # FIXME: this expects text to be only a filename, but what about long listings.
100
+ # In long listings the left_margin char will print at start whereas the filename
101
+ # comes later in last slot of array
102
+ class DirectoryRenderer < ListRenderer
103
+ attr_accessor :hash
104
+ attr_accessor :prefix
105
+ # specify if long, short or full listing
106
+ attr_accessor :mode
107
+ def initialize obj
108
+ super
109
+ @hash = {}
110
+ @prefix = {}
111
+ create_mapping
112
+ end
113
+ def pre_render
114
+ super
115
+ # hack to get path
116
+ @path = @source.title
117
+ end
118
+ def create_mapping
119
+ @hash[:dir] = [:white, nil, BOLD]
120
+ @hash[:file] = [:white, nil, nil]
121
+ @hash[:link] = [:red, nil, nil]
122
+ @hash[:executable] = [:red, nil, BOLD]
123
+ @hash[:text] = [:magenta, nil, nil]
124
+ @hash[:zip] = [:cyan, nil, nil]
125
+ @hash[:other] = [:blue, nil, nil]
126
+ ##
127
+ @prefix[:dir] = "/"
128
+ @prefix[:link] = "@"
129
+ @prefix[:executable] = "*"
130
+ end
131
+ def get_category t
132
+ text = File.join(@path, t)
133
+ if File.directory? text
134
+ return :dir
135
+ elsif File.executable? text
136
+ return :executable
137
+ elsif File.symlink? text
138
+ return :link
139
+ elsif File.exists? text
140
+ if text =~ /\.txt$/
141
+ return :text
142
+ elsif text =~ /\.zip$/ or text =~ /gz$/
143
+ return :zip
144
+ else
145
+ return :file
146
+ end
147
+ else
148
+ return :other
149
+ end
150
+ end
151
+
152
+ def render pad, lineno, text
153
+ klass = get_category fullname
154
+ @fg = @hash[klass][0]
155
+ bg = @hash[klass][1]
156
+ @bg = bg #if bg
157
+ bg = @hash[klass][2]
158
+ @attr = bg # if bg
159
+ prefix = @prefix[klass] || " "
160
+ @left_margin_text = prefix
161
+
162
+
163
+ super
164
+ end
165
+ end
166
+ class LongDirectoryRenderer < ListRenderer
167
+ attr_accessor :hash
168
+ attr_accessor :prefix
169
+ # specify if long, short or full listing
170
+ attr_accessor :mode
171
+ attr_accessor :formatter
172
+ def initialize obj
173
+ super
174
+ @hash = {}
175
+ @prefix = {}
176
+ @default_formatter = Formatter.new
177
+ @formatter = nil
178
+ create_mapping
179
+ end
180
+ def format_message(fname, stat, prefix=nil)
181
+ (@formatter || @default_formatter).call(fname, stat, prefix)
182
+ end
183
+ # Set date-time format.
184
+ #
185
+ # +datetime_format+:: A string suitable for passing to +strftime+.
186
+ def datetime_format=(datetime_format)
187
+ @default_formatter.datetime_format = datetime_format
188
+ end
189
+
190
+ # Returns the date format being used. See #datetime_format=
191
+ def datetime_format
192
+ @default_formatter.datetime_format
193
+ end
194
+ def pre_render
195
+ super
196
+ # hack to get path
197
+ @path = @source.title
198
+ end
199
+ def create_mapping
200
+ @hash[:dir] = [:white, nil, BOLD]
201
+ @hash[:file] = [:white, nil, nil]
202
+ @hash[:link] = [:red, nil, nil]
203
+ @hash[:executable] = [:red, nil, BOLD]
204
+ @hash[:text] = [:magenta, nil, nil]
205
+ @hash[:zip] = [:cyan, nil, nil]
206
+ @hash[:other] = [:blue, nil, nil]
207
+ ##
208
+ @prefix[:dir] = "/"
209
+ @prefix[:link] = "@"
210
+ @prefix[:executable] = "*"
211
+ end
212
+ # recieves the full path and returns a symbol for category
213
+ def get_category text
214
+ #text = File.join(@path, t)
215
+ if File.directory? text
216
+ return :dir
217
+ elsif File.executable? text
218
+ return :executable
219
+ elsif File.symlink? text
220
+ return :link
221
+ elsif File.exists? text
222
+ if text =~ /\.txt$/
223
+ return :text
224
+ elsif text =~ /\.zip$/ or text =~ /gz$/
225
+ return :zip
226
+ else
227
+ return :file
228
+ end
229
+ else
230
+ return :other
231
+ end
232
+ end
233
+
234
+ # long directory renderer
235
+ # text is only the file name without path
236
+ def render pad, lineno, text
237
+ fullname = File.join(@path, text)
238
+ klass = get_category fullname
239
+ $log.info "fullname is #{fullname}, #{klass} "
240
+ # some links throw up an error of no such file
241
+ _stat = File.stat(fullname) rescue File.lstat(fullname)
242
+ @fg = @hash[klass][0]
243
+ bg = @hash[klass][1]
244
+ @bg = bg #if bg
245
+ bg = @hash[klass][2]
246
+ @attr = bg # if bg
247
+ prefix = @prefix[klass] || " "
248
+ #@left_margin_text = prefix
249
+ ftext = format_message( text, _stat, prefix)
250
+
251
+ super pad, lineno, ftext
252
+ end
253
+ class Formatter
254
+ #Format = "%s, [%s#%d] %5s -- %s: %s\n"
255
+ Format = "%10s %s %s%s"
256
+ # % [readable_file_size(stat.size,1), date_format(stat.mtime), f]
257
+
258
+ attr_accessor :datetime_format
259
+
260
+ def initialize
261
+ @datetime_format = nil
262
+ end
263
+
264
+ def call(fname, stat, prefix=nil)
265
+ #Format % [severity[0..0], format_datetime(time), $$, severity, progname,
266
+ #msg2str(msg)]
267
+ Format % [stat.size, format_datetime(stat.mtime), prefix, fname]
268
+ end
269
+
270
+ private
271
+
272
+ def format_datetime(time)
273
+ if @datetime_format.nil?
274
+ #time.strftime("%Y-%m-%dT%H:%M:%S") << "%06d " % time.usec
275
+ time.strftime("%Y-%m-%d %H:%M")
276
+ else
277
+ time.strftime(@datetime_format)
278
+ end
279
+ end
280
+
281
+ end # class Formatter
282
+
283
+ end
284
+ =begin
285
+ def file_edit fp #=@current_list.filepath
286
+ #$log.debug " edit #{fp}"
287
+ editor = ENV['EDITOR'] || 'vi'
288
+ vimp = %x[which #{editor}].chomp
289
+ shell_out "#{vimp} #{fp}"
290
+ Window.refresh_all
291
+ end
292
+
293
+ # TODO we need to move these to some common file so differnt programs and demos
294
+ # can use them on pressing space or enter.
295
+ def file_page fp #=@current_list.filepath
296
+ unless File.exists? fp
297
+ pwd = %x[pwd]
298
+ alert "No such file. My pwd is #{pwd} "
299
+ return
300
+ end
301
+ ft=%x[file #{fp}]
302
+ if ft.index("text")
303
+ pager = ENV['PAGER'] || 'less'
304
+ vimp = %x[which #{pager}].chomp
305
+ shell_out "#{vimp} #{fp}"
306
+ elsif ft.index(/zip/i)
307
+ shell_out "tar tvf #{fp} | less"
308
+ elsif ft.index(/directory/i)
309
+ shell_out "ls -lh #{fp} | less"
310
+ else
311
+ alert "#{fp} is not text, not paging "
312
+ #use_on_file "als", fp # only zip or archive
313
+ end
314
+ end
315
+ =end
316
+
317
+ end # module
318
+ end # module
319
+ include Canis::Devel