yap-shell 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.travis.lock +104 -0
  3. data/bin/yap +6 -0
  4. data/bin/yap-dev +37 -0
  5. data/lib/yap.rb +29 -39
  6. data/lib/yap/addon.rb +24 -0
  7. data/lib/yap/addon/base.rb +52 -0
  8. data/lib/yap/addon/export_as.rb +12 -0
  9. data/lib/yap/addon/loader.rb +84 -0
  10. data/lib/yap/addon/path.rb +56 -0
  11. data/lib/yap/addon/rc_file.rb +21 -0
  12. data/lib/yap/addon/reference.rb +22 -0
  13. data/lib/yap/cli.rb +4 -0
  14. data/lib/yap/cli/commands.rb +6 -0
  15. data/lib/yap/cli/commands/addon.rb +14 -0
  16. data/lib/yap/cli/commands/addon/disable.rb +35 -0
  17. data/lib/yap/cli/commands/addon/enable.rb +35 -0
  18. data/lib/yap/cli/commands/addon/list.rb +37 -0
  19. data/lib/yap/cli/commands/addon/search.rb +99 -0
  20. data/lib/yap/cli/commands/generate.rb +13 -0
  21. data/lib/yap/cli/commands/generate/addon.rb +258 -0
  22. data/lib/yap/cli/commands/generate/addonrb.template +22 -0
  23. data/lib/yap/cli/commands/generate/gemspec.template +25 -0
  24. data/lib/yap/cli/commands/generate/license.template +21 -0
  25. data/lib/yap/cli/commands/generate/rakefile.template +6 -0
  26. data/lib/yap/cli/commands/generate/readme.template +40 -0
  27. data/lib/yap/cli/options.rb +162 -0
  28. data/lib/yap/cli/options/addon.rb +64 -0
  29. data/lib/yap/cli/options/addon/disable.rb +62 -0
  30. data/lib/yap/cli/options/addon/enable.rb +63 -0
  31. data/lib/yap/cli/options/addon/list.rb +65 -0
  32. data/lib/yap/cli/options/addon/search.rb +76 -0
  33. data/lib/yap/cli/options/generate.rb +59 -0
  34. data/lib/yap/cli/options/generate/addon.rb +63 -0
  35. data/lib/yap/configuration.rb +10 -3
  36. data/lib/yap/gem_helper.rb +195 -0
  37. data/lib/yap/gem_tasks.rb +6 -0
  38. data/lib/yap/shell.rb +1 -1
  39. data/lib/yap/shell/repl.rb +1 -1
  40. data/lib/yap/shell/version.rb +1 -1
  41. data/lib/yap/world.rb +45 -7
  42. data/rcfiles/yaprc +90 -10
  43. data/spec/features/addons/generating_an_addon_spec.rb +55 -0
  44. data/spec/features/addons/using_an_addon_spec.rb +182 -0
  45. data/spec/features/aliases_spec.rb +6 -6
  46. data/spec/features/grouping_spec.rb +18 -18
  47. data/spec/features/line_editing_spec.rb +9 -1
  48. data/spec/features/redirection_spec.rb +12 -3
  49. data/spec/spec_helper.rb +21 -11
  50. data/spec/support/matchers/have_printed.rb +38 -0
  51. data/spec/support/yap_spec_dsl.rb +24 -6
  52. data/yap-shell.gemspec +6 -11
  53. metadata +51 -45
  54. data/addons/history/README.md +0 -16
  55. data/addons/history/history.rb +0 -58
  56. data/addons/history_search/history_search.rb +0 -197
  57. data/addons/keyboard_macros/keyboard_macros.rb +0 -425
  58. data/addons/keyboard_macros/lib/keyboard_macros/cycle.rb +0 -38
  59. data/addons/prompt/Gemfile +0 -1
  60. data/addons/prompt/right_prompt.rb +0 -17
  61. data/addons/prompt_updates/prompt_updates.rb +0 -28
  62. data/addons/tab_completion/Gemfile +0 -0
  63. data/addons/tab_completion/lib/tab_completion/basic_completion.rb +0 -151
  64. data/addons/tab_completion/lib/tab_completion/completer.rb +0 -62
  65. data/addons/tab_completion/lib/tab_completion/custom_completion.rb +0 -33
  66. data/addons/tab_completion/lib/tab_completion/dsl_methods.rb +0 -7
  67. data/addons/tab_completion/tab_completion.rb +0 -174
  68. data/lib/tasks/addons.rake +0 -97
  69. data/lib/yap/world/addons.rb +0 -181
