coderunner 0.17.11 → 0.18.0
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 +4 -4
- data/CONTRIBUTING.md +18 -0
- data/README.md +34 -5
- data/VERSION +1 -1
- data/coderunner.gemspec +11 -8
- data/dependencies/Makefile +101 -0
- data/dependencies/README.md +34 -0
- data/dependencies/download_dependencies.sh +20 -0
- data/lib/coderunner.rb +284 -321
- data/lib/coderunner/class_methods.rb +3 -13
- data/lib/coderunner/config.rb +87 -0
- data/lib/coderunner/fortran_namelist.rb +6 -6
- data/lib/coderunner/interactive_config.rb +57 -0
- data/lib/coderunner/interactive_methods.rb +333 -687
- data/lib/coderunner/repository.rb +1 -1
- data/lib/coderunner/run.rb +4 -0
- metadata +8 -5
- data/README.rdoc +0 -19
- data/test/test_coderunnerrepo.rb +0 -108
@@ -278,24 +278,14 @@ class CodeRunner
|
|
278
278
|
end
|
279
279
|
end
|
280
280
|
|
281
|
+
# Used by the help method defined in interactive_methods.rb
|
281
282
|
def self.reference(class_or_method, copts={})
|
282
|
-
code_folders = Dir.recursive_entries(SCRIPT_FOLDER + '/code_modules').grep(/\/ri$/).map{|fold| ['-d', fold]}.flatten
|
283
|
-
# ep code_folders
|
284
|
-
|
285
|
-
# require 'rdoc/ri/driver'
|
286
|
-
|
287
|
-
# "
|
288
|
-
# op = @ri_count ? [] : (@ri_count = true; ['--no-use-cache'])
|
289
|
-
# trap(1){puts 'No help available'}
|
290
|
-
# at_exit{raise ""}
|
291
|
-
# p op
|
292
283
|
begin
|
293
284
|
eputs "Looking up #{class_or_method}"
|
294
|
-
RDoc::RI::Driver.run [
|
295
|
-
rescue => err
|
285
|
+
RDoc::RI::Driver.run [class_or_method.to_s]
|
286
|
+
rescue SystemExit => err
|
296
287
|
eputs "Unknown class or method or no help available: #{err}"
|
297
288
|
end
|
298
|
-
# trap(1){}
|
299
289
|
end
|
300
290
|
|
301
291
|
def self.directory(id, copts={})
|
@@ -0,0 +1,87 @@
|
|
1
|
+
#In this file we set up the global coderunner configuration
|
2
|
+
#
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require "rubyhacks"
|
6
|
+
require 'fileutils'
|
7
|
+
|
8
|
+
class CodeRunner
|
9
|
+
|
10
|
+
GLOBAL_OPTIONS = {
|
11
|
+
system: 'generic_linux', # See coderunner/system_modules for more options
|
12
|
+
short_run_name: false, # If true, use simple run_names like v_id_1
|
13
|
+
no_repo: true, # Disable CodeRunner repo, true for now as in development
|
14
|
+
simple_prompt: false, # If true have a less fancy prompt in interactive mode
|
15
|
+
non_interactive: false, # If true, don't prompt for feedback when executing commands. Use with caution.
|
16
|
+
}
|
17
|
+
|
18
|
+
class CodeRunner::ConfigError < StandardError
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def self.global_options(option)
|
23
|
+
raise CodeRunner::ConfigError.new(
|
24
|
+
"Missing value for global option #{option.inspect}. Global options are #{GLOBAL_OPTIONS.inspect}."
|
25
|
+
) unless GLOBAL_OPTIONS.keys.include?(option)
|
26
|
+
return GLOBAL_OPTIONS[option]
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
CONFIG_FOLDER = ENV['HOME'] + "/.coderunner"
|
31
|
+
CONFIG_FILE = CONFIG_FOLDER + '/config.rb'
|
32
|
+
#Create the coderunner config directory if it doesn't exist
|
33
|
+
FileUtils.makedirs(CONFIG_FOLDER)
|
34
|
+
COMMAND_FOLDER = Dir.pwd
|
35
|
+
SCRIPT_FOLDER = File.dirname(File.expand_path(__FILE__)) #i.e. where this script is
|
36
|
+
|
37
|
+
|
38
|
+
if FileTest.exist? CONFIG_FILE
|
39
|
+
load CONFIG_FILE
|
40
|
+
end
|
41
|
+
# Deprecated as insecure
|
42
|
+
if ENV['CODE_RUNNER_OPTIONS']
|
43
|
+
$stderr.puts 'WARNING: CODE_RUNNER_OPTIONS is insecure and deprecated. Please use ~/.coderunner/config instead'
|
44
|
+
begin
|
45
|
+
env_global_options = eval(ENV['CODE_RUNNER_OPTIONS']) # global options are set by the environment but some can be changed.
|
46
|
+
env_global_options.each{|k,v| GLOBAL_OPTIONS[k] = v}
|
47
|
+
rescue
|
48
|
+
raise CodeRunner::ConfigError.new("Environment variable CODE_RUNNER_OPTIONS is not a valid hash")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
GLOBAL_OPTIONS.keys.each do |key|
|
52
|
+
env_string = 'CODE_RUNNER_' + key.to_s.upcase
|
53
|
+
if env_val = ENV[env_string]
|
54
|
+
GLOBAL_OPTIONS[:key] =
|
55
|
+
case env_val
|
56
|
+
when 'true'
|
57
|
+
true
|
58
|
+
when 'false'
|
59
|
+
false
|
60
|
+
when /\d+/
|
61
|
+
env_val.to_i
|
62
|
+
when /\d[\deE+-\.]*/
|
63
|
+
env_val.to_f
|
64
|
+
else
|
65
|
+
env_val
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
SYS = GLOBAL_OPTIONS[:system]
|
71
|
+
require SCRIPT_FOLDER + "/system_modules/#{SYS}.rb"
|
72
|
+
SYSTEM_MODULE = const_get(SYS.variable_to_class_name)
|
73
|
+
include SYSTEM_MODULE
|
74
|
+
class << self
|
75
|
+
include SYSTEM_MODULE
|
76
|
+
end
|
77
|
+
@@sys = SYS
|
78
|
+
def gets #No reading from the command line thank you very much!
|
79
|
+
$stdin.gets
|
80
|
+
end
|
81
|
+
def self.gets
|
82
|
+
$stdin.gets
|
83
|
+
end
|
84
|
+
|
85
|
+
CodeRunner::CODE_RUNNER_VERSION = Version.new(Gem.loaded_specs['coderunner'].version.to_s) rescue "test"
|
86
|
+
|
87
|
+
end
|
@@ -301,10 +301,10 @@ def self.add_code_variable_to_namelist(namelist, var, value)
|
|
301
301
|
enum = $~ ? $~[:num] : nil
|
302
302
|
return if rcp.namelists[namelist] and rcp.namelists[namelist][:variables].map{|v, h| (h[:code_name] or v).to_s.downcase.to_sym}.include? var
|
303
303
|
namelists = rcp.namelists
|
304
|
-
|
304
|
+
_namelist_file = 'namelists.rb'
|
305
305
|
# end
|
306
306
|
raise "This namelist: #{namelist} should have an enumerator and does not have one" if enum and (not rcp.namelists[namelist] or not rcp.namelists[namelist][:enumerator])
|
307
|
-
unless
|
307
|
+
unless CodeRunner.global_options(:non_interactive)
|
308
308
|
return unless Feedback.get_boolean("An unknown variable has been found in this input file: \n\n\t Namelist: #{namelist}, Name: #{code_name}, Sample Value: #{value.inspect}.\n\nDo you wish to add it to the CodeRunner module? (Recommended: answer yes as long as the variable is not a typo)")
|
309
309
|
end
|
310
310
|
|
@@ -320,7 +320,7 @@ def self.add_code_variable_to_namelist(namelist, var, value)
|
|
320
320
|
namelists[namelist][:should_include] ||= "true"
|
321
321
|
namelists[namelist][:variables] ||= {}
|
322
322
|
raise "Shouldn't have got here" if namelists[namelist][:variables][var]
|
323
|
-
|
323
|
+
_tst = nil
|
324
324
|
|
325
325
|
case value
|
326
326
|
when Float
|
@@ -366,7 +366,7 @@ def self.add_code_variable_to_namelist(namelist, var, value)
|
|
366
366
|
attr_accessor var
|
367
367
|
end
|
368
368
|
save_namelists
|
369
|
-
edit_variable_help(namelist, var) unless
|
369
|
+
edit_variable_help(namelist, var) unless CodeRunner.global_options(:non_interactive)
|
370
370
|
# folder = File.dirname(__FILE__)
|
371
371
|
# File.open(folder + '/' + namelist_file, 'w'){|f| f.puts namelists.pretty_inspect}
|
372
372
|
end
|
@@ -1230,14 +1230,14 @@ def self.process_synchronisation(source, nms, all_variables_in_source, namelist_
|
|
1230
1230
|
|
1231
1231
|
raise "No namelists found" if nms.size == 0
|
1232
1232
|
eputs nms.keys.zip(nms.values.map{|vs| vs.size})
|
1233
|
-
eputs "Namelists to be added to. (Press Enter)"; STDIN.gets unless
|
1233
|
+
eputs "Namelists to be added to. (Press Enter)"; STDIN.gets unless CodeRunner.global_options(:non_interactive)
|
1234
1234
|
n = 0
|
1235
1235
|
ep nms
|
1236
1236
|
# ep nms.values.sum
|
1237
1237
|
nms.values.sum.each do |var|
|
1238
1238
|
eputs var if variable_exists? var
|
1239
1239
|
end
|
1240
|
-
eputs "Conflicting Variables. (Press Enter)";; STDIN.gets unless
|
1240
|
+
eputs "Conflicting Variables. (Press Enter)";; STDIN.gets unless CodeRunner.global_options(:non_interactive)
|
1241
1241
|
nms.each do |namelist, vars|
|
1242
1242
|
ep namelist
|
1243
1243
|
ep vars
|
@@ -0,0 +1,57 @@
|
|
1
|
+
#############################################
|
2
|
+
## Default configuration for interactive mode
|
3
|
+
############################################
|
4
|
+
|
5
|
+
|
6
|
+
$has_put_startup_message_for_code_runner = true #please leave!
|
7
|
+
$code_runner_interactive_mode = true #please leave!
|
8
|
+
require 'yaml'
|
9
|
+
|
10
|
+
def reset
|
11
|
+
Dispatcher.reset_application!
|
12
|
+
end
|
13
|
+
|
14
|
+
IRB.conf[:AUTO_INDENT] = true
|
15
|
+
IRB.conf[:USE_READLINE] = true
|
16
|
+
IRB.conf[:LOAD_MODULES] = [] unless IRB.conf.key?(:LOAD_MODULES)
|
17
|
+
|
18
|
+
unless IRB.conf[:LOAD_MODULES].include?('irb/completion')
|
19
|
+
IRB.conf[:LOAD_MODULES] << 'irb/completion'
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
require 'irb/completion'
|
24
|
+
require 'irb/ext/save-history'
|
25
|
+
require 'socket'
|
26
|
+
unless CodeRunner.global_options(:simple_prompt)
|
27
|
+
#prompt_start = "\001#{Terminal::LIGHT_GREEN}\002CodeRunner\001#{Terminal::RESET}\002 v#{CODE_RUNNER_VERSION} - \001#{Terminal::CYAN}\002#{ENV['USER']}@#{Socket::gethostname}:#{File.basename(Dir.pwd)}\001#{Terminal::RESET}\002 timemarker\n"
|
28
|
+
prompt_start = "\001#{Terminal::LIGHT_GREEN}\002CodeRunner\001#{Terminal::RESET}\002 v#{CodeRunner::CODE_RUNNER_VERSION} - \001#{Terminal::CYAN}\002#{Socket::gethostname}:#{File.basename(Dir.pwd)}\001#{Terminal::RESET}\002 timemarker %02n,%i \n"
|
29
|
+
else
|
30
|
+
prompt_start = "CodeRunner #{File.basename(Dir.pwd)}"
|
31
|
+
end
|
32
|
+
#IRB.conf[:PROMPT][:CODE_RUNNER] = {:PROMPT_I=>"#{prompt_start}>> %02n,%i >> ", :PROMPT_N=>"#{prompt_start}>> %02n:%i > ", :PROMPT_S=>"#{prompt_start}>> %02n:%i (%l)> ", :PROMPT_C=>"#{prompt_start}>> %02n:%i >> ", :RETURN=>""}
|
33
|
+
IRB.conf[:PROMPT][:CODE_RUNNER] = {:PROMPT_I=>"#{prompt_start}>> ", :PROMPT_N=>"#{prompt_start}> ", :PROMPT_S=>"#{prompt_start}(%l)> ", :PROMPT_C=>"#{prompt_start}>> ", :RETURN=>""}
|
34
|
+
# IRB.conf[:PROMPT][:CODE_RUNNER] = {:PROMPT_I=>"#{prompt_start} %02n,%i>> ", :PROMPT_N=>"#{prompt_start} %02n:%i> ", :PROMPT_S=>"#{prompt_start} %02n:%i (%l)> ", :PROMPT_C=>"#{prompt_start} %02n:%i>> ", :RETURN=>""}
|
35
|
+
|
36
|
+
|
37
|
+
IRB.conf[:PROMPT_MODE] = :CODE_RUNNER
|
38
|
+
IRB.conf[:SAVE_HISTORY] = 400
|
39
|
+
IRB.conf[:HISTORY_FILE] = "#{Dir.pwd}/.code-runner-irb-save-history"
|
40
|
+
IRB.conf[:INSPECT_MODE] = false
|
41
|
+
|
42
|
+
if FileTest.exist? conf = CodeRunner::CONFIG_FOLDER + '/interactive_config.rb'
|
43
|
+
load conf
|
44
|
+
end
|
45
|
+
|
46
|
+
module Kernel
|
47
|
+
|
48
|
+
alias_method(:shell_do, "`".to_sym)
|
49
|
+
def `(cmd)
|
50
|
+
c =caller
|
51
|
+
if c[0] =~ /irb_binding/
|
52
|
+
system(cmd)
|
53
|
+
else
|
54
|
+
shell_do(cmd)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -1,22 +1,22 @@
|
|
1
1
|
class CodeRunner
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
#
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
2
|
+
|
3
|
+
module InteractiveMethods
|
4
|
+
COMMANDS.each do |command|
|
5
|
+
eval("def #{command[1]}(*args)
|
6
|
+
# if args[-1].kind_of?
|
7
|
+
CodeRunner.send(#{command[0].to_sym.inspect}, *args)
|
8
|
+
end")
|
9
|
+
end
|
10
|
+
def up
|
11
|
+
ObjectSpace.each_object{|obj| obj.update if obj.class.to_s =~ /CodeRunner$/}
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
def cd(dirct)
|
15
|
+
Dir.chdir(dirct)
|
16
|
+
end
|
17
|
+
def setup_interactive
|
18
|
+
@runner = CodeRunner.fetch_runner(CodeRunner::DEFAULT_COMMAND_OPTIONS.dup) unless CodeRunner::DEFAULT_COMMAND_OPTIONS[:q]
|
19
|
+
@r = @runner
|
20
20
|
if @r
|
21
21
|
histfile = @r.root_folder + '/.code-runner-irb-save-history'
|
22
22
|
if FileTest.exist?(histfile)
|
@@ -28,13 +28,13 @@ class CodeRunner
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
31
|
+
end
|
32
|
+
def pwd
|
33
|
+
puts Dir.pwd
|
34
|
+
end
|
35
|
+
def runs
|
36
|
+
CodeRunner.runner.run_list
|
37
|
+
end
|
38
38
|
# Change the default root folder(s) for commands. If a runner
|
39
39
|
# has not been loaded for a given folder, it will be loaded
|
40
40
|
# as subsequently required.
|
@@ -44,84 +44,27 @@ class CodeRunner
|
|
44
44
|
alias :crf :change_root_folder
|
45
45
|
|
46
46
|
|
47
|
-
|
48
47
|
|
49
|
-
|
50
|
-
INTERACTIVE_METHODS = <<EOF
|
51
48
|
|
52
49
|
|
50
|
+
INTERACTIVE_METHODS = <<EOF
|
53
51
|
include CodeRunner::InteractiveMethods
|
54
52
|
setup_interactive
|
55
|
-
module Kernel
|
56
|
-
|
57
|
-
alias_method(:shell_do, "`".to_sym)
|
58
|
-
def `(cmd)
|
59
|
-
c =caller
|
60
|
-
if c[0] =~ /irb_binding/
|
61
|
-
system(cmd)
|
62
|
-
else
|
63
|
-
shell_do(cmd)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
53
|
EOF
|
68
54
|
|
69
|
-
|
70
|
-
|
71
|
-
def CodeRunner.interactive_mode(copts={})
|
72
|
-
process_command_options(copts)
|
73
|
-
unless false and FileTest.exist? (ENV['HOME'] + '/code_runner_interactive_options.rb')
|
74
|
-
File.open(ENV['HOME'] + '/.code_runner_interactive_options.rb', 'w') do |file|
|
75
|
-
file.puts <<EOF
|
76
|
-
$has_put_startup_message_for_code_runner = true #please leave!
|
77
|
-
$code_runner_interactive_mode = true #please leave!
|
78
|
-
require 'yaml'
|
79
|
-
|
80
|
-
def reset
|
81
|
-
Dispatcher.reset_application!
|
82
|
-
end
|
83
|
-
|
84
|
-
IRB.conf[:AUTO_INDENT] = true
|
85
|
-
IRB.conf[:USE_READLINE] = true
|
86
|
-
IRB.conf[:LOAD_MODULES] = [] unless IRB.conf.key?(:LOAD_MODULES)
|
87
|
-
unless IRB.conf[:LOAD_MODULES].include?('irb/completion')
|
88
|
-
IRB.conf[:LOAD_MODULES] << 'irb/completion'
|
89
|
-
end
|
90
|
-
|
91
|
-
|
92
|
-
require 'irb/completion'
|
93
|
-
require 'irb/ext/save-history'
|
94
|
-
require 'socket'
|
95
|
-
unless ENV['CODE_RUNNER_SYSTEM'] == 'macosx'
|
96
|
-
prompt_start = "\001#{Terminal::LIGHT_GREEN}\002CodeRunner\001#{Terminal::RESET}\002 v#{CODE_RUNNER_VERSION} - \001#{Terminal::CYAN}\002#\{ENV['USER']\}@#\{Socket::gethostname\}:#\{File.basename(Dir.pwd)}\001#{Terminal::RESET}\002 timemarker\n"
|
97
|
-
prompt_start = "\001#{Terminal::LIGHT_GREEN}\002CodeRunner\001#{Terminal::RESET}\002 v#{CODE_RUNNER_VERSION} - \001#{Terminal::CYAN}\002#\{Socket::gethostname\}:#\{File.basename(Dir.pwd)}\001#{Terminal::RESET}\002 timemarker %02n,%i \n"
|
98
|
-
else
|
99
|
-
prompt_start = "CodeRunner #\{File.basename(Dir.pwd)}"
|
100
|
-
end
|
101
|
-
IRB.conf[:PROMPT][:CODE_RUNNER] = {:PROMPT_I=>"#\{prompt_start}>> %02n,%i >> ", :PROMPT_N=>"#\{prompt_start}>> %02n:%i > ", :PROMPT_S=>"#\{prompt_start}>> %02n:%i (%l)> ", :PROMPT_C=>"#\{prompt_start}>> %02n:%i >> ", :RETURN=>""}
|
102
|
-
IRB.conf[:PROMPT][:CODE_RUNNER] = {:PROMPT_I=>"#\{prompt_start}>> ", :PROMPT_N=>"#\{prompt_start}> ", :PROMPT_S=>"#\{prompt_start}(%l)> ", :PROMPT_C=>"#\{prompt_start}>> ", :RETURN=>""}
|
103
|
-
# IRB.conf[:PROMPT][:CODE_RUNNER] = {:PROMPT_I=>"#\{prompt_start} %02n,%i>> ", :PROMPT_N=>"#\{prompt_start} %02n:%i> ", :PROMPT_S=>"#\{prompt_start} %02n:%i (%l)> ", :PROMPT_C=>"#\{prompt_start} %02n:%i>> ", :RETURN=>""}
|
104
|
-
|
55
|
+
end # module InteractiveMethods
|
105
56
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
57
|
+
def CodeRunner.interactive_mode(copts={})
|
58
|
+
process_command_options(copts)
|
59
|
+
File.open(".int.tmp.rb", 'w')do |file|
|
60
|
+
file.puts "#{copts.inspect}.each do |key, val|
|
61
|
+
CodeRunner::DEFAULT_COMMAND_OPTIONS[key] = val
|
62
|
+
end"
|
63
|
+
file.puts CodeRunner::InteractiveMethods::INTERACTIVE_METHODS
|
64
|
+
end
|
65
|
+
exec %[#{RbConfig::CONFIG['bindir']}/irb#{RbConfig::CONFIG['ruby_install_name'].sub(/ruby/, '')} -f -I '#{Dir.pwd}' -I '#{SCRIPT_FOLDER}' -I '#{ENV['HOME']}' -r 'coderunner/config' -r 'coderunner/interactive_config' -r 'coderunner' -r .int.tmp ]
|
66
|
+
end
|
111
67
|
|
112
|
-
EOF
|
113
|
-
end # File.open
|
114
|
-
end # unless
|
115
|
-
File.open(".int.tmp.rb", 'w')do |file|
|
116
|
-
file.puts "#{copts.inspect}.each do |key, val|
|
117
|
-
CodeRunner::DEFAULT_COMMAND_OPTIONS[key] = val
|
118
|
-
end"
|
119
|
-
file.puts CodeRunner::InteractiveMethods::INTERACTIVE_METHODS
|
120
|
-
end
|
121
|
-
# asdfa
|
122
|
-
exec %[#{RbConfig::CONFIG['bindir']}/irb#{RbConfig::CONFIG['ruby_install_name'].sub(/ruby/, '')} -f -I '#{Dir.pwd}' -I '#{SCRIPT_FOLDER}' -I '#{ENV['HOME']}' -r '.code_runner_interactive_options' -r 'coderunner' -r .int.tmp ]
|
123
|
-
end
|
124
|
-
|
125
68
|
|
126
69
|
end
|
127
70
|
|
@@ -130,343 +73,317 @@ require "readline"
|
|
130
73
|
|
131
74
|
|
132
75
|
module IRB
|
133
|
-
|
134
|
-
|
135
|
-
#
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
#
|
149
|
-
|
76
|
+
|
77
|
+
COMMANDS = ENV['PATH'].split(':').inject([]) do |comms,dir|
|
78
|
+
# ep dir
|
79
|
+
begin
|
80
|
+
dir = dir.sub(/~/, ENV['HOME'])
|
81
|
+
Dir.entries(dir).each do |file|
|
82
|
+
file = "#{dir}/#{file}"
|
83
|
+
# ep file
|
84
|
+
comms.push(File.basename(file)) if FileTest.executable? file #and File.file? file
|
85
|
+
end
|
86
|
+
rescue
|
87
|
+
end
|
88
|
+
comms
|
89
|
+
end
|
90
|
+
COMMANDS.delete_if{|com| com =~ /^\./}
|
91
|
+
# ep 'COMMANDS', COMMANDS
|
92
|
+
|
150
93
|
module InputCompletor
|
151
|
-
|
152
|
-
|
153
|
-
#
|
154
|
-
#
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
dir = old_dir.chomp("/")
|
174
|
-
message = message.sub(Regexp.new("#{Regexp.escape(dir)}\\/"), '')
|
175
|
-
if dir.size > 0
|
176
|
-
# eputs 'dir', dir
|
177
|
-
# unless old_dir ~= /^\//
|
178
|
-
dir = Dir.pwd + '/' + dir
|
179
|
-
# end
|
180
|
-
# eputs 'dir', dir, FileTest.directory?(dir)
|
181
|
-
if FileTest.directory? dir
|
182
|
-
files = Dir.entries(dir)
|
183
|
-
else
|
184
|
-
files = []
|
185
|
-
end
|
186
|
-
else
|
187
|
-
dir = Dir.pwd
|
188
|
-
files = Dir.entries(dir)
|
189
|
-
end
|
190
|
-
# ep files
|
191
|
-
# ep 'mess', message
|
192
|
-
Dir.chdir(dir){files= files.map{|file| FileTest.directory?(file) ? file + "/" : file}}
|
193
|
-
# ep dir, files
|
194
|
-
candidates = message.size > 0 ? files.find_all{|com| com[0...message.size] == message} : files
|
195
|
-
candidates.map{|com| receiver + old_dir + com}
|
196
|
-
rescue
|
197
|
-
return []
|
198
|
-
end
|
94
|
+
|
95
|
+
def self.complete_files(receiver, message)
|
96
|
+
# files = message.split(/\s+/)
|
97
|
+
# message = files.pop
|
98
|
+
dir = message.sub(/[^\/]*$/, '')
|
99
|
+
message = message.sub(Regexp.new("#{Regexp.escape(dir)}"), '')
|
100
|
+
dir.sub!(/^~/, ENV['HOME'])
|
101
|
+
short_dir = dir
|
102
|
+
dir = Dir.pwd + '/' + dir unless dir =~ /^\//
|
103
|
+
#$stderr.puts "Dir to scan: #{dir}"
|
104
|
+
|
105
|
+
files = Dir.entries(dir)
|
106
|
+
|
107
|
+
#$stderr.puts "entries", files
|
108
|
+
Dir.chdir(dir){files= files.map{|file| FileTest.directory?(file) ? file + "/" : file}}
|
109
|
+
#$stderr.puts "entries - directories", files
|
110
|
+
|
111
|
+
candidates = message.size > 0 ? files.find_all{|com| com[0...message.size] == message} : files
|
112
|
+
return candidates.map{|com| receiver + short_dir + com}
|
113
|
+
rescue
|
114
|
+
return []
|
115
|
+
end
|
199
116
|
|
200
117
|
@RCS_ID='-$Id: completion.rb 23233 2009-04-19 13:35:47Z yugui $-'
|
201
118
|
|
202
|
-
|
119
|
+
|
203
120
|
CodeRunnerCompletionProc = proc do |input|
|
204
121
|
bind = IRB.conf[:MAIN_CONTEXT].workspace.binding
|
205
122
|
Readline.completion_append_character = nil
|
206
|
-
# eputs "\n\ninput: #{input}"
|
123
|
+
# eputs "\n\ninput: #{input}"
|
207
124
|
|
208
125
|
|
209
126
|
case input
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
#
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
#
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
#
|
235
|
-
#
|
236
|
-
#
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
#
|
242
|
-
|
243
|
-
|
244
|
-
#
|
245
|
-
#
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
#
|
250
|
-
#
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
127
|
+
when Regexp.new("^(#{/\w+\b.*(?:\s|,)(?::p\s+\=\>|p:)\s+\[?\s*/}(?:#{Regexp.quoted_string}\\s*,\\s*)*#{/'\{(?:[^}]*\s)?:?/})(\\w+)$")
|
128
|
+
# matches CodeRunner parameter list.... command [stuff] p: '{var: value, var
|
129
|
+
receiver = $1
|
130
|
+
message = $2
|
131
|
+
# ep 'mess', message
|
132
|
+
if CodeRunner.runner and CodeRunner.runner.run_class
|
133
|
+
candidates = CodeRunner.runner.run_class.rcp.variables.map{|var| var.to_s}.find_all{|var| var[0...message.size] == message}.map{|var| receiver + var}
|
134
|
+
else
|
135
|
+
candidates = []
|
136
|
+
end
|
137
|
+
when /^('(?:(?:\\ |[^'\s])*\s+)*)((?:\\ |[^'\s])*)$/, Regexp.new("^((?:[^']|#{Regexp.quoted_string})*')([^']*)$")
|
138
|
+
#filename in a single quoted string
|
139
|
+
receiver = "#$1" # "`" #$~[1]
|
140
|
+
message = "#$2" #Regexp.quote($~[2]) # $2 #Regexp.quote($2)
|
141
|
+
# ep 'mess', message
|
142
|
+
complete_files(receiver, message)
|
143
|
+
|
144
|
+
|
145
|
+
|
146
|
+
when /^(\`\w+\s+(?:\S+\s+)*)([^`\s]*)$/, /^([^`]*`\w+\s+)([^`]*)$/
|
147
|
+
#shell command with an executable
|
148
|
+
receiver = $1 # "`" #$~[1]
|
149
|
+
message = $2 #Regexp.quote($~[2]) # $2 #Regexp.quote($2)
|
150
|
+
complete_files(receiver, message)
|
151
|
+
# files = Dir.entries(File.dirname(message))
|
152
|
+
# candidates = message.size > 0 ? files.find_all{|com| com[0...message.size] == message} : files
|
153
|
+
# candidates.map{|com| receiver + com}
|
154
|
+
|
155
|
+
when /^(\`)([^`]*)$/, /^([^`]*`)([^`]*)$/
|
156
|
+
#shell command without an excutable
|
157
|
+
|
158
|
+
# p $~
|
159
|
+
receiver = $1 # "`" #$~[1]
|
160
|
+
message = $2 #Regexp.quote($~[2]) # $2 #Regexp.quote($2)
|
161
|
+
# ep "message is", message
|
162
|
+
# ep COMMANDS.grep(//)
|
163
|
+
candidates = message.size > 0 ? COMMANDS.find_all{|com| com[0...message.size] == message} : COMMANDS
|
164
|
+
candidates.map{|com| receiver + com}
|
165
|
+
#.grep(Regexp.new("^#{message}")) #("^#{Regexp.escape(message)}")) #.map{|com| "#{com}"} #.map{|com| receiver + com}
|
166
|
+
# ep candidates
|
167
|
+
# select_message(receiver, message, COMMANDS)
|
168
|
+
|
169
|
+
when /^([^\/]*\/[^\/]*\/)\.([^.]*)$/
|
170
|
+
# Regexp
|
171
|
+
receiver = $1
|
172
|
+
message = Regexp.quote($2)
|
173
|
+
|
174
|
+
candidates = Regexp.instance_methods.collect{|m| m.to_s}
|
175
|
+
select_message(receiver, message, candidates)
|
259
176
|
|
260
177
|
when /^([^\]]*\])\.([^.]*)$/
|
261
|
-
|
262
|
-
|
263
|
-
|
178
|
+
# Array
|
179
|
+
receiver = $1
|
180
|
+
message = Regexp.quote($2)
|
264
181
|
|
265
|
-
|
266
|
-
|
182
|
+
candidates = Array.instance_methods.collect{|m| m.to_s}
|
183
|
+
select_message(receiver, message, candidates)
|
267
184
|
|
268
185
|
when /([^\}]*\})\.([^.]*)$/
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
186
|
+
# Proc or Hash
|
187
|
+
receiver = $1
|
188
|
+
message = Regexp.quote($2)
|
189
|
+
|
190
|
+
candidates = Proc.instance_methods.collect{|m| m.to_s}
|
191
|
+
candidates |= Hash.instance_methods.collect{|m| m.to_s}
|
192
|
+
select_message(receiver, message, candidates)
|
193
|
+
|
194
|
+
|
195
|
+
when /^((?:(::)?[A-Z][^:.(]*)+)\.help :(\w*)$/
|
196
|
+
# CodeRunner help method
|
197
|
+
receiver = $1
|
198
|
+
message = Regexp.quote($3)
|
199
|
+
begin
|
200
|
+
candidates = eval("(#{receiver}.constants - Object.constants).collect{|m| m.to_s}", bind)
|
201
|
+
candidates |= eval("(#{receiver}.methods - Object.methods).collect{|m| m.to_s}", bind)
|
202
|
+
begin
|
203
|
+
candidates |= eval("(#{receiver}.instance_methods - Object.instance_methods).collect{|m| m.to_s}", bind)
|
204
|
+
rescue
|
205
|
+
end
|
206
|
+
rescue Exception
|
207
|
+
candidates = []
|
208
|
+
end
|
209
|
+
candidates.grep(/^#{message}/).collect{|e| receiver + '.help :' + e}
|
293
210
|
|
294
211
|
when /^((?:.*[^:])?:[^:.]*)$/
|
295
|
-
#
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
212
|
+
# eputs 'found symbol'
|
213
|
+
# Symbol
|
214
|
+
if Symbol.respond_to?(:all_symbols)
|
215
|
+
sym = $1
|
216
|
+
candidates = Symbol.all_symbols.collect{|s| ":" + s.id2name}
|
217
|
+
candidates.grep(/^#{sym}/)
|
218
|
+
else
|
219
|
+
[]
|
220
|
+
end
|
304
221
|
|
305
222
|
when /^(.*\s)?(((::)?[A-Z][^:.(]*)+)(::|\.)([^:.]*)$/
|
306
|
-
|
307
|
-
#
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
223
|
+
# Constant or class methods
|
224
|
+
# p "CCC"
|
225
|
+
start = $1
|
226
|
+
receiver = $2
|
227
|
+
message = Regexp.quote($6)
|
228
|
+
joiner = "#$5"
|
229
|
+
begin
|
230
|
+
candidates = eval("#{receiver}.constants.collect{|m| m.to_s}", bind)
|
231
|
+
candidates |= eval("#{receiver}.methods.collect{|m| m.to_s}", bind)
|
232
|
+
rescue Exception
|
233
|
+
candidates = []
|
234
|
+
end
|
235
|
+
candidates.grep(/^#{message}/).collect{|e| (start or "") + receiver + (joiner or "::") + e}
|
236
|
+
|
237
|
+
|
321
238
|
when /^(.*)(\b[A-Z][^:\.\(]*)$/
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
239
|
+
# Absolute Constant or class methods
|
240
|
+
receiver = $1
|
241
|
+
message = $2
|
242
|
+
candidates = Object.constants.collect{|m| m.to_s}
|
243
|
+
candidates.grep(/^#{message}/).collect{|e| receiver + e}
|
327
244
|
|
328
|
-
|
329
245
|
|
330
|
-
when /^(.*-?(0[dbo])?[0-9_]+(\.[0-9_]+)?([eE]-?[0-9]+)?)\.([^.]*)$/
|
331
|
-
# Numeric
|
332
|
-
receiver = $1
|
333
|
-
message = Regexp.quote($5)
|
334
246
|
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
247
|
+
when /^(.*-?(0[dbo])?[0-9_]+(\.[0-9_]+)?([eE]-?[0-9]+)?)\.([^.]*)$/
|
248
|
+
# Numeric
|
249
|
+
receiver = $1
|
250
|
+
message = Regexp.quote($5)
|
251
|
+
|
252
|
+
begin
|
253
|
+
candidates = eval(receiver, bind).methods.collect{|m| m.to_s}
|
254
|
+
rescue Exception
|
255
|
+
candidates = []
|
256
|
+
end
|
257
|
+
select_message(receiver, message, candidates)
|
341
258
|
|
342
259
|
when /^(.*-?0x[0-9a-fA-F_]+)\.([^.]*)$/
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
260
|
+
# Numeric(0xFFFF)
|
261
|
+
receiver = $1
|
262
|
+
message = Regexp.quote($2)
|
263
|
+
|
264
|
+
begin
|
265
|
+
candidates = eval(receiver, bind).methods.collect{|m| m.to_s}
|
266
|
+
rescue Exception
|
267
|
+
candidates = []
|
268
|
+
end
|
269
|
+
select_message(receiver, message, candidates)
|
353
270
|
|
354
271
|
when /^(.*[\s\{\[])?(\$[^.]*)$/
|
355
|
-
|
356
|
-
|
272
|
+
regmessage = Regexp.new(Regexp.quote($1))
|
273
|
+
candidates = global_variables.collect{|m| m.to_s}.grep(regmessage)
|
357
274
|
|
358
|
-
# when /^(\$?(\.?[^.]+)+)\.([^.]*)$/
|
275
|
+
# when /^(\$?(\.?[^.]+)+)\.([^.]*)$/
|
359
276
|
when /^((\.?[^.]+)+)\.([^.]*)$/
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
277
|
+
# variable
|
278
|
+
receiver = $1
|
279
|
+
message = Regexp.quote($3)
|
280
|
+
|
281
|
+
gv = eval("global_variables", bind).collect{|m| m.to_s}
|
282
|
+
lv = eval("local_variables", bind).collect{|m| m.to_s}
|
283
|
+
cv = eval("self.class.constants", bind).collect{|m| m.to_s}
|
284
|
+
|
285
|
+
if (gv | lv | cv).include?(receiver)
|
286
|
+
# foo.func and foo is local var.
|
287
|
+
candidates = eval("#{receiver}.methods", bind).collect{|m| m.to_s}
|
288
|
+
elsif /^[A-Z]/ =~ receiver and /\./ !~ receiver
|
289
|
+
# Foo::Bar.func
|
290
|
+
begin
|
291
|
+
candidates = eval("#{receiver}.methods", bind).collect{|m| m.to_s}
|
292
|
+
rescue Exception
|
293
|
+
candidates = []
|
294
|
+
end
|
295
|
+
else
|
296
|
+
# func1.func2
|
297
|
+
candidates = []
|
298
|
+
ObjectSpace.each_object(Module){|m|
|
299
|
+
begin
|
300
|
+
name = m.name
|
301
|
+
rescue Exception
|
302
|
+
name = ""
|
303
|
+
end
|
304
|
+
next if name != "IRB::Context" and
|
305
|
+
/^(IRB|SLex|RubyLex|RubyToken)/ =~ name
|
306
|
+
candidates.concat m.instance_methods(false).collect{|x| x.to_s}
|
307
|
+
}
|
308
|
+
candidates.sort!
|
309
|
+
candidates.uniq!
|
310
|
+
end
|
311
|
+
select_message(receiver, message, candidates)
|
395
312
|
|
396
313
|
when /^\.([^.]*)$/
|
397
|
-
|
314
|
+
# unknown(maybe String)
|
398
315
|
|
399
|
-
|
400
|
-
|
316
|
+
receiver = ""
|
317
|
+
message = Regexp.quote($1)
|
401
318
|
|
402
|
-
|
403
|
-
|
319
|
+
candidates = String.instance_methods(true).collect{|m| m.to_s}
|
320
|
+
select_message(receiver, message, candidates)
|
404
321
|
|
405
322
|
else
|
406
|
-
|
407
|
-
|
408
|
-
|
323
|
+
candidates = eval("methods | private_methods | local_variables | self.class.constants", bind).collect{|m| m.to_s}
|
324
|
+
|
325
|
+
(candidates|ReservedWords).grep(/^#{Regexp.quote(input)}/)
|
409
326
|
|
410
327
|
end
|
411
|
-
|
328
|
+
end
|
412
329
|
|
413
330
|
end
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
end
|
331
|
+
|
332
|
+
def self.select_message(receiver, message, candidates)
|
333
|
+
candidates.grep(/^#{message}/).collect do |e|
|
334
|
+
if receiver =~ /^.*`/
|
335
|
+
receiver + e
|
336
|
+
else
|
337
|
+
case e
|
338
|
+
when /^[a-zA-Z_]/
|
339
|
+
receiver + "." + e
|
340
|
+
when /^[0-9]/
|
341
|
+
when *Operators
|
342
|
+
|
343
|
+
|
344
|
+
#receiver + " " + e
|
345
|
+
end
|
430
346
|
end
|
431
347
|
end
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
prompt_end +=" (#{CodeRunner::SETUP_RUN_CLASSES.join(",")})"
|
446
|
-
if l = readline(@prompt.gsub(/timemarker/, prompt_end) , false)
|
447
|
-
#HISTORY.push(l) if !l.empty? and (HISTORY.size ==0 or l != HISTORY[-1])
|
448
|
-
HISTORY.push(l) if !l.empty? and (HISTORY.size ==0 or l != HISTORY[-1])
|
449
|
-
|
450
|
-
i = 0
|
451
|
-
loop do
|
452
|
-
break if HISTORY.size == 1
|
453
|
-
(HISTORY.delete_at(i); i-=1) if HISTORY[i] == l
|
454
|
-
i+=1
|
455
|
-
#ep "i: #{i}, HS: #{HISTORY.size}"
|
456
|
-
break if i >= HISTORY.size - 1
|
457
|
-
end
|
458
|
-
#HISTORY.reverse!
|
459
|
-
#HISTORY.uniq!
|
460
|
-
#HISTORY.reverse!
|
461
|
-
#HISTORY.push(l) if !l.empty? and (HISTORY.size ==0 or !HISTORY.include? l)
|
462
|
-
@line[@line_no += 1] = l + "\n"
|
463
|
-
else
|
464
|
-
@eof = true
|
465
|
-
l
|
466
|
-
end
|
348
|
+
end
|
349
|
+
class InputMethod
|
350
|
+
end
|
351
|
+
class ReadlineInputMethod < InputMethod
|
352
|
+
include Readline
|
353
|
+
def gets
|
354
|
+
Readline.input = @stdin
|
355
|
+
Readline.output = @stdout
|
356
|
+
prompt_end = Time.now.to_s[11...16]
|
357
|
+
begin
|
358
|
+
memsize = `ps ax -o pid,rss | grep -E "^[[:space:]]*#{Process::pid}"`.chomp.split(/\s+/).map {|s| s.strip.to_i}[1].to_i/1000
|
359
|
+
prompt_end += " #{memsize}k"
|
360
|
+
rescue
|
467
361
|
end
|
468
|
-
|
469
|
-
|
362
|
+
prompt_end +=" (#{CodeRunner::SETUP_RUN_CLASSES.join(",")})"
|
363
|
+
if l = readline(@prompt.gsub(/timemarker/, prompt_end) , false)
|
364
|
+
#HISTORY.push(l) if !l.empty? and (HISTORY.size ==0 or l != HISTORY[-1])
|
365
|
+
HISTORY.push(l) if !l.empty? and (HISTORY.size ==0 or l != HISTORY[-1])
|
366
|
+
|
367
|
+
i = 0
|
368
|
+
loop do
|
369
|
+
break if HISTORY.size == 1
|
370
|
+
(HISTORY.delete_at(i); i-=1) if HISTORY[i] == l
|
371
|
+
i+=1
|
372
|
+
#ep "i: #{i}, HS: #{HISTORY.size}"
|
373
|
+
break if i >= HISTORY.size - 1
|
374
|
+
end
|
375
|
+
#HISTORY.reverse!
|
376
|
+
#HISTORY.uniq!
|
377
|
+
#HISTORY.reverse!
|
378
|
+
#HISTORY.push(l) if !l.empty? and (HISTORY.size ==0 or !HISTORY.include? l)
|
379
|
+
@line[@line_no += 1] = l + "\n"
|
380
|
+
else
|
381
|
+
@eof = true
|
382
|
+
l
|
383
|
+
end
|
384
|
+
end
|
385
|
+
end
|
386
|
+
|
470
387
|
end #module IRB
|
471
388
|
|
472
389
|
if Readline.respond_to?("basic_word_break_characters=")
|
@@ -476,9 +393,9 @@ Readline.completion_append_character = "BB"
|
|
476
393
|
Readline.completion_proc = IRB::InputCompletor::CodeRunnerCompletionProc
|
477
394
|
|
478
395
|
begin
|
479
|
-
if Readline.respond_to?("basic_quote_characters=")
|
480
|
-
|
481
|
-
end
|
396
|
+
if Readline.respond_to?("basic_quote_characters=")
|
397
|
+
Readline.basic_quote_characters= "\"'`"
|
398
|
+
end
|
482
399
|
rescue NotImplementedError
|
483
400
|
end
|
484
401
|
|
@@ -489,306 +406,35 @@ end
|
|
489
406
|
require 'rdoc'
|
490
407
|
require 'rdoc/ri/driver'
|
491
408
|
|
492
|
-
class
|
493
|
-
def
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
method_map = display_class name
|
503
|
-
if(@interactive)
|
504
|
-
method_name = @display.get_class_method_choice(method_map)
|
505
|
-
|
506
|
-
if(method_name != nil)
|
507
|
-
method = lookup_method "#{name}#{method_name}", name
|
508
|
-
display_method method
|
509
|
-
end
|
510
|
-
end
|
511
|
-
elsif name =~ /::|\#|\./ then
|
512
|
-
klass, = parse_name name
|
513
|
-
|
514
|
-
orig_klass = klass
|
515
|
-
orig_name = name
|
516
|
-
|
517
|
-
loop do
|
518
|
-
method = lookup_method name, klass
|
519
|
-
|
520
|
-
break method if method
|
521
|
-
|
522
|
-
ancestor = lookup_ancestor klass, orig_klass
|
523
|
-
|
524
|
-
break unless ancestor
|
525
|
-
|
526
|
-
name = name.sub klass, ancestor
|
527
|
-
klass = ancestor
|
528
|
-
end
|
529
|
-
|
530
|
-
# return unless method
|
531
|
-
|
532
|
-
raise NotFoundError, orig_name unless method
|
533
|
-
|
534
|
-
display_method method
|
535
|
-
else
|
536
|
-
methods = select_methods(/#{name}/)
|
537
|
-
|
538
|
-
if methods.size == 0
|
539
|
-
return
|
540
|
-
raise NotFoundError, name
|
541
|
-
elsif methods.size == 1
|
542
|
-
display_method methods[0]
|
543
|
-
else
|
544
|
-
if(@interactive)
|
545
|
-
@display.display_method_list_choice methods
|
546
|
-
else
|
547
|
-
@display.display_method_list methods
|
548
|
-
end
|
549
|
-
end
|
550
|
-
end
|
409
|
+
class Object
|
410
|
+
def self.help(meth_or_const=nil)
|
411
|
+
join = ""
|
412
|
+
if meth_or_const
|
413
|
+
if self.constants.include? meth_or_const.to_sym
|
414
|
+
join = "::"
|
415
|
+
elsif self.methods.include? meth_or_const.to_sym
|
416
|
+
join = "."
|
417
|
+
elsif self.instance_methods.include? meth_or_const.to_sym
|
418
|
+
join = "#"
|
551
419
|
end
|
552
420
|
end
|
553
|
-
#
|
554
|
-
# eputs e
|
555
|
-
# return
|
421
|
+
CodeRunner.reference("#{self.to_s}#{join}#{meth_or_const}")
|
556
422
|
end
|
557
|
-
|
558
|
-
def self.process_args(argv)
|
559
|
-
options = default_options
|
560
|
-
|
561
|
-
opts = OptionParser.new do |opt|
|
562
|
-
opt.program_name = File.basename $0
|
563
|
-
opt.version = RDoc::VERSION
|
564
|
-
opt.release = nil
|
565
|
-
opt.summary_indent = ' ' * 4
|
566
|
-
|
567
|
-
directories = [
|
568
|
-
RDoc::RI::Paths::SYSDIR,
|
569
|
-
RDoc::RI::Paths::SITEDIR,
|
570
|
-
RDoc::RI::Paths::HOMEDIR
|
571
|
-
]
|
572
|
-
|
573
|
-
if RDoc::RI::Paths::GEMDIRS then
|
574
|
-
Gem.path.each do |dir|
|
575
|
-
directories << "#{dir}/doc/*/ri"
|
576
|
-
end
|
577
|
-
end
|
578
|
-
|
579
|
-
opt.banner = <<-EOT
|
580
|
-
Usage: #{opt.program_name} [options] [names...]
|
581
|
-
|
582
|
-
Where name can be:
|
583
|
-
|
584
|
-
Class | Class::method | Class#method | Class.method | method
|
585
|
-
|
586
|
-
All class names may be abbreviated to their minimum unambiguous form. If a name
|
587
|
-
is ambiguous, all valid options will be listed.
|
588
|
-
|
589
|
-
The form '.' method matches either class or instance methods, while #method
|
590
|
-
matches only instance and ::method matches only class methods.
|
591
|
-
|
592
|
-
For example:
|
593
|
-
|
594
|
-
#{opt.program_name} Fil
|
595
|
-
#{opt.program_name} File
|
596
|
-
#{opt.program_name} File.new
|
597
|
-
#{opt.program_name} zip
|
598
|
-
|
599
|
-
Note that shell quoting may be required for method names containing
|
600
|
-
punctuation:
|
601
|
-
|
602
|
-
#{opt.program_name} 'Array.[]'
|
603
|
-
#{opt.program_name} compact\\!
|
604
|
-
|
605
|
-
By default ri searches for documentation in the following directories:
|
606
|
-
|
607
|
-
#{directories.join "\n "}
|
608
|
-
|
609
|
-
Specifying the --system, --site, --home, --gems or --doc-dir options will
|
610
|
-
limit ri to searching only the specified directories.
|
611
|
-
|
612
|
-
Options may also be set in the 'RI' environment variable.
|
613
|
-
EOT
|
614
|
-
|
615
|
-
opt.separator nil
|
616
|
-
opt.separator "Options:"
|
617
|
-
opt.separator nil
|
618
|
-
|
619
|
-
opt.on("--fmt=FORMAT", "--format=FORMAT", "-f",
|
620
|
-
RDoc::RI::Formatter::FORMATTERS.keys,
|
621
|
-
"Format to use when displaying output:",
|
622
|
-
" #{RDoc::RI::Formatter.list}",
|
623
|
-
"Use 'bs' (backspace) with most pager",
|
624
|
-
"programs. To use ANSI, either disable the",
|
625
|
-
"pager or tell the pager to allow control",
|
626
|
-
"characters.") do |value|
|
627
|
-
options[:formatter] = RDoc::RI::Formatter.for value
|
628
|
-
end
|
629
|
-
|
630
|
-
opt.separator nil
|
631
|
-
|
632
|
-
opt.on("--doc-dir=DIRNAME", "-d", Array,
|
633
|
-
"List of directories from which to source",
|
634
|
-
"documentation in addition to the standard",
|
635
|
-
"directories. May be repeated.") do |value|
|
636
|
-
value.each do |dir|
|
637
|
-
unless File.directory? dir then
|
638
|
-
raise OptionParser::InvalidArgument, "#{dir} is not a directory"
|
639
|
-
end
|
640
|
-
|
641
|
-
options[:extra_doc_dirs] << File.expand_path(dir)
|
642
|
-
end
|
643
|
-
end
|
644
|
-
|
645
|
-
opt.separator nil
|
646
|
-
|
647
|
-
opt.on("--[no-]use-cache",
|
648
|
-
"Whether or not to use ri's cache.",
|
649
|
-
"True by default.") do |value|
|
650
|
-
options[:use_cache] = value
|
651
|
-
end
|
652
|
-
|
653
|
-
opt.separator nil
|
654
|
-
|
655
|
-
opt.on("--no-standard-docs",
|
656
|
-
"Do not include documentation from",
|
657
|
-
"the Ruby standard library, site_lib,",
|
658
|
-
"installed gems, or ~/.rdoc.",
|
659
|
-
"Equivalent to specifying",
|
660
|
-
"the options --no-system, --no-site, --no-gems,",
|
661
|
-
"and --no-home") do
|
662
|
-
options[:use_system] = false
|
663
|
-
options[:use_site] = false
|
664
|
-
options[:use_gems] = false
|
665
|
-
options[:use_home] = false
|
666
|
-
end
|
667
|
-
|
668
|
-
opt.separator nil
|
669
|
-
|
670
|
-
opt.on("--[no-]system",
|
671
|
-
"Include documentation from Ruby's standard",
|
672
|
-
"library. Defaults to true.") do |value|
|
673
|
-
options[:use_system] = value
|
674
|
-
end
|
675
|
-
|
676
|
-
opt.separator nil
|
677
|
-
|
678
|
-
opt.on("--[no-]site",
|
679
|
-
"Include documentation from libraries",
|
680
|
-
"installed in site_lib.",
|
681
|
-
"Defaults to true.") do |value|
|
682
|
-
options[:use_site] = value
|
683
|
-
end
|
684
|
-
|
685
|
-
opt.separator nil
|
686
|
-
|
687
|
-
opt.on("--[no-]gems",
|
688
|
-
"Include documentation from RubyGems.",
|
689
|
-
"Defaults to true.") do |value|
|
690
|
-
options[:use_gems] = value
|
691
|
-
end
|
692
|
-
|
693
|
-
opt.separator nil
|
694
|
-
|
695
|
-
opt.on("--[no-]home",
|
696
|
-
"Include documentation stored in ~/.rdoc.",
|
697
|
-
"Defaults to true.") do |value|
|
698
|
-
options[:use_home] = value
|
699
|
-
end
|
700
|
-
|
701
|
-
opt.separator nil
|
702
|
-
|
703
|
-
opt.on("--list-doc-dirs",
|
704
|
-
"List the directories from which ri will",
|
705
|
-
"source documentation on stdout and exit.") do
|
706
|
-
options[:list_doc_dirs] = true
|
707
|
-
end
|
708
|
-
|
709
|
-
opt.separator nil
|
710
|
-
|
711
|
-
opt.on("--no-pager", "-T",
|
712
|
-
"Send output directly to stdout,",
|
713
|
-
"rather than to a pager.") do
|
714
|
-
options[:use_stdout] = true
|
715
|
-
end
|
716
|
-
|
717
|
-
opt.on("--interactive", "-i",
|
718
|
-
"This makes ri go into interactive mode.",
|
719
|
-
"When ri is in interactive mode it will",
|
720
|
-
"allow the user to disambiguate lists of",
|
721
|
-
"methods in case multiple methods match",
|
722
|
-
"against a method search string. It also",
|
723
|
-
"will allow the user to enter in a method",
|
724
|
-
"name (with auto-completion, if readline",
|
725
|
-
"is supported) when viewing a class.") do
|
726
|
-
options[:interactive] = true
|
727
|
-
end
|
728
|
-
|
729
|
-
opt.separator nil
|
423
|
+
end
|
730
424
|
|
731
|
-
|
732
|
-
|
733
|
-
|
425
|
+
class Module
|
426
|
+
|
427
|
+
def help(meth_or_const=nil)
|
428
|
+
join = ""
|
429
|
+
if meth_or_const
|
430
|
+
if self.constants.include? meth_or_const.to_sym
|
431
|
+
join = "::"
|
432
|
+
elsif self.methods.include? meth_or_const.to_sym
|
433
|
+
join = "."
|
434
|
+
elsif self.instance_methods.include? meth_or_const.to_sym
|
435
|
+
join = "#"
|
734
436
|
end
|
735
437
|
end
|
736
|
-
|
737
|
-
argv = ENV['RI'].to_s.split.concat argv
|
738
|
-
|
739
|
-
opts.parse! argv
|
740
|
-
|
741
|
-
options[:names] = argv
|
742
|
-
|
743
|
-
options[:formatter] ||= RDoc::RI::Formatter.for('plain')
|
744
|
-
options[:use_stdout] ||= !$stdout.tty?
|
745
|
-
options[:use_stdout] ||= options[:interactive]
|
746
|
-
options[:width] ||= 72
|
747
|
-
|
748
|
-
options
|
749
|
-
|
750
|
-
rescue OptionParser::InvalidArgument, OptionParser::InvalidOption => e
|
751
|
-
puts opts
|
752
|
-
puts
|
753
|
-
puts e
|
754
|
-
# exit 1
|
438
|
+
CodeRunner.reference("#{self.to_s}#{join}#{meth_or_const}")
|
755
439
|
end
|
756
|
-
|
757
440
|
end
|
758
|
-
|
759
|
-
|
760
|
-
class Object
|
761
|
-
# def help
|
762
|
-
# CodeRunner.ri(self.to_s)
|
763
|
-
# end
|
764
|
-
def self.help(meth_or_const=nil)
|
765
|
-
join = ""
|
766
|
-
if meth_or_const
|
767
|
-
if self.constants.include? meth_or_const.to_sym
|
768
|
-
join = "::"
|
769
|
-
elsif self.methods.include? meth_or_const.to_sym
|
770
|
-
join = "."
|
771
|
-
elsif self.instance_methods.include? meth_or_const.to_sym
|
772
|
-
join = "#"
|
773
|
-
end
|
774
|
-
end
|
775
|
-
CodeRunner.reference("#{self.to_s}#{join}#{meth_or_const}")
|
776
|
-
end
|
777
|
-
end
|
778
|
-
|
779
|
-
class Module
|
780
|
-
|
781
|
-
def help(meth_or_const=nil)
|
782
|
-
join = ""
|
783
|
-
if meth_or_const
|
784
|
-
if self.constants.include? meth_or_const.to_sym
|
785
|
-
join = "::"
|
786
|
-
elsif self.methods.include? meth_or_const.to_sym
|
787
|
-
join = "."
|
788
|
-
elsif self.instance_methods.include? meth_or_const.to_sym
|
789
|
-
join = "#"
|
790
|
-
end
|
791
|
-
end
|
792
|
-
CodeRunner.reference("#{self.to_s}#{join}#{meth_or_const}")
|
793
|
-
end
|
794
|
-
end
|