rs 35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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