ripl-fresh 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +38 -12
- data/lib/bond/completions/ripl-fresh.rb +11 -1
- data/lib/ripl/fresh/prompt.rb +86 -0
- data/lib/ripl/fresh.rb +12 -13
- metadata +3 -2
data/README.rdoc
CHANGED
@@ -20,34 +20,58 @@ Start it with:
|
|
20
20
|
|
21
21
|
(or just <tt>fresh</tt>)
|
22
22
|
|
23
|
+
Note, that it will also load your <tt>.irbrc</tt> file. To avoid this, you can do:
|
24
|
+
|
25
|
+
ripl -f fresh
|
26
|
+
|
23
27
|
== Usage & configuration options
|
24
28
|
|
25
29
|
For an example session, see {this blog entry}[http://rbjl.net/43-use-fresh-ruby-as-your-shell].
|
26
30
|
|
27
|
-
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[:
|
31
|
+
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_match_regexp]</tt>.
|
28
32
|
|
29
|
-
|
33
|
+
If this regexp matches or the input is a single word <tt>([a-z_-]+)</tt>, _fresh_ searches through the <tt>Ripl.config[:fresh_ruby_words]</tt> array for exceptions that still should get interpreted as Ruby (e.g. <tt>def </tt>).
|
30
34
|
|
31
|
-
|
35
|
+
Then, the <tt>Ripl.config[:fresh_system_words]</tt> arrays is checked, if it contains the command. This array defaults to your <tt>ENV['PATH']</tt>. You can add your own system commands there.
|
32
36
|
|
33
37
|
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+).
|
34
38
|
|
39
|
+
As a fallback, _fresh_ checks <tt>Kernel.respond_to?</tt>, if there is a ruby method with that name.
|
40
|
+
|
41
|
+
If the regexp does match, but the command could not be found in any of the three word arrays, the command mode will be set to <tt>Ripl.config[:fresh_match_default]</tt> (<tt>:ruby</tt>). If the regexp does not match, <tt>Ripl.config[:fresh_default]</tt> is used (also defaults to <tt>:ruby</tt>).
|
42
|
+
|
35
43
|
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>.
|
36
44
|
|
37
45
|
You need to take a look at <tt>get_input</tt> method in the source file to 100% understand the command mode detection way.
|
38
46
|
|
47
|
+
=== Prompt
|
48
|
+
There is <tt>Riplc.config[:fresh_prompt]</tt> option, which takes a wide range of possible values. You can pass in a proc or a direct string. Furthermore, you can pass a symbol to get one of the following:
|
49
|
+
* <tt>:default</tt> - usual fresh (directory) prompt
|
50
|
+
* <tt>:PS1</tt> - use PS1 environment variable
|
51
|
+
* <tt>:ripl</tt> - don't change prompt
|
52
|
+
* <tt>:irb</tt> - use irbs :PROMPT_I (if set)
|
53
|
+
* <tt>:simple</tt> - ">> "
|
54
|
+
|
39
55
|
=== Defaults
|
40
56
|
|
41
57
|
# prefixes
|
42
|
-
Ripl.config[:fresh_system_prefix]
|
43
|
-
Ripl.config[:fresh_ruby_prefix]
|
44
|
-
#
|
45
|
-
Ripl.config[:
|
46
|
-
Ripl.config[:
|
47
|
-
|
48
|
-
|
58
|
+
Ripl.config[:fresh_system_prefix] = %w[^]
|
59
|
+
Ripl.config[:fresh_ruby_prefix] = [' ']
|
60
|
+
# word arrays
|
61
|
+
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]
|
62
|
+
Ripl.config[:fresh_system_words] =
|
63
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).uniq.map {|e|
|
64
|
+
File.directory?(e) ? Dir.entries(e) : []
|
65
|
+
}.flatten.uniq - ['.', '..']
|
66
|
+
Ripl.config[:fresh_mixed_words] = %w[cd]
|
49
67
|
# main regexp
|
50
|
-
Ripl.config[:
|
68
|
+
Ripl.config[:fresh_match_regexp] = /^([a-z\/_-]+)\s+(?!(?:[=%*]|!=|\+=|-=|\/=))/i
|
69
|
+
# regex matched but word not in one of the three arrays, possible values: :ruby, :system, :mixed
|
70
|
+
Ripl.config[:fresh_match_default] = :ruby
|
71
|
+
# regex did not match
|
72
|
+
Ripl.config[:fresh_default] = :ruby
|
73
|
+
# configure prompt
|
74
|
+
Ripl.config[:fresh_prompt] = :default
|
51
75
|
|
52
76
|
== Customization
|
53
77
|
|
@@ -63,10 +87,12 @@ There are lots of things which can get better:
|
|
63
87
|
|
64
88
|
* Improve auto-completion
|
65
89
|
* More cool (and colorful?) <tt>:mixed</tt> Ruby commands
|
66
|
-
* Improve interaction between system and
|
90
|
+
* Improve interaction between system and Ruby commands
|
67
91
|
* <tt>ripl-multi_line</tt> for system commands
|
68
92
|
* Result of system commands should be available for ruby, not only printed to stdout
|
93
|
+
* Respect "..." (single argument) for :mixed commands
|
69
94
|
* Improve default configuration
|
95
|
+
* Add tests
|
70
96
|
* Fresh ideas
|
71
97
|
|
72
98
|
Feel free to fork in your improvements ;)
|
@@ -9,7 +9,14 @@ file_completion = proc{ |input|
|
|
9
9
|
|
10
10
|
system_command_completion = proc{ Ripl.config[:fresh_system_words] }
|
11
11
|
|
12
|
-
|
12
|
+
everything_completion = proc{ # TODO: improve
|
13
|
+
# file_completion.call +
|
14
|
+
system_command_completion.call +
|
15
|
+
Kernel.instance_methods +
|
16
|
+
Object.instance_methods +
|
17
|
+
Object.constants
|
18
|
+
}
|
19
|
+
|
13
20
|
|
14
21
|
complete :on => Ripl.config[:fresh_match_regexp],
|
15
22
|
:search => false,
|
@@ -20,4 +27,7 @@ complete :on => Ripl::Fresh.option_array_to_regexp( Ripl.config[:fresh_system_pr
|
|
20
27
|
# :search => false,
|
21
28
|
&system_command_completion
|
22
29
|
|
30
|
+
complete :on => /^[a-z\/_-]*/i,
|
31
|
+
&everything_completion
|
32
|
+
|
23
33
|
# J-_-L
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'etc'
|
3
|
+
|
4
|
+
# save current prompt
|
5
|
+
ripl_prompt = Ripl.config[:prompt] # TODO currently not working
|
6
|
+
|
7
|
+
# setup default prompt
|
8
|
+
default_prompt = proc{ |path|
|
9
|
+
path.gsub! /#{ File.expand_path('~') }/, '~'
|
10
|
+
path + '> '
|
11
|
+
}
|
12
|
+
|
13
|
+
# PS environment variable prompt
|
14
|
+
ps_prompt = proc{ |prompt_number|
|
15
|
+
prompt = ENV['PS' + prompt_number.to_s].dup
|
16
|
+
prompt.gsub!('\a', '') # unsupported
|
17
|
+
prompt.gsub!('\d', Time.now.strftime("%a %b %d"))
|
18
|
+
prompt.gsub!(/\\D\{([^}]+)\}/){Time.now.strftime($1)}
|
19
|
+
prompt.gsub!('\e', "\033")
|
20
|
+
prompt.gsub!('\h', Socket.gethostname.split('.')[0])
|
21
|
+
prompt.gsub!('\H', Socket.gethostname.chomp)
|
22
|
+
prompt.gsub!('\j', '') # unsupported
|
23
|
+
prompt.gsub!('\l', '') # unsupported
|
24
|
+
prompt.gsub!('\n', "\n")
|
25
|
+
prompt.gsub!('\r', "\r")
|
26
|
+
prompt.gsub!('\s', 'fresh')
|
27
|
+
prompt.gsub!('\t', Time.now.strftime("%H:%M:%S"))
|
28
|
+
prompt.gsub!('\T', Time.now.strftime("%I:%M:%S"))
|
29
|
+
prompt.gsub!('\@', Time.now.strftime("%I:%M %p"))
|
30
|
+
prompt.gsub!('\A', Time.now.strftime("%H:%M"))
|
31
|
+
prompt.gsub!('\u', Etc.getlogin)
|
32
|
+
prompt.gsub!('\v', `#{`echo $SHELL`.chomp} --version`.gsub(/(.*(\d+\.\d+)\..*)/m){$2})
|
33
|
+
prompt.gsub!('\V', `#{`echo $SHELL`.chomp} --version`.gsub(/(.*(\d+\.\d+\.\d+).*)/m){$2})
|
34
|
+
prompt.gsub!('\w', FileUtils.pwd.gsub(/#{ File.expand_path('~') }/, '~'))
|
35
|
+
prompt.gsub!('\W', File.basename(FileUtils.pwd.gsub(/#{ File.expand_path('~') }/, '~')))
|
36
|
+
prompt.gsub!('\!', '') # unsupported
|
37
|
+
prompt.gsub!('\#', '') # unsupported
|
38
|
+
prompt.gsub!('\$'){uid = nil; Etc.passwd{|u| uid = u.uid if u.name == Etc.getlogin}; uid == 0 ? '#' : '$'}
|
39
|
+
prompt
|
40
|
+
}
|
41
|
+
|
42
|
+
# feel free to add your own creative one ;)
|
43
|
+
prompt_collection = {
|
44
|
+
:default => default_prompt,
|
45
|
+
:ripl => ripl_prompt,
|
46
|
+
:irb => proc{ IRB.conf[:PROMPT][IRB.conf[:PROMPT_MODE]][:PROMPT_I] },
|
47
|
+
:simple => '>> ',
|
48
|
+
}
|
49
|
+
|
50
|
+
# register proc ;)
|
51
|
+
Ripl.config[:prompt] = proc{
|
52
|
+
fp = Ripl.config[:fresh_prompt]
|
53
|
+
|
54
|
+
# transform symbol to valid prompt
|
55
|
+
if fp.is_a? Symbol
|
56
|
+
fp_known = prompt_collection[fp]
|
57
|
+
if !fp_known
|
58
|
+
fp_known =
|
59
|
+
case fp.to_s # maybe it's a special symbol
|
60
|
+
when /^PS(\d+)/
|
61
|
+
ps_prompt[ $1 ]
|
62
|
+
else # really unknown
|
63
|
+
Ripl.config[:fresh_prompt] = :default
|
64
|
+
default_prompt
|
65
|
+
end
|
66
|
+
end
|
67
|
+
fp = fp_known
|
68
|
+
end
|
69
|
+
|
70
|
+
# call if proc or return directly
|
71
|
+
if fp.respond_to? :call
|
72
|
+
fp.arity == 1 ? fp[ FileUtils.pwd ] : fp.call
|
73
|
+
else
|
74
|
+
case fp
|
75
|
+
when nil, false
|
76
|
+
''
|
77
|
+
when String
|
78
|
+
fp
|
79
|
+
else
|
80
|
+
Ripl.config[:fresh_prompt] = :default
|
81
|
+
default_proc.call[ FileUtils.pwd ]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
}
|
85
|
+
|
86
|
+
# J-_-L
|
data/lib/ripl/fresh.rb
CHANGED
@@ -3,7 +3,7 @@ require 'fileutils'
|
|
3
3
|
|
4
4
|
module Ripl
|
5
5
|
module Fresh
|
6
|
-
VERSION = '0.1.
|
6
|
+
VERSION = '0.1.2'
|
7
7
|
|
8
8
|
class << self
|
9
9
|
# helper to parse options
|
@@ -49,13 +49,15 @@ module Ripl
|
|
49
49
|
input = input[$1.size..-1]
|
50
50
|
:ruby
|
51
51
|
# single words, and main regex to match shell commands
|
52
|
-
when /^(
|
52
|
+
when /^([a-z_-]+)$/i, Ripl.config[:fresh_match_regexp]
|
53
53
|
if Ripl.config[:fresh_ruby_words].include?($1)
|
54
54
|
:ruby
|
55
55
|
elsif Ripl.config[:fresh_mixed_words].include?($1)
|
56
56
|
:mixed
|
57
57
|
elsif Ripl.config[:fresh_system_words].include?($1)
|
58
58
|
:system
|
59
|
+
elsif Kernel.respond_to? $1.to_sym
|
60
|
+
:ruby
|
59
61
|
else
|
60
62
|
Ripl.config[:fresh_match_default]
|
61
63
|
end
|
@@ -130,25 +132,22 @@ require File.dirname(__FILE__) + '/fresh/commands'
|
|
130
132
|
# prefixes
|
131
133
|
Ripl.config[:fresh_system_prefix] = %w[^]
|
132
134
|
Ripl.config[:fresh_ruby_prefix] = [' ']
|
133
|
-
#
|
135
|
+
# word arrays
|
134
136
|
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]
|
135
137
|
Ripl.config[:fresh_system_words] =
|
136
138
|
ENV['PATH'].split(File::PATH_SEPARATOR).uniq.map {|e|
|
137
139
|
File.directory?(e) ? Dir.entries(e) : []
|
138
140
|
}.flatten.uniq - ['.', '..']
|
139
|
-
# catch mix words
|
140
141
|
Ripl.config[:fresh_mixed_words] = %w[cd]
|
141
142
|
# main regexp
|
142
|
-
Ripl.config[:fresh_match_regexp] = /^([a-
|
143
|
+
Ripl.config[:fresh_match_regexp] = /^([a-z\/_-]+)\s+(?!(?:[=%*]|!=|\+=|-=|\/=))/i
|
143
144
|
# regex matched but word not in one of the three arrays, possible values: :ruby, :system, :mixed
|
144
|
-
Ripl.config[:fresh_match_default] = :ruby
|
145
|
+
Ripl.config[:fresh_match_default] = :ruby
|
145
146
|
# regex did not match
|
146
|
-
Ripl.config[:fresh_default] = :ruby
|
147
|
-
# configure
|
148
|
-
Ripl.config[:
|
149
|
-
|
150
|
-
|
151
|
-
path + '> '
|
152
|
-
}
|
147
|
+
Ripl.config[:fresh_default] = :ruby
|
148
|
+
# configure prompt
|
149
|
+
Ripl.config[:fresh_prompt] = :default
|
150
|
+
|
151
|
+
require File.dirname(__FILE__) + '/fresh/prompt'
|
153
152
|
|
154
153
|
# J-_-L
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
version: 0.1.
|
8
|
+
- 2
|
9
|
+
version: 0.1.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Jan Lelis
|
@@ -44,6 +44,7 @@ extra_rdoc_files:
|
|
44
44
|
- LICENSE
|
45
45
|
files:
|
46
46
|
- lib/ripl/fresh/commands.rb
|
47
|
+
- lib/ripl/fresh/prompt.rb
|
47
48
|
- lib/ripl/fresh.rb
|
48
49
|
- lib/ripl-fresh/bond_workaround.rb
|
49
50
|
- lib/bond/completions/ripl-fresh.rb
|