ruco 0.0.50 → 0.0.51

Sign up to get free protection for your applications and to get access to all the features.
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 only) or 'select mode' Ctrl+b + arrow-keys
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.50
1
+ 0.0.51
data/bin/ruco CHANGED
@@ -137,4 +137,4 @@ init_screen do
137
137
  break if result == :quit
138
138
  show_app app
139
139
  end
140
- end
140
+ end
@@ -19,9 +19,8 @@ module Ruco
19
19
  end
20
20
 
21
21
  def style_map
22
- reverse = StyleMap.new(1)
23
- reverse.add(:reverse, 0, 0...@options[:columns])
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
@@ -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
@@ -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{|s,c|c.last}.max
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
- def self.curses_style(styles)
87
- styles.sum{|style| STYLES[style] or raise("Unknown style #{style}") }
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.50"
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-21}
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.4.2}
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
- end
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
@@ -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
- [[:reverse], nil, nil, nil, nil, []],
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, [:reverse], nil, nil, nil, nil, []],
508
- [[:reverse], nil, []],
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, [:reverse], 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, [:reverse], 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, [:reverse], nil, nil, nil, nil, []], # start to end of screen
551
- [[:reverse], nil, nil, nil, nil, nil, []], # 0 to end of screen
552
- [[:reverse], nil, nil, []] # 0 to end of selection
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
@@ -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, [:red], 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, [:reverse], [:reverse, :red], nil, [:red], []],
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
- [[:reverse], nil, []],
41
- [nil, nil, [:reverse], 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 == [[[:reverse],nil,[]]]
51
- s.flatten.should == [[nil, [:reverse],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, [:reverse],nil,[]]]
59
- s.flatten.should == [[[:reverse],nil,[]]]
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 == [[[], "a"]]
102
+ Ruco::StyleMap.styled("a", nil).should == [[:normal, "a"]]
66
103
  end
67
104
 
68
- it "can style an styled line" do
69
- Ruco::StyleMap.styled("a", [[:reverse],nil]).should == [[[], ""], [[:reverse], "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", [[:reverse],[]]).should == [[[], ""], [[:reverse], "a"],[[],'bc']]
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([]).should == Curses::A_NORMAL
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([:red]).should == Curses::color_pair( Curses::COLOR_RED )
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([:reverse]).should == Curses::A_REVERSE
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([:foo])
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
- hash: 123
5
- prerelease:
4
+ prerelease: false
6
5
  segments:
7
6
  - 0
8
7
  - 0
9
- - 50
10
- version: 0.0.50
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-21 00:00:00 +01:00
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: 3
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.4.2
119
+ rubygems_version: 1.3.7
123
120
  signing_key:
124
121
  specification_version: 3
125
122
  summary: Commandline editor written in ruby