rs 35

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,14 @@
1
+ config.rb
2
+ InstalledFiles
3
+
4
+ rs.gemspec
5
+ pkg/
6
+
7
+ *.log
8
+ *.swp
9
+ .DS_Store
10
+
11
+ old
12
+
13
+ # ctags
14
+ tags
@@ -0,0 +1,52 @@
1
+ begin
2
+ require "rubygems"
3
+ require "jeweler"
4
+
5
+ namespace :jeweler do
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "rs"
8
+
9
+ gem.version = `git log --pretty=oneline | wc -l`.chomp
10
+
11
+
12
+ gem.summary = "Object-oriented shell in full Ruby environment."
13
+ gem.description = <<-END.gsub /\s+/, " "
14
+
15
+ rs is the result of my object-oriented shell musings,
16
+ experiments and implementations. Its focus is above
17
+ all on simplicity and the best possible implementation
18
+ of modern shell usage and needs.
19
+
20
+ END
21
+
22
+ gem.email = "rs@projects.kittensoft.org"
23
+ gem.homepage = "http://github.com/rue/rs"
24
+ gem.authors = ["Eero Saynatkari"]
25
+
26
+
27
+ gem.add_development_dependency "rspec", ">= 1.3.0"
28
+
29
+ gem.post_install_message = <<-END
30
+
31
+ =======================================
32
+
33
+ /path/to/cwd rs> _
34
+
35
+ =======================================
36
+
37
+ END
38
+ end
39
+
40
+ Jeweler::GemcutterTasks.new
41
+ end
42
+
43
+ rescue LoadError
44
+ puts "Jeweler not available. Install it with: gem install jeweler"
45
+ end
46
+
47
+
48
+ # Main tasks
49
+
50
+ desc "Generate Gem and push it."
51
+ task :release_gem => %w[jeweler:gemcutter:release]
52
+
data/bin/rs ADDED
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # The 'executable' rs program.
4
+ #
5
+ # == Copyright
6
+ # Copyright (c) 2005-2010 Eero Saynatkari, all rights reserved.
7
+ #
8
+ # == Licence
9
+ # Redistribution and use in source and binary forms, with or without
10
+ # modification, are permitted provided that the following conditions
11
+ # are met:
12
+ #
13
+ # - Redistributions of source code must retain the above copyright
14
+ # notice, this list of conditions, the following disclaimer and
15
+ # attribution to the original authors.
16
+ #
17
+ # - Redistributions in binary form must reproduce the above copyright
18
+ # notice, this list of conditions, the following disclaimer and
19
+ # attribution to the original authors in the documentation and/or
20
+ # other materials provided with the distribution.
21
+ #
22
+ # - The names of the authors may not be used to endorse or promote
23
+ # products derived from this software without specific prior
24
+ # written permission.
25
+ #
26
+ # == Disclaimer
27
+ # This software is provided "as is" and without any express or
28
+ # implied warranties, including, without limitation, the implied
29
+ # warranties of merchantability and fitness for a particular purpose.
30
+ # Authors are not responsible for any damages, direct or indirect.
31
+
32
+
33
+ # We might need the files in development
34
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), "..", "lib")
35
+
36
+
37
+ # System
38
+
39
+ # Project
40
+ require "rs/eval"
41
+ require "rs/ui"
42
+
43
+
44
+ # TODO: Yeah...ugh. --rue
45
+ #
46
+ RS.start {|rs|
47
+
48
+ # Minor configulabulous
49
+ config = rs.main.send(:rs).config
50
+
51
+ config.default_prompt = lambda { "#{Dir.pwd} rs> " }
52
+ config.continuation_prompt = lambda { "#{Dir.pwd} ..> " }
53
+
54
+
55
+ RS::UI.new {|ui|
56
+
57
+ ui.on_SIGINT {
58
+ @earlier_incomplete = nil
59
+ ui.puts ""
60
+ ui.prompt = config.default_prompt
61
+ }
62
+
63
+ ui.on_input {|line|
64
+ next if line.empty?
65
+
66
+ if @earlier_incomplete
67
+ line = @earlier_incomplete + line
68
+ @earlier_incomplete = nil
69
+ end
70
+
71
+ begin
72
+ output = rs.execute line
73
+
74
+ ui.puts "=> #{output.inspect}"
75
+ ui.prompt = config.default_prompt
76
+
77
+ rescue RS::IncompleteExpression
78
+ @earlier_incomplete = line + "\n" # Only allow where newlines appropriate.
79
+ ui.prompt = config.continuation_prompt
80
+
81
+ rescue LocalJumpError => e # next and redo in 1.8
82
+ output = e
83
+ end
84
+ }
85
+
86
+ ui.prompt = config.default_prompt
87
+ ui.run
88
+ }
89
+
90
+ }
91
+
@@ -0,0 +1,29 @@
1
+ = LICENCE
2
+
3
+ == Copyright
4
+ Copyright (c) 2005-2010 Eero Saynatkari, all rights reserved.
5
+
6
+ == Licence
7
+ Redistribution and use in source and binary forms, with or without
8
+ modification, are permitted provided that the following conditions
9
+ are met:
10
+
11
+ - Redistributions of source code must retain the above copyright
12
+ notice, this list of conditions, the following disclaimer and
13
+ attribution to the original authors.
14
+
15
+ - Redistributions in binary form must reproduce the above copyright
16
+ notice, this list of conditions, the following disclaimer and
17
+ attribution to the original authors in the documentation and/or
18
+ other materials provided with the distribution.
19
+
20
+ - The names of the authors may not be used to endorse or promote
21
+ products derived from this software without specific prior
22
+ written permission.
23
+
24
+ == Disclaimer
25
+ This software is provided "as is" and without any express or
26
+ implied warranties, including, without limitation, the implied
27
+ warranties of merchantability and fitness for a particular purpose.
28
+ Authors are not responsible for any damages, direct or indirect.
29
+
@@ -0,0 +1,62 @@
1
+ rs
2
+ ====
3
+
4
+ rs is the result of my object-oriented shell musings, experiments and
5
+ implementations. Its focus is above all on simplicity and the best
6
+ possible implementation of modern shell usage and needs.
7
+
8
+
9
+
10
+ Features
11
+ ==========
12
+
13
+ Currently extremely rudimentary and exploratory:
14
+
15
+ - Executes normal Ruby code, unrestricted.
16
+
17
+
18
+
19
+ Requirements
20
+ ==============
21
+
22
+ - Ruby
23
+ - 1.8.7, 1.9.1, 1.9.2
24
+
25
+ - For development
26
+ - RSpec (>= 1.3.0)
27
+
28
+
29
+
30
+ Where?
31
+ ========
32
+
33
+ $ gem install rs
34
+
35
+ Source is found on [Github](http://github.com/rue/rs).
36
+
37
+
38
+
39
+ Who Do I Complain To?
40
+ =======================
41
+
42
+ * rs MEOW projects _purr_ kittensoft _rawr_ org.
43
+ * IRC channels #rs and ##rs on Freenode ('rue', if not the only person.)
44
+
45
+
46
+
47
+ Legal
48
+ =======
49
+
50
+ Copyright (c) 2005-2010 Eero Saynatkari. See doc/LICENCE.
51
+
52
+
53
+
54
+ Acknowledgements
55
+ ==================
56
+
57
+ The original spark was provided by Reyn Vlietstra's ruSH back in 2005.
58
+ It was an excellent implementation of a novel concept, and I thoroughly
59
+ enjoyed working on it. The first incarnation of rs was a complete rewrite
60
+ effort of ruSH, and now I am starting from scratch again. Thanks to Reyn
61
+ and all the other collaborators on ruSH and the earlier rs.
62
+
@@ -0,0 +1,129 @@
1
+ # == Copyright
2
+ # Copyright (c) 2005-2010 Eero Saynatkari, all rights reserved.
3
+ #
4
+ # == Licence
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions
7
+ # are met:
8
+ #
9
+ # - Redistributions of source code must retain the above copyright
10
+ # notice, this list of conditions, the following disclaimer and
11
+ # attribution to the original authors.
12
+ #
13
+ # - Redistributions in binary form must reproduce the above copyright
14
+ # notice, this list of conditions, the following disclaimer and
15
+ # attribution to the original authors in the documentation and/or
16
+ # other materials provided with the distribution.
17
+ #
18
+ # - The names of the authors may not be used to endorse or promote
19
+ # products derived from this software without specific prior
20
+ # written permission.
21
+ #
22
+ # == Disclaimer
23
+ # This software is provided "as is" and without any express or
24
+ # implied warranties, including, without limitation, the implied
25
+ # warranties of merchantability and fitness for a particular purpose.
26
+ # Authors are not responsible for any damages, direct or indirect.
27
+
28
+ # Libs
29
+ require "ostruct"
30
+
31
+
32
+ module RS
33
+
34
+ # Creates and yields a new Evaluator.
35
+ #
36
+ # The block given should implement whatever logic is
37
+ # desired. Will clean up as necessary.
38
+ #
39
+ # TODO: This needs much improvement, probably. --rue
40
+ #
41
+ def self.start(&block)
42
+ rs = Evaluator.new
43
+
44
+ begin
45
+ rs.send :run, &block
46
+
47
+ rescue SystemExit => e
48
+ # No need to print errors etc., but set return code.
49
+ exit! e.status
50
+ end
51
+ end
52
+
53
+
54
+ #
55
+ # Error raised trying to execute an incomplete expression.
56
+ #
57
+ class IncompleteExpression < SyntaxError; end
58
+
59
+
60
+ # Runtime environment for executing user input as Ruby.
61
+ #
62
+ class Evaluator
63
+
64
+ # Create a new execution environment.
65
+ #
66
+ # You should use RS.start instead.
67
+ #
68
+ # TODO: Generate unique bindings?
69
+ #
70
+ def initialize()
71
+ @binding = eval "lambda { binding }.call", TOPLEVEL_BINDING
72
+
73
+ stash = OpenStruct.new :evaluator => self,
74
+ :config => OpenStruct.new
75
+
76
+ @main = execute "self"
77
+ @main.instance_variable_set "@rs", stash
78
+
79
+ # Work around MRI changing description.
80
+ def @main.inspect(); :rs_main; end
81
+
82
+ execute "def rs(); @rs; end"
83
+ end
84
+
85
+
86
+ # Allow accessing main from the outside.
87
+ #
88
+ attr_reader :main
89
+
90
+
91
+ # Execute a presumably valid String of Ruby code.
92
+ #
93
+ # Trying to execute an incomplete Ruby expression
94
+ # raises IncompleteExpression.
95
+ #
96
+ # Errors are caught etc. (except top-level next and redo
97
+ # LocalJumpErrors, those need to be caught outside this
98
+ # scope), and returned as objects.
99
+ #
100
+ def execute(expression, file = "<no file>", line = "<no line>")
101
+ eval expression, @binding
102
+
103
+ rescue SyntaxError => e
104
+ case e.message
105
+ when /(parse|syntax) error.*?\$end/i, /unterminated/i # Should catch most
106
+ raise IncompleteExpression
107
+ else
108
+ e
109
+ end
110
+ rescue SystemExit
111
+ raise
112
+ rescue Exception => e
113
+ e
114
+ end
115
+
116
+
117
+ # Yields this instance to block.
118
+ #
119
+ # Use RS.start.
120
+ #
121
+ def run()
122
+ yield self
123
+ end
124
+ private :run
125
+
126
+ end
127
+
128
+ end
129
+
@@ -0,0 +1,39 @@
1
+ # == Authors
2
+ # Please see doc/AUTHORS.
3
+ #
4
+ # == Copyright
5
+ # Copyright (c) 2005-2010 the Authors, all rights reserved.
6
+ #
7
+ # == Licence
8
+ # Redistribution and use in source and binary forms, with or without
9
+ # modification, are permitted provided that the following conditions
10
+ # are met:
11
+ #
12
+ # - Redistributions of source code must retain the above copyright
13
+ # notice, this list of conditions, the following disclaimer and
14
+ # attribution to the original authors.
15
+ #
16
+ # - Redistributions in binary form must reproduce the above copyright
17
+ # notice, this list of conditions, the following disclaimer and
18
+ # attribution to the original authors in the documentation and/or
19
+ # other materials provided with the distribution.
20
+ #
21
+ # - The names of the authors may not be used to endorse or promote
22
+ # products derived from this software without specific prior
23
+ # written permission.
24
+ #
25
+ # == Disclaimer
26
+ # This software is provided "as is" and without any express or
27
+ # implied warranties, including, without limitation, the implied
28
+ # warranties of merchantability and fitness for a particular purpose.
29
+ # Authors are not responsible for any damages, direct or indirect.
30
+
31
+
32
+
33
+ # Extensions to String needed for rs.
34
+ #
35
+ class String
36
+
37
+ # Nothing yet, but will need this later anyway.. --rue
38
+
39
+ end
@@ -0,0 +1,114 @@
1
+ # == Copyright
2
+ # Copyright (c) 2005-2010 Eero Saynatkari, all rights reserved.
3
+ #
4
+ # == Licence
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions
7
+ # are met:
8
+ #
9
+ # - Redistributions of source code must retain the above copyright
10
+ # notice, this list of conditions, the following disclaimer and
11
+ # attribution to the original authors.
12
+ #
13
+ # - Redistributions in binary form must reproduce the above copyright
14
+ # notice, this list of conditions, the following disclaimer and
15
+ # attribution to the original authors in the documentation and/or
16
+ # other materials provided with the distribution.
17
+ #
18
+ # - The names of the authors may not be used to endorse or promote
19
+ # products derived from this software without specific prior
20
+ # written permission.
21
+ #
22
+ # == Disclaimer
23
+ # This software is provided "as is" and without any express or
24
+ # implied warranties, including, without limitation, the implied
25
+ # warranties of merchantability and fitness for a particular purpose.
26
+ # Authors are not responsible for any damages, direct or indirect.
27
+
28
+ module RS
29
+
30
+ # Readline-based console UI.
31
+ #
32
+ class UI
33
+
34
+ # Lib
35
+ require "readline"
36
+
37
+
38
+ # Default prompt is unexciting.
39
+ #
40
+ DefaultPrompt = lambda { "#{Dir.pwd} rs> " }
41
+
42
+
43
+ # UI is set up and prepared to be read/written.
44
+ #
45
+ # Initial prompt may be given as an argument, and can
46
+ # later be changed using #prompt=.
47
+ #
48
+ def initialize(initial_prompt = DefaultPrompt)
49
+ $stdin.sync = true
50
+ $stdout.sync = true
51
+ $stderr.sync = true
52
+
53
+ # Work around Readline binding to get full line of input
54
+ Readline.completer_word_break_characters = 0.chr # NUL byte unlikely?
55
+ Readline.completion_append_character = nil
56
+
57
+ self.prompt = initial_prompt
58
+
59
+ yield self
60
+ end
61
+
62
+ # Prompt used for next input read.
63
+ #
64
+ attr_accessor :prompt
65
+
66
+
67
+ # Signal handlers
68
+ #
69
+ # TODO: Perhaps autogenerate these? --rue
70
+
71
+
72
+ # ^C, keyboard interrupt.
73
+ #
74
+ def on_SIGINT(&block); @sigint = block; end
75
+
76
+
77
+ # Other event handlers
78
+
79
+ # Block to call with each line of input.
80
+ #
81
+ def on_input(&block); @input = block; end
82
+
83
+
84
+ # Write #to_s to output.
85
+ #
86
+ # TODO: Probably need a .print version, huh? --rue
87
+ #
88
+ def puts(data)
89
+ $stdout.puts data.to_s
90
+ end
91
+
92
+ # Input loop.
93
+ #
94
+ # Calls the block given in #on_input for each line of
95
+ # input, as well as any other #on_* handlers as needed.
96
+ #
97
+ def run()
98
+ loop {
99
+ begin
100
+ if input = Readline.readline(@prompt.call, true)
101
+ @input.call input.chomp
102
+ else
103
+ puts ""
104
+ return
105
+ end
106
+ rescue Interrupt
107
+ @sigint.call
108
+ end
109
+ }
110
+ end
111
+
112
+ end
113
+
114
+ end