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 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