rcodetools 0.4.1.0 → 0.5.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/CHANGES +9 -0
- data/README +2 -2
- data/README.vim +16 -0
- data/bin/rct-complete +3 -0
- data/bin/rct-meth-args +15 -7
- data/icicles-rcodetools.el +6 -3
- data/lib/rcodetools/completion.rb +99 -26
- data/lib/rcodetools/doc.rb +8 -23
- data/lib/rcodetools/options.rb +12 -0
- data/lib/rcodetools/xmpfilter.rb +2 -2
- data/rcodetools.el +5 -5
- data/rcodetools.vim +23 -3
- data/test/data/completion_emacs-output.rb +1 -0
- data/test/data/completion_emacs_icicles-output.rb +2 -1
- data/test/test_completion.rb +145 -0
- data/test/test_doc.rb +22 -0
- data/test/test_options.rb +32 -0
- metadata +4 -2
data/CHANGES
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
rcodetools history
|
2
2
|
==================
|
3
|
+
|
4
|
+
User-visible changes since 0.4.1
|
5
|
+
--------------------------------
|
6
|
+
* --dev: adds project directories to $:
|
7
|
+
* --completion-class-info: list completion candidates and class info
|
8
|
+
* display completion candidates with description, both in emacs
|
9
|
+
and vim (using the menu+preview window).
|
10
|
+
|
3
11
|
User-visible changes since 0.4.0
|
12
|
+
--------------------------------
|
4
13
|
* rct-meth-args: implemented -I
|
5
14
|
* many bug fixes
|
6
15
|
|
data/README
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
|
2
2
|
rcodetools http://eigenclass.org/hiki.rb?rcodetools
|
3
|
-
Copyright (c) 2005-
|
4
|
-
Copyright (c)
|
3
|
+
Copyright (c) 2005-2007 Mauricio Fernandez <mfp@acm.org> http://eigenclass.org
|
4
|
+
Copyright (c) 2006-2007 rubikitch <rubikitch@ruby-lang.org> http://www.rubyist.net/~rubikitch/
|
5
5
|
Use and distribution subject to the terms of the Ruby license.
|
6
6
|
|
7
7
|
= Overview
|
data/README.vim
CHANGED
@@ -9,6 +9,22 @@ rcodetools.vim redefines user-defined completion for Ruby programs, so you can
|
|
9
9
|
use the intelligent, 100%-accurate completion with <C-X><C-U> in insert mode.
|
10
10
|
Note that this runs the code to obtain the exact candidate list.
|
11
11
|
|
12
|
+
If you've set completeopt to menu,preview then rcodetools.vim can display
|
13
|
+
information about the completion candidates. The menu will show the synopsis
|
14
|
+
as given in the RI documentation, and the preview window will contain the full
|
15
|
+
RI documentation.
|
16
|
+
|
17
|
+
This functionality relies on fri for quick lookups. It can be enabled by setting
|
18
|
+
|
19
|
+
let g:rct_completion_use_fri = 1 " 0 by default (disabled)
|
20
|
+
|
21
|
+
in your .vimrc (don't forget to run fastri-server too).
|
22
|
+
Obtaining the documentation for many candidates can be slow, so you can set
|
23
|
+
the threshold above which additional documentation will not be shown with
|
24
|
+
|
25
|
+
" 20 by default, about a couple secs max wait on a normal machine
|
26
|
+
let g:rct_completion_info_max_len = 20
|
27
|
+
|
12
28
|
Quick RI documentation and exact tag jumping
|
13
29
|
============================================
|
14
30
|
When you're editing a Ruby file, <C-]> will jump to the definition of the
|
data/bin/rct-complete
CHANGED
@@ -21,6 +21,9 @@ opts = OptionParser.new do |opts|
|
|
21
21
|
opts.on("--completion-emacs-icicles", "Generate completion code for Emacs/Icicles.") do
|
22
22
|
klass = XMPCompletionEmacsIciclesFilter
|
23
23
|
end
|
24
|
+
opts.on("--completion-class-info", "List completion candidates with class.") do
|
25
|
+
klass = XMPCompletionClassInfoFilter
|
26
|
+
end
|
24
27
|
|
25
28
|
opts.handle_position options
|
26
29
|
opts.handle_interpreter options
|
data/bin/rct-meth-args
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
|
1
|
+
#! /home/batsman/usr//bin/ruby
|
2
2
|
# Copyright (c)
|
3
|
-
# 2006 Mauricio Fernandez <mfp@acm.org> http://eigenclass.org
|
4
|
-
# 2006 rubikitch <rubikitch@ruby-lang.org> http://www.rubyist.net/~rubikitch/
|
3
|
+
# 2006-2007 Mauricio Fernandez <mfp@acm.org> http://eigenclass.org
|
4
|
+
# 2006-2007 rubikitch <rubikitch@ruby-lang.org> http://www.rubyist.net/~rubikitch/
|
5
5
|
#
|
6
6
|
# Use and distribution subject to the same conditions as Ruby.
|
7
7
|
|
8
|
-
|
8
|
+
require 'rcodetools/options'
|
9
9
|
$VERBOSE = nil
|
10
10
|
$__method_args_off = true
|
11
11
|
|
@@ -14,7 +14,8 @@ if ARGV.empty? or ARGV.include? '-h' or ARGV.include? '--help'
|
|
14
14
|
rct-meth-args [-Idirectory] [-i] [-m] [-c] [-n] <file> [<file> ...]
|
15
15
|
|
16
16
|
-Idirectory specify $LOAD_PATH directory (same as ruby)
|
17
|
-
|
17
|
+
--dev Add this project's bin/ and lib/ to $LOAD_PATH.
|
18
|
+
A directory that has Rakefile is considered as project base direcotry.
|
18
19
|
-i omit instance methods defined in classes
|
19
20
|
-m omit instance methods defined in modules
|
20
21
|
-c omit class methods
|
@@ -256,7 +257,8 @@ ARGV.each do |arg|
|
|
256
257
|
when "-t"; $__printer = TagsPrinter.new; $__with_location = true
|
257
258
|
when /-I(.+)$/; $:.unshift $1
|
258
259
|
when "-I"; i_opt_p = true
|
259
|
-
when
|
260
|
+
when "--dev"; OptionHandler.auto_include_paths($:, Dir.pwd)
|
261
|
+
when /^-.$/; omissions[$&] = true
|
260
262
|
else
|
261
263
|
if i_opt_p
|
262
264
|
$:.unshift arg
|
@@ -397,7 +399,13 @@ end
|
|
397
399
|
|
398
400
|
$__method_args_off = false
|
399
401
|
|
400
|
-
ARGV.each{|x|
|
402
|
+
ARGV.each{|x|
|
403
|
+
begin
|
404
|
+
require x
|
405
|
+
rescue LoadError
|
406
|
+
load x
|
407
|
+
end
|
408
|
+
}
|
401
409
|
|
402
410
|
$__method_args_off = true
|
403
411
|
# END { puts "zzzz OK" }
|
data/icicles-rcodetools.el
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
;;; icicles-rcodetools.el -- accurate completion with icicles
|
2
2
|
|
3
|
-
;;; Copyright (c) 2006 rubikitch <rubikitch@ruby-lang.org>
|
3
|
+
;;; Copyright (c) 2006-2007 rubikitch <rubikitch@ruby-lang.org>
|
4
4
|
;;;
|
5
5
|
;;; Use and distribution subject to the terms of the Ruby license.
|
6
6
|
|
@@ -23,9 +23,12 @@ See also `rct-interactive'."
|
|
23
23
|
rct-method-completion-table
|
24
24
|
nil nil pattern nil nil nil
|
25
25
|
((end (point)) beg
|
26
|
-
|
26
|
+
(icicle-list-join-string "\t")
|
27
|
+
(icicle-list-use-nth-parts '(1))
|
28
|
+
(icicle-point-position-in-candidate 'input-end)
|
29
|
+
pattern klass alist
|
27
30
|
(icicle-candidate-help-fn
|
28
|
-
(lambda (result) (ri result
|
31
|
+
(lambda (result) (ri (cdr (assoc result alist)))))) ;bindings
|
29
32
|
(rct-exec-and-eval rct-complete-command-name "--completion-emacs-icicles"))
|
30
33
|
|
31
34
|
(provide 'icicles-rcodetools)
|
@@ -1,3 +1,6 @@
|
|
1
|
+
# Nearly 100% accurate completion for any editors!!
|
2
|
+
# by rubikitch <rubikitch@ruby-lang.org>
|
3
|
+
|
1
4
|
require 'rcodetools/xmpfilter'
|
2
5
|
require 'enumerator'
|
3
6
|
# Common routines for XMPCompletionFilter/XMPDocFilter
|
@@ -150,7 +153,7 @@ XXX
|
|
150
153
|
i+1==lineno ? prepare_line(line.chomp, column) : line
|
151
154
|
}.join
|
152
155
|
newcode << add_BEGIN if @ignore_NoMethodError
|
153
|
-
debugprint "newcode", newcode, "-"*80
|
156
|
+
debugprint "newcode", newcode.gsub(/;/, "\n"), "-"*80
|
154
157
|
stdout, stderr = execute(newcode)
|
155
158
|
output = stderr.readlines
|
156
159
|
debugprint "stdout", output, "-"*80
|
@@ -171,6 +174,15 @@ XXX
|
|
171
174
|
runtime_data_with_class(code, lineno, column)[1]
|
172
175
|
end
|
173
176
|
|
177
|
+
def __magic_help_code(result, v, meth)
|
178
|
+
code = <<-EOC
|
179
|
+
#{result} = #{v}.method(#{meth}).inspect.match( %r[\\A#<(?:Unbound)?Method: (.*?)>\\Z] )[1].sub(/\\A.*?\\((.*?)\\)(.*)\\Z/){ "\#{$1}\#{$2}" }.sub(/#<Class:(.*?)>#/) { "\#{$1}." }
|
180
|
+
#{result} = #{v}.to_s + ".new" if #{result} == 'Class#new' and #{v}.private_method_defined?(:initialize)
|
181
|
+
#{result} = "Object#" + #{meth} if #{result} =~ /^Kernel#/ and Kernel.instance_methods(false).include? #{meth}
|
182
|
+
#{result}
|
183
|
+
EOC
|
184
|
+
end
|
185
|
+
|
174
186
|
end
|
175
187
|
|
176
188
|
# Nearly 100% accurate completion for any editors!!
|
@@ -178,6 +190,11 @@ end
|
|
178
190
|
class XMPCompletionFilter < XMPFilter
|
179
191
|
include ProcessParticularLine
|
180
192
|
|
193
|
+
class << self
|
194
|
+
attr_accessor :candidates_with_description_flag
|
195
|
+
end
|
196
|
+
@candidates_with_description_flag = false
|
197
|
+
|
181
198
|
# String completion begins with this.
|
182
199
|
attr :prefix
|
183
200
|
|
@@ -185,49 +202,77 @@ class XMPCompletionFilter < XMPFilter
|
|
185
202
|
new(opts).completion_code(code, opts[:lineno], opts[:column])
|
186
203
|
end
|
187
204
|
|
205
|
+
def magic_help_code(recv, meth)
|
206
|
+
oneline_ize __magic_help_code("#{VAR}_result", recv, meth)
|
207
|
+
end
|
208
|
+
|
209
|
+
def methods_map_code(recv)
|
210
|
+
# delimiter is \0
|
211
|
+
%Q[map{|m| "\#{m}\\0" + #{magic_help_code((recv), 'm')}}]
|
212
|
+
end
|
213
|
+
|
214
|
+
def split_method_info(minfo)
|
215
|
+
minfo.split(/\0/,2)
|
216
|
+
end
|
217
|
+
|
188
218
|
def prepare_line(expr, column)
|
189
219
|
set_expr_and_postfix!(expr, column){|c| /^.{#{c}}/ }
|
190
220
|
@prefix = expr
|
191
221
|
case expr
|
192
222
|
when /^\$\w+$/ # global variable
|
193
|
-
__prepare_line 'nil', 'global_variables'
|
223
|
+
__prepare_line 'nil', 'global_variables', '%n'
|
194
224
|
when /^@@\w+$/ # class variable
|
195
|
-
__prepare_line 'nil', 'Module === self ? class_variables : self.class.class_variables'
|
225
|
+
__prepare_line 'nil', 'Module === self ? class_variables : self.class.class_variables', '%n'
|
196
226
|
when /^@\w+$/ # instance variable
|
197
|
-
__prepare_line 'nil', 'instance_variables'
|
227
|
+
__prepare_line 'nil', 'instance_variables', '%n'
|
198
228
|
when /^([A-Z].*)::([^.]*)$/ # nested constants / class methods
|
199
229
|
@prefix = $2
|
200
|
-
__prepare_line $1, "#$1.constants | #$1.methods(true)"
|
230
|
+
__prepare_line $1, "#$1.constants | #$1.methods(true)",
|
231
|
+
%Q[#$1.constants + #$1.methods(true).#{methods_map_code($1)}]
|
201
232
|
when /^[A-Z]\w*$/ # normal constants
|
202
|
-
__prepare_line 'nil', 'Module.constants'
|
233
|
+
__prepare_line 'nil', 'Module.constants', '%n'
|
203
234
|
when /^(.*::.+)\.(.+)$/ # toplevel class methods
|
204
235
|
@prefix = $2
|
205
|
-
__prepare_line $1, "#$1.methods"
|
236
|
+
__prepare_line $1, "#$1.methods",
|
237
|
+
%Q[%n.#{methods_map_code($1)}]
|
206
238
|
when /^(::.+)::(.*)$/ # toplevel nested constants
|
207
239
|
@prefix = $2
|
208
|
-
__prepare_line $1, "#$1.constants | #$1.methods"
|
240
|
+
__prepare_line $1, "#$1.constants | #$1.methods",
|
241
|
+
%Q[#$1.constants + #$1.methods.#{methods_map_code($1)}]
|
209
242
|
when /^::(.*)/ # toplevel constant
|
210
243
|
@prefix = $1
|
211
|
-
__prepare_line 'nil', 'Object.constants'
|
244
|
+
__prepare_line 'nil', 'Object.constants', '%n'
|
212
245
|
when /^(:[^:.]*)$/ # symbol
|
213
|
-
__prepare_line 'nil', 'Symbol.all_symbols.map{|s| ":" + s.id2name}'
|
246
|
+
__prepare_line 'nil', 'Symbol.all_symbols.map{|s| ":" + s.id2name}', '%n'
|
214
247
|
when /\.([^.]*)$/ # method call
|
215
248
|
@prefix = $1
|
216
249
|
recv = Regexp.last_match.pre_match
|
217
|
-
__prepare_line recv, "(#{recv}).methods(true)"
|
250
|
+
__prepare_line recv, "(#{recv}).methods(true)",
|
251
|
+
%Q[%n.#{methods_map_code(recv)}]
|
218
252
|
else # bare words
|
219
|
-
__prepare_line 'self', "methods | private_methods | local_variables | self.class.constants"
|
253
|
+
__prepare_line 'self', "methods | private_methods | local_variables | self.class.constants",
|
254
|
+
%Q[(methods | private_methods).#{methods_map_code('self')} + local_variables | self.class.constants]
|
220
255
|
end
|
221
256
|
end
|
222
257
|
|
223
|
-
def __prepare_line(recv, all_completion_expr)
|
258
|
+
def __prepare_line(recv, all_completion_expr, all_completion_expr_verbose)
|
259
|
+
if self.class.candidates_with_description_flag
|
260
|
+
___prepare_line(recv, all_completion_expr_verbose.gsub(/%n/, '('+all_completion_expr+')'))
|
261
|
+
else
|
262
|
+
___prepare_line(recv, all_completion_expr)
|
263
|
+
end
|
264
|
+
|
265
|
+
end
|
266
|
+
|
267
|
+
def ___prepare_line(recv, all_completion_expr)
|
224
268
|
v = "#{VAR}"
|
269
|
+
rcv = "#{VAR}_recv"
|
225
270
|
idx = 1
|
226
271
|
oneline_ize(<<EOC)
|
272
|
+
#{rcv} = (#{recv})
|
227
273
|
#{v} = (#{all_completion_expr}).grep(/^#{Regexp.quote(@prefix)}/)
|
228
|
-
#{
|
229
|
-
#{
|
230
|
-
$stderr.puts("#{MARKER}[#{idx}] => " + #{v}2.to_s + " " + #{v}.join(" ")) || #{v}
|
274
|
+
#{rcv} = Module === #{rcv} ? #{rcv} : #{rcv}.class
|
275
|
+
$stderr.puts("#{MARKER}[#{idx}] => " + #{rcv}.to_s + " " + #{v}.join(" ")) || #{v}
|
231
276
|
exit
|
232
277
|
EOC
|
233
278
|
end
|
@@ -235,7 +280,7 @@ EOC
|
|
235
280
|
# Array of completion candidates.
|
236
281
|
def candidates(code, lineno, column=nil)
|
237
282
|
methods = runtime_data(code, lineno, column) rescue ""
|
238
|
-
methods.split.sort
|
283
|
+
methods.split(/ /).sort
|
239
284
|
end
|
240
285
|
|
241
286
|
# Completion code for editors.
|
@@ -244,18 +289,38 @@ EOC
|
|
244
289
|
end
|
245
290
|
end
|
246
291
|
|
292
|
+
# for debugging XMPCompletionEmacsFilter
|
293
|
+
class XMPCompletionVerboseFilter < XMPCompletionFilter
|
294
|
+
@candidates_with_description_flag = true
|
295
|
+
end
|
296
|
+
|
297
|
+
class XMPCompletionClassInfoFilter < XMPCompletionFilter
|
298
|
+
@candidates_with_description_flag = true
|
299
|
+
|
300
|
+
def completion_code(code, lineno, column=nil)
|
301
|
+
candidates(code, lineno, column).join("\n").tr("\0", "\t")
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
247
305
|
class XMPCompletionEmacsFilter < XMPCompletionFilter
|
306
|
+
@candidates_with_description_flag = true
|
307
|
+
|
248
308
|
def completion_code(code, lineno, column=nil)
|
249
309
|
elisp = "(progn\n"
|
250
|
-
|
310
|
+
table = "(setq rct-method-completion-table '("
|
311
|
+
alist = "(setq alist '("
|
251
312
|
begin
|
252
|
-
candidates(code, lineno, column).each do |
|
253
|
-
|
313
|
+
candidates(code, lineno, column).sort.each do |minfo|
|
314
|
+
meth, description = split_method_info(minfo)
|
315
|
+
table << format('("%s") ', meth)
|
316
|
+
alist << format('("%s\\t[%s]") ', meth, description)
|
254
317
|
end
|
318
|
+
table << "))\n"
|
319
|
+
alist << "))\n"
|
255
320
|
rescue Exception => err
|
256
321
|
return %Q[(error "#{err.message}")]
|
257
322
|
end
|
258
|
-
elisp <<
|
323
|
+
elisp << table << alist
|
259
324
|
elisp << %Q[(setq pattern "#{prefix}")\n]
|
260
325
|
elisp << %Q[(try-completion pattern rct-method-completion-table nil)\n]
|
261
326
|
elisp << ")" # /progn
|
@@ -263,23 +328,31 @@ class XMPCompletionEmacsFilter < XMPCompletionFilter
|
|
263
328
|
end
|
264
329
|
|
265
330
|
class XMPCompletionEmacsIciclesFilter < XMPCompletionFilter
|
331
|
+
@candidates_with_description_flag = true
|
332
|
+
|
266
333
|
def candidates(code, lineno, column=nil)
|
267
334
|
klass, methods = runtime_data_with_class(code, lineno, column) rescue ["", ""]
|
268
335
|
@klass = klass
|
269
|
-
methods.split.sort
|
336
|
+
methods.split(/ /).sort
|
270
337
|
end
|
271
338
|
|
272
339
|
def completion_code(code, lineno, column=nil)
|
273
340
|
elisp = "(progn\n"
|
274
|
-
|
341
|
+
table = "(setq rct-method-completion-table '("
|
342
|
+
help_alist = "(setq alist '("
|
343
|
+
|
275
344
|
begin
|
276
|
-
candidates(code, lineno, column).each do |
|
277
|
-
|
345
|
+
candidates(code, lineno, column).sort.each do |minfo|
|
346
|
+
meth, description = split_method_info(minfo)
|
347
|
+
table << format('("%s\\t[%s]") ', meth, description)
|
348
|
+
help_alist << format('("%s" . "%s")', meth, description)
|
278
349
|
end
|
350
|
+
table << "))\n"
|
351
|
+
help_alist << "))\n"
|
279
352
|
rescue Exception => err
|
280
353
|
return %Q[(error "#{err.message}")]
|
281
354
|
end
|
282
|
-
elisp <<
|
355
|
+
elisp << table << help_alist
|
283
356
|
elisp << %Q[(setq pattern "#{prefix}")\n]
|
284
357
|
elisp << %Q[(setq klass "#{@klass}")\n]
|
285
358
|
elisp << ")" # /progn
|
data/lib/rcodetools/doc.rb
CHANGED
@@ -46,6 +46,7 @@ class XMPDocFilter < XMPFilter
|
|
46
46
|
|
47
47
|
def __prepare_line(x)
|
48
48
|
v = "#{VAR}"
|
49
|
+
result = "#{VAR}_result"
|
49
50
|
klass = "#{VAR}_klass"
|
50
51
|
flag = "#{VAR}_flag"
|
51
52
|
which_methods = "#{VAR}_methods"
|
@@ -55,34 +56,18 @@ class XMPDocFilter < XMPFilter
|
|
55
56
|
meth = x[:meth_or_constant] || x[:meth]
|
56
57
|
debugprint "recv=#{recv}", "meth=#{meth}"
|
57
58
|
if meth
|
59
|
+
# imported from fastri/MagicHelp
|
58
60
|
code = <<-EOC
|
59
61
|
#{v} = (#{recv})
|
60
|
-
if Class === #{v}
|
61
|
-
#{flag} = #{v}.respond_to?('#{meth}') ? "." : "::"
|
62
|
-
#{klass} = #{v}
|
63
|
-
#{which_methods} = :methods
|
64
|
-
else
|
65
|
-
#{flag} = "#"
|
66
|
-
#{klass} = #{v}.class
|
67
|
-
#{which_methods} = :instance_methods
|
68
|
-
end
|
69
|
-
#{ancestor_class} = #{klass}.ancestors.delete_if{|c| c==Kernel }.find{|c| c.__send__(#{which_methods}, false).include? '#{meth}' }
|
70
62
|
$stderr.print("#{MARKER}[#{idx}] => " + #{v}.class.to_s + " ")
|
71
63
|
|
72
|
-
if #{
|
73
|
-
|
64
|
+
if Module === #{v} and '#{meth}' =~ /^[A-Z]/ and #{v}.const_defined?('#{meth}')
|
65
|
+
#{result} = #{v}.to_s + "::#{meth}"
|
74
66
|
else
|
75
|
-
|
76
|
-
$stderr.puts(#{v}.to_s + #{flag} + '#{meth}'); exit
|
77
|
-
end
|
78
|
-
|
79
|
-
[Kernel, Module, Class].each do |k|
|
80
|
-
if (k.instance_methods(false) + k.private_instance_methods(false)).include? '#{meth}'
|
81
|
-
$stderr.printf("%s#%s\\n", k, '#{meth}'); exit
|
82
|
-
end
|
83
|
-
end
|
84
|
-
$stderr.puts(#{v}.to_s + '::' + '#{meth}')
|
67
|
+
#{__magic_help_code result, v, meth.dump}
|
85
68
|
end
|
69
|
+
|
70
|
+
$stderr.puts(#{result})
|
86
71
|
exit
|
87
72
|
EOC
|
88
73
|
else
|
@@ -154,7 +139,7 @@ end
|
|
154
139
|
|
155
140
|
class XMPRiFilter < XMPDocFilter
|
156
141
|
def doc(code, lineno, column=nil)
|
157
|
-
"ri '#{super}'"
|
142
|
+
"ri '#{super.sub(/\./, '::')}'"
|
158
143
|
end
|
159
144
|
end
|
160
145
|
|
data/lib/rcodetools/options.rb
CHANGED
@@ -26,6 +26,10 @@ module OptionHandler
|
|
26
26
|
on("-I PATH", "Add PATH to $LOAD_PATH") do |path|
|
27
27
|
options[:include_paths] << path
|
28
28
|
end
|
29
|
+
on("--dev", "Add this project's bin/ and lib/ to $LOAD_PATH.",
|
30
|
+
"A directory with a Rakefile is considered a project base directory.") do
|
31
|
+
auto_include_paths(options[:include_paths], Dir.pwd)
|
32
|
+
end
|
29
33
|
on("-r LIB", "Require LIB before execution.") do |lib|
|
30
34
|
options[:libs] << lib
|
31
35
|
end
|
@@ -55,6 +59,14 @@ module OptionHandler
|
|
55
59
|
end
|
56
60
|
end
|
57
61
|
|
62
|
+
def auto_include_paths(include_paths, pwd)
|
63
|
+
if pwd =~ %r!^(.+)/(lib|bin)!
|
64
|
+
include_paths.unshift("#$1/lib").unshift("#$1/bin")
|
65
|
+
elsif File.file? "#{pwd}/Rakefile" or File.file? "#{pwd}/rakefile"
|
66
|
+
include_paths.unshift("#{pwd}/lib").unshift("#{pwd}/bin")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
module_function :auto_include_paths
|
58
70
|
|
59
71
|
end
|
60
72
|
|
data/lib/rcodetools/xmpfilter.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
# Copyright (c) 2005-
|
2
|
+
# Copyright (c) 2005-2007 Mauricio Fernandez <mfp@acm.org> http://eigenclass.org
|
3
3
|
# rubikitch <rubikitch@ruby-lang.org>
|
4
4
|
# Use and distribution subject to the terms of the Ruby license.
|
5
5
|
|
6
6
|
class XMPFilter
|
7
|
-
VERSION = "0.
|
7
|
+
VERSION = "0.5.0"
|
8
8
|
|
9
9
|
MARKER = "!XMP#{Time.new.to_i}_#{Process.pid}_#{rand(1000000)}!"
|
10
10
|
XMP_RE = Regexp.new("^" + Regexp.escape(MARKER) + '\[([0-9]+)\] (=>|~>|==>) (.*)')
|
data/rcodetools.el
CHANGED
@@ -4,11 +4,11 @@
|
|
4
4
|
;;;
|
5
5
|
;;; Use and distribution subject to the terms of the Ruby license.
|
6
6
|
|
7
|
-
(defvar xmpfilter-command-name "ruby -S xmpfilter"
|
7
|
+
(defvar xmpfilter-command-name "ruby -S xmpfilter --dev"
|
8
8
|
"The xmpfilter command name.")
|
9
|
-
(defvar rct-doc-command-name "ruby -S rct-doc"
|
9
|
+
(defvar rct-doc-command-name "ruby -S rct-doc --dev"
|
10
10
|
"The rct-doc command name.")
|
11
|
-
(defvar rct-complete-command-name "ruby -S rct-complete"
|
11
|
+
(defvar rct-complete-command-name "ruby -S rct-complete --dev"
|
12
12
|
"The rct-complete command name.")
|
13
13
|
(defvar rct-option-history nil) ;internal
|
14
14
|
(defvar rct-option-local nil) ;internal
|
@@ -89,7 +89,7 @@ See also `rct-interactive', `rct-complete-symbol--normal', and `rct-complete-sym
|
|
89
89
|
See also `rct-interactive'."
|
90
90
|
(interactive (rct-interactive))
|
91
91
|
(let ((end (point)) beg
|
92
|
-
pattern
|
92
|
+
pattern alist
|
93
93
|
completion)
|
94
94
|
(setq completion (rct-try-completion)) ; set also pattern / completion
|
95
95
|
(save-excursion
|
@@ -108,7 +108,7 @@ See also `rct-interactive'."
|
|
108
108
|
(message "Making completion list...")
|
109
109
|
(with-output-to-temp-buffer "*Completions*"
|
110
110
|
(display-completion-list
|
111
|
-
(all-completions pattern
|
111
|
+
(all-completions pattern alist)))
|
112
112
|
(message "Making completion list...%s" "done")))))
|
113
113
|
|
114
114
|
;; (define-key ruby-mode-map "\M-\C-i" 'rct-complete-symbol)
|
data/rcodetools.vim
CHANGED
@@ -58,10 +58,30 @@ function! <SID>RCT_completion(findstart, base)
|
|
58
58
|
else
|
59
59
|
let line = line('.')
|
60
60
|
let column = s:rct_completion_col
|
61
|
-
let command = "rct-complete --line=" . line . " --column=" . column . " " . s:rct_tmpfile
|
62
|
-
let
|
61
|
+
let command = "rct-complete --completion-class-info --line=" . line . " --column=" . column . " " . s:rct_tmpfile
|
62
|
+
let data = split(system(command), '\n')
|
63
|
+
|
64
|
+
for dline in data
|
65
|
+
let parts = split(dline, "\t")
|
66
|
+
let name = get(parts, 0)
|
67
|
+
let selector = get(parts, 1)
|
68
|
+
echo name
|
69
|
+
echo selector
|
70
|
+
if s:GetOption('rct_completion_use_fri', 0) && s:GetOption('rct_completion_info_max_len', 20) >= len(data)
|
71
|
+
let fri_data = system('fri -f plain ' . "'" . selector . "'" . ' 2>/dev/null')
|
72
|
+
call complete_add({'word': name,
|
73
|
+
\ 'menu': get(split(fri_data), 2, ''),
|
74
|
+
\ 'info': fri_data } )
|
75
|
+
else
|
76
|
+
call complete_add(name)
|
77
|
+
endif
|
78
|
+
if complete_check()
|
79
|
+
break
|
80
|
+
endif
|
81
|
+
endfor
|
82
|
+
|
63
83
|
call delete(s:rct_tmpfile)
|
64
|
-
return
|
84
|
+
return []
|
65
85
|
endif
|
66
86
|
endfunction
|
67
87
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
(progn
|
2
|
-
(setq rct-method-completion-table '(("div") ("divmod") ))
|
2
|
+
(setq rct-method-completion-table '(("div\t[Fixnum#div]") ("divmod\t[Fixnum#divmod]") ))
|
3
|
+
(setq alist '(("div" . "Fixnum#div")("divmod" . "Fixnum#divmod")))
|
3
4
|
(setq pattern "div")
|
4
5
|
(setq klass "Fixnum")
|
5
6
|
)
|
data/test/test_completion.rb
CHANGED
@@ -493,3 +493,148 @@ EOC
|
|
493
493
|
assert_equal("String", get_class("'a'.siz", 1))
|
494
494
|
end
|
495
495
|
end
|
496
|
+
|
497
|
+
|
498
|
+
class TestXMPCompletionVerboseFilter < Test::Unit::TestCase
|
499
|
+
def doit(code, lineno, column=nil, options={})
|
500
|
+
xmp = XMPCompletionVerboseFilter.new options
|
501
|
+
xmp.candidates(code, lineno, column).sort
|
502
|
+
end
|
503
|
+
|
504
|
+
def test_complete_global_variable
|
505
|
+
assert_equal(["$hoge"], doit(<<EOC, 2))
|
506
|
+
$hoge = 100
|
507
|
+
$ho
|
508
|
+
EOC
|
509
|
+
end
|
510
|
+
|
511
|
+
def test_complete_instance_variable
|
512
|
+
assert_equal(["@hoge"], doit(<<EOC, 2))
|
513
|
+
@hoge = 100
|
514
|
+
@ho
|
515
|
+
EOC
|
516
|
+
end
|
517
|
+
|
518
|
+
def test_complete_class_variable_module
|
519
|
+
assert_equal(["@@hoge"], doit(<<EOC, 3))
|
520
|
+
module X
|
521
|
+
@@hoge = 100
|
522
|
+
@@ho
|
523
|
+
end
|
524
|
+
EOC
|
525
|
+
end
|
526
|
+
|
527
|
+
def test_complete_constant__nested
|
528
|
+
assert_equal(["Stat"], doit('File::Sta',1))
|
529
|
+
end
|
530
|
+
|
531
|
+
def test_complete_class_method
|
532
|
+
assert_equal(["popen\0IO.popen"], doit('File::pop',1))
|
533
|
+
assert_equal(["popen\0IO.popen"], doit('::File::pop',1))
|
534
|
+
|
535
|
+
assert_equal(["popen\0IO.popen"], doit('File.pop',1))
|
536
|
+
assert_equal(["popen\0IO.popen"], doit('::File.pop',1))
|
537
|
+
|
538
|
+
assert_equal(["new\0File::Stat.new"], doit('::File::Stat.ne', 1))
|
539
|
+
assert_equal(["new\0File::Stat.new"], doit('File::Stat.ne',1))
|
540
|
+
|
541
|
+
end
|
542
|
+
|
543
|
+
def test_complete_constant__in_class
|
544
|
+
assert_equal(["Fixclass", "Fixnum"], doit(<<EOC, 3))
|
545
|
+
class Fixclass
|
546
|
+
class Bar
|
547
|
+
Fix
|
548
|
+
end
|
549
|
+
end
|
550
|
+
EOC
|
551
|
+
end
|
552
|
+
|
553
|
+
|
554
|
+
def test_complete_toplevel_constant
|
555
|
+
assert_equal(["Fixnum"], doit(<<EOC,3))
|
556
|
+
class Foo
|
557
|
+
class Fixnum
|
558
|
+
::Fixn
|
559
|
+
end
|
560
|
+
end
|
561
|
+
EOC
|
562
|
+
|
563
|
+
assert_equal(["Fixnum"], doit(<<EOC,3))
|
564
|
+
class Foo
|
565
|
+
class Fixnum
|
566
|
+
::Foo::Fixn
|
567
|
+
end
|
568
|
+
end
|
569
|
+
EOC
|
570
|
+
|
571
|
+
assert_equal(["Bar"], doit(<<EOC,5))
|
572
|
+
class Foo
|
573
|
+
class Bar
|
574
|
+
end
|
575
|
+
end
|
576
|
+
::Foo::B
|
577
|
+
EOC
|
578
|
+
end
|
579
|
+
|
580
|
+
def test_complete_symbol
|
581
|
+
assert_equal([":vccaex"], doit(<<EOC,2))
|
582
|
+
a = :vccaex
|
583
|
+
:vcca
|
584
|
+
EOC
|
585
|
+
|
586
|
+
end
|
587
|
+
|
588
|
+
def test_method_chain__String
|
589
|
+
assert_equal(["length\0String#length"], doit('"a".upcase.capitalize.leng', 1))
|
590
|
+
end
|
591
|
+
|
592
|
+
def test_bare_word__local_variable
|
593
|
+
assert_equal(["aaaaaxx"], doit(<<EOC,2))
|
594
|
+
aaaaaxx = 1
|
595
|
+
aaaa
|
596
|
+
EOC
|
597
|
+
end
|
598
|
+
|
599
|
+
def test_bare_word__method
|
600
|
+
assert_equal(["trace_var\0Kernel#trace_var"], doit("trace",1))
|
601
|
+
end
|
602
|
+
|
603
|
+
def test_bare_word__constant
|
604
|
+
assert_equal(["Fixnum"], doit("Fixn",1))
|
605
|
+
end
|
606
|
+
|
607
|
+
def test_bare_word__method_in_class
|
608
|
+
assert_equal(["attr_accessor\0Module#attr_accessor"], doit(<<EOC,2))
|
609
|
+
class X
|
610
|
+
attr_acc
|
611
|
+
end
|
612
|
+
EOC
|
613
|
+
end
|
614
|
+
|
615
|
+
def test_bare_word__public_method
|
616
|
+
assert_equal(["hoge\0X#hoge"], doit(<<EOC,4))
|
617
|
+
class X
|
618
|
+
def hoge() end
|
619
|
+
def boke
|
620
|
+
hog
|
621
|
+
end
|
622
|
+
new.boke
|
623
|
+
end
|
624
|
+
EOC
|
625
|
+
end
|
626
|
+
|
627
|
+
def test_bare_word__private_method
|
628
|
+
assert_equal(["hoge\0X#hoge"], doit(<<EOC,5))
|
629
|
+
class X
|
630
|
+
def hoge() end
|
631
|
+
private :hoge
|
632
|
+
def boke
|
633
|
+
hog
|
634
|
+
end
|
635
|
+
new.boke
|
636
|
+
end
|
637
|
+
EOC
|
638
|
+
end
|
639
|
+
|
640
|
+
end
|
data/test/test_doc.rb
CHANGED
@@ -150,6 +150,14 @@ end
|
|
150
150
|
EOC
|
151
151
|
end
|
152
152
|
|
153
|
+
def test_bare_word__Class_object_id
|
154
|
+
assert_equal("Object#object_id", doit(<<EOC, 2))
|
155
|
+
class Foo
|
156
|
+
object_id
|
157
|
+
end
|
158
|
+
EOC
|
159
|
+
end
|
160
|
+
|
153
161
|
|
154
162
|
def test_bare_word__self
|
155
163
|
assert_equal("Foo#foo", doit(<<EOC, 3))
|
@@ -417,6 +425,20 @@ end
|
|
417
425
|
EOC
|
418
426
|
end
|
419
427
|
end
|
428
|
+
end
|
429
|
+
|
430
|
+
class TestXMPRiFilter < Test::Unit::TestCase
|
431
|
+
def doit(code, lineno, column=nil, options={})
|
432
|
+
xmp = XMPRiFilter.new options
|
433
|
+
xmp.doc(code, lineno, column)
|
434
|
+
end
|
420
435
|
|
436
|
+
def test_class_method__IO_popen
|
437
|
+
assert_equal("ri 'IO::popen'", doit("IO::popen", 1))
|
438
|
+
assert_equal("ri 'IO::popen'", doit("IO.popen", 1))
|
439
|
+
end
|
421
440
|
|
441
|
+
def test_instance_method__Array
|
442
|
+
assert_equal("ri 'Array#length'", doit("[].length", 1))
|
443
|
+
end
|
422
444
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
$: << ".." << "../lib"
|
2
|
+
require 'rcodetools/options'
|
3
|
+
require 'test/unit'
|
4
|
+
require 'tmpdir'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
class TestOptionHandler < Test::Unit::TestCase
|
8
|
+
include OptionHandler
|
9
|
+
|
10
|
+
def include_paths_check
|
11
|
+
options = { :include_paths => [] }
|
12
|
+
auto_include_paths options[:include_paths], Dir.pwd
|
13
|
+
assert options[:include_paths].include?("#{@basedir}/lib")
|
14
|
+
assert options[:include_paths].include?("#{@basedir}/bin")
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_auto_include_paths
|
18
|
+
Dir.chdir(Dir.tmpdir) do
|
19
|
+
begin
|
20
|
+
FileUtils.mkdir_p ["project", "project/lib/project", "project/bin", "project/share"]
|
21
|
+
open("project/Rakefile","w"){}
|
22
|
+
@basedir = File.expand_path "project"
|
23
|
+
Dir.chdir("project/lib/project/") { include_paths_check }
|
24
|
+
Dir.chdir("project/lib/") { include_paths_check }
|
25
|
+
Dir.chdir("project/bin/") { include_paths_check }
|
26
|
+
Dir.chdir("project/") { include_paths_check }
|
27
|
+
ensure
|
28
|
+
FileUtils.rm_rf "project"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: rcodetools
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2007-01-
|
6
|
+
version: 0.5.0.0
|
7
|
+
date: 2007-01-28 00:00:00 +01:00
|
8
8
|
summary: rcodetools is a collection of Ruby code manipulation tools
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -76,6 +76,7 @@ files:
|
|
76
76
|
- test/test_method_args.rb
|
77
77
|
- test/test_method_analyzer.rb
|
78
78
|
- test/test_run.rb
|
79
|
+
- test/test_options.rb
|
79
80
|
- test/data/simple_annotation-input.rb
|
80
81
|
- test/data/unit_test-input.rb
|
81
82
|
- test/data/rspec-input.rb
|
@@ -119,6 +120,7 @@ test_files:
|
|
119
120
|
- test/test_method_args.rb
|
120
121
|
- test/test_method_analyzer.rb
|
121
122
|
- test/test_run.rb
|
123
|
+
- test/test_options.rb
|
122
124
|
rdoc_options:
|
123
125
|
- --main
|
124
126
|
- README
|