canis 0.0.4

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 (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