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