@@ -0,0 +1,22 @@
1
+ require 'yap/addon'
2
+ require '%{addon_dir}/version'
3
+
4
+ module %{constant_name}
5
+ class Addon < ::Yap::Addon::Base
6
+ self.export_as :%{export_as}
7
+
8
+ def initialize_world(world)
9
+ @world = world
10
+
11
+ # Initialize your addon here. A few helpful things:
12
+ #
13
+ # @world is an Yap::World instance and it brings together
14
+ # all the things you may want to interact with. E.g.
15
+ # aliases, builtins, env, shell_commands, key bindings,
16
+ # editor, prompt, etc.
17
+ #
18
+ # For more information see:
19
+ # https://github.com/zdennis/yap-shell/wiki/Addons
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,25 @@
1
+ require File.dirname(__FILE__) + '/lib/%{addon_dir}/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = '%{addon_dir}'
5
+ spec.version = %{constant_name}::VERSION
6
+ spec.authors = ['Your name']
7
+ spec.email = '%{email}'
8
+ spec.date = Date.today.to_s
9
+
10
+ spec.summary = '%{summary}'
11
+ spec.description = '%{description}'
12
+ spec.homepage = '%{homepage}'
13
+ spec.license = '%{license}'
14
+
15
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(/^(test|spec|features)\//) }
16
+ spec.bindir = "exe"
17
+ spec.executables = spec.files.grep(/^exe\//) { |f| File.basename(f) }
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_dependency "yap-shell", "~> %{yap_version}"
21
+
22
+ spec.add_development_dependency "bundler", "~> %{bundler_version}"
23
+ spec.add_development_dependency "rake", "~> %{rake_version}"
24
+ spec.add_development_dependency "rspec", "~> %{rspec_version}"
25
+ end
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 %{username}
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,6 @@
1
+ require "yap/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,40 @@
1
+ # %{addon_name} for yap-shell
2
+
3
+ Welcome to your new yap addon! In this directory, you'll find the files you need to be able to package up your addon into a gem. Put your Ruby code in the file `%{lib_addon_path}`.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem '%{gem_safe_addon_name}'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install %{gem_safe_addon_name}
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/%{gem_safe_addon_name}.
36
+
37
+
38
+ ## License
39
+
40
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,162 @@
1
+ require 'pathname'
2
+ require 'yap/cli/options'
3
+
4
+ module Yap
5
+ module Cli
6
+ module OptionsLoader
7
+
8
+ def load_command(path)
9
+ load_constant_from_path Pathname.new('yap/cli/commands').join(path)
10
+ end
11
+
12
+ def load_constant_from_path(path)
13
+ requiring_parts = []
14
+ path_parts = path.to_s.split('/')
15
+ requiring_path = nil
16
+ constant = path_parts.reduce(Object) do |constant, path_part|
17
+ requiring_parts << path_part
18
+ file2load = Yap.root.join('lib', requiring_parts.join('/') + "*.rb")
19
+ requiring_path = Dir[ file2load ].sort.first
20
+ if requiring_path
21
+ require requiring_path
22
+ path_part = File.basename(requiring_path).sub(/\.rb$/, '')
23
+ requiring_parts.pop
24
+ requiring_parts.push path_part
25
+ constant_name = path_part.capitalize
26
+ if constant.const_defined?(constant_name)
27
+ constant = constant.const_get(constant_name)
28
+ else
29
+ fail "Couldn't find #{path_part} in #{constant}"
30
+ end
31
+ else
32
+ fail LoadError, "Couldn't load any file for #{file2load}"
33
+ end
34
+ end
35
+ Treefell['shell'].puts "#{inspect} loaded: #{constant}"
36
+ constant
37
+ end
38
+
39
+ def load_relative_constant(path_str)
40
+ base_path = self.class.name.downcase.gsub(/::/, '/')
41
+ require_path = Pathname.new(base_path)
42
+ load_constant_from_path require_path.join(path_str).to_s
43
+ end
44
+ end
45
+
46
+ class Options
47
+ include OptionsLoader
48
+
49
+ attr_reader :options
50
+
51
+ def initialize(options: {})
52
+ @options = options
53
+ @commands = []
54
+ end
55
+
56
+ def [](key)
57
+ @options[key]
58
+ end
59
+
60
+ def commands
61
+ @commands.dup.freeze
62
+ end
63
+
64
+ def parse(args)
65
+ option_parser.order!(args)
66
+ options_instance = self
67
+
68
+ Yap.configuration.run_shell = false if args.any?
69
+
70
+ scope = []
71
+ require_path = Pathname.new("yap/cli/options")
72
+ args_processed = []
73
+
74
+ while args.any?
75
+ if args_processed == args
76
+ puts "Unknown option(s*): #{scope.concat([args.first]).join(' ')}"
77
+ exit 1
78
+ end
79
+ args_processed = args.dup
80
+
81
+ option_str = args.shift
82
+ current_scope = scope + [option_str]
83
+
84
+
85
+ begin
86
+ options_class = load_relative_constant current_scope.join('/')
87
+ options_instance = options_class.new(options: options)
88
+ options[:option] = options_instance
89
+ options_instance.parse(args)
90
+ @commands << options_instance.command
91
+
92
+ scope << option_str
93
+ rescue LoadError => ex
94
+ puts "Unknown option: #{option_str}"
95
+ puts
96
+ puts options_instance.help_message
97
+ exit 1
98
+ end
99
+ end
100
+ end
101
+
102
+ def help_message
103
+ option_parse.to_s
104
+ end
105
+
106
+ private
107
+
108
+ def option_parser
109
+ OptionParser.new do |opts|
110
+ opts.banner = <<-TEXT.gsub(/^\s*\|/, '')
111
+ |Usage: #{opts.program_name} [option|command]
112
+ |
113
+ |When a command is omitted the yap shell starts an interactive
114
+ |session. Otherwise, the command is executed.
115
+ |
116
+ |Shell options:
117
+ TEXT
118
+ opts.on('-h', '--help', 'Prints this help') do
119
+ puts opts
120
+ commands = Dir[ File.dirname(__FILE__) + '/commands/*.rb' ].map do |path|
121
+ command = File.basename(path).sub(/\.rb$/, '')
122
+ "#{command}: #{Term::ANSIColor.cyan(opts.program_name + ' ' + command + ' --help')}"
123
+ end
124
+ commands = %| #{commands.join("\n ")}|
125
+ puts <<-TEXT.gsub(/^\s*\|/, '')
126
+ |
127
+ |Commands:
128
+ |
129
+ |#{commands}
130
+ |
131
+ TEXT
132
+ exit 0
133
+ end
134
+
135
+ opts.on('--skip-first-time', 'Disables creating ~/.yap directory on shell startup') do
136
+ Yap.configuration.skip_first_time = true
137
+ end
138
+
139
+ opts.on('--addon-paths=PATHS', 'Paths to directories containing addons (comma-separated). This overwrites the default addon paths.') do |paths|
140
+ Yap.configuration.addon_paths = paths.split(',').map(&:strip)
141
+ end
142
+
143
+ opts.on('--no-addons', 'Disables auto-loading addons on shell startup') do
144
+ Yap.configuration.use_addons = false
145
+ end
146
+
147
+ opts.on('--no-history', 'Disables auto-loading or saving history') do
148
+ Yap.configuration.use_history = false
149
+ end
150
+
151
+ opts.on('--rcfiles=PATHS', 'Paths to Yap rcfiles in the order they should load (comma-separated). This overwrites the default rcfiles.') do |paths|
152
+ Yap.configuration.rcfiles = paths.split(',').map(&:strip)
153
+ end
154
+
155
+ opts.on('--no-rcfiles', 'Disables auto-loading rcfiles on shell startup') do
156
+ Yap.configuration.use_rcfiles = false
157
+ end
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,64 @@
1
+ module Yap
2
+ module Cli
3
+ class Options::Addon
4
+ include OptionsLoader
5
+
6
+ attr_reader :command, :options
7
+
8
+ def initialize(options:)
9
+ @options = options
10
+ end
11
+
12
+ def parse(args)
13
+ option_parser.order!(args)
14
+ end
15
+
16
+ def command
17
+ @command
18
+ end
19
+
20
+ def help_message
21
+ option_parser.to_s
22
+ end
23
+
24
+ private
25
+
26
+ def set_command(command)
27
+ @command = load_command('addon').new
28
+ end
29
+
30
+ def option_parser
31
+ OptionParser.new do |opts|
32
+ opts.banner = <<-TEXT.gsub(/^\s*\|/, '')
33
+ |Usage: #{opts.program_name} addon [command] [addon-name] [options]
34
+ |
35
+ |#{Term::ANSIColor.cyan('yap addon')} can be used to control yap addons
36
+ |
37
+ |Generate commands:
38
+ |
39
+ | #{Term::ANSIColor.yellow('enable')} - enables a yap addon
40
+ | #{Term::ANSIColor.yellow('disable')} - disables a yap addon
41
+ |
42
+ |Generate options:
43
+ TEXT
44
+
45
+ opts.on('-h', '--help', 'Prints this help') do
46
+ puts opts
47
+ puts
48
+ puts <<-TEXT.gsub(/^\s*\|/, '')
49
+ |Example: disabling an addon
50
+ |
51
+ | #{opts.program_name} addon disable foo-bar
52
+ |
53
+ |Example: enabling an addon
54
+ |
55
+ | #{opts.program_name} addon enable foo-bar
56
+ |
57
+ TEXT
58
+ exit 0
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,62 @@
1
+ module Yap
2
+ module Cli
3
+ class Options::Addon::Disable
4
+ include OptionsLoader
5
+
6
+ attr_reader :command, :options
7
+
8
+ def initialize(options:)
9
+ @options = options
10
+ end
11
+
12
+ def parse(args)
13
+ @addon_name = args.shift unless args.first =~ /^-/
14
+ unless @addon_name
15
+ args.unshift '--help'
16
+ STDERR.puts "Missing addon-name!"
17
+ @exit_status = 1
18
+ puts
19
+ end
20
+ option_parser.order!(args)
21
+ end
22
+
23
+ def command
24
+ @command ||= load_command('addon/disable').new(@addon_name)
25
+ end
26
+
27
+ def help_message
28
+ option_parser.to_s
29
+ end
30
+
31
+ private
32
+
33
+ def option_parser
34
+ OptionParser.new do |opts|
35
+ opts.banner = <<-TEXT.gsub(/^\s*\|/, '')
36
+ |Usage: #{opts.program_name} addon disable [addon-name] [options]
37
+ |
38
+ |#{Term::ANSIColor.cyan('yap addon disable')} can be used to disable yap addons.
39
+ |
40
+ |Addon disable options:
41
+ TEXT
42
+
43
+ opts.on('-h', '--help', 'Prints this help') do
44
+ puts opts
45
+ puts
46
+ puts <<-TEXT.gsub(/^\s*\|/, '')
47
+ |Example: Disable an addon
48
+ |
49
+ | #{opts.program_name} addon disable magical-key-bindings
50
+ |
51
+ |Example: Enable an addon
52
+ |
53
+ | #{opts.program_name} addon disable magical-key-bindings
54
+ |
55
+ TEXT
56
+ exit @exit_status
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,63 @@
1
+ module Yap
2
+ module Cli
3
+ class Options::Addon::Enable
4
+ include OptionsLoader
5
+
6
+ attr_reader :command, :options
7
+
8
+ def initialize(options:)
9
+ @options = options
10
+ @exit_status = 0
11
+ end
12
+
13
+ def parse(args)
14
+ @addon_name = args.shift unless args.first =~ /^-/
15
+ unless @addon_name
16
+ args.unshift '--help'
17
+ STDERR.puts "Missing addon-name!"
18
+ @exit_status = 1
19
+ puts
20
+ end
21
+ option_parser.order!(args)
22
+ end
23
+
24
+ def command
25
+ @command ||= load_command('addon/enable').new(@addon_name)
26
+ end
27
+
28
+ def help_message
29
+ option_parser.to_s
30
+ end
31
+
32
+ private
33
+
34
+ def option_parser
35
+ OptionParser.new do |opts|
36
+ opts.banner = <<-TEXT.gsub(/^\s*\|/, '')
37
+ |Usage: #{opts.program_name} addon enable [addon-name] [options]
38
+ |
39
+ |#{Term::ANSIColor.cyan('yap addon enable')} can be used to enable yap addons.
40
+ |
41
+ |Addon enable options:
42
+ TEXT
43
+
44
+ opts.on('-h', '--help', 'Prints this help') do
45
+ puts opts
46
+ puts
47
+ puts <<-TEXT.gsub(/^\s*\|/, '')
48
+ |Example: Disable an addon
49
+ |
50
+ | #{opts.program_name} addon disable magical-key-bindings
51
+ |
52
+ |Example: Enable an addon
53
+ |
54
+ | #{opts.program_name} addon enable magical-key-bindings
55
+ |
56
+ TEXT
57
+ exit @exit_status
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end