ruco 0.0.50 → 0.0.51
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.
- data/Readme.md +2 -5
- data/VERSION +1 -1
- data/bin/ruco +1 -1
- data/lib/ruco/application.rb +2 -3
- data/lib/ruco/command_bar.rb +14 -2
- data/lib/ruco/form.rb +7 -1
- data/lib/ruco/style_map.rb +43 -14
- data/ruco.gemspec +4 -3
- data/spec/ruco/command_bar_spec.rb +17 -1
- data/spec/ruco/editor_spec.rb +9 -9
- data/spec/ruco/style_map_spec.rb +55 -18
- metadata +8 -11
data/Readme.md
CHANGED
@@ -3,7 +3,7 @@ Simple, extendable, test-driven commandline editor written in ruby.
|
|
3
3
|
Features:
|
4
4
|
|
5
5
|
- **Intuitive interface**
|
6
|
-
- selecting via Shift + arrow-keys (Linux
|
6
|
+
- selecting via Shift + arrow-keys (only Linux or iTerm) or 'select mode' Ctrl+b + arrow-keys
|
7
7
|
- move line up/down (Alt+Ctrl+up/down)
|
8
8
|
- Tab -> indent / Shift+Tab -> unindent
|
9
9
|
- keeps indentation (+ paste-detection e.g. via Cmd+v)
|
@@ -69,6 +69,7 @@ Customize
|
|
69
69
|
|
70
70
|
TIPS
|
71
71
|
====
|
72
|
+
- [Mac] arow-keys + Shift/Alt does not work in default terminal (use iTerm)
|
72
73
|
- [Tabs] Ruco does not like tabs. Existing tabs are displayed as ' ' and pressing tab inserts 2*' '
|
73
74
|
- [RVM] `alias r="rvm ree exec ruco"` and you only have to install ruco once
|
74
75
|
- [Ruby1.9] Unicode support -> install libncursesw5-dev before installing ruby (does not work for 1.8)
|
@@ -78,11 +79,9 @@ TIPS
|
|
78
79
|
TODO
|
79
80
|
=====
|
80
81
|
- align soft-tabs
|
81
|
-
- handle \\r and \\r\\n nicely <-> breaks curses output
|
82
82
|
- highlight tabs (e.g. strange character or reverse/underline/color)
|
83
83
|
- big warning when editing a not-writable file
|
84
84
|
- find next (Alt+n)
|
85
|
-
- add selection colors to forms in command_bar
|
86
85
|
- smart staying at column when changing line
|
87
86
|
- syntax highlighting
|
88
87
|
- raise when binding to a unsupported key
|
@@ -90,8 +89,6 @@ TODO
|
|
90
89
|
- search options regex + case-sensitive
|
91
90
|
- add auto-confirm to 'replace?' dialog -> type s == skip, no enter needed
|
92
91
|
- 1.8: unicode support <-> already finished but unusable due to Curses (see encoding branch)
|
93
|
-
- support Alt+Fx keys
|
94
|
-
- (later) extract keyboard and html-style components into separate project
|
95
92
|
|
96
93
|
Author
|
97
94
|
======
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.51
|
data/bin/ruco
CHANGED
data/lib/ruco/application.rb
CHANGED
@@ -19,9 +19,8 @@ module Ruco
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def style_map
|
22
|
-
reverse = StyleMap.
|
23
|
-
reverse.
|
24
|
-
reverse + editor.style_map + reverse
|
22
|
+
reverse = StyleMap.single_line_reversed(@options[:columns])
|
23
|
+
reverse + editor.style_map + @command.style_map
|
25
24
|
end
|
26
25
|
|
27
26
|
def cursor
|
data/lib/ruco/command_bar.rb
CHANGED
@@ -9,7 +9,8 @@ module Ruco
|
|
9
9
|
'^F Find',
|
10
10
|
'^R Replace',
|
11
11
|
'^D Delete line',
|
12
|
-
'^G Go to line'
|
12
|
+
'^G Go to line',
|
13
|
+
'^B Select mode'
|
13
14
|
]
|
14
15
|
|
15
16
|
def initialize(options)
|
@@ -26,6 +27,17 @@ module Ruco
|
|
26
27
|
end
|
27
28
|
end
|
28
29
|
|
30
|
+
def style_map
|
31
|
+
if @form
|
32
|
+
map = @form.style_map
|
33
|
+
map.invert!
|
34
|
+
map.prepend(:reverse, 0, 0..@options[:columns])
|
35
|
+
map
|
36
|
+
else
|
37
|
+
StyleMap.single_line_reversed(@options[:columns])
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
29
41
|
def ask(question, options={}, &block)
|
30
42
|
@form = cached_form_if(options[:cache], question) do
|
31
43
|
Form.new(question, :columns => @options[:columns]) do |result|
|
@@ -72,4 +84,4 @@ module Ruco
|
|
72
84
|
shortcuts_that_fit * spacer
|
73
85
|
end
|
74
86
|
end
|
75
|
-
end
|
87
|
+
end
|
data/lib/ruco/form.rb
CHANGED
@@ -13,6 +13,12 @@ module Ruco
|
|
13
13
|
@label + @text_field.view
|
14
14
|
end
|
15
15
|
|
16
|
+
def style_map
|
17
|
+
map = @text_field.style_map
|
18
|
+
map.left_pad!(@label.size)
|
19
|
+
map
|
20
|
+
end
|
21
|
+
|
16
22
|
def insert(text)
|
17
23
|
@text_field.insert(text.gsub("\n",''))
|
18
24
|
@submit.call(@text_field.value) if text.include?("\n")
|
@@ -30,4 +36,4 @@ module Ruco
|
|
30
36
|
|
31
37
|
attr_reader :text_field
|
32
38
|
end
|
33
|
-
end
|
39
|
+
end
|
data/lib/ruco/style_map.rb
CHANGED
@@ -11,29 +11,51 @@ module Ruco
|
|
11
11
|
@lines[line] << [style, columns]
|
12
12
|
end
|
13
13
|
|
14
|
+
def prepend(style, line, columns)
|
15
|
+
@lines[line] ||= []
|
16
|
+
@lines[line].unshift [style, columns]
|
17
|
+
end
|
18
|
+
|
14
19
|
def flatten
|
15
20
|
@lines.map do |styles|
|
16
21
|
next unless styles
|
17
22
|
|
18
23
|
# start and one after end of every column-range changes styles
|
19
|
-
points_of_change = styles.map{|s,c| [c.first, c.last+1] }.flatten
|
24
|
+
points_of_change = styles.map{|s,c| [c.first, c.last+1] }.flatten.uniq
|
20
25
|
|
21
26
|
flat = []
|
22
27
|
|
23
28
|
styles.each do |style, columns|
|
24
29
|
points_of_change.each do |point|
|
25
30
|
next unless columns.include?(point)
|
26
|
-
flat[point]
|
27
|
-
flat[point].unshift style
|
31
|
+
flat[point] = style
|
28
32
|
end
|
29
33
|
end
|
30
34
|
|
31
|
-
max = styles.map{|
|
32
|
-
flat[max+1] =
|
35
|
+
max = styles.map{|_,columns| columns.last }.max
|
36
|
+
flat[max+1] = :normal
|
33
37
|
flat
|
34
38
|
end
|
35
39
|
end
|
36
40
|
|
41
|
+
def left_pad!(offset)
|
42
|
+
@lines.compact.each do |styles|
|
43
|
+
next unless styles
|
44
|
+
styles.map! do |style, columns|
|
45
|
+
[style, (columns.first + offset)..(columns.last + offset)]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def invert!
|
51
|
+
map = {:reverse => :normal, :normal => :reverse}
|
52
|
+
@lines.compact.each do |styles|
|
53
|
+
styles.map! do |style, columns|
|
54
|
+
[map[style] || style, columns]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
37
59
|
def +(other)
|
38
60
|
lines = self.lines + other.lines
|
39
61
|
new = StyleMap.new(0)
|
@@ -55,18 +77,13 @@ module Ruco
|
|
55
77
|
def pop
|
56
78
|
slice!(-1, 1)
|
57
79
|
end
|
58
|
-
|
59
|
-
STYLES = {
|
60
|
-
:normal => 0,
|
61
|
-
:reverse => Curses::A_REVERSE
|
62
|
-
}
|
63
80
|
|
64
81
|
def self.styled(content, styles)
|
65
82
|
styles ||= []
|
66
83
|
content = content.dup
|
67
84
|
|
68
85
|
build = []
|
69
|
-
build << [
|
86
|
+
build << [:normal]
|
70
87
|
|
71
88
|
buffered = ''
|
72
89
|
styles.each do |style|
|
@@ -83,8 +100,20 @@ module Ruco
|
|
83
100
|
build
|
84
101
|
end
|
85
102
|
|
86
|
-
|
87
|
-
|
103
|
+
STYLES = {
|
104
|
+
:normal => 0,
|
105
|
+
:reverse => Curses::A_REVERSE
|
106
|
+
}
|
107
|
+
|
108
|
+
def self.curses_style(style)
|
109
|
+
return 0 unless style
|
110
|
+
STYLES[style] or raise("Unknown style #{style.inspect}")
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.single_line_reversed(columns)
|
114
|
+
map = StyleMap.new(1)
|
115
|
+
map.add(:reverse, 0, 0...columns)
|
116
|
+
map
|
88
117
|
end
|
89
118
|
end
|
90
|
-
end
|
119
|
+
end
|
data/ruco.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{ruco}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.51"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Michael Grosser"]
|
12
|
-
s.date = %q{2011-02-
|
12
|
+
s.date = %q{2011-02-24}
|
13
13
|
s.default_executable = %q{ruco}
|
14
14
|
s.email = %q{michael@grosser.it}
|
15
15
|
s.executables = ["ruco"]
|
@@ -63,7 +63,7 @@ Gem::Specification.new do |s|
|
|
63
63
|
]
|
64
64
|
s.homepage = %q{http://github.com/grosser/ruco}
|
65
65
|
s.require_paths = ["lib"]
|
66
|
-
s.rubygems_version = %q{1.
|
66
|
+
s.rubygems_version = %q{1.3.7}
|
67
67
|
s.summary = %q{Commandline editor written in ruby}
|
68
68
|
s.test_files = [
|
69
69
|
"spec/ruco/application_spec.rb",
|
@@ -85,6 +85,7 @@ Gem::Specification.new do |s|
|
|
85
85
|
]
|
86
86
|
|
87
87
|
if s.respond_to? :specification_version then
|
88
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
88
89
|
s.specification_version = 3
|
89
90
|
|
90
91
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
@@ -89,4 +89,20 @@ describe Ruco::CommandBar do
|
|
89
89
|
@result.should == 'abcd'
|
90
90
|
end
|
91
91
|
end
|
92
|
-
|
92
|
+
|
93
|
+
describe :style_map do
|
94
|
+
let(:bar){ Ruco::CommandBar.new(:columns => 10) }
|
95
|
+
|
96
|
+
it "is reverse" do
|
97
|
+
bar.style_map.flatten.should == [[:reverse, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, :normal]]
|
98
|
+
end
|
99
|
+
|
100
|
+
it "has normal style for selected input field" do
|
101
|
+
bar.ask('Q'){}
|
102
|
+
bar.insert('abc')
|
103
|
+
bar.selecting{ move(:to, 0,0) }
|
104
|
+
bar.view.should == 'Q abc'
|
105
|
+
bar.style_map.flatten.should == [[:reverse, nil, :normal, nil, nil, nil, :reverse, nil, nil, nil, nil, :normal]]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
data/spec/ruco/editor_spec.rb
CHANGED
@@ -121,7 +121,7 @@ describe Ruco::Editor do
|
|
121
121
|
read.should == "aaa\n\n"
|
122
122
|
end
|
123
123
|
end
|
124
|
-
|
124
|
+
|
125
125
|
describe 'convert tabs' do
|
126
126
|
before do
|
127
127
|
write("\t\ta")
|
@@ -491,7 +491,7 @@ describe Ruco::Editor do
|
|
491
491
|
move(:to, 0, 4)
|
492
492
|
end
|
493
493
|
editor.style_map.flatten.should == [
|
494
|
-
[
|
494
|
+
[:reverse, nil, nil, nil, nil, :normal],
|
495
495
|
nil,
|
496
496
|
nil
|
497
497
|
]
|
@@ -504,8 +504,8 @@ describe Ruco::Editor do
|
|
504
504
|
move(:to, 1, 1)
|
505
505
|
end
|
506
506
|
editor.style_map.flatten.should == [
|
507
|
-
[nil,
|
508
|
-
[
|
507
|
+
[nil, :reverse, nil, nil, nil, nil, :normal],
|
508
|
+
[:reverse, nil, :normal],
|
509
509
|
nil
|
510
510
|
]
|
511
511
|
end
|
@@ -517,7 +517,7 @@ describe Ruco::Editor do
|
|
517
517
|
move(:to, 0, 4)
|
518
518
|
end
|
519
519
|
editor.style_map.flatten.should == [
|
520
|
-
[nil, nil,
|
520
|
+
[nil, nil, :reverse, nil, nil, :normal],
|
521
521
|
nil,
|
522
522
|
nil
|
523
523
|
]
|
@@ -531,7 +531,7 @@ describe Ruco::Editor do
|
|
531
531
|
end
|
532
532
|
editor.style_map.flatten.should == [
|
533
533
|
nil,
|
534
|
-
[nil, nil,
|
534
|
+
[nil, nil, :reverse, nil, nil, :normal],
|
535
535
|
nil
|
536
536
|
]
|
537
537
|
end
|
@@ -547,9 +547,9 @@ describe Ruco::Editor do
|
|
547
547
|
editor.view.should == "789\n789\n789\n"
|
548
548
|
editor.cursor.should == [2,2]
|
549
549
|
editor.style_map.flatten.should == [
|
550
|
-
[nil,
|
551
|
-
[
|
552
|
-
[
|
550
|
+
[nil, :reverse, nil, nil, nil, nil, :normal], # start to end of screen
|
551
|
+
[:reverse, nil, nil, nil, nil, nil, :normal], # 0 to end of screen
|
552
|
+
[:reverse, nil, nil, :normal] # 0 to end of selection
|
553
553
|
]
|
554
554
|
end
|
555
555
|
end
|
data/spec/ruco/style_map_spec.rb
CHANGED
@@ -13,18 +13,28 @@ describe Ruco::StyleMap do
|
|
13
13
|
# red from 3 to 5
|
14
14
|
map.flatten.should == [
|
15
15
|
nil,
|
16
|
-
[nil, nil, nil,
|
16
|
+
[nil, nil, nil, :red, nil, nil, :normal],
|
17
17
|
nil
|
18
18
|
]
|
19
19
|
end
|
20
20
|
|
21
21
|
it "reproduces merged styles" do
|
22
|
-
map.add(:red, 1, 3..5)
|
23
22
|
map.add(:reverse, 1, 2..4)
|
23
|
+
map.add(:red, 1, 3..5)
|
24
24
|
# reverse at 2 -- reverse and red at 3,4 -- red at 5
|
25
25
|
map.flatten.should == [
|
26
26
|
nil,
|
27
|
-
[nil, nil,
|
27
|
+
[nil, nil, :reverse, :red, nil, :red, :normal],
|
28
|
+
nil
|
29
|
+
]
|
30
|
+
end
|
31
|
+
|
32
|
+
it "overwrites styles" do
|
33
|
+
map.add(:reverse, 0, 0..1)
|
34
|
+
map.add(:normal, 0, 0..1)
|
35
|
+
map.flatten.should == [
|
36
|
+
[:normal, nil, :normal],
|
37
|
+
nil,
|
28
38
|
nil
|
29
39
|
]
|
30
40
|
end
|
@@ -37,8 +47,8 @@ describe Ruco::StyleMap do
|
|
37
47
|
s2 = Ruco::StyleMap.new(2)
|
38
48
|
s2.add(:reverse, 0, 2..3)
|
39
49
|
(s1 + s2).flatten.should == [
|
40
|
-
[
|
41
|
-
[nil, nil,
|
50
|
+
[:reverse, nil, :normal],
|
51
|
+
[nil, nil, :reverse, nil, :normal],
|
42
52
|
nil
|
43
53
|
]
|
44
54
|
end
|
@@ -47,51 +57,78 @@ describe Ruco::StyleMap do
|
|
47
57
|
s = Ruco::StyleMap.new(2)
|
48
58
|
s.add(:reverse, 0, 0..1)
|
49
59
|
s.add(:reverse, 1, 1..2)
|
50
|
-
s.shift.flatten.should == [[
|
51
|
-
s.flatten.should == [[nil,
|
60
|
+
s.shift.flatten.should == [[:reverse, nil, :normal]]
|
61
|
+
s.flatten.should == [[nil, :reverse, nil, :normal]]
|
52
62
|
end
|
53
63
|
|
54
64
|
it "can pop" do
|
55
65
|
s = Ruco::StyleMap.new(2)
|
56
66
|
s.add(:reverse, 0, 0..1)
|
57
67
|
s.add(:reverse, 1, 1..2)
|
58
|
-
s.pop.flatten.should == [[nil,
|
59
|
-
s.flatten.should == [[
|
68
|
+
s.pop.flatten.should == [[nil, :reverse, nil, :normal]]
|
69
|
+
s.flatten.should == [[:reverse, nil, :normal]]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe :left_pad! do
|
74
|
+
it "adds whitespace to left side" do
|
75
|
+
s = Ruco::StyleMap.new(2)
|
76
|
+
s.add(:reverse, 0, 0..1)
|
77
|
+
s.add(:reverse, 1, 1..2)
|
78
|
+
s.left_pad!(3)
|
79
|
+
s.flatten.should == [
|
80
|
+
[nil, nil, nil, :reverse, nil, :normal],
|
81
|
+
[nil, nil, nil, nil, :reverse, nil, :normal]
|
82
|
+
]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe :invert! do
|
87
|
+
it "inverts styles" do
|
88
|
+
s = Ruco::StyleMap.new(2)
|
89
|
+
s.add(:reverse, 0, 0..1)
|
90
|
+
s.add(:normal, 1, 1..2)
|
91
|
+
s.add(:red, 1, 4..5)
|
92
|
+
s.invert!
|
93
|
+
s.flatten.should == [
|
94
|
+
[:normal, nil, :normal],
|
95
|
+
[nil, :reverse, nil, nil, :red, nil, :normal]
|
96
|
+
]
|
60
97
|
end
|
61
98
|
end
|
62
99
|
|
63
100
|
describe :styled do
|
64
101
|
it "can style an unstyled line" do
|
65
|
-
Ruco::StyleMap.styled("a", nil).should == [[
|
102
|
+
Ruco::StyleMap.styled("a", nil).should == [[:normal, "a"]]
|
66
103
|
end
|
67
104
|
|
68
|
-
it "can style
|
69
|
-
Ruco::StyleMap.styled("a", [
|
105
|
+
it "can style a styled line" do
|
106
|
+
Ruco::StyleMap.styled("a", [:reverse ,nil]).should == [[:normal, ""], [:reverse, "a"]]
|
70
107
|
end
|
71
108
|
|
72
109
|
it "keeps unstyled parts" do
|
73
|
-
Ruco::StyleMap.styled("abc", [
|
110
|
+
Ruco::StyleMap.styled("abc", [:reverse, :normal]).should == [[:normal, ""], [:reverse, "a"],[:normal,'bc']]
|
74
111
|
end
|
75
112
|
end
|
76
113
|
|
77
114
|
describe :curses_style do
|
78
115
|
it "is 'normal' for nothing" do
|
79
|
-
Ruco::StyleMap.curses_style(
|
116
|
+
Ruco::StyleMap.curses_style(:normal).should == Curses::A_NORMAL
|
80
117
|
end
|
81
118
|
|
82
119
|
it "is red for red" do
|
83
120
|
pending
|
84
|
-
Ruco::StyleMap.curses_style(
|
121
|
+
Ruco::StyleMap.curses_style(:red).should == Curses::color_pair( Curses::COLOR_RED )
|
85
122
|
end
|
86
123
|
|
87
124
|
it "is reverse for reverse" do
|
88
|
-
Ruco::StyleMap.curses_style(
|
125
|
+
Ruco::StyleMap.curses_style(:reverse).should == Curses::A_REVERSE
|
89
126
|
end
|
90
127
|
|
91
128
|
it "raises on unknown style" do
|
92
129
|
lambda{
|
93
|
-
Ruco::StyleMap.curses_style(
|
130
|
+
Ruco::StyleMap.curses_style(:foo)
|
94
131
|
}.should raise_error
|
95
132
|
end
|
96
133
|
end
|
97
|
-
end
|
134
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruco
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
4
|
+
prerelease: false
|
6
5
|
segments:
|
7
6
|
- 0
|
8
7
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
8
|
+
- 51
|
9
|
+
version: 0.0.51
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Michael Grosser
|
@@ -15,25 +14,24 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date: 2011-02-
|
17
|
+
date: 2011-02-24 00:00:00 +01:00
|
19
18
|
default_executable: ruco
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
21
|
+
name: clipboard
|
22
22
|
requirement: &id001 !ruby/object:Gem::Requirement
|
23
23
|
none: false
|
24
24
|
requirements:
|
25
25
|
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
hash: 51
|
28
27
|
segments:
|
29
28
|
- 0
|
30
29
|
- 9
|
31
30
|
- 4
|
32
31
|
version: 0.9.4
|
32
|
+
type: :runtime
|
33
33
|
prerelease: false
|
34
34
|
version_requirements: *id001
|
35
|
-
type: :runtime
|
36
|
-
name: clipboard
|
37
35
|
description:
|
38
36
|
email: michael@grosser.it
|
39
37
|
executables:
|
@@ -103,7 +101,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
103
101
|
requirements:
|
104
102
|
- - ">="
|
105
103
|
- !ruby/object:Gem::Version
|
106
|
-
hash:
|
104
|
+
hash: 955347375
|
107
105
|
segments:
|
108
106
|
- 0
|
109
107
|
version: "0"
|
@@ -112,14 +110,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
112
110
|
requirements:
|
113
111
|
- - ">="
|
114
112
|
- !ruby/object:Gem::Version
|
115
|
-
hash: 3
|
116
113
|
segments:
|
117
114
|
- 0
|
118
115
|
version: "0"
|
119
116
|
requirements: []
|
120
117
|
|
121
118
|
rubyforge_project:
|
122
|
-
rubygems_version: 1.
|
119
|
+
rubygems_version: 1.3.7
|
123
120
|
signing_key:
|
124
121
|
specification_version: 3
|
125
122
|
summary: Commandline editor written in ruby
|