canis 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +45 -0
- data/CHANGES +52 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +24 -0
- data/Rakefile +2 -0
- data/canis.gemspec +25 -0
- data/examples/alpmenu.rb +46 -0
- data/examples/app.sample +19 -0
- data/examples/appemail.rb +191 -0
- data/examples/atree.rb +105 -0
- data/examples/bline.rb +181 -0
- data/examples/common/devel.rb +319 -0
- data/examples/common/file.rb +93 -0
- data/examples/data/README.markdown +9 -0
- data/examples/data/brew.txt +38 -0
- data/examples/data/color.2 +37 -0
- data/examples/data/gemlist.txt +59 -0
- data/examples/data/lotr.txt +12 -0
- data/examples/data/ports.txt +136 -0
- data/examples/data/table.txt +37 -0
- data/examples/data/tasks.csv +88 -0
- data/examples/data/tasks.txt +27 -0
- data/examples/data/todo.txt +16 -0
- data/examples/data/todocsv.csv +28 -0
- data/examples/data/unix1.txt +21 -0
- data/examples/data/unix2.txt +11 -0
- data/examples/dbdemo.rb +506 -0
- data/examples/dirtree.rb +177 -0
- data/examples/newtabbedwindow.rb +100 -0
- data/examples/newtesttabp.rb +92 -0
- data/examples/tabular.rb +212 -0
- data/examples/tasks.rb +179 -0
- data/examples/term2.rb +88 -0
- data/examples/testbuttons.rb +307 -0
- data/examples/testcombo.rb +102 -0
- data/examples/testdb.rb +182 -0
- data/examples/testfields.rb +208 -0
- data/examples/testflowlayout.rb +43 -0
- data/examples/testkeypress.rb +98 -0
- data/examples/testlistbox.rb +187 -0
- data/examples/testlistbox1.rb +199 -0
- data/examples/testmessagebox.rb +144 -0
- data/examples/testprogress.rb +116 -0
- data/examples/testree.rb +107 -0
- data/examples/testsplitlayout.rb +53 -0
- data/examples/testsplitlayout1.rb +49 -0
- data/examples/teststacklayout.rb +48 -0
- data/examples/testwsshortcuts.rb +68 -0
- data/examples/testwsshortcuts2.rb +129 -0
- data/lib/canis.rb +16 -0
- data/lib/canis/core/docs/index.txt +104 -0
- data/lib/canis/core/docs/list.txt +16 -0
- data/lib/canis/core/docs/style_help.yml +34 -0
- data/lib/canis/core/docs/tabbedpane.txt +15 -0
- data/lib/canis/core/docs/table.txt +31 -0
- data/lib/canis/core/docs/textpad.txt +48 -0
- data/lib/canis/core/docs/tree.txt +23 -0
- data/lib/canis/core/include/.DS_Store +0 -0
- data/lib/canis/core/include/action.rb +83 -0
- data/lib/canis/core/include/actionmanager.rb +49 -0
- data/lib/canis/core/include/appmethods.rb +179 -0
- data/lib/canis/core/include/bordertitle.rb +49 -0
- data/lib/canis/core/include/canisparser.rb +100 -0
- data/lib/canis/core/include/colorparser.rb +437 -0
- data/lib/canis/core/include/defaultfilerenderer.rb +64 -0
- data/lib/canis/core/include/io.rb +320 -0
- data/lib/canis/core/include/layouts/SplitLayout.rb +161 -0
- data/lib/canis/core/include/layouts/abstractlayout.rb +213 -0
- data/lib/canis/core/include/layouts/flowlayout.rb +104 -0
- data/lib/canis/core/include/layouts/stacklayout.rb +109 -0
- data/lib/canis/core/include/listbindings.rb +89 -0
- data/lib/canis/core/include/listeditable.rb +319 -0
- data/lib/canis/core/include/listoperations.rb +61 -0
- data/lib/canis/core/include/listselectionmodel.rb +388 -0
- data/lib/canis/core/include/multibuffer.rb +173 -0
- data/lib/canis/core/include/ractionevent.rb +73 -0
- data/lib/canis/core/include/rchangeevent.rb +27 -0
- data/lib/canis/core/include/rhistory.rb +95 -0
- data/lib/canis/core/include/rinputdataevent.rb +47 -0
- data/lib/canis/core/include/textdocument.rb +111 -0
- data/lib/canis/core/include/vieditable.rb +175 -0
- data/lib/canis/core/include/widgetmenu.rb +66 -0
- data/lib/canis/core/system/colormap.rb +165 -0
- data/lib/canis/core/system/keydefs.rb +32 -0
- data/lib/canis/core/system/ncurses.rb +237 -0
- data/lib/canis/core/system/panel.rb +129 -0
- data/lib/canis/core/system/window.rb +1081 -0
- data/lib/canis/core/util/ansiparser.rb +119 -0
- data/lib/canis/core/util/app.rb +696 -0
- data/lib/canis/core/util/basestack.rb +412 -0
- data/lib/canis/core/util/defaultcolorparser.rb +84 -0
- data/lib/canis/core/util/extras/README +5 -0
- data/lib/canis/core/util/extras/bottomline.rb +1815 -0
- data/lib/canis/core/util/extras/padreader.rb +192 -0
- data/lib/canis/core/util/focusmanager.rb +31 -0
- data/lib/canis/core/util/helpmanager.rb +160 -0
- data/lib/canis/core/util/oldwidgetshortcuts.rb +304 -0
- data/lib/canis/core/util/promptmenu.rb +235 -0
- data/lib/canis/core/util/rcommandwindow.rb +933 -0
- data/lib/canis/core/util/rdialogs.rb +520 -0
- data/lib/canis/core/util/textutils.rb +74 -0
- data/lib/canis/core/util/viewer.rb +238 -0
- data/lib/canis/core/util/widgetshortcuts.rb +508 -0
- data/lib/canis/core/widgets/applicationheader.rb +103 -0
- data/lib/canis/core/widgets/box.rb +58 -0
- data/lib/canis/core/widgets/divider.rb +310 -0
- data/lib/canis/core/widgets/extras/README.md +12 -0
- data/lib/canis/core/widgets/extras/rtextarea.rb +960 -0
- data/lib/canis/core/widgets/extras/stackflow.rb +474 -0
- data/lib/canis/core/widgets/keylabelprinter.rb +194 -0
- data/lib/canis/core/widgets/listbox.rb +326 -0
- data/lib/canis/core/widgets/listfooter.rb +86 -0
- data/lib/canis/core/widgets/rcombo.rb +210 -0
- data/lib/canis/core/widgets/rcontainer.rb +415 -0
- data/lib/canis/core/widgets/rlink.rb +30 -0
- data/lib/canis/core/widgets/rmenu.rb +970 -0
- data/lib/canis/core/widgets/rmenulink.rb +30 -0
- data/lib/canis/core/widgets/rmessagebox.rb +400 -0
- data/lib/canis/core/widgets/rprogress.rb +118 -0
- data/lib/canis/core/widgets/rtabbedpane.rb +631 -0
- data/lib/canis/core/widgets/rtabbedwindow.rb +70 -0
- data/lib/canis/core/widgets/rwidget.rb +3634 -0
- data/lib/canis/core/widgets/scrollbar.rb +147 -0
- data/lib/canis/core/widgets/statusline.rb +113 -0
- data/lib/canis/core/widgets/table.rb +1072 -0
- data/lib/canis/core/widgets/tabular.rb +264 -0
- data/lib/canis/core/widgets/textpad.rb +1674 -0
- data/lib/canis/core/widgets/tree.rb +690 -0
- data/lib/canis/core/widgets/tree/treecellrenderer.rb +150 -0
- data/lib/canis/core/widgets/tree/treemodel.rb +432 -0
- data/lib/canis/version.rb +3 -0
- 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
|