bond 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/{gemspec → .gemspec} +10 -5
- data/CHANGELOG.rdoc +5 -0
- data/README.rdoc +1 -0
- data/Rakefile +3 -3
- data/ext/readline_line_buffer/extconf.rb +18 -3
- data/lib/bond.rb +54 -38
- data/lib/bond/agent.rb +34 -32
- data/lib/bond/completions/bond.rb +8 -1
- data/lib/bond/input.rb +2 -2
- data/lib/bond/m.rb +25 -24
- data/lib/bond/mission.rb +5 -6
- data/lib/bond/missions/anywhere_mission.rb +4 -8
- data/lib/bond/missions/default_mission.rb +2 -4
- data/lib/bond/missions/method_mission.rb +40 -43
- data/lib/bond/missions/object_mission.rb +8 -10
- data/lib/bond/missions/operator_method_mission.rb +1 -2
- data/lib/bond/rc.rb +2 -2
- data/lib/bond/readline.rb +1 -18
- data/lib/bond/search.rb +1 -1
- data/lib/bond/version.rb +1 -1
- data/lib/bond/yard.rb +2 -2
- data/test/deps.rip +4 -0
- data/test/search_test.rb +8 -0
- data/test/test_helper.rb +2 -3
- metadata +37 -12
- data/test/bacon_extensions.rb +0 -26
data/{gemspec → .gemspec}
RENAMED
@@ -12,10 +12,15 @@ Gem::Specification.new do |s|
|
|
12
12
|
s.description = "Bond is on a mission to improve irb’s autocompletion. Aside from doing everything irb’s can do and fixing its quirks, Bond can autocomplete argument(s) to methods, uniquely completing per module, per method and per argument. Bond brings irb’s completion closer to bash/zsh as it provides a configuration system and a DSL for creating custom completions and completion rules. With this configuration system, users can customize their irb autocompletions and share it with others. Bond can also generate completions from yard documentation and load completions that ship with gems. Bond is able to offer more than irb’s completion since it uses a Readline C extension to get the full line of input when completing as opposed to irb’s last-word approach."
|
13
13
|
s.required_rubygems_version = ">= 1.3.6"
|
14
14
|
s.rubyforge_project = 'tagaholic'
|
15
|
-
s.
|
16
|
-
s.
|
15
|
+
s.has_rdoc = 'yard'
|
16
|
+
s.rdoc_options = ['--title', "Bond #{Bond::VERSION} Documentation"]
|
17
|
+
s.add_development_dependency 'bacon', '>= 1.1.0'
|
18
|
+
s.add_development_dependency 'mocha', '>= 0.9.8'
|
17
19
|
s.add_development_dependency 'mocha-on-bacon'
|
18
|
-
s.
|
20
|
+
s.add_development_dependency 'bacon-bits'
|
21
|
+
s.files = Dir.glob(%w[{lib,test}/**/*.rb bin/* [A-Z]*.{txt,rdoc} ext/**/*.{rb,c}]) + %w{Rakefile .gemspec}
|
22
|
+
s.files += Dir.glob('**/*.rip')
|
19
23
|
s.extra_rdoc_files = ["README.rdoc", "LICENSE.txt"]
|
20
|
-
s.extensions =
|
21
|
-
|
24
|
+
s.extensions = ["ext/readline_line_buffer/extconf.rb"]
|
25
|
+
s.license = 'MIT'
|
26
|
+
end
|
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
== 0.2.2
|
2
|
+
* Moved documentation to yard.
|
3
|
+
* Better extconf.rb thanks to @timcharper
|
4
|
+
* Better error when failing to require extension.
|
5
|
+
|
1
6
|
== 0.2.1
|
2
7
|
* Added Bond.load_yard_gems which generates argument completions from yard documentation.
|
3
8
|
* Added Bond.load_gems which loads completions from gem's directory.
|
data/README.rdoc
CHANGED
@@ -206,6 +206,7 @@ has good instructions for reinstalling ruby with the official Readline.
|
|
206
206
|
* Csaba Hank for {providing the C extension}[http://www.creo.hu/~csaba/ruby/irb-enhancements/doc/files/README.html] which Bond uses to read Readline's full buffer.
|
207
207
|
* Takao Kouji for {commiting}[http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ext/readline/readline.c?view=diff&r1=24018&r2=24019] this Readline enhancement to ruby 1.9.2.
|
208
208
|
* pd for compatibility with emacs' inf-ruby mode.
|
209
|
+
* timcharper for improving extconf.rb.
|
209
210
|
|
210
211
|
== Links
|
211
212
|
* http://tagaholic.me/2010/05/07/screencast-of-argument-autocompletion-for-methods-in-irb.html
|
data/Rakefile
CHANGED
@@ -2,12 +2,12 @@ require 'rake'
|
|
2
2
|
require 'fileutils'
|
3
3
|
|
4
4
|
def gemspec
|
5
|
-
@gemspec ||= eval(File.read('gemspec'), binding, 'gemspec')
|
5
|
+
@gemspec ||= eval(File.read('.gemspec'), binding, '.gemspec')
|
6
6
|
end
|
7
7
|
|
8
8
|
desc "Build the gem"
|
9
9
|
task :gem=>:gemspec do
|
10
|
-
sh "gem build gemspec"
|
10
|
+
sh "gem build .gemspec"
|
11
11
|
FileUtils.mkdir_p 'pkg'
|
12
12
|
FileUtils.mv "#{gemspec.name}-#{gemspec.version}.gem", 'pkg'
|
13
13
|
end
|
@@ -32,4 +32,4 @@ task :test do |t|
|
|
32
32
|
sh 'bacon -q -Ilib -I. test/*_test.rb'
|
33
33
|
end
|
34
34
|
|
35
|
-
task :default => :test
|
35
|
+
task :default => :test
|
@@ -1,4 +1,19 @@
|
|
1
1
|
require "mkmf"
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
|
3
|
+
if RUBY_VERSION < '1.9.2'
|
4
|
+
dir_config("readline")
|
5
|
+
unless have_header('readline/readline.h')
|
6
|
+
$stderr.puts "-" * 80
|
7
|
+
$stderr.puts "Error! Cannot find readline/readline.h."
|
8
|
+
$stderr.puts "Readline was probably installed in a non-standard directory.",
|
9
|
+
"Try `gem install bond -- --with-readline-dir=/path/to/readline`."
|
10
|
+
$stderr.puts "-" * 80
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
create_makefile 'readline_line_buffer'
|
14
|
+
else
|
15
|
+
# Create dummy Makefile to placate rubygems when running `make install`.
|
16
|
+
File.open(File.join(File.dirname(__FILE__), "Makefile"), "w") {|f|
|
17
|
+
f.puts %[install:\n\techo "This is a dummy extension"]
|
18
|
+
}
|
19
|
+
end
|
data/lib/bond.rb
CHANGED
@@ -17,38 +17,50 @@ require 'bond/yard'
|
|
17
17
|
module Bond
|
18
18
|
extend self
|
19
19
|
|
20
|
-
#
|
20
|
+
# Creates a completion rule (Mission). A valid Mission consists of a condition and an action. A
|
21
21
|
# condition is specified with one of the following options: :on, :object, :anywhere or :method(s). Each
|
22
|
-
# of these options creates a different Mission class. An action is either
|
22
|
+
# of these options creates a different Mission class. An action is either the method's block or :action.
|
23
23
|
# An action takes what the user has typed (Input) and returns an array of possible completions. Bond
|
24
24
|
# searches these completions and returns matching completions. This searching behavior can be configured
|
25
25
|
# or turned off per mission with :search. If turned off, the action must also handle searching.
|
26
|
-
#
|
27
|
-
# [*:on*] Regular expression which matches the full line of input to create a Mission object.
|
28
|
-
# [*:method*, *:methods*, *:class*] See MethodMission.
|
29
|
-
# [*:anywhere*, *:prefix*] See AnywhereMission.
|
30
|
-
# [*:object*] See ObjectMission.
|
31
|
-
# [*:search*] A symbol or false which determines how completions are searched. Defaults to
|
32
|
-
# Search.default_search. If false, search is turned off and assumed to be done in the action.
|
33
|
-
# Possible symbols are :anywhere, :ignore_case, :underscore, :normal, :files and :modules.
|
34
|
-
# See Search for more info.
|
35
|
-
# [*:action*] Rc method name that takes an Input and returns possible completions. See MethodMission for
|
36
|
-
# specific behavior with :method(s).
|
37
|
-
# [*:place*] A number or :last which indicates where a mission is inserted amongst existing missions.
|
38
|
-
# If the symbol :last, places the mission at the end regardless of missions defined after
|
39
|
-
# it. Multiple declarations of :last are kept last in the order they are defined.
|
40
|
-
# [*:name*] A symbol or string that serves a unique id for a mission. This unique id can be passed by
|
41
|
-
# Bond.recomplete to identify and replace the mission.
|
26
|
+
#
|
42
27
|
# ==== Examples:
|
43
28
|
# Bond.complete(:method=>'shoot') {|input| %w{to kill} }
|
44
29
|
# Bond.complete(:on=>/^((([a-z][^:.\(]*)+):)+/, :search=>false) {|input| Object.constants.grep(/#{input.matched[1]}/) }
|
45
30
|
# Bond.complete(:object=>ActiveRecord::Base, :search=>:underscore, :place=>:last)
|
46
31
|
# Bond.complete(:method=>'you', :search=>proc {|input, list| list.grep(/#{input}/i)} ) {|input| %w{Only Live Twice} }
|
47
32
|
# Bond.complete(:method=>'system', :action=>:shell_commands)
|
33
|
+
#
|
34
|
+
# @param [Hash] options When using :method(s) or :object, some hash keys may have different behavior. See
|
35
|
+
# Bond.complete sections of {MethodMission} and {ObjectMission} respectively.
|
36
|
+
# @option options [Regexp] :on Matches the full line of input to create a {Mission} object.
|
37
|
+
# @option options [String] :method An instance (Class#method) or class method (Class.method). Creates
|
38
|
+
# {MethodMission} object. A method's class can be set by :class or detected automatically if '#' or '.' is
|
39
|
+
# present. If no class is detected, 'Kernel#' is assumed.
|
40
|
+
# @option options [Array<String>] :methods Instance or class method(s) in the format of :method. Creates
|
41
|
+
# {MethodMission} objects.
|
42
|
+
# @option options [String] :class Optionally used with :method or :methods to represent module/class.
|
43
|
+
# Must end in '#' or '.' to indicate instance/class method. Suggested for use with :methods.
|
44
|
+
# @option options [String] :object Module or class of an object whose methods are completed. Creates
|
45
|
+
# {ObjectMission} object.
|
46
|
+
# @option options [String] :anywhere String representing a regular expression to match a mission. Creates
|
47
|
+
# {AnywhereMission} object.
|
48
|
+
# @option options [String] :prefix Optional string to prefix :anywhere.
|
49
|
+
# @option options [Symbol,false] :search Determines how completions are searched. Defaults to
|
50
|
+
# Search.default_search. If false, search is turned off and assumed to be done in the action.
|
51
|
+
# Possible symbols are :anywhere, :ignore_case, :underscore, :normal, :files and :modules.
|
52
|
+
# See {Search} for more info.
|
53
|
+
# @option options [String,Symbol] :action Rc method name that takes an Input and returns possible completions.
|
54
|
+
# See {MethodMission} for specific behavior with :method(s).
|
55
|
+
# @option options [Integer,:last] :place Indicates where a mission is inserted amongst existing
|
56
|
+
# missions. If the symbol :last, places the mission at the end regardless of missions defined
|
57
|
+
# after it. Multiple declarations of :last are kept last in the order they are defined.
|
58
|
+
# @option options [Symbol,String] :name Unique id for a mission which can be passed by
|
59
|
+
# Bond.recomplete to identify and replace the mission.
|
48
60
|
def complete(options={}, &block); M.complete(options, &block); end
|
49
61
|
|
50
62
|
# Redefines an existing completion mission to have a different action. The condition can only be varied if :name is
|
51
|
-
# used to identify and replace a mission. Takes same options as
|
63
|
+
# used to identify and replace a mission. Takes same options as {#complete}.
|
52
64
|
# ==== Example:
|
53
65
|
# Bond.recomplete(:on=>/man/, :name=>:count) { %w{4 5 6}}
|
54
66
|
def recomplete(options={}, &block); M.recomplete(options, &block); end
|
@@ -60,41 +72,45 @@ module Bond
|
|
60
72
|
# Possible completions: ["octopussy"]
|
61
73
|
def spy(*args); M.spy(*args); end
|
62
74
|
|
63
|
-
# Global config
|
64
|
-
# [*:readline_plugin*] Specifies a Bond plugin to interface with a Readline-like library. Available
|
65
|
-
# plugins are Readline and Rawline. Defaults to Readline.
|
66
|
-
# [*:default_mission*] A proc or name of an Rc method to use as the default completion when no
|
67
|
-
# missions match.
|
68
|
-
# [*:default_search*] Name of a *_search method in Rc to use as the default search in completions.
|
69
|
-
# Default is :underscore. See Bond.complete's :search option for valid values.
|
70
|
-
# [*:eval_binding*] Specifies a binding to use when evaluating objects in ObjectMission and MethodMission.
|
71
|
-
# When in irb, defaults to irb's current binding. Otherwise defaults to TOPLEVEL_BINDING.
|
72
|
-
# [*:debug*] Boolean to show the stacktrace when autocompletion fails and raise exceptions in Rc.eval.
|
73
|
-
# Default is false.
|
74
|
-
# [*:eval_debug*] Boolean to raise eval errors occuring when finding a matching completion. Useful to debug
|
75
|
-
# an incorrect completion. Default is false.
|
75
|
+
# @return [Hash] Global config
|
76
76
|
def config; M.config; end
|
77
77
|
|
78
78
|
# Starts Bond with a default set of completions that replace and improve irb's completion. Loads completions
|
79
79
|
# in this order: lib/bond/completion.rb, lib/bond/completions/*.rb and the following optional completions:
|
80
80
|
# completions from :gems, completions from :yard_gems, ~/.bondrc, ~/.bond/completions/*.rb and from block. See
|
81
|
-
# Rc for the DSL to use in completion files and in the block.
|
82
|
-
#
|
83
|
-
# [*:yard_gems*] Array of gems using yard documentation to generate completions. See Yard.
|
81
|
+
# {Rc} for the DSL to use in completion files and in the block.
|
82
|
+
#
|
84
83
|
# ==== Examples:
|
85
84
|
# Bond.start :gems=>%w{hirb}
|
86
85
|
# Bond.start(:default_search=>:ignore_case) do
|
87
86
|
# complete(:method=>"Object#respond_to?") {|e| e.object.methods }
|
88
87
|
# end
|
88
|
+
#
|
89
|
+
# @param [Hash] options Sets global keys in {#config}, some which specify what completions to load.
|
90
|
+
# @option options [Array<String>] :gems Gems which have their completions loaded from
|
91
|
+
# @gem_source/lib/bond/completions/*.rb.
|
92
|
+
# @option options [Array<String>] :yard_gems Gems using yard documentation to generate completions. See {Yard}.
|
93
|
+
# @option options [Module] :readline_plugin (Bond::Readline) Specifies a Bond plugin to interface with a Readline-like
|
94
|
+
# library. Available plugins are Bond::Readline and Bond::Rawline.
|
95
|
+
# @option options [Proc] :default_mission (DefaultMission) Sets default completion to use when no missions match.
|
96
|
+
# See {Agent#default_mission}.
|
97
|
+
# @option options [Symbol] :default_search (:underscore) Name of a *_search method in Rc to use as the default
|
98
|
+
# search in completions. See {#complete}'s :search option for valid values.
|
99
|
+
# @option options [Binding] :eval_binding (TOPLEVEL_BINDING) Binding to use when evaluating objects in
|
100
|
+
# ObjectMission and MethodMission. When in irb, defaults to irb's current binding.
|
101
|
+
# @option options [Boolean] :debug (false) Shows the stacktrace when autocompletion fails and raises exceptions
|
102
|
+
# in Rc.eval.
|
103
|
+
# @option options [Boolean] :eval_debug (false) Raises eval errors occuring when finding a matching completion.
|
104
|
+
# Useful to debug an incorrect completion.
|
89
105
|
def start(options={}, &block); M.start(options, &block); end
|
90
106
|
|
91
107
|
# Loads completions for gems that ship with them under lib/bond/completions/, relative to the gem's base directory.
|
92
108
|
def load_gems(*gems); M.load_gems(*gems); end
|
93
109
|
|
94
110
|
# Generates and loads completions for yardoc documented gems.
|
95
|
-
#
|
96
|
-
#
|
97
|
-
# [
|
111
|
+
# @param *gems Gem(s) with optional options hash at the end
|
112
|
+
# @option *gems :verbose[Boolean] (false) Displays additional information when building yardoc.
|
113
|
+
# @option *gems :reload[Boolean] (false) Rebuilds yard databases. Use when gems have changed versions.
|
98
114
|
def load_yard_gems(*gems); Yard.load_yard_gems(*gems); end
|
99
115
|
|
100
116
|
# An Agent who saves all Bond.complete missions and executes the correct one when a completion is called.
|
data/lib/bond/agent.rb
CHANGED
@@ -7,7 +7,7 @@ module Bond
|
|
7
7
|
# An agent's best friend a.k.a. the readline plugin.
|
8
8
|
attr_reader :weapon
|
9
9
|
|
10
|
-
def initialize(options={})
|
10
|
+
def initialize(options={}) #@private
|
11
11
|
setup_readline_plugin(options[:readline_plugin])
|
12
12
|
@default_mission_action = options[:default_mission] if options[:default_mission]
|
13
13
|
Mission.eval_binding = options[:eval_binding] if options[:eval_binding]
|
@@ -15,14 +15,6 @@ module Bond
|
|
15
15
|
@missions = []
|
16
16
|
end
|
17
17
|
|
18
|
-
def setup_readline_plugin(plugin) #:nodoc:
|
19
|
-
raise ArgumentError unless plugin.is_a?(Module)
|
20
|
-
@weapon = plugin.extend(plugin)
|
21
|
-
@weapon.setup(self)
|
22
|
-
rescue
|
23
|
-
$stderr.puts "Bond Error: Failed #{plugin.to_s[/[^:]+$/]} setup with '#{$!.message}'"
|
24
|
-
end
|
25
|
-
|
26
18
|
# Creates a mission.
|
27
19
|
def complete(options={}, &block)
|
28
20
|
if (mission = create_mission(options, &block)).is_a?(Mission)
|
@@ -32,14 +24,6 @@ module Bond
|
|
32
24
|
mission
|
33
25
|
end
|
34
26
|
|
35
|
-
def create_mission(options, &block) #:nodoc:
|
36
|
-
Mission.create options.merge!(:action=>options[:action] || block)
|
37
|
-
rescue InvalidMissionError
|
38
|
-
"Invalid #{$!.message} for completion with options: #{options.inspect}"
|
39
|
-
rescue
|
40
|
-
"Unexpected error while creating completion with options #{options.inspect} and message:\n#{$!}"
|
41
|
-
end
|
42
|
-
|
43
27
|
# Creates a mission and replaces the mission it matches if possible.
|
44
28
|
def recomplete(options={}, &block)
|
45
29
|
if (mission = create_mission(options, &block)).is_a?(Mission)
|
@@ -53,14 +37,6 @@ module Bond
|
|
53
37
|
mission
|
54
38
|
end
|
55
39
|
|
56
|
-
def sort_last_missions #:nodoc:
|
57
|
-
@missions.replace @missions.partition {|e| e.place != :last }.flatten
|
58
|
-
end
|
59
|
-
|
60
|
-
def reset #:nodoc:
|
61
|
-
@missions = []
|
62
|
-
end
|
63
|
-
|
64
40
|
# This is where the action starts when a completion is initiated. Optional line_buffer
|
65
41
|
# overrides line buffer from readline plugin.
|
66
42
|
def call(input, line_buffer=nil)
|
@@ -74,12 +50,6 @@ module Bond
|
|
74
50
|
"Please report this issue with debug on: Bond.config[:debug] = true."
|
75
51
|
end
|
76
52
|
|
77
|
-
def completion_error(desc, message) #:nodoc:
|
78
|
-
arr = ["Bond Error: #{desc}", message]
|
79
|
-
arr << "Stack Trace: #{$!.backtrace.inspect}" if Bond.config[:debug]
|
80
|
-
arr
|
81
|
-
end
|
82
|
-
|
83
53
|
# Given a hypothetical user input, reports back what mission it would have found and executed.
|
84
54
|
def spy(input)
|
85
55
|
if (mission = find_mission(input))
|
@@ -93,7 +63,7 @@ module Bond
|
|
93
63
|
"Matches for #{e.mission.condition.inspect} are #{e.mission.matched.to_a.inspect}"
|
94
64
|
end
|
95
65
|
|
96
|
-
def find_mission(input)
|
66
|
+
def find_mission(input) #@private
|
97
67
|
@missions.find {|mission| mission.matches?(input) }
|
98
68
|
end
|
99
69
|
|
@@ -101,5 +71,37 @@ module Bond
|
|
101
71
|
def default_mission
|
102
72
|
@default_mission ||= DefaultMission.new(:action=>@default_mission_action)
|
103
73
|
end
|
74
|
+
|
75
|
+
# Resets an agent's missions
|
76
|
+
def reset
|
77
|
+
@missions = []
|
78
|
+
end
|
79
|
+
|
80
|
+
protected
|
81
|
+
def setup_readline_plugin(plugin)
|
82
|
+
raise ArgumentError unless plugin.is_a?(Module)
|
83
|
+
@weapon = plugin.extend(plugin)
|
84
|
+
@weapon.setup(self)
|
85
|
+
rescue
|
86
|
+
$stderr.puts "Bond Error: Failed #{plugin.to_s[/[^:]+$/]} setup with '#{$!.message}'"
|
87
|
+
end
|
88
|
+
|
89
|
+
def create_mission(options, &block)
|
90
|
+
Mission.create options.merge!(:action=>options[:action] || block)
|
91
|
+
rescue InvalidMissionError
|
92
|
+
"Invalid #{$!.message} for completion with options: #{options.inspect}"
|
93
|
+
rescue
|
94
|
+
"Unexpected error while creating completion with options #{options.inspect} and message:\n#{$!}"
|
95
|
+
end
|
96
|
+
|
97
|
+
def sort_last_missions
|
98
|
+
@missions.replace @missions.partition {|e| e.place != :last }.flatten
|
99
|
+
end
|
100
|
+
|
101
|
+
def completion_error(desc, message)
|
102
|
+
arr = ["Bond Error: #{desc}", message]
|
103
|
+
arr << "Stack Trace: #{$!.backtrace.inspect}" if Bond.config[:debug]
|
104
|
+
arr
|
105
|
+
end
|
104
106
|
end
|
105
107
|
end
|
@@ -1,2 +1,9 @@
|
|
1
1
|
complete(:methods=>%w{Bond.complete Bond.recomplete}) {
|
2
|
-
|
2
|
+
["on", "method", "methods", "class", "object", "anywhere", "prefix", "search", "action", "place", "name"]
|
3
|
+
}
|
4
|
+
complete(:method=>'Bond.start') {
|
5
|
+
["gems", "yard_gems", "readline_plugin", "default_mission", "default_search", "eval_binding", "debug", "eval_debug"]
|
6
|
+
}
|
7
|
+
complete(:method=>'Bond.load_yard_gems') {
|
8
|
+
["verbose", "reload"]
|
9
|
+
}
|
data/lib/bond/input.rb
CHANGED
@@ -11,7 +11,7 @@ module Bond
|
|
11
11
|
attr_accessor :argument, :arguments
|
12
12
|
# The full line the user has typed.
|
13
13
|
attr_reader :line
|
14
|
-
def initialize(str, options={})
|
14
|
+
def initialize(str, options={}) #@private
|
15
15
|
super(str || '')
|
16
16
|
@matched = options[:matched]
|
17
17
|
@line = options[:line]
|
@@ -20,7 +20,7 @@ module Bond
|
|
20
20
|
@arguments = options[:arguments] if options[:arguments]
|
21
21
|
end
|
22
22
|
|
23
|
-
def inspect
|
23
|
+
def inspect #@private
|
24
24
|
"#<Bond::Input #{self.to_s.inspect} @matched=#{@matched.to_a.inspect} @line=#{@line.inspect} "+
|
25
25
|
"@argument=#{@argument.inspect} @arguments=#{@arguments.inspect} @object=#{@object.inspect}>"
|
26
26
|
end
|
data/lib/bond/m.rb
CHANGED
@@ -3,7 +3,7 @@ module Bond
|
|
3
3
|
module M
|
4
4
|
extend self
|
5
5
|
|
6
|
-
# See Bond
|
6
|
+
# See {Bond#complete}
|
7
7
|
def complete(options={}, &block)
|
8
8
|
if (result = agent.complete(options, &block)).is_a?(String)
|
9
9
|
$stderr.puts "Bond Error: "+result
|
@@ -13,7 +13,7 @@ module Bond
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
# See Bond
|
16
|
+
# See {Bond#recomplete}
|
17
17
|
def recomplete(options={}, &block)
|
18
18
|
if (result = agent.recomplete(options, &block)).is_a?(String)
|
19
19
|
$stderr.puts "Bond Error: "+result
|
@@ -23,12 +23,12 @@ module Bond
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
# See Bond
|
26
|
+
# See {Bond#agent}
|
27
27
|
def agent
|
28
28
|
@agent ||= Agent.new(config)
|
29
29
|
end
|
30
30
|
|
31
|
-
# See Bond
|
31
|
+
# See {Bond#config}
|
32
32
|
def config
|
33
33
|
@config ||= {:readline_plugin=>Bond::Readline, :debug=>false, :default_search=>:underscore}
|
34
34
|
end
|
@@ -39,7 +39,7 @@ module Bond
|
|
39
39
|
@agent = nil
|
40
40
|
end
|
41
41
|
|
42
|
-
# See Bond
|
42
|
+
# See {Bond#spy}
|
43
43
|
def spy(input)
|
44
44
|
agent.spy(input)
|
45
45
|
end
|
@@ -54,7 +54,7 @@ module Bond
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
-
# See Bond
|
57
|
+
# See {Bond#start}
|
58
58
|
def start(options={}, &block)
|
59
59
|
debrief options
|
60
60
|
load_completions
|
@@ -62,30 +62,12 @@ module Bond
|
|
62
62
|
true
|
63
63
|
end
|
64
64
|
|
65
|
-
def load_gem_completion(rubygem) #:nodoc:
|
66
|
-
(dir = find_gem_file(rubygem, File.join(rubygem, '..', 'bond'))) ?
|
67
|
-
load_dir(dir) : $stderr.puts("Bond Error: No completions found for gem '#{rubygem}'.")
|
68
|
-
end
|
69
|
-
|
70
65
|
# Finds the full path to a gem's file relative it's load path directory. Returns nil if not found.
|
71
66
|
def find_gem_file(rubygem, file)
|
72
67
|
begin gem(rubygem); rescue Exception; end
|
73
68
|
(dir = $:.find {|e| File.exists?(File.join(e, file)) }) && File.join(dir, file)
|
74
69
|
end
|
75
70
|
|
76
|
-
def load_gems(*gems) #:nodoc:
|
77
|
-
gems.select {|e| load_gem_completion(e) }
|
78
|
-
end
|
79
|
-
|
80
|
-
def load_completions #:nodoc:
|
81
|
-
load_file File.join(File.dirname(__FILE__), 'completion.rb')
|
82
|
-
load_dir File.dirname(__FILE__)
|
83
|
-
load_gems *config[:gems] if config[:gems]
|
84
|
-
Yard.load_yard_gems *config[:yard_gems] if config[:yard_gems]
|
85
|
-
load_file(File.join(home,'.bondrc')) if File.exists?(File.join(home, '.bondrc'))
|
86
|
-
load_dir File.join(home, '.bond')
|
87
|
-
end
|
88
|
-
|
89
71
|
# Loads a completion file in Rc namespace.
|
90
72
|
def load_file(file)
|
91
73
|
Rc.module_eval File.read(file)
|
@@ -108,5 +90,24 @@ module Bond
|
|
108
90
|
rescue
|
109
91
|
File::ALT_SEPARATOR ? "C:/" : "/"
|
110
92
|
end
|
93
|
+
|
94
|
+
protected
|
95
|
+
def load_gem_completion(rubygem)
|
96
|
+
(dir = find_gem_file(rubygem, File.join(rubygem, '..', 'bond'))) ?
|
97
|
+
load_dir(dir) : $stderr.puts("Bond Error: No completions found for gem '#{rubygem}'.")
|
98
|
+
end
|
99
|
+
|
100
|
+
def load_gems(*gems)
|
101
|
+
gems.select {|e| load_gem_completion(e) }
|
102
|
+
end
|
103
|
+
|
104
|
+
def load_completions
|
105
|
+
load_file File.join(File.dirname(__FILE__), 'completion.rb')
|
106
|
+
load_dir File.dirname(__FILE__)
|
107
|
+
load_gems *config[:gems] if config[:gems]
|
108
|
+
Yard.load_yard_gems *config[:yard_gems] if config[:yard_gems]
|
109
|
+
load_file(File.join(home,'.bondrc')) if File.exists?(File.join(home, '.bondrc'))
|
110
|
+
load_dir File.join(home, '.bond')
|
111
|
+
end
|
111
112
|
end
|
112
113
|
end
|
data/lib/bond/mission.rb
CHANGED
@@ -5,7 +5,7 @@ module Bond
|
|
5
5
|
class FailedMissionError < StandardError
|
6
6
|
# Mission that failed
|
7
7
|
attr_reader :mission
|
8
|
-
def initialize(mission); @mission = mission; end
|
8
|
+
def initialize(mission); @mission = mission; end #@private
|
9
9
|
end
|
10
10
|
|
11
11
|
# Represents a completion rule, given a condition (:on) on which to match and an action
|
@@ -30,7 +30,7 @@ module Bond
|
|
30
30
|
eval(string, ebinding)
|
31
31
|
end
|
32
32
|
|
33
|
-
def eval_binding
|
33
|
+
def eval_binding #@private
|
34
34
|
@eval_binding || IRB.CurrentContext.workspace.binding rescue ::TOPLEVEL_BINDING
|
35
35
|
end
|
36
36
|
end
|
@@ -44,13 +44,13 @@ module Bond
|
|
44
44
|
# Generates array of possible completions and searches them if search is disabled. Any values
|
45
45
|
# that aren't strings are automatically converted with to_s.
|
46
46
|
attr_reader :action
|
47
|
-
# See Bond
|
47
|
+
# See {Bond#complete}'s :place.
|
48
48
|
attr_reader :place
|
49
49
|
# A MatchData object generated from matching the user input with the condition.
|
50
50
|
attr_reader :matched
|
51
51
|
# Regexp condition
|
52
52
|
attr_reader :on
|
53
|
-
# Takes same options as Bond
|
53
|
+
# Takes same options as {Bond#complete}.
|
54
54
|
def initialize(options)
|
55
55
|
raise InvalidMissionError, ":action" unless (options[:action] || respond_to?(:default_action))
|
56
56
|
raise InvalidMissionError, ":on" unless (options[:on] && options[:on].is_a?(Regexp)) || respond_to?(:default_on)
|
@@ -126,7 +126,7 @@ module Bond
|
|
126
126
|
create_input(input[/\S+$/])
|
127
127
|
end
|
128
128
|
|
129
|
-
|
129
|
+
private
|
130
130
|
def condition_with_objects
|
131
131
|
self.class.const_get(:CONDITION).sub('OBJECTS', self.class.const_get(:OBJECTS).join('|'))
|
132
132
|
end
|
@@ -150,6 +150,5 @@ module Bond
|
|
150
150
|
def create_input(input, options={})
|
151
151
|
@input = Input.new(input, options.merge(:line=>@line, :matched=>@matched))
|
152
152
|
end
|
153
|
-
#:startdoc:
|
154
153
|
end
|
155
154
|
end
|
@@ -1,17 +1,13 @@
|
|
1
1
|
# A mission which completes anywhere i.e. even after non word break characters such as '[' or '}'.
|
2
|
-
#
|
3
|
-
# capture group to the mission action.
|
4
|
-
#
|
5
|
-
# ==== Bond.complete Options:
|
6
|
-
# [*:anywhere*] A regexp string which generates the first capture group in the above regexp.
|
7
|
-
# [*:prefix*] An optional string which prefixes the first capture group in the above regexp.
|
2
|
+
# With options :prefix and :anywhere, this mission matches on the following regexp condition
|
3
|
+
# /:prefix?(:anywhere)$/ and passes the first capture group to the mission action.
|
8
4
|
class Bond::AnywhereMission < Bond::Mission
|
9
|
-
def initialize(options={})
|
5
|
+
def initialize(options={}) #@private
|
10
6
|
options[:on] = Regexp.new("#{options[:prefix]}(#{options[:anywhere]})$")
|
11
7
|
super
|
12
8
|
end
|
13
9
|
|
14
|
-
def after_match(input)
|
10
|
+
def after_match(input) #@private
|
15
11
|
@completion_prefix = input.to_s.sub(/#{Regexp.escape(@matched[1])}$/, '')
|
16
12
|
create_input @matched[1]
|
17
13
|
end
|
@@ -6,13 +6,11 @@ class Bond::DefaultMission < Bond::Mission
|
|
6
6
|
"then", "true", "undef", "unless", "until", "when", "while", "yield"
|
7
7
|
]
|
8
8
|
|
9
|
-
|
10
|
-
def initialize(options={})
|
9
|
+
def initialize(options={}) #@private
|
11
10
|
options[:action] ||= method(:default)
|
12
11
|
super
|
13
12
|
end
|
14
|
-
def default_on; end
|
15
|
-
#:startdoc:
|
13
|
+
def default_on; end #@private
|
16
14
|
|
17
15
|
# Default action which generates methods, private methods, reserved words, local variables and constants.
|
18
16
|
def default(input)
|
@@ -5,24 +5,13 @@ module Bond
|
|
5
5
|
# has two ancestors that have completions for the same method, the ancestor closer to the object is
|
6
6
|
# picked. For example, if Array#collect and Enumerable#collect have completions, argument completion on
|
7
7
|
# '[].collect ' would use Array#collect.
|
8
|
-
|
9
|
-
# Unlike other missions, creating these missions with Bond.complete doesn't add more completion rules
|
10
|
-
# for an Agent to look through. Instead, all :method(s) completions are handled by one MethodMission
|
11
|
-
# object which looks them up with its own hashes. In the same way, all operator methods are
|
12
|
-
# handled by one OperatorMethodMission object.
|
13
|
-
#++
|
8
|
+
#
|
14
9
|
# ==== Bond.complete Options:
|
15
|
-
# [
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
# [
|
20
|
-
# indicate instance/class method. Suggested for use with :methods.
|
21
|
-
# [*:action*] If a string, value is assumed to be a :method and that method's action is copied.
|
22
|
-
# Otherwise defaults to normal :action behavior.
|
23
|
-
# [*:search*] If :action is a :method string, defaults to copying its search.
|
24
|
-
# Otherwise defaults to normal :search behavior.
|
25
|
-
# [*:name*, *:place*] These options aren't supported by a MethodMission/OperatorMethodMission completion.
|
10
|
+
# [:action] If a string, value is assumed to be a :method and that method's action is copied.
|
11
|
+
# Otherwise defaults to normal :action behavior.
|
12
|
+
# [:search] If :action is a :method string, defaults to copying its search.
|
13
|
+
# Otherwise defaults to normal :search behavior.
|
14
|
+
# [:name, :place] These options aren't supported by a MethodMission/OperatorMethodMission completion.
|
26
15
|
# ==== Examples:
|
27
16
|
# Bond.complete(:methods=>%w{delete index rindex}, :class=>"Array#") {|e| e.object }
|
28
17
|
# Bond.complete(:method=>"Hash#index") {|e| e.object.values }
|
@@ -54,6 +43,12 @@ module Bond
|
|
54
43
|
# >> FileUtils.chown 'root', 'admin', 'some_file', :v[TAB]
|
55
44
|
# >> FileUtils.chown 'root', 'admin', 'some_file', :verbose
|
56
45
|
# >> FileUtils.chown 'root', 'admin', 'some_file', :verbose=>true
|
46
|
+
#
|
47
|
+
# ==== Developer Notes
|
48
|
+
# Unlike other missions, creating these missions with Bond.complete doesn't add more completion rules
|
49
|
+
# for an Agent to look through. Instead, all :method(s) completions are handled by one MethodMission
|
50
|
+
# object which looks them up with its own hashes. In the same way, all operator methods are
|
51
|
+
# handled by one OperatorMethodMission object.
|
57
52
|
class MethodMission < Bond::Mission
|
58
53
|
class<<self
|
59
54
|
# Hash of instance method completions which maps methods to hashes of modules to arrays ([action, search])
|
@@ -97,25 +92,17 @@ module Bond
|
|
97
92
|
@class_actions = {}
|
98
93
|
end
|
99
94
|
|
100
|
-
|
95
|
+
# Lists method names
|
96
|
+
def action_methods
|
101
97
|
(actions.keys + class_actions.keys).uniq
|
102
98
|
end
|
103
99
|
|
104
|
-
# Lists
|
100
|
+
# Lists full method names, prefixed with class/module
|
105
101
|
def all_methods
|
106
102
|
(class_actions.map {|m,h| h.map {|k,v| "#{k}.#{m}" } } +
|
107
103
|
actions.map {|m,h| h.map {|k,v| "#{k}##{m}" } }).flatten.sort
|
108
104
|
end
|
109
105
|
|
110
|
-
def current_actions(meth) #:nodoc:
|
111
|
-
meth.include?('.') ? @class_actions : @actions
|
112
|
-
end
|
113
|
-
|
114
|
-
def split_method(meth) #:nodoc:
|
115
|
-
meth = "Kernel##{meth}" if !meth.to_s[/[.#]/]
|
116
|
-
meth.split(/[.#]/,2)
|
117
|
-
end
|
118
|
-
|
119
106
|
# Returns the first completion by looking up the object's ancestors and finding the closest
|
120
107
|
# one that has a completion definition for the given method. Completion is returned
|
121
108
|
# as an array containing action proc and optional search to go with it.
|
@@ -126,16 +113,6 @@ module Bond
|
|
126
113
|
@last_find = last_find ? last_find[1] : last_find
|
127
114
|
end
|
128
115
|
|
129
|
-
def find_with(obj, meth, find_meth, actions) #:nodoc:
|
130
|
-
(actions[meth] || {}).select {|k,v| get_class(k) }.
|
131
|
-
sort {|a,b| get_class(a[0]) <=> get_class(b[0]) || -1 }.
|
132
|
-
find {|k,v| obj.send(find_meth, get_class(k)) }
|
133
|
-
end
|
134
|
-
|
135
|
-
def get_class(klass) #:nodoc:
|
136
|
-
(@klasses ||= {})[klass] ||= any_const_get(klass)
|
137
|
-
end
|
138
|
-
|
139
116
|
# Returns a constant like Module#const_get no matter what namespace it's nested in.
|
140
117
|
# Returns nil if the constant is not found.
|
141
118
|
def any_const_get(name)
|
@@ -146,13 +123,37 @@ module Bond
|
|
146
123
|
rescue
|
147
124
|
nil
|
148
125
|
end
|
126
|
+
|
127
|
+
protected
|
128
|
+
def current_actions(meth)
|
129
|
+
meth.include?('.') ? @class_actions : @actions
|
130
|
+
end
|
131
|
+
|
132
|
+
def split_method(meth)
|
133
|
+
meth = "Kernel##{meth}" if !meth.to_s[/[.#]/]
|
134
|
+
meth.split(/[.#]/,2)
|
135
|
+
end
|
136
|
+
|
137
|
+
def find_with(obj, meth, find_meth, actions)
|
138
|
+
(actions[meth] || {}).select {|k,v| get_class(k) }.
|
139
|
+
sort {|a,b| get_class(a[0]) <=> get_class(b[0]) || -1 }.
|
140
|
+
find {|k,v| obj.send(find_meth, get_class(k)) }
|
141
|
+
end
|
142
|
+
|
143
|
+
def get_class(klass)
|
144
|
+
(@klasses ||= {})[klass] ||= any_const_get(klass)
|
145
|
+
end
|
149
146
|
end
|
150
147
|
|
151
148
|
self.reset
|
152
149
|
OBJECTS = Mission::OBJECTS + %w{\S*?}
|
153
150
|
CONDITION = %q{(OBJECTS)\.?(METHODS)(?:\s+|\()(['":])?(.*)$}
|
154
151
|
|
155
|
-
|
152
|
+
def match_message #@private
|
153
|
+
"Matches completion for method '#{@meth}' in '#{MethodMission.last_class}'."
|
154
|
+
end
|
155
|
+
|
156
|
+
protected
|
156
157
|
def do_match(input)
|
157
158
|
(@on = default_on) && super && eval_object(@matched[1] ? @matched[1] : 'self') &&
|
158
159
|
MethodMission.find(@evaled_object, @meth = matched_method)
|
@@ -192,9 +193,5 @@ module Bond
|
|
192
193
|
create_input typed, input_options
|
193
194
|
end
|
194
195
|
|
195
|
-
def match_message
|
196
|
-
"Matches completion for method '#{@meth}' in '#{MethodMission.last_class}'."
|
197
|
-
end
|
198
|
-
#:startdoc:
|
199
196
|
end
|
200
197
|
end
|
@@ -4,22 +4,25 @@
|
|
4
4
|
# object attribute.
|
5
5
|
#
|
6
6
|
# ==== Bond.complete Options:
|
7
|
-
# [
|
8
|
-
# [*:action*] If an action is not specified, the default action is to complete an object's
|
7
|
+
# [:action] If an action is not specified, the default action is to complete an object's
|
9
8
|
# non-operator methods.
|
10
9
|
#
|
11
10
|
# ===== Example:
|
12
|
-
# Bond.complete(:object=>ActiveRecord::Base) {|input| input.object.class.instance_methods(false) }
|
11
|
+
# Bond.complete(:object=>'ActiveRecord::Base') {|input| input.object.class.instance_methods(false) }
|
13
12
|
class Bond::ObjectMission < Bond::Mission
|
14
|
-
#:stopdoc:
|
15
13
|
OBJECTS = %w<\S+> + Bond::Mission::OBJECTS
|
16
14
|
CONDITION = '(OBJECTS)\.(\w*(?:\?|!)?)$'
|
17
|
-
def initialize(options={})
|
15
|
+
def initialize(options={}) #@private
|
18
16
|
@object_condition = /^#{options[:object]}$/
|
19
17
|
options[:on] ||= Regexp.new condition_with_objects
|
20
18
|
super
|
21
19
|
end
|
22
20
|
|
21
|
+
def match_message #@private
|
22
|
+
"Matches completion for object with ancestor matching #{@object_condition.inspect}."
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
23
26
|
def unique_id
|
24
27
|
"#{@object_condition.inspect}+#{@on.inspect}"
|
25
28
|
end
|
@@ -38,9 +41,4 @@ class Bond::ObjectMission < Bond::Mission
|
|
38
41
|
def default_action(obj)
|
39
42
|
obj.methods.map {|e| e.to_s} - OPERATORS
|
40
43
|
end
|
41
|
-
|
42
|
-
def match_message
|
43
|
-
"Matches completion for object with ancestor matching #{@object_condition.inspect}."
|
44
|
-
end
|
45
|
-
#:startdoc:
|
46
44
|
end
|
@@ -7,7 +7,7 @@ module Bond
|
|
7
7
|
OBJECTS = Mission::OBJECTS + %w{\S+}
|
8
8
|
CONDITION = %q{(OBJECTS)\s*(METHODS)\s*(['":])?(.*)$}
|
9
9
|
|
10
|
-
|
10
|
+
protected
|
11
11
|
def current_methods
|
12
12
|
(OPERATORS & MethodMission.action_methods) + ['[']
|
13
13
|
end
|
@@ -21,6 +21,5 @@ module Bond
|
|
21
21
|
@completion_prefix, typed = input.to_s.sub(/#{Regexp.quote(@matched[-1])}$/, ''), @matched[-1]
|
22
22
|
create_input typed, :object=>@evaled_object, :argument=>1
|
23
23
|
end
|
24
|
-
#:startdoc:
|
25
24
|
end
|
26
25
|
end
|
data/lib/bond/rc.rb
CHANGED
@@ -18,9 +18,9 @@ module Bond
|
|
18
18
|
module Rc
|
19
19
|
extend self, Search
|
20
20
|
|
21
|
-
# See Bond
|
21
|
+
# See {Bond#complete}
|
22
22
|
def complete(*args, &block); M.complete(*args, &block); end
|
23
|
-
# See Bond
|
23
|
+
# See {Bond#recomplete}
|
24
24
|
def recomplete(*args, &block); M.recomplete(*args, &block); end
|
25
25
|
|
26
26
|
# Action method with search which returns array of files that match current input.
|
data/lib/bond/readline.rb
CHANGED
@@ -24,24 +24,7 @@ module Bond
|
|
24
24
|
def load_extension
|
25
25
|
require 'readline_line_buffer'
|
26
26
|
rescue LoadError
|
27
|
-
$stderr.puts "Bond Error: Failed to load readline_line_buffer
|
28
|
-
require 'inline'
|
29
|
-
eval %[
|
30
|
-
module ::Readline
|
31
|
-
inline do |builder|
|
32
|
-
%w(<errno.h> <stdio.h> <readline/readline.h>).each{|h| builder.include h }
|
33
|
-
builder.c_raw_singleton <<-EOC
|
34
|
-
static VALUE line_buffer(VALUE self)
|
35
|
-
{
|
36
|
-
rb_secure(4);
|
37
|
-
if (rl_line_buffer == NULL)
|
38
|
-
return Qnil;
|
39
|
-
return rb_tainted_str_new2(rl_line_buffer);
|
40
|
-
}
|
41
|
-
EOC
|
42
|
-
end
|
43
|
-
end
|
44
|
-
]
|
27
|
+
$stderr.puts "Bond Error: Failed to load readline_line_buffer.bundle. Ensure that it exists and was built correctly."
|
45
28
|
end
|
46
29
|
|
47
30
|
# Returns full line of what the user has typed.
|
data/lib/bond/search.rb
CHANGED
@@ -37,7 +37,7 @@ module Bond
|
|
37
37
|
# at the beginning of an underscored word. For example, to choose the first completion between 'so_long'
|
38
38
|
# and 'so_larger', type 's_lo'.
|
39
39
|
def underscore_search(input, list)
|
40
|
-
if input[/_(
|
40
|
+
if input[/_([^_]+)$/]
|
41
41
|
regex = input.split('_').map {|e| Regexp.escape(e) }.join("([^_]+)?_")
|
42
42
|
list.select {|e| e =~ /^#{regex}/ }
|
43
43
|
else
|
data/lib/bond/version.rb
CHANGED
data/lib/bond/yard.rb
CHANGED
@@ -4,7 +4,7 @@ module Bond
|
|
4
4
|
module Yard
|
5
5
|
extend self
|
6
6
|
|
7
|
-
#
|
7
|
+
# Loads completions for yard gem(s)
|
8
8
|
def load_yard_gems(*gems)
|
9
9
|
@options = gems[-1].is_a?(Hash) ? gems.pop : {}
|
10
10
|
require 'yard'
|
@@ -14,6 +14,7 @@ module Bond
|
|
14
14
|
$stderr.puts "Bond Error: yard gem (version >= 0.5.2) not installed "
|
15
15
|
end
|
16
16
|
|
17
|
+
protected
|
17
18
|
def load_yard_gem(rubygem)
|
18
19
|
raise("Unable to find gem.") unless (yardoc = find_yardoc(rubygem))
|
19
20
|
completion_file = File.join(dir('yard_completions'), rubygem+'.rb')
|
@@ -68,6 +69,5 @@ module Bond
|
|
68
69
|
%Q[complete(:method=>'#{meth}') {\n #{options.inspect}\n}]
|
69
70
|
end.join("\n")
|
70
71
|
end
|
71
|
-
#:startdoc:
|
72
72
|
end
|
73
73
|
end
|
data/test/deps.rip
ADDED
data/test/search_test.rb
CHANGED
@@ -38,6 +38,14 @@ describe "Search" do
|
|
38
38
|
tab("blah i").should == ["include?", "instance_variable_defined?", "include_and_exclude?"]
|
39
39
|
end
|
40
40
|
|
41
|
+
it "underscore search autocompletes strings starting with __" do
|
42
|
+
completions = ["include?", "__id__", "__send__"]
|
43
|
+
complete(:on=>/blah/, :search=>:underscore) { completions }
|
44
|
+
tab('blah _').should == ["__id__", "__send__"]
|
45
|
+
tab('blah __').should == ["__id__", "__send__"]
|
46
|
+
tab('blah __i').should == ["__id__"]
|
47
|
+
end
|
48
|
+
|
41
49
|
it "underscore search can match first unique strings of each underscored word" do
|
42
50
|
completions = %w{so_long so_larger so_louder}
|
43
51
|
complete(:on=>/blah/, :search=>:underscore) { completions }
|
data/test/test_helper.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'bacon'
|
2
|
-
require
|
2
|
+
require 'bacon/bits'
|
3
3
|
require 'mocha'
|
4
4
|
require 'mocha-on-bacon'
|
5
5
|
require 'bond'
|
@@ -56,9 +56,8 @@ end
|
|
56
56
|
|
57
57
|
class Bacon::Context
|
58
58
|
include TestHelpers
|
59
|
-
include BaconExtensions
|
60
59
|
end
|
61
60
|
|
62
61
|
# Default settings
|
63
62
|
Bond::M.debrief(:readline_plugin=>TestHelpers.valid_readline_plugin, :debug=>true)
|
64
|
-
include Bond
|
63
|
+
include Bond
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bond
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 19
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 0
|
7
8
|
- 2
|
8
|
-
-
|
9
|
-
version: 0.2.
|
9
|
+
- 2
|
10
|
+
version: 0.2.2
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Gabriel Horner
|
@@ -14,7 +15,7 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2010-
|
18
|
+
date: 2010-07-17 00:00:00 -04:00
|
18
19
|
default_executable:
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
@@ -25,9 +26,12 @@ dependencies:
|
|
25
26
|
requirements:
|
26
27
|
- - ">="
|
27
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 19
|
28
30
|
segments:
|
31
|
+
- 1
|
32
|
+
- 1
|
29
33
|
- 0
|
30
|
-
version:
|
34
|
+
version: 1.1.0
|
31
35
|
type: :development
|
32
36
|
version_requirements: *id001
|
33
37
|
- !ruby/object:Gem::Dependency
|
@@ -38,9 +42,12 @@ dependencies:
|
|
38
42
|
requirements:
|
39
43
|
- - ">="
|
40
44
|
- !ruby/object:Gem::Version
|
45
|
+
hash: 43
|
41
46
|
segments:
|
42
47
|
- 0
|
43
|
-
|
48
|
+
- 9
|
49
|
+
- 8
|
50
|
+
version: 0.9.8
|
44
51
|
type: :development
|
45
52
|
version_requirements: *id002
|
46
53
|
- !ruby/object:Gem::Dependency
|
@@ -51,11 +58,26 @@ dependencies:
|
|
51
58
|
requirements:
|
52
59
|
- - ">="
|
53
60
|
- !ruby/object:Gem::Version
|
61
|
+
hash: 3
|
54
62
|
segments:
|
55
63
|
- 0
|
56
64
|
version: "0"
|
57
65
|
type: :development
|
58
66
|
version_requirements: *id003
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: bacon-bits
|
69
|
+
prerelease: false
|
70
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
hash: 3
|
76
|
+
segments:
|
77
|
+
- 0
|
78
|
+
version: "0"
|
79
|
+
type: :development
|
80
|
+
version_requirements: *id004
|
59
81
|
description: "Bond is on a mission to improve irb\xE2\x80\x99s autocompletion. Aside from doing everything irb\xE2\x80\x99s can do and fixing its quirks, Bond can autocomplete argument(s) to methods, uniquely completing per module, per method and per argument. Bond brings irb\xE2\x80\x99s completion closer to bash/zsh as it provides a configuration system and a DSL for creating custom completions and completion rules. With this configuration system, users can customize their irb autocompletions and share it with others. Bond can also generate completions from yard documentation and load completions that ship with gems. Bond is able to offer more than irb\xE2\x80\x99s completion since it uses a Readline C extension to get the full line of input when completing as opposed to irb\xE2\x80\x99s last-word approach."
|
60
82
|
email: gabriel.horner@gmail.com
|
61
83
|
executables: []
|
@@ -93,7 +115,6 @@ files:
|
|
93
115
|
- lib/bond.rb
|
94
116
|
- test/agent_test.rb
|
95
117
|
- test/anywhere_mission_test.rb
|
96
|
-
- test/bacon_extensions.rb
|
97
118
|
- test/bond_test.rb
|
98
119
|
- test/completion_test.rb
|
99
120
|
- test/completions_test.rb
|
@@ -110,14 +131,16 @@ files:
|
|
110
131
|
- ext/readline_line_buffer/extconf.rb
|
111
132
|
- ext/readline_line_buffer/readline_line_buffer.c
|
112
133
|
- Rakefile
|
113
|
-
- gemspec
|
114
|
-
|
134
|
+
- .gemspec
|
135
|
+
- test/deps.rip
|
136
|
+
has_rdoc: yard
|
115
137
|
homepage: http://tagaholic.me/bond/
|
116
|
-
licenses:
|
117
|
-
|
138
|
+
licenses:
|
139
|
+
- MIT
|
118
140
|
post_install_message:
|
119
|
-
rdoc_options:
|
120
|
-
|
141
|
+
rdoc_options:
|
142
|
+
- --title
|
143
|
+
- Bond 0.2.2 Documentation
|
121
144
|
require_paths:
|
122
145
|
- lib
|
123
146
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -125,6 +148,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
125
148
|
requirements:
|
126
149
|
- - ">="
|
127
150
|
- !ruby/object:Gem::Version
|
151
|
+
hash: 3
|
128
152
|
segments:
|
129
153
|
- 0
|
130
154
|
version: "0"
|
@@ -133,6 +157,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
133
157
|
requirements:
|
134
158
|
- - ">="
|
135
159
|
- !ruby/object:Gem::Version
|
160
|
+
hash: 23
|
136
161
|
segments:
|
137
162
|
- 1
|
138
163
|
- 3
|
data/test/bacon_extensions.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
module BaconExtensions
|
2
|
-
def self.included(mod)
|
3
|
-
mod.module_eval do
|
4
|
-
# nested context methods automatically inherit methods from parent contexts
|
5
|
-
def describe(*args, &block)
|
6
|
-
context = Bacon::Context.new(args.join(' '), &block)
|
7
|
-
(parent_context = self).methods(false).each {|e|
|
8
|
-
class<<context; self end.send(:define_method, e) {|*args| parent_context.send(e, *args)}
|
9
|
-
}
|
10
|
-
@before.each { |b| context.before(&b) }
|
11
|
-
@after.each { |b| context.after(&b) }
|
12
|
-
context.run
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def xit(*args); end
|
18
|
-
def xdescribe(*args); end
|
19
|
-
def before_all; yield; end
|
20
|
-
def after_all; yield; end
|
21
|
-
def assert(description, &block)
|
22
|
-
it(description) do
|
23
|
-
block.call.should == true
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|