lsl 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/lsl.rb +16 -1
- data/lib/lsl/command/args.rb +43 -0
- data/lib/lsl/command/completion.rb +79 -0
- data/lib/lsl/command/execution.rb +14 -27
- data/lib/lsl/command/single.rb +1 -1
- data/lib/lsl/dsl/dsl.rb +22 -0
- data/lib/lsl/ext/ext.rb +51 -16
- data/lib/lsl/grammars/compound_command.treetop +12 -10
- data/lib/lsl/grammars/list.treetop +5 -1
- data/lib/lsl/grammars/quoting.treetop +13 -2
- data/lib/lsl/grammars/single_command.treetop +14 -16
- data/lib/lsl/junk.rb +25 -0
- data/lib/lsl/shell.rb +45 -6
- data/lsl.gemspec +6 -2
- data/spec/compound_command_spec.rb +6 -0
- data/spec/quoting_spec.rb +6 -0
- data/spec/shell_spec.rb +17 -4
- data/spec/single_command_spec.rb +1 -0
- metadata +8 -4
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/lib/lsl.rb
CHANGED
@@ -6,7 +6,7 @@ require 'mharris_ext'
|
|
6
6
|
require File.dirname(__FILE__) + "/lsl/grammars/#{g}"
|
7
7
|
end
|
8
8
|
|
9
|
-
%w(single compound execution).each do |f|
|
9
|
+
%w(args single compound execution completion).each do |f|
|
10
10
|
require File.dirname(__FILE__) + "/lsl/command/#{f}"
|
11
11
|
end
|
12
12
|
|
@@ -22,6 +22,21 @@ end
|
|
22
22
|
require File.dirname(__FILE__) + "/lsl/#{f}"
|
23
23
|
end
|
24
24
|
|
25
|
+
%w(dsl).each do |f|
|
26
|
+
f = File.expand_path(File.dirname(__FILE__)) + "/lsl/dsl/#{f}"
|
27
|
+
#puts f
|
28
|
+
require f
|
29
|
+
end
|
30
|
+
|
31
|
+
def load_config!
|
32
|
+
f = ENV['HOME'] + "/.lsl"
|
33
|
+
if FileTest.exist?(f)
|
34
|
+
eval(File.read(f))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
load_config!
|
39
|
+
|
25
40
|
module LSL
|
26
41
|
module ExecutionStrategy
|
27
42
|
class Base
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module LSL
|
2
|
+
module CommandExecution
|
3
|
+
class Args
|
4
|
+
class ArrayWithBlanks
|
5
|
+
include Enumerable
|
6
|
+
fattr(:list) { [] }
|
7
|
+
def each(&b); list.each(&b); end
|
8
|
+
fattr(:blank_spots) do
|
9
|
+
res = []
|
10
|
+
list.each_with_index do |x,i|
|
11
|
+
res << i if x == '_'
|
12
|
+
end
|
13
|
+
res
|
14
|
+
end
|
15
|
+
def <<(x)
|
16
|
+
i = blank_spots.shift || list.length
|
17
|
+
list[i] = x
|
18
|
+
end
|
19
|
+
def add_list(l)
|
20
|
+
blank_spots!
|
21
|
+
l.each { |x| self << x }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
include FromHash
|
25
|
+
fattr(:list) { [] }
|
26
|
+
fattr(:options) { {} }
|
27
|
+
fattr(:lists) do
|
28
|
+
list.select { |x| x }.reject { |x| x.flat_all_nil? }#.map { |x| x.kind_of?(Array) ? x : [x] }
|
29
|
+
end
|
30
|
+
fattr(:flat_args) do
|
31
|
+
res = ArrayWithBlanks.new
|
32
|
+
lists.each do |a|
|
33
|
+
res.add_list(a)
|
34
|
+
end
|
35
|
+
res << options unless options.empty?
|
36
|
+
res.list
|
37
|
+
end
|
38
|
+
def each(&b)
|
39
|
+
flat_args.each(&b)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'readline'
|
2
|
+
|
3
|
+
Readline.basic_word_break_characters = ""
|
4
|
+
Readline.completion_proc = lambda do |s|
|
5
|
+
#puts [s].inspect
|
6
|
+
LSL::Completion::Base.instance.new_instance(:full_command => s).matching_options
|
7
|
+
end
|
8
|
+
|
9
|
+
module LSL
|
10
|
+
module Completion
|
11
|
+
class Base
|
12
|
+
class << self
|
13
|
+
fattr(:instance) { new }
|
14
|
+
end
|
15
|
+
fattr(:mappings) { LSL::Completion::Mappings.new }
|
16
|
+
fattr(:instances) { [] }
|
17
|
+
include FromHash
|
18
|
+
def shell
|
19
|
+
LSL::Shell.instance
|
20
|
+
end
|
21
|
+
def new_instance(ops)
|
22
|
+
res = LSL::Completion::Instance.new(ops)
|
23
|
+
self.instances << res
|
24
|
+
res
|
25
|
+
end
|
26
|
+
end
|
27
|
+
class Mapping
|
28
|
+
include FromHash
|
29
|
+
fattr(:base) { LSL::Completion::Base.instance }
|
30
|
+
attr_accessor :command_matcher, :option_generator
|
31
|
+
def options
|
32
|
+
res = if option_generator.kind_of?(String)
|
33
|
+
base.shell.run(option_generator).result
|
34
|
+
else
|
35
|
+
option_generator.call
|
36
|
+
end
|
37
|
+
[res].flatten.select { |x| x }
|
38
|
+
end
|
39
|
+
def match?(cmd)
|
40
|
+
cmd =~ command_matcher
|
41
|
+
end
|
42
|
+
class << self
|
43
|
+
fattr(:file_matcher) do
|
44
|
+
new(:option_generator => "ls")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
class Mappings
|
49
|
+
fattr(:all) { [] }
|
50
|
+
def add(ops)
|
51
|
+
self.all << LSL::Completion::Mapping.new(ops)
|
52
|
+
end
|
53
|
+
def options(cmd)
|
54
|
+
res = all.find { |x| x.match?(cmd) }
|
55
|
+
return res.options if res
|
56
|
+
LSL::Completion::Mapping.file_matcher.options
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
class Instance
|
61
|
+
include FromHash
|
62
|
+
fattr(:base) { LSL::Completion::Base.instance }
|
63
|
+
def shell; base.shell; end
|
64
|
+
attr_accessor :full_command
|
65
|
+
fattr(:options) do
|
66
|
+
base.mappings.options(full_command)
|
67
|
+
end
|
68
|
+
fattr(:prefix) { full_command.split(" ").last }
|
69
|
+
fattr(:preceding) { full_command.split(" ")[0..-2].join(" ") }
|
70
|
+
|
71
|
+
fattr(:matching_options) do
|
72
|
+
options.grep(/^#{prefix}/i).map { |x| "#{preceding} #{x}".strip }
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
|
@@ -15,11 +15,7 @@ end
|
|
15
15
|
|
16
16
|
class Object
|
17
17
|
def array_aware_each(&b)
|
18
|
-
|
19
|
-
each(&b)
|
20
|
-
else
|
21
|
-
yield(self)
|
22
|
-
end
|
18
|
+
[self].flatten.each(&b)
|
23
19
|
end
|
24
20
|
def send_with_expansion(sym,*args,&b)
|
25
21
|
return send(sym,&b) if args.empty?
|
@@ -51,24 +47,10 @@ module LSL
|
|
51
47
|
m = LSL::Mapping.new
|
52
48
|
m.method(command) || simple_obj
|
53
49
|
end
|
54
|
-
fattr(:command_args) do
|
55
|
-
res = command.args
|
56
|
-
res << [command.options] unless command.options.empty?
|
57
|
-
res
|
58
|
-
end
|
59
|
-
def fixed_input_args
|
60
|
-
return [] unless input_args
|
61
|
-
return [] if input_args.respond_to?("empty?") && input_args.empty?
|
62
|
-
res = input_args
|
63
|
-
res = [res] unless res.kind_of?(Array)
|
64
|
-
#puts "ia #{res.inspect}"
|
65
|
-
res
|
66
|
-
[res]
|
67
|
-
end
|
68
50
|
fattr(:args) do
|
69
|
-
|
51
|
+
LSL::CommandExecution::Args.new(:list => [command.args, [input_args]], :options => command.options).flat_args
|
70
52
|
end
|
71
|
-
def my_eval(ops
|
53
|
+
def my_eval(str,ops)
|
72
54
|
OpenStruct.new(ops).instance_eval(str)
|
73
55
|
rescue => exp
|
74
56
|
puts "failed #{exp.message}"
|
@@ -83,12 +65,13 @@ module LSL
|
|
83
65
|
res << my_eval(command.raw[1..-2],:args => a, :arg => a.first)
|
84
66
|
end
|
85
67
|
end
|
86
|
-
#puts res.inspect
|
87
68
|
res
|
88
69
|
elsif obj.respond_to?(command.method)
|
89
|
-
|
90
|
-
|
91
|
-
|
70
|
+
if command.inbound_pipe == '^'
|
71
|
+
obj.send(command.method,*args)
|
72
|
+
else
|
73
|
+
obj.send_with_expansion(command.method,*args)
|
74
|
+
end
|
92
75
|
else
|
93
76
|
`#{command.raw}`.output_to_array
|
94
77
|
end
|
@@ -113,16 +96,20 @@ module LSL
|
|
113
96
|
end
|
114
97
|
def run!
|
115
98
|
if !command
|
116
|
-
puts "
|
99
|
+
#puts "|#{command_str}|"
|
100
|
+
puts "can't parsex"
|
117
101
|
return
|
118
102
|
end
|
119
103
|
command_executions
|
120
104
|
if command.output_filename
|
121
105
|
::File.create(command.output_filename,result.join("\n"))
|
122
106
|
else
|
123
|
-
puts result_str if result
|
107
|
+
#puts result_str if result
|
124
108
|
end
|
125
109
|
end
|
110
|
+
def print!
|
111
|
+
puts result_str if result
|
112
|
+
end
|
126
113
|
def result
|
127
114
|
command_executions.last.result
|
128
115
|
end
|
data/lib/lsl/command/single.rb
CHANGED
data/lib/lsl/dsl/dsl.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
module LSL
|
2
|
+
def self.configure
|
3
|
+
d = LSL::DSL::Base.new
|
4
|
+
yield(d)
|
5
|
+
d.run!
|
6
|
+
end
|
7
|
+
module DSL
|
8
|
+
class Base
|
9
|
+
dsl_method_arr :completion
|
10
|
+
def run!
|
11
|
+
completion.each do |c|
|
12
|
+
LSL::Completion::Base.instance.mappings.add(c)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
def mapping(n,&b)
|
16
|
+
LSL::ShellLike.send(:define_method,n) do |*args|
|
17
|
+
b.call
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/lsl/ext/ext.rb
CHANGED
@@ -16,28 +16,63 @@ class Object
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
+
class Object
|
20
|
+
def send_if_respond(meth)
|
21
|
+
respond_to?(meth) ? send(meth) : nil
|
22
|
+
end
|
23
|
+
def get_spaced_node(meth)
|
24
|
+
parent = send("spaced_#{meth}")
|
25
|
+
parent.send_if_respond(meth)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
19
29
|
class Object
|
20
30
|
def list_values
|
21
31
|
elements.map { |x| x.text_value.strip }.map { |x| x.split(" ") }.flatten.map { |x| x.strip }.select { |x| x.present? }.map { |x| x.unquoted }
|
22
32
|
end
|
23
|
-
|
24
|
-
|
33
|
+
end
|
34
|
+
|
35
|
+
class Array
|
36
|
+
def flat_all_nil?
|
37
|
+
flatten.select { |x| x }.empty?
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class Object
|
42
|
+
def dsl_method(meth,ops={})
|
43
|
+
define_method(meth) do |*args|
|
44
|
+
if args.size > 0
|
45
|
+
send("#{meth}=",*args)
|
46
|
+
elsif false && b
|
47
|
+
send("#{meth}=",b)
|
48
|
+
else
|
49
|
+
instance_variable_get("@#{meth}")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
attr_writer meth
|
53
|
+
define_method("#{meth}!") do
|
54
|
+
send("#{meth}=",true)
|
55
|
+
end
|
25
56
|
end
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
#puts
|
31
|
-
if
|
32
|
-
|
57
|
+
def dsl_method_arr(meth,ops={},&obj_blk)
|
58
|
+
define_method(meth) do |*args|
|
59
|
+
#puts 'start'
|
60
|
+
send("#{meth}=",[]) unless instance_variable_get("@#{meth}")
|
61
|
+
#puts 'start set'
|
62
|
+
if args.size == 1
|
63
|
+
instance_variable_get("@#{meth}") << args.first
|
64
|
+
elsif args.size == 2
|
65
|
+
arg = args[1]
|
66
|
+
arg[:name] = args.first
|
67
|
+
instance_variable_get("@#{meth}") << arg
|
68
|
+
elsif false && b
|
69
|
+
instance_variable_get("@#{meth}") << b
|
33
70
|
else
|
34
|
-
res
|
71
|
+
res = instance_variable_get("@#{meth}")
|
72
|
+
res = res.map { |x| obj_blk[x,self] } if obj_blk
|
73
|
+
res
|
35
74
|
end
|
36
75
|
end
|
37
|
-
|
38
|
-
res
|
76
|
+
attr_writer meth
|
39
77
|
end
|
40
|
-
|
41
|
-
find_child_node(node)
|
42
|
-
end
|
43
|
-
end
|
78
|
+
end
|
@@ -3,25 +3,27 @@ module LSL
|
|
3
3
|
include LSL::SingleCommand
|
4
4
|
include LSL::File
|
5
5
|
rule full_command
|
6
|
-
some_command (ows
|
6
|
+
some_command more:(ows pipe ows some_command)* spaced_filename:(ows ">" ows filename)? {
|
7
7
|
def filename
|
8
|
-
|
8
|
+
get_spaced_node(:filename)
|
9
9
|
end
|
10
10
|
def single_commands
|
11
|
-
|
12
11
|
res = [some_command.command_hash]
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
res += more.elements.map do |x|
|
13
|
+
single = x.some_command.command_hash
|
14
|
+
single.inbound_pipe = x.pipe.text_value
|
15
|
+
single
|
16
|
+
end if more
|
17
|
+
res
|
17
18
|
end
|
18
19
|
def command_hash
|
19
|
-
|
20
|
-
res.output_filename = filename.text_value if filename
|
21
|
-
res
|
20
|
+
LSL::Command::Compound.new(:commands => single_commands, :output_filename => filename.andand.text_value)
|
22
21
|
end
|
23
22
|
}
|
24
23
|
end
|
24
|
+
rule pipe
|
25
|
+
"|" / "^"
|
26
|
+
end
|
25
27
|
rule eval_str
|
26
28
|
"{" (!"}" .)+ "}" {
|
27
29
|
def command_hash
|
@@ -2,10 +2,21 @@ module LSL
|
|
2
2
|
grammar Quoting
|
3
3
|
include LSL::Base
|
4
4
|
rule optionally_quoted_string
|
5
|
-
quoted_string /
|
5
|
+
quoted_string / unquoted_word
|
6
|
+
end
|
7
|
+
rule unquoted_word
|
8
|
+
word {
|
9
|
+
def unquotedx
|
10
|
+
text_value
|
11
|
+
end
|
12
|
+
}
|
6
13
|
end
|
7
14
|
rule quoted_string
|
8
|
-
'"' quoteless_string '"'
|
15
|
+
'"' quoteless_string '"' {
|
16
|
+
def unquotedx
|
17
|
+
quoteless_string.text_value
|
18
|
+
end
|
19
|
+
}
|
9
20
|
end
|
10
21
|
rule quoteless_string
|
11
22
|
(!'"' . quoteless_string) / ""
|
@@ -3,16 +3,16 @@ module LSL
|
|
3
3
|
include LSL::Quoting
|
4
4
|
include LSL::List
|
5
5
|
rule single_command
|
6
|
-
ex (ws args)? (ws options)? {
|
6
|
+
ex spaced_args:(ws args)? spaced_options:(ws options)? {
|
7
7
|
def args
|
8
|
-
|
8
|
+
get_spaced_node(:args)
|
9
9
|
end
|
10
10
|
def options
|
11
|
-
|
11
|
+
get_spaced_node(:options)
|
12
12
|
end
|
13
13
|
def command_hash
|
14
14
|
LSL::Command::Single.new(:raw => text_value, :ex => ex.text_value,
|
15
|
-
:args => args.andand.
|
15
|
+
:args => args.andand.arg_values || [], :options => options.andand.hash_values || {})
|
16
16
|
end
|
17
17
|
}
|
18
18
|
end
|
@@ -25,29 +25,27 @@ module LSL
|
|
25
25
|
comma_list
|
26
26
|
end
|
27
27
|
rule args
|
28
|
-
arg (ws
|
28
|
+
arg spaced_args:(ws args)? {
|
29
|
+
def arg_values
|
30
|
+
[arg.unquotedx] + (get_spaced_node(:args).andand.arg_values || [])
|
31
|
+
end
|
32
|
+
}
|
29
33
|
end
|
30
34
|
|
31
35
|
rule option_flag
|
32
|
-
'-' word
|
36
|
+
'-' 1..2 word
|
33
37
|
end
|
34
38
|
rule option
|
35
|
-
option_flag (ws optionally_quoted_string)? {
|
39
|
+
option_flag spaced_option_value:(ws option_value:optionally_quoted_string)? {
|
36
40
|
def kv
|
37
|
-
|
38
|
-
{option_flag.word.text_value => n.andand.text_value}
|
41
|
+
{option_flag.word.text_value => get_spaced_node(:option_value).andand.unquotedx}
|
39
42
|
end
|
40
43
|
}
|
41
44
|
end
|
42
45
|
rule options
|
43
|
-
option (ws
|
46
|
+
option spaced_options:(ws options)? {
|
44
47
|
def hash_values
|
45
|
-
|
46
|
-
elements[1..-1].each do |e|
|
47
|
-
n = e.find_child_node2(:option)
|
48
|
-
res = res.merge(n.kv) if n
|
49
|
-
end
|
50
|
-
res
|
48
|
+
option.kv.merge(get_spaced_node(:options).andand.hash_values || {})
|
51
49
|
end
|
52
50
|
}
|
53
51
|
end
|
data/lib/lsl/junk.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
class Object
|
2
|
+
def list_values
|
3
|
+
elements.map { |x| x.text_value.strip }.map { |x| x.split(" ") }.flatten.map { |x| x.strip }.select { |x| x.present? }.map { |x| x.unquoted }
|
4
|
+
end
|
5
|
+
def find_child_nodexx(node)
|
6
|
+
find_child_nodes(node).first
|
7
|
+
end
|
8
|
+
def find_child_nodesxx(node)
|
9
|
+
return [] unless elements
|
10
|
+
res = []
|
11
|
+
elements.each do |e|
|
12
|
+
#puts e.inspect if $debug and node.to_s == 'single_command'
|
13
|
+
if e.respond_to?(node)
|
14
|
+
res << e.send(node)
|
15
|
+
else
|
16
|
+
res += e.find_child_nodes(node)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
#return send(node) if respond_to?(node)
|
20
|
+
res
|
21
|
+
end
|
22
|
+
def find_child_node2x(node)
|
23
|
+
find_child_node(node)
|
24
|
+
end
|
25
|
+
end
|
data/lib/lsl/shell.rb
CHANGED
@@ -15,13 +15,16 @@ $printed ||= []
|
|
15
15
|
module LSL
|
16
16
|
module ShellLike
|
17
17
|
module Inner
|
18
|
+
def pipe(*args)
|
19
|
+
args
|
20
|
+
end
|
18
21
|
def echo(*args)
|
19
22
|
#puts args.inspect
|
20
23
|
ops = (args.last.kind_of?(Hash) ? args.pop : {})
|
21
24
|
str = args.join(" ")
|
22
25
|
str = str.upcase if ops.has_key?('upper')
|
23
|
-
puts str
|
24
|
-
|
26
|
+
#puts str
|
27
|
+
str
|
25
28
|
end
|
26
29
|
def echot(*args)
|
27
30
|
echo(*args)
|
@@ -47,6 +50,7 @@ module LSL
|
|
47
50
|
puts a.length * b.length
|
48
51
|
end
|
49
52
|
def cc(*args)
|
53
|
+
puts "cc args #{args.inspect}"
|
50
54
|
args.reverse.join("")
|
51
55
|
end
|
52
56
|
def la(*args)
|
@@ -68,6 +72,35 @@ module LSL
|
|
68
72
|
def pt(a,b)
|
69
73
|
puts a==b
|
70
74
|
end
|
75
|
+
def get(url)
|
76
|
+
require 'open-uri'
|
77
|
+
open(url).read
|
78
|
+
end
|
79
|
+
def p(*args)
|
80
|
+
ec "python -c " + args.join(" ")
|
81
|
+
end
|
82
|
+
def without_left(n,arg)
|
83
|
+
arg[n.to_i..-1]
|
84
|
+
end
|
85
|
+
def sub(a,b,arg)
|
86
|
+
arg[a.to_i..b.to_i]
|
87
|
+
end
|
88
|
+
def crop_top(arr,i)
|
89
|
+
arr[i.to_i..-1]
|
90
|
+
end
|
91
|
+
def column(arr,a,b)
|
92
|
+
arr.map { |x| x[a.to_i..b.to_i].andand.strip }
|
93
|
+
end
|
94
|
+
def sum(*args)
|
95
|
+
args.flatten.inject(0.0) { |s,i| s + i.to_f }
|
96
|
+
end
|
97
|
+
def sumt(*args)
|
98
|
+
args.flatten.inject { |s,i| s + (i.kind_of?(String) ? i.to_f : i) }
|
99
|
+
end
|
100
|
+
def remove(str,c)
|
101
|
+
str.gsub(c,"").strip
|
102
|
+
end
|
103
|
+
|
71
104
|
end
|
72
105
|
include FileUtils
|
73
106
|
include Inner
|
@@ -79,26 +112,32 @@ module LSL
|
|
79
112
|
end
|
80
113
|
|
81
114
|
class Shell
|
115
|
+
class << self
|
116
|
+
fattr(:instance) { new }
|
117
|
+
end
|
118
|
+
attr_accessor :last_execution
|
82
119
|
fattr(:env) { LSL::CommandEnv.new }
|
83
120
|
fattr(:parser) { LSL::CompoundCommandParser.new }
|
84
121
|
def run(str)
|
85
|
-
LSL::CommandExecution::Compound.new(:command_str => str, :shell => self).tap { |x| x.run! }
|
122
|
+
self.last_execution = LSL::CommandExecution::Compound.new(:command_str => str, :shell => self).tap { |x| x.run! }
|
86
123
|
end
|
87
124
|
def get_input
|
88
|
-
STDIN.gets.strip
|
125
|
+
#STDIN.gets.strip
|
126
|
+
require 'readline'
|
127
|
+
Readline.readline("#{Dir.getwd}> ",true).strip
|
89
128
|
end
|
90
129
|
def run_loop
|
91
130
|
loop do
|
92
|
-
print "#{Dir.getwd}> "
|
93
131
|
str = get_input
|
94
132
|
run(str)
|
133
|
+
last_execution.print!
|
95
134
|
end
|
96
135
|
end
|
97
136
|
end
|
98
137
|
end
|
99
138
|
|
100
139
|
def run_shell!(obj=nil)
|
101
|
-
s = LSL::Shell.
|
140
|
+
s = LSL::Shell.instance
|
102
141
|
s.env = obj if obj
|
103
142
|
s.run_loop
|
104
143
|
end
|
data/lsl.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{lsl}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["mharris717"]
|
12
|
-
s.date = %q{
|
12
|
+
s.date = %q{2011-01-03}
|
13
13
|
s.default_executable = %q{lsl}
|
14
14
|
s.description = %q{little shell language}
|
15
15
|
s.email = %q{mharris717@gmail.com}
|
@@ -29,9 +29,12 @@ Gem::Specification.new do |s|
|
|
29
29
|
"VERSION",
|
30
30
|
"bin/lsl",
|
31
31
|
"lib/lsl.rb",
|
32
|
+
"lib/lsl/command/args.rb",
|
33
|
+
"lib/lsl/command/completion.rb",
|
32
34
|
"lib/lsl/command/compound.rb",
|
33
35
|
"lib/lsl/command/execution.rb",
|
34
36
|
"lib/lsl/command/single.rb",
|
37
|
+
"lib/lsl/dsl/dsl.rb",
|
35
38
|
"lib/lsl/ext/ext.rb",
|
36
39
|
"lib/lsl/grammars/base.treetop",
|
37
40
|
"lib/lsl/grammars/compound_command.treetop",
|
@@ -39,6 +42,7 @@ Gem::Specification.new do |s|
|
|
39
42
|
"lib/lsl/grammars/list.treetop",
|
40
43
|
"lib/lsl/grammars/quoting.treetop",
|
41
44
|
"lib/lsl/grammars/single_command.treetop",
|
45
|
+
"lib/lsl/junk.rb",
|
42
46
|
"lib/lsl/mapping/mapping.rb",
|
43
47
|
"lib/lsl/sandbox.rb",
|
44
48
|
"lib/lsl/server.rb",
|
@@ -36,6 +36,12 @@ describe "CompoundCommand" do
|
|
36
36
|
c.ex.should == 'ls'
|
37
37
|
c.args.should == ['c','d']
|
38
38
|
end
|
39
|
+
it 'many pipes' do
|
40
|
+
parse("cp a b | cp c d | cp e f | cp g h").command_hash.commands.size.should == 4
|
41
|
+
end
|
42
|
+
it 'inbound pipe' do
|
43
|
+
parse("cp a b ^ cp c d").command_hash.commands.last.inbound_pipe.should == '^'
|
44
|
+
end
|
39
45
|
describe "execution" do
|
40
46
|
it "each_command args" do
|
41
47
|
res = []
|
data/spec/quoting_spec.rb
CHANGED
@@ -20,6 +20,12 @@ describe "Quoting" do
|
|
20
20
|
it "unquoted phrase" do
|
21
21
|
parser.should_not be_parsed("abc xyz")
|
22
22
|
end
|
23
|
+
it 'has unquoted method for quoted phrase' do
|
24
|
+
parser.parse('"abc xyz"').unquotedx.should == 'abc xyz'
|
25
|
+
end
|
26
|
+
it 'has unquoted method for unquoted word' do
|
27
|
+
parser.parse('abc').unquotedx.should == 'abc'
|
28
|
+
end
|
23
29
|
#it "escaped quotes"
|
24
30
|
end
|
25
31
|
|
data/spec/shell_spec.rb
CHANGED
@@ -14,7 +14,7 @@ describe "Shell" do
|
|
14
14
|
end
|
15
15
|
it 'piping' do
|
16
16
|
@shell.run('ls VERSION | pf')
|
17
|
-
$printed.should == ['0.1.
|
17
|
+
$printed.should == ['0.1.1']
|
18
18
|
end
|
19
19
|
it 'foo' do
|
20
20
|
#30.times do
|
@@ -28,15 +28,28 @@ describe "Shell" do
|
|
28
28
|
run("ls Gemfile*").result.should == ['Gemfile','Gemfile.lock']
|
29
29
|
end
|
30
30
|
it 'remote call' do
|
31
|
-
run("remote_call foo").result.should == 'rc'
|
32
|
-
run("remote_call foo | echo")
|
31
|
+
#run("remote_call foo").result.should == 'rc'
|
32
|
+
#run("remote_call foo | echo")
|
33
33
|
end
|
34
34
|
it 'rake' do
|
35
35
|
#run("abc").result.should == "ran"
|
36
36
|
end
|
37
37
|
it 'eval' do
|
38
|
-
run("{2 + 2}").result.should == 4
|
38
|
+
run("{2 + 2}").result.should == [4]
|
39
39
|
end
|
40
|
+
it 'underscore' do
|
41
|
+
run("echo \"Gemfile*\" | ls").result.should == ['Gemfile','Gemfile.lock']
|
42
|
+
run("echo \"Gemfile*\" | ls _").result.should == ['Gemfile','Gemfile.lock']
|
43
|
+
end
|
44
|
+
it 'underscore 2' do
|
45
|
+
run("pipe a b | cc _ x").result.should == ['xa','xb']
|
46
|
+
run("echo a | cc _ x").result.should == 'xa'
|
47
|
+
end
|
48
|
+
it 'splat pipe' do
|
49
|
+
run('pipe a b | echo').result.should == ['a','b']
|
50
|
+
run('pipe a b ^ echo').result.should == 'a b'
|
51
|
+
end
|
52
|
+
|
40
53
|
describe 'output redirection' do
|
41
54
|
before do
|
42
55
|
@file = "spec/mock_dir/output.txt"
|
data/spec/single_command_spec.rb
CHANGED
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 2
|
8
|
+
- 0
|
9
|
+
version: 0.2.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- mharris717
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date:
|
17
|
+
date: 2011-01-03 00:00:00 -05:00
|
18
18
|
default_executable: lsl
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -127,9 +127,12 @@ files:
|
|
127
127
|
- VERSION
|
128
128
|
- bin/lsl
|
129
129
|
- lib/lsl.rb
|
130
|
+
- lib/lsl/command/args.rb
|
131
|
+
- lib/lsl/command/completion.rb
|
130
132
|
- lib/lsl/command/compound.rb
|
131
133
|
- lib/lsl/command/execution.rb
|
132
134
|
- lib/lsl/command/single.rb
|
135
|
+
- lib/lsl/dsl/dsl.rb
|
133
136
|
- lib/lsl/ext/ext.rb
|
134
137
|
- lib/lsl/grammars/base.treetop
|
135
138
|
- lib/lsl/grammars/compound_command.treetop
|
@@ -137,6 +140,7 @@ files:
|
|
137
140
|
- lib/lsl/grammars/list.treetop
|
138
141
|
- lib/lsl/grammars/quoting.treetop
|
139
142
|
- lib/lsl/grammars/single_command.treetop
|
143
|
+
- lib/lsl/junk.rb
|
140
144
|
- lib/lsl/mapping/mapping.rb
|
141
145
|
- lib/lsl/sandbox.rb
|
142
146
|
- lib/lsl/server.rb
|