ripl-fresh 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gemspec ADDED
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'rubygems' unless defined?(::Gem)
3
+ require File.dirname(__FILE__) + "/lib/ripl/fresh"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "ripl-fresh"
7
+ s.version = Ripl::Fresh::VERSION
8
+ s.authors = ["Jan Lelis"]
9
+ s.email = "mail@janlelis.de"
10
+ s.homepage = "http://github.com/janlelis/fresh"
11
+ s.summary = "Fresh Ruby Enhanced SHell"
12
+ s.description = "Fresh Ruby Enhanced SHell automatically detects, if your current command should be Ruby or a system command."
13
+ s.required_rubygems_version = ">= 1.3.6"
14
+ s.executables = ['ripl-fresh', 'fresh']
15
+ s.add_dependency 'ripl', '>= 0.2.5'
16
+ s.files = Dir.glob(%w[{lib,test}/**/*.rb bin/* [A-Z]*.{txt,rdoc} ext/**/*.{rb,c} **/deps.rip]) + %w{Rakefile .gemspec}
17
+ s.extra_rdoc_files = ["README.rdoc", "LICENSE"]
18
+ s.license = 'MIT'
19
+ end
data/CHANGELOG.rdoc ADDED
@@ -0,0 +1,2 @@
1
+ == 0.1.0
2
+ * Initial release
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT LICENSE
2
+
3
+ Copyright (c) 2010 Jan Lelis
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,76 @@
1
+ = Fresh Ruby Enhanced SHell
2
+
3
+ We love Ruby. We love the command line. So... the shell needs to be rubyfied ;).
4
+
5
+ == How does it work?
6
+
7
+ Basically, fresh is a Ruby console like irb: Enter a Ruby expression and it gets evaluated. But not everything is interpreted as Ruby: The input is thrown against a regular expression to determine if it is meant to be a Ruby or a system command.
8
+
9
+ May sound like voodoo, but works surprisingly well in practice ;).
10
+
11
+ == Get fresh
12
+
13
+ Install the gem with:
14
+
15
+ gem install ripl-fresh
16
+
17
+ Start it with:
18
+
19
+ ripl fresh
20
+
21
+ (or just <tt>fresh</tt>)
22
+
23
+ == Usage & configuration options
24
+
25
+ The main regexp to determine if the command should be interpreted as system command is similar to this one: <tt>/^[a-z_-]+\s+.*/i</tt> (match a single word followed by at least one space). It can be adjusted in <tt>Ripl.config[:fresh_system_regexp]</tt>.
26
+
27
+ Of course, there are also exceptions that should still get interpreted as Ruby (e.g. <tt>def </tt>). These can be found and modified in the <tt>Ripl.config[:fresh_ruby_words]</tt> array.
28
+
29
+ Single words get interpreted as Ruby by default. You can set your "single system words" in <tt>Ripl.config[:fresh_system_words]</tt> (e.g. <tt>ls</tt>).
30
+
31
+ There is also a third kind of command mode (besides <tt>:ruby</tt> and <tt>:system</tt>): <tt>:mixed</tt>. They look and feel like system commands, but redirect to the Ruby method described by the first word. You can register them in <tt> Ripl.config[:fresh_mixed_words]</tt> (e.g. +cd+).
32
+
33
+ Of course, there is a way to explicitly set your command mode: You can prefix your input with a space to force Ruby mode as well as you can prefix it with <tt>^</tt> to force system mode. The strings used for this can be customized in <tt>Ripl.config[:fresh_system_prefix]</tt> and <tt>Ripl.config[:fresh_ruby_prefix]</tt>.
34
+
35
+ You need to take a look at <tt>get_input</tt> method in the source file to 100% understand the command mode detection way.
36
+
37
+ === Defaults
38
+
39
+ # prefixes
40
+ Ripl.config[:fresh_system_prefix] = %w[^]
41
+ Ripl.config[:fresh_ruby_prefix] = [' ']
42
+ # single words
43
+ Ripl.config[:fresh_system_words] = %w[top ls]
44
+ Ripl.config[:fresh_ruby_words] = %w[begin case class def for if module undef unless until while puts warn print p pp ap raise fail loop require load lambda proc system]
45
+ # catch mix words
46
+ Ripl.config[:fresh_mixed_words] = %w[cd]
47
+ # main regexp
48
+ Ripl.config[:fresh_system_regexp] = /^([a-z_-]+)\s+(?!(?:[=%*]|!=|\+=|-=|\/=))/i
49
+
50
+ == Customization
51
+
52
+ Besides customizing your fresh with the configuration options, you can further enhance it with Ruby plugins, because it's based on {ripl}[https://github.com/cldwalker/ripl]. Just install the <tt>ripl-plugin_name</tt> and add it to your <tt>.riplrc</tt> file:
53
+
54
+ require 'ripl/plugin_name'
55
+
56
+ Currently, most {plugins}[http://github.com/cldwalker/ripl-color_error] {enable}[http://github.com/janlelis/ripl-color_result] {colors}[http://github.com/janlelis/ripl-color_streams] and {IRB}[http://github.com/janlelis/ripl-multi_line] -{like}[http://github.com/cldwalker/ripl-commands] {features}[http://github.com/cldwalker/ripl-irb].
57
+
58
+ == TODO
59
+
60
+ There are lots of things which can get better:
61
+
62
+ * Improve auto-completion
63
+ * More cool (and colorful?) <tt>:mixed</tt> Ruby commands
64
+ * Improve interaction between system and ruby commands
65
+ * <tt>ripl-multi_line</tt> for system commands
66
+ * Result of system commands should be available for ruby, not only printed to stdout
67
+ * Improve default configuration
68
+ * Fresh ideas
69
+
70
+ Feel free to fork in your improvements ;)
71
+
72
+ == Copyright
73
+
74
+ Copyright (c) 2010 Jan Lelis <http://code-needs-smileys.com> released under the MIT license.
75
+
76
+ J-_-L
data/Rakefile ADDED
@@ -0,0 +1,28 @@
1
+ require 'rake'
2
+ require 'fileutils'
3
+
4
+ def gemspec
5
+ @gemspec ||= eval(File.read('.gemspec'), binding, '.gemspec')
6
+ end
7
+
8
+ desc "Build the gem"
9
+ task :gem=>:gemspec do
10
+ sh "gem build .gemspec"
11
+ FileUtils.mkdir_p 'pkg'
12
+ FileUtils.mv "#{gemspec.name}-#{gemspec.version}.gem", 'pkg'
13
+ end
14
+
15
+ desc "Install the gem locally"
16
+ task :install => :gem do
17
+ sh %{gem install pkg/#{gemspec.name}-#{gemspec.version}}
18
+ end
19
+
20
+ desc "Generate the gemspec"
21
+ task :generate do
22
+ puts gemspec.to_ruby
23
+ end
24
+
25
+ desc "Validate the gemspec"
26
+ task :gemspec do
27
+ gemspec.validate
28
+ end
data/bin/fresh ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ exec File.expand_path( 'ripl-fresh', File.dirname(__FILE__) )
data/bin/ripl-fresh ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'ripl'
4
+ require 'ripl/fresh'
5
+ Ripl.start
data/deps.rip ADDED
@@ -0,0 +1 @@
1
+ ripl >=0.2.5
@@ -0,0 +1,17 @@
1
+ # no advanced auto completion, yet
2
+ # only do some file completion - because it's the most important completion ;)
3
+
4
+ require 'readline'
5
+
6
+ file_completion = proc{ |input|
7
+ ::Readline::FILENAME_COMPLETION_PROC.call(input) || []
8
+ }
9
+
10
+ complete :on => Ripl.config[:fresh_system_regexp],
11
+ :search=>false,
12
+ &file_completion
13
+
14
+ # TODO fires only when space after ^
15
+ complete :on => Ripl::Fresh.option_array_to_regexp( Ripl.config[:fresh_system_prefix] ),
16
+ :search=>false,
17
+ &file_completion
File without changes
data/lib/ripl/fresh.rb ADDED
@@ -0,0 +1,156 @@
1
+ require 'ripl'
2
+ require 'fileutils'
3
+
4
+ module Ripl
5
+ module Fresh
6
+ VERSION = '0.1.0'
7
+
8
+ class << self
9
+ # helper to parse options
10
+ def option_array_to_regexp(option)
11
+ case option
12
+ when Regexp # note: some options still _have_ to be arrays
13
+ option
14
+ when Array, Set
15
+ /^(#{
16
+ option.map{ |char|
17
+ Regexp.escape char.to_s
18
+ }*'|'
19
+ })/
20
+ else
21
+ option.to_s
22
+ end
23
+ end
24
+ end
25
+
26
+ module Shell
27
+ # setup Fresh
28
+ def before_loop
29
+ @command_mode = :ruby
30
+ super
31
+ # register bond completion
32
+ Ripl.config[:completion][:gems] ||= []
33
+ Ripl.config[:completion][:gems] << 'ripl-fresh'
34
+ # load :mixed commands
35
+ require File.dirname(__FILE__) + '/fresh/commands'
36
+ end
37
+
38
+ # determine @command_mode
39
+ def get_input
40
+ input = super
41
+
42
+ return input if @buffer # ripl-multi_line
43
+
44
+ @command_mode = case input
45
+ # force system with a single ^
46
+ when Ripl::Fresh.option_array_to_regexp( Ripl.config[:fresh_system_prefix] )
47
+ input = input[$1.size..-1] # TODO refactor, too hacky?
48
+ :system
49
+ # force ruby with a space
50
+ when Ripl::Fresh.option_array_to_regexp( Ripl.config[:fresh_ruby_prefix] )
51
+ input = input[$1.size..-1]
52
+ :ruby
53
+ # single words
54
+ when /^\w+$/i
55
+ if Ripl.config[:fresh_ruby_words].include?($&)
56
+ :ruby
57
+ elsif Ripl.config[:fresh_mixed_words].include?($&)
58
+ :mixed
59
+ elsif Ripl.config[:fresh_system_words].include?($&)
60
+ :system
61
+ else
62
+ :ruby
63
+ end
64
+ # set of commands that call the ruby method but have command line style calling (args without "")
65
+ when Ripl::Fresh.option_array_to_regexp( Ripl.config[:fresh_mixed_words] )
66
+ :mixed
67
+ # here is the important magical regex for shell commands
68
+ when Ripl.config[:fresh_system_regexp]
69
+ if Ripl.config[:fresh_ruby_words].include? $1
70
+ :ruby
71
+ else
72
+ :system
73
+ end
74
+ # default is still ruby ;)
75
+ else
76
+ :ruby
77
+ end
78
+
79
+ input
80
+ end
81
+
82
+ # get result (depending on @command_mode)
83
+ def loop_eval(input)
84
+ if input == ''
85
+ @command_mode = :system and return
86
+ end
87
+
88
+ case @command_mode
89
+ when :system # execute command
90
+ ret = system input
91
+ case ret
92
+ when false
93
+ warn '[non-nil exit status]' # too verbose?
94
+ when nil
95
+ warn "[command error #{$?.exitstatus}]" # add message?
96
+ end
97
+ ret
98
+
99
+ when :mixed # call the ruby method, but with shell style arguments
100
+ m, *args = *input.split
101
+ super "#{m}(*#{args.to_s})"
102
+
103
+ else # good old :ruby
104
+ super
105
+ end
106
+ end
107
+
108
+
109
+ # system commands don't have output values and Ruby is displayed normally
110
+ def print_result(result)
111
+ if @error_raised ||
112
+ @command_mode == :system ||
113
+ @command_mode == :mixed && (!result || result == '')
114
+ # don't display anything
115
+ else
116
+ super # puts(format_result(result))
117
+ end
118
+ end
119
+
120
+ # catch ctrl+c
121
+ def loop_once(*args)
122
+ super
123
+ rescue Interrupt
124
+ @buffer = @error_raised = nil
125
+ puts '[C]'
126
+ retry
127
+ end
128
+ end
129
+ end
130
+ end
131
+
132
+ # hook in (and work around readline loading behaviour)
133
+ Ripl.config[:readline] = false
134
+ require 'ripl/readline'
135
+ Ripl::Shell.send :include, Ripl::Fresh::Shell
136
+
137
+ ## fresh config ###
138
+
139
+ # prefixes
140
+ Ripl.config[:fresh_system_prefix] = %w[^]
141
+ Ripl.config[:fresh_ruby_prefix] = [' ']
142
+ # single words
143
+ Ripl.config[:fresh_system_words] = %w[top ls]
144
+ Ripl.config[:fresh_ruby_words] = %w[begin case class def for if module undef unless until while puts warn print p pp ap raise fail loop require load lambda proc system]
145
+ # catch mix words
146
+ Ripl.config[:fresh_mixed_words] = %w[cd]
147
+ # main regexp
148
+ Ripl.config[:fresh_system_regexp] = /^([a-z_-]+)\s+(?!(?:[=%*]|!=|\+=|-=|\/=))/i
149
+ # configure directory prompt
150
+ Ripl.config[:prompt] = proc{
151
+ path = FileUtils.pwd
152
+ path.gsub! /#{ File.expand_path('~') }/, '~'
153
+ path + '> '
154
+ }
155
+
156
+ # J-_-L
@@ -0,0 +1,32 @@
1
+ require 'ripl'
2
+ require 'fileutils'
3
+
4
+ module Ripl
5
+ module Fresh
6
+ module Commands
7
+ =begin
8
+ def ls(path='.')
9
+ Dir[ File.join( path, '*' )].map{|res| res =~ /^#{path}\/?/; $' }
10
+ end
11
+ alias dir ls
12
+ =end
13
+
14
+ def cd( path = File.expand_path('~') )
15
+ new_last_path = FileUtils.pwd
16
+ if path == '-'
17
+ if @last_path
18
+ path = @last_path
19
+ else
20
+ warn 'Sorry, there is no previous directory.'
21
+ return
22
+ end
23
+ end
24
+ FileUtils.cd path
25
+ @last_path = new_last_path
26
+ nil
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ Ripl::Commands.send :include, Ripl::Fresh::Commands if defined? Ripl::Commands
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ripl-fresh
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Jan Lelis
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-11-24 00:00:00 +01:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: ripl
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ - 2
31
+ - 5
32
+ version: 0.2.5
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ description: Fresh Ruby Enhanced SHell automatically detects, if your current command should be Ruby or a system command.
36
+ email: mail@janlelis.de
37
+ executables:
38
+ - ripl-fresh
39
+ - fresh
40
+ extensions: []
41
+
42
+ extra_rdoc_files:
43
+ - README.rdoc
44
+ - LICENSE
45
+ files:
46
+ - lib/ripl/fresh/commands.rb
47
+ - lib/ripl/fresh.rb
48
+ - lib/ripl-fresh/bond_workaround.rb
49
+ - lib/bond/completions/ripl-fresh.rb
50
+ - bin/fresh
51
+ - bin/ripl-fresh
52
+ - README.rdoc
53
+ - CHANGELOG.rdoc
54
+ - deps.rip
55
+ - Rakefile
56
+ - .gemspec
57
+ - LICENSE
58
+ has_rdoc: true
59
+ homepage: http://github.com/janlelis/fresh
60
+ licenses:
61
+ - MIT
62
+ post_install_message:
63
+ rdoc_options: []
64
+
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ segments:
81
+ - 1
82
+ - 3
83
+ - 6
84
+ version: 1.3.6
85
+ requirements: []
86
+
87
+ rubyforge_project:
88
+ rubygems_version: 1.3.7
89
+ signing_key:
90
+ specification_version: 3
91
+ summary: Fresh Ruby Enhanced SHell
92
+ test_files: []
93
+