fastri 0.1.0.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.
- data/COPYING +340 -0
- data/LEGAL +4 -0
- data/LICENSE +56 -0
- data/README.en +93 -0
- data/Rakefile +95 -0
- data/bin/fastri-server +188 -0
- data/bin/fri +67 -0
- data/bin/ri-emacs +188 -0
- data/lib/fastri/ri_index.rb +566 -0
- data/lib/fastri/ri_service.rb +264 -0
- data/lib/fastri/version.rb +8 -0
- data/setup.rb +1585 -0
- data/test/test_functional_ri_service.rb +60 -0
- data/test/test_ri_index.rb +267 -0
- metadata +88 -0
data/Rakefile
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
$:.unshift "lib" if File.directory? "lib"
|
2
|
+
require 'rake/testtask'
|
3
|
+
|
4
|
+
desc "Run the functional and unit tests."
|
5
|
+
Rake::TestTask.new(:test) do |t|
|
6
|
+
t.test_files = FileList['test/test*.rb']
|
7
|
+
t.verbose = true
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'rcov/rcovtask'
|
11
|
+
desc "Run rcov."
|
12
|
+
Rcov::RcovTask.new do |t|
|
13
|
+
t.test_files = FileList['test/test_*.rb'].to_a.reject{|x| /test_functional/ =~ x}
|
14
|
+
t.verbose = true
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "Save current coverage state for later comparisons."
|
18
|
+
Rcov::RcovTask.new(:rcovsave) do |t|
|
19
|
+
t.rcov_opts << "--save"
|
20
|
+
t.test_files = FileList['test/test_*.rb'].to_a.reject{|x| /test_functional/ =~ x}
|
21
|
+
t.verbose = true
|
22
|
+
end
|
23
|
+
|
24
|
+
task :default => :test
|
25
|
+
|
26
|
+
# {{{ Package tasks
|
27
|
+
|
28
|
+
require 'fastri/version'
|
29
|
+
|
30
|
+
PKG_REVISION = ".0"
|
31
|
+
PKG_FILES = FileList[
|
32
|
+
"bin/fri", "bin/fastri-server", "bin/ri-emacs",
|
33
|
+
"lib/**/*.rb",
|
34
|
+
"COPYING", "LEGAL", "LICENSE", "Rakefile", "README.*", "test/*.rb",
|
35
|
+
"setup.rb",
|
36
|
+
]
|
37
|
+
|
38
|
+
require 'rake/gempackagetask'
|
39
|
+
Spec = Gem::Specification.new do |s|
|
40
|
+
s.name = "fastri"
|
41
|
+
s.version = FastRI::FASTRI_VERSION + PKG_REVISION
|
42
|
+
s.summary = "RI docs across machines, faster and smarter than ri."
|
43
|
+
s.description = <<EOF
|
44
|
+
FastRI is an alternative to the ri command-line tool. It is *much* faster, and
|
45
|
+
also allows you to offer RI lookup services over DRb. FastRI is a bit smarter
|
46
|
+
than ri, and can find classes anywhere in the hierarchy without specifying the
|
47
|
+
"full path". It also knows about gems, and can tell you e.g. which extensions
|
48
|
+
to a core class were added by a specific gem.
|
49
|
+
EOF
|
50
|
+
s.files = PKG_FILES.to_a
|
51
|
+
s.require_path = 'lib'
|
52
|
+
s.author = "Mauricio Fernandez"
|
53
|
+
s.email = "mfp@acm.org"
|
54
|
+
s.homepage = "http://eigenclass.org/hiki.rb?fastri"
|
55
|
+
s.bindir = "bin"
|
56
|
+
s.executables = %w[fri fastri-server ri-emacs]
|
57
|
+
s.has_rdoc = true
|
58
|
+
#s.extra_rdoc_files = %w[]
|
59
|
+
s.rdoc_options << "--title" << 'FastRI: better, faster ri'
|
60
|
+
s.test_files = Dir["test/test_*.rb"]
|
61
|
+
s.post_install_message = <<EOF
|
62
|
+
|
63
|
+
A small note about the RubyGems + FastRI.
|
64
|
+
=========================================
|
65
|
+
RubyGems adds a noticable overhead to fri, making it run slower than if you
|
66
|
+
installed it directly from the tarball with setup.rb.
|
67
|
+
|
68
|
+
Compare the execution time when installed with RubyGems:
|
69
|
+
$ time fri -f plain String > /dev/null
|
70
|
+
|
71
|
+
real 0m0.385s
|
72
|
+
user 0m0.244s
|
73
|
+
sys 0m0.036s
|
74
|
+
|
75
|
+
to the time fri actually takes to run, without the overhead introduced by
|
76
|
+
RubyGems:
|
77
|
+
$ time ruby bin/fri -f plain String > /dev/null
|
78
|
+
|
79
|
+
real 0m0.088s
|
80
|
+
user 0m0.040s
|
81
|
+
sys 0m0.008s
|
82
|
+
|
83
|
+
If you care about those extra 300ms (and there are situations where they will
|
84
|
+
matter, e.g. when using fri for method completion), get FastRI from the
|
85
|
+
tarballs.
|
86
|
+
|
87
|
+
EOF
|
88
|
+
end
|
89
|
+
|
90
|
+
task :gem => [:test]
|
91
|
+
Rake::GemPackageTask.new(Spec) do |p|
|
92
|
+
p.need_tar = true
|
93
|
+
end
|
94
|
+
|
95
|
+
# vim: set sw=2 ft=ruby:
|
data/bin/fastri-server
ADDED
@@ -0,0 +1,188 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# fastri-server: serve RI documentation over DRb
|
3
|
+
# Copyright (C) 2006 Mauricio Fernandez <mfp@acm.org>
|
4
|
+
|
5
|
+
require 'fastri/version'
|
6
|
+
require 'fastri/ri_index'
|
7
|
+
require 'fastri/ri_service'
|
8
|
+
|
9
|
+
FASTRI_SERVER_VERSION = "0.0.1"
|
10
|
+
|
11
|
+
def make_index(index_file)
|
12
|
+
# The local environment is trusted --- what we don't trust is what would come
|
13
|
+
# from the DRb connection. This way the RiService will be untainted, and we
|
14
|
+
# will be able to use it with $SAFE = 1.
|
15
|
+
ObjectSpace.each_object{|obj| obj.untaint unless obj.frozen? }
|
16
|
+
|
17
|
+
paths = [ RI::Paths::SYSDIR, RI::Paths::SITEDIR, RI::Paths::HOMEDIR ].find_all do |p|
|
18
|
+
p && File.directory?(p)
|
19
|
+
end
|
20
|
+
begin
|
21
|
+
require 'rubygems'
|
22
|
+
gemdirs = Dir["#{Gem.path}/doc/*/ri"]
|
23
|
+
gems = Hash.new{|h,k| h[k] = []}
|
24
|
+
gemdirs.each do |path|
|
25
|
+
gemname, version = %r{/([^/]+)-(.*)/ri$}.match(path).captures
|
26
|
+
if gemname.nil? # doesn't follow any conventions :(
|
27
|
+
gems[path[%r{/([^/]+)/ri$}, 1]] << ["unknown", path]
|
28
|
+
else
|
29
|
+
gems[gemname] << [version, path]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
gems.sort_by{|name, _| name}.each do |name, versions|
|
33
|
+
version, path = versions.sort.last
|
34
|
+
puts "Indexing RI docs for #{name} version #{version}."
|
35
|
+
paths << path
|
36
|
+
end
|
37
|
+
rescue LoadError
|
38
|
+
end
|
39
|
+
|
40
|
+
puts "Building index."
|
41
|
+
t0 = Time.new
|
42
|
+
#ri_reader = RI::RiReader.new(RI::RiCache.new(paths))
|
43
|
+
ri_reader = FastRI::RiIndex.new_from_paths(paths)
|
44
|
+
open(index_file, "wb"){|io| Marshal.dump ri_reader, io}
|
45
|
+
puts <<EOF
|
46
|
+
Indexed:
|
47
|
+
* #{ri_reader.num_methods} methods
|
48
|
+
* #{ri_reader.num_namespaces} classes/modules
|
49
|
+
Needed #{Time.new - t0} seconds
|
50
|
+
EOF
|
51
|
+
ri_reader
|
52
|
+
end
|
53
|
+
|
54
|
+
#{{{ Main program
|
55
|
+
|
56
|
+
require 'optparse'
|
57
|
+
|
58
|
+
options = {:allowed_hosts => ["127.0.0.1"], :addr => "127.0.0.1",
|
59
|
+
:index_file => File.expand_path("~/.fastri-index")}
|
60
|
+
OptionParser.new do |opts|
|
61
|
+
opts.banner = "Usage: fastri-server.rb [options]"
|
62
|
+
|
63
|
+
opts.on("-a", "--allow HOST", "Allow connections from HOST.",
|
64
|
+
"(default: 127.0.0.1)") do |host|
|
65
|
+
options[:allowed_hosts] << host
|
66
|
+
end
|
67
|
+
|
68
|
+
opts.on("-s", "--bind ADDR", "Listen to connections on ADDR.",
|
69
|
+
"(default: 127.0.0.1)") do |addr|
|
70
|
+
options[:addr] = addr
|
71
|
+
end
|
72
|
+
|
73
|
+
opts.on("--index-file=FILE", "Use index file.",
|
74
|
+
"(default: #{options[:index_file]})") do |file|
|
75
|
+
options[:index_file] = file
|
76
|
+
end
|
77
|
+
|
78
|
+
opts.on("-b", "--rebuild-index", "Only rebuild index.") do
|
79
|
+
make_index(options[:index_file])
|
80
|
+
exit 0
|
81
|
+
end
|
82
|
+
|
83
|
+
opts.on("-h", "--help", "Show this help message") do
|
84
|
+
puts opts
|
85
|
+
exit
|
86
|
+
end
|
87
|
+
end.parse!
|
88
|
+
|
89
|
+
if File.exist?(options[:index_file])
|
90
|
+
ri_reader = open(options[:index_file], "rb"){|io| Marshal.load io } rescue nil
|
91
|
+
end
|
92
|
+
|
93
|
+
ri_reader ||= make_index(options[:index_file])
|
94
|
+
|
95
|
+
service = FastRI::RiService.new(ri_reader)
|
96
|
+
GC.start
|
97
|
+
|
98
|
+
require 'rinda/ring'
|
99
|
+
require 'rinda/tuplespace'
|
100
|
+
require 'drb/acl'
|
101
|
+
|
102
|
+
class FastRI::RiService
|
103
|
+
include DRbUndumped
|
104
|
+
end
|
105
|
+
|
106
|
+
#{{{ start DRb service
|
107
|
+
acl_opt = ["deny", "all"]
|
108
|
+
options[:allowed_hosts].each{|host| acl_opt.concat ["allow", host.strip]}
|
109
|
+
acl = ACL.new(acl_opt)
|
110
|
+
DRb.install_acl(acl)
|
111
|
+
|
112
|
+
drb_addr = "druby://#{options[:addr]}:0"
|
113
|
+
DRb.start_service(drb_addr)
|
114
|
+
|
115
|
+
$SAFE = 1
|
116
|
+
|
117
|
+
$stdout.sync = true
|
118
|
+
begin
|
119
|
+
puts "Looking for Ring server..."
|
120
|
+
finder = Rinda::RingFinger.new
|
121
|
+
service_ts = finder.lookup_ring_any(2)
|
122
|
+
puts "Located Ring server at #{service_ts.__drburi}"
|
123
|
+
rescue Exception
|
124
|
+
puts "No Ring server found, starting my own."
|
125
|
+
service_ts = Rinda::TupleSpace.new
|
126
|
+
ring_server = Rinda::RingServer.new(service_ts)
|
127
|
+
end
|
128
|
+
|
129
|
+
begin
|
130
|
+
service_ts.write([:name, :FastRI, service, 'FastRI documentation'], Rinda::SimpleRenewer.new)
|
131
|
+
rescue Exception
|
132
|
+
puts <<EOF
|
133
|
+
The FastRI service could not be registered in the Ring.
|
134
|
+
This is probably due to the Ring being bound to an unreachable address.
|
135
|
+
You can specify which address the Ring should be bound to with
|
136
|
+
fastri-server --bind ADDRESS --allow ADDRESS
|
137
|
+
EOF
|
138
|
+
exit
|
139
|
+
end
|
140
|
+
|
141
|
+
# {{{ Init message
|
142
|
+
require 'enumerator'
|
143
|
+
puts "fastri-server #{FASTRI_SERVER_VERSION} (FastRI #{FastRI::FASTRI_VERSION}) listening on #{DRb.uri}"
|
144
|
+
puts "ACL:"
|
145
|
+
acl_opt.each_slice(2){|action, host| puts "%-5s %s" % [action, host]}
|
146
|
+
|
147
|
+
# {{{ GC periodically
|
148
|
+
# keeps the process hot too :)
|
149
|
+
Thread.new do
|
150
|
+
loop do
|
151
|
+
GC.start
|
152
|
+
sleep 300
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
if $DEBUG
|
157
|
+
# trying to see where our memory is going
|
158
|
+
population = Hash.new{|h,k| h[k] = [0,0]}
|
159
|
+
array_sizes = Hash.new{|h,k| h[k] = 0}
|
160
|
+
ObjectSpace.each_object do |object|
|
161
|
+
size = case object # rough estimates
|
162
|
+
when Array
|
163
|
+
array_sizes[object.size / 10] += 1
|
164
|
+
case object.size
|
165
|
+
when 0..16
|
166
|
+
20 + 64
|
167
|
+
else
|
168
|
+
20 + 4 * object.size * 1.5
|
169
|
+
end
|
170
|
+
when Hash; 40 + 4 * [object.size / 5, 11].max + 16 * object.size
|
171
|
+
when String; 30 + object.size
|
172
|
+
else 120 # the iv_tbl, etc
|
173
|
+
end
|
174
|
+
count, tsize = population[object.class]
|
175
|
+
population[object.class] = [count + 1, tsize + size]
|
176
|
+
end
|
177
|
+
|
178
|
+
population.sort_by{|k,(c,s)| s}.reverse[0..10].each do |klass, (count, bytes)|
|
179
|
+
puts "%-20s %7d %9d" % [klass, count, bytes]
|
180
|
+
end
|
181
|
+
|
182
|
+
puts "Array sizes:"
|
183
|
+
array_sizes.sort.each{|k,v| puts "%5d %6d" % [k * 10, v]}
|
184
|
+
end
|
185
|
+
|
186
|
+
DRb.thread.join
|
187
|
+
|
188
|
+
# vi: set sw=2 expandtab:
|
data/bin/fri
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# fri: access RI documentation through DRb
|
3
|
+
# Copyright (C) 2006 Mauricio Fernandez <mfp@acm.org>
|
4
|
+
#
|
5
|
+
|
6
|
+
require 'rinda/ring'
|
7
|
+
require 'optparse'
|
8
|
+
|
9
|
+
# we bind to 127.0.0.1 by default, because otherwise Ruby will try with
|
10
|
+
# 0.0.0.0, which results in a DNS request, adding way too much latency
|
11
|
+
options = {
|
12
|
+
:addr => "127.0.0.1",
|
13
|
+
:format => "ansi"
|
14
|
+
}
|
15
|
+
override_addr_env = false
|
16
|
+
optparser = OptionParser.new do |opts|
|
17
|
+
opts.banner = "Usage: fri [options] <query>"
|
18
|
+
|
19
|
+
opts.on("-s", "--bind ADDR", "Bind to ADDR for incoming DRb connections.",
|
20
|
+
"(default: 127.0.0.1)") do |addr|
|
21
|
+
options[:addr] = addr
|
22
|
+
override_addr_env = true
|
23
|
+
end
|
24
|
+
|
25
|
+
opts.on("-f", "--format FMT", "Format to use when displaying output:",
|
26
|
+
" ansi, plain (default: ansi)") do |format|
|
27
|
+
options[:format] = format
|
28
|
+
end
|
29
|
+
|
30
|
+
opts.on("-h", "--help", "Show this help message") do
|
31
|
+
puts opts
|
32
|
+
exit
|
33
|
+
end
|
34
|
+
end
|
35
|
+
optparser.parse!
|
36
|
+
|
37
|
+
if ARGV.empty?
|
38
|
+
puts optparser
|
39
|
+
exit
|
40
|
+
end
|
41
|
+
|
42
|
+
if override_addr_env
|
43
|
+
addr = "druby://#{options[:addr]}:0"
|
44
|
+
else
|
45
|
+
addr = "druby://#{ENV["FASTRI_ADDR"]||options[:addr]}:0"
|
46
|
+
end
|
47
|
+
|
48
|
+
begin
|
49
|
+
DRb.start_service(addr)
|
50
|
+
ring_server = Rinda::RingFinger.primary
|
51
|
+
rescue Exception
|
52
|
+
puts <<EOF
|
53
|
+
Couldn't initialize DRb and locate the Ring server.
|
54
|
+
|
55
|
+
Please make sure that:
|
56
|
+
* the fastri-server is running, the server is bound to the correct interface,
|
57
|
+
and the ACL setup allows connections from this host
|
58
|
+
* fri is using the correct interface for incoming DRb requests:
|
59
|
+
either set the FASTRI_ADDR environment variable, or use --bind ADDR, e.g
|
60
|
+
export FASTRI_ADDR="192.168.1.12"
|
61
|
+
fri Array
|
62
|
+
EOF
|
63
|
+
exit(-1)
|
64
|
+
end
|
65
|
+
service = ring_server.read([:name, :FastRI, nil, nil])[2]
|
66
|
+
puts service.info(ARGV[0], options[:format])
|
67
|
+
# vi: set sw=2 expandtab:
|
data/bin/ri-emacs
ADDED
@@ -0,0 +1,188 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
## drop-in replacement for the ri-emacs helper script for use
|
3
|
+
# with ri-ruby.el, using the FastRI service via DRb
|
4
|
+
#
|
5
|
+
# Based on ri-emacs.rb by Kristof Bastiaensen <kristof@vleeuwen.org>
|
6
|
+
#
|
7
|
+
# Copyright (C) 2004,2006 Kristof Bastiaensen
|
8
|
+
# 2006 Mauricio Fernandez <mfp@acm.org>
|
9
|
+
#
|
10
|
+
# This program is free software; you can redistribute it and/or modify
|
11
|
+
# it under the terms of the GNU General Public License as published by
|
12
|
+
# the Free Software Foundation; either version 2 of the License, or
|
13
|
+
# (at your option) any later version.
|
14
|
+
#
|
15
|
+
# This program is distributed in the hope that it will be useful,
|
16
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
17
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
18
|
+
# GNU General Public License for more details.
|
19
|
+
#
|
20
|
+
# You should have received a copy of the GNU General Public License
|
21
|
+
# along with this program; if not, write to the Free Software
|
22
|
+
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
23
|
+
#----------------------------------------------------------------------
|
24
|
+
|
25
|
+
require 'rinda/ring'
|
26
|
+
require 'optparse'
|
27
|
+
|
28
|
+
# {{{ cmdline parsing and service discovery
|
29
|
+
# we bind to 127.0.0.1 by default, because otherwise Ruby will try with
|
30
|
+
# 0.0.0.0, which results in a DNS request, adding way too much latency
|
31
|
+
options = {:addr => "127.0.0.1"}
|
32
|
+
override_addr_env = false
|
33
|
+
optparser = OptionParser.new do |opts|
|
34
|
+
opts.banner = "Usage: ri-emacs [options] <query>"
|
35
|
+
|
36
|
+
opts.on("-s", "--bind [ADDR]", "Bind to ADDR for incoming DRb connections.",
|
37
|
+
"(default: 127.0.0.1)") do |addr|
|
38
|
+
options[:addr] = addr
|
39
|
+
override_addr_env = true
|
40
|
+
end
|
41
|
+
|
42
|
+
opts.on("-h", "--help", "Show this help message") do
|
43
|
+
puts opts
|
44
|
+
exit
|
45
|
+
end
|
46
|
+
end
|
47
|
+
optparser.parse!
|
48
|
+
|
49
|
+
if override_addr_env
|
50
|
+
addr = "druby://#{options[:addr]}:0"
|
51
|
+
else
|
52
|
+
addr = "druby://#{ENV["FASTRI_ADDR"]||options[:addr]}:0"
|
53
|
+
end
|
54
|
+
|
55
|
+
begin
|
56
|
+
DRb.start_service(addr)
|
57
|
+
ring_server = Rinda::RingFinger.primary
|
58
|
+
rescue Exception
|
59
|
+
puts <<EOF
|
60
|
+
Couldn't initialize DRb and locate the Ring server.
|
61
|
+
|
62
|
+
Please make sure that:
|
63
|
+
* the fastri-server is running, the server is bound to the correct interface,
|
64
|
+
and the ACL setup allows connections from this host
|
65
|
+
* fri is using the correct interface for incoming DRb requests:
|
66
|
+
either set the FASTRI_ADDR environment variable, or use --bind ADDR, e.g
|
67
|
+
export FASTRI_ADDR="192.168.1.12"
|
68
|
+
fri Array
|
69
|
+
EOF
|
70
|
+
exit(-1)
|
71
|
+
end
|
72
|
+
service = ring_server.read([:name, :FastRI, nil, nil])[2]
|
73
|
+
|
74
|
+
class EventLoop
|
75
|
+
def initialize(ri)
|
76
|
+
@ri = ri
|
77
|
+
end
|
78
|
+
|
79
|
+
def run
|
80
|
+
puts "READY"
|
81
|
+
loop do
|
82
|
+
line = $stdin.gets
|
83
|
+
cmd, p = /(\w+)(.*)$/.match(line)[1..2]
|
84
|
+
p.strip!
|
85
|
+
case cmd
|
86
|
+
when "TRY_COMPLETION"; puts complete_try(p)
|
87
|
+
when "COMPLETE_ALL"; puts complete_all(p)
|
88
|
+
when "LAMBDA"; puts complete_lambda(p)
|
89
|
+
when "CLASS_LIST"; puts class_list(p)
|
90
|
+
when "CLASS_LIST_WITH_FLAG"; puts class_list_with_flag(p)
|
91
|
+
when "DISPLAY_ARGS"; display_args(p)
|
92
|
+
when "DISPLAY_INFO"; display_info(p)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def complete_try(keyw)
|
98
|
+
list = @ri.completion_list(keyw)
|
99
|
+
if list.nil?
|
100
|
+
return "nil"
|
101
|
+
elsif list.size == 1 and
|
102
|
+
list[0].split(/(::)|#|\./) == keyw.split(/(::)|#|\./)
|
103
|
+
return "t"
|
104
|
+
end
|
105
|
+
|
106
|
+
first = list.shift;
|
107
|
+
if first =~ /(.*)((?:::)|(?:#))(.*)/
|
108
|
+
other = $1 + ($2 == "::" ? "#" : "::") + $3
|
109
|
+
end
|
110
|
+
|
111
|
+
len = first.size
|
112
|
+
match_both = false
|
113
|
+
list.each do |w|
|
114
|
+
while w[0, len] != first[0, len]
|
115
|
+
if other and w[0, len] == other[0, len]
|
116
|
+
match_both = true
|
117
|
+
break
|
118
|
+
end
|
119
|
+
len -= 1
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
if match_both
|
124
|
+
return other.sub(/(.*)((?:::)|(?:#))/) { $1 + "." }[0, len].inspect
|
125
|
+
else
|
126
|
+
return first[0, len].inspect
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def complete_all(keyw)
|
131
|
+
list = @ri.completion_list(keyw)
|
132
|
+
if list.nil?
|
133
|
+
"nil"
|
134
|
+
else
|
135
|
+
"(" + list.map { |w| w.inspect }.join(" ") + ")"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def complete_lambda(keyw)
|
140
|
+
list = @ri.completion_list(keyw)
|
141
|
+
if list.nil?
|
142
|
+
"nil"
|
143
|
+
else
|
144
|
+
if list.find { |n| n.split(/(::)|#|\./) == keyw.split(/(::)|#|\./) }
|
145
|
+
"t"
|
146
|
+
else
|
147
|
+
"nil"
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def class_list(keyw)
|
153
|
+
list = @ri.class_list(keyw)
|
154
|
+
if list
|
155
|
+
"(" + list.map{|x| "(#{x.inspect})"}.join(" ") + ")"
|
156
|
+
else
|
157
|
+
"nil"
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def class_list_with_flag(keyw)
|
162
|
+
list = @ri.class_list_with_flag(keyw)
|
163
|
+
if list
|
164
|
+
"(" + list.map{|x| "(#{x.inspect})"}.join(" ") + ")"
|
165
|
+
else
|
166
|
+
"nil"
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def display_args(keyw)
|
171
|
+
data = @ri.args(keyw)
|
172
|
+
puts data if data
|
173
|
+
puts "RI_EMACS_END_OF_INFO"
|
174
|
+
end
|
175
|
+
|
176
|
+
def display_info(keyw)
|
177
|
+
data = @ri.info(keyw)
|
178
|
+
puts data if data
|
179
|
+
puts "RI_EMACS_END_OF_INFO"
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
|
184
|
+
#{{{ event loop
|
185
|
+
$stdout.sync = true
|
186
|
+
EventLoop.new(service).run
|
187
|
+
|
188
|
+
# vi: set sw=2 expandtab:
|