ruco 0.0.5 → 0.0.6

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
@@ -11,6 +11,7 @@ Finished:
11
11
  - writeable indicator
12
12
  - backspace / delete
13
13
  - find / go to line
14
+ - delete line
14
15
 
15
16
  Install
16
17
  =======
@@ -22,8 +23,6 @@ Usage
22
23
 
23
24
  TODO
24
25
  =====
25
- - delete line
26
- - scrolling inside text field
27
26
  - smart staying at end of line/column when changing line
28
27
  - indentation + paste support
29
28
  - warnings / messages
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.5
1
+ 0.0.6
data/bin/ruco CHANGED
@@ -76,19 +76,19 @@ init_screen do
76
76
  display editor, status_lines, Curses::A_NORMAL
77
77
  display command, status_lines + editor_lines, Curses::A_REVERSE
78
78
 
79
- Curses.setpos(focused.cursor_line + status_lines, focused.cursor_column)
79
+ Curses.setpos(focused.cursor.line + status_lines, focused.cursor.column)
80
80
 
81
81
  key = Curses.getch
82
82
 
83
83
  case key
84
84
 
85
85
  # move
86
- when Curses::Key::UP then focused.move(-1,0)
87
- when Curses::Key::DOWN then focused.move(1,0)
88
- when Curses::Key::RIGHT then focused.move(0,1)
89
- when Curses::Key::LEFT then focused.move(0,-1)
90
- when Curses::KEY_END then focused.move_to_eol
91
- when Curses::KEY_HOME then focused.move_to_bol
86
+ when Curses::Key::UP then focused.move(:relative, -1,0)
87
+ when Curses::Key::DOWN then focused.move(:relative, 1,0)
88
+ when Curses::Key::RIGHT then focused.move(:relative, 0,1)
89
+ when Curses::Key::LEFT then focused.move(:relative, 0,-1)
90
+ when Curses::KEY_END then focused.move :to_eol
91
+ when Curses::KEY_HOME then focused.move :to_bol
92
92
 
93
93
  # modify
94
94
  when 9 then focused.insert(key.chr) # tab
@@ -103,6 +103,8 @@ init_screen do
103
103
  when Curses::KEY_DC then focused.delete(1) # delete
104
104
 
105
105
  # misc
106
+ when ?\C-d then
107
+ editor.delete_line
106
108
  when ?\C-f then
107
109
  focused = command
108
110
  command.find
data/lib/ruco.rb CHANGED
@@ -2,7 +2,7 @@ require 'ruco/core_ext/object'
2
2
  require 'ruco/core_ext/string'
3
3
  require 'ruco/core_ext/array'
4
4
 
5
- require 'ruco/focusable'
5
+ require 'ruco/cursor'
6
6
  require 'ruco/command'
7
7
 
8
8
  require 'ruco/editor'
@@ -10,6 +10,7 @@ require 'ruco/status_bar'
10
10
  require 'ruco/command_bar'
11
11
 
12
12
  require 'ruco/form'
13
+ require 'ruco/text_area'
13
14
  require 'ruco/text_field'
14
15
 
15
16
  module Ruco
@@ -1,7 +1,5 @@
1
1
  module Ruco
2
2
  class CommandBar
3
- include Focusable
4
-
5
3
  attr_accessor :cursor_line, :form
6
4
  delegate :move, :delete, :insert, :to => :form
7
5
 
@@ -13,8 +11,6 @@ module Ruco
13
11
  '^G Go to line'
14
12
  ]
15
13
 
16
- SEARCH_PREFIX = "Find: "
17
-
18
14
  def initialize(options)
19
15
  @options = options
20
16
  @forms_cache = {}
@@ -30,11 +26,17 @@ module Ruco
30
26
  end
31
27
 
32
28
  def find
33
- @form = @forms_cache[:find] ||= Form.new('Find: ', :columns => @options[:columns], :command => :find)
29
+ @forms_cache[:find] ||= Form.new('Find: ', :columns => @options[:columns]) do |value|
30
+ Command.new(:find, value)
31
+ end
32
+ @form = @forms_cache[:find]
34
33
  end
35
34
 
36
35
  def move_to_line
37
- @form = Form.new('Go to Line: ', :columns => @options[:columns], :command => :move_to_line, :type => :integer)
36
+ @form = Form.new('Go to Line: ', :columns => @options[:columns], :type => :integer) do |value|
37
+ reset
38
+ Command.new(:move, :to_line, value.to_i)
39
+ end
38
40
  end
39
41
 
40
42
  def reset
@@ -42,11 +44,11 @@ module Ruco
42
44
  @form = nil
43
45
  end
44
46
 
45
- def cursor_column
47
+ def cursor
46
48
  if @form
47
- @form.cursor[1]
49
+ Cursor.new cursor_line, @form.cursor.column
48
50
  else
49
- 0
51
+ Cursor.new cursor_line, 0
50
52
  end
51
53
  end
52
54
 
@@ -0,0 +1,10 @@
1
+ module Ruco
2
+ class Cursor < Array
3
+ def initialize(line, column)
4
+ super([line, column])
5
+ end
6
+
7
+ alias_method :line, :first
8
+ alias_method :column, :last
9
+ end
10
+ end
data/lib/ruco/editor.rb CHANGED
@@ -1,202 +1,56 @@
1
1
  module Ruco
2
2
  class Editor
3
- include Focusable
4
-
5
- SCROLLING_OFFSET = 20
6
-
7
- attr_reader :cursor_line, :cursor_column, :file
3
+ attr_reader :file
4
+ delegate :view, :move, :cursor, :to => :text_area
8
5
 
9
6
  def initialize(file, options)
10
7
  @file = file
11
8
  @options = options
12
- @content = tabs_to_spaces((File.exist?(@file) ? File.read(@file) : ''))
13
- @line = 0
14
- @column = 0
15
- @cursor_line = 0
16
- @cursor_column = 0
17
- @scrolled_lines = 0
18
- @scrolled_columns = 0
9
+ content = (File.exist?(@file) ? File.read(@file) : '')
10
+ @text_area = TextArea.new(content, @options)
19
11
  @modified = false
20
- @options[:line_scrolling_offset] ||= @options[:lines] / 2
21
- @options[:column_scrolling_offset] ||= @options[:columns] / 2
22
- end
23
-
24
- def view
25
- Array.new(@options[:lines]).map_with_index do |_,i|
26
- (lines[i + @scrolled_lines] || "").slice(@scrolled_columns, @options[:columns])
27
- end * "\n" + "\n"
28
- end
29
-
30
- def move(line, column)
31
- @line += line
32
- @column += column
33
- adjust_view
34
- end
35
-
36
- def move_to(line, column)
37
- @line = line
38
- @column = column
39
- adjust_view
40
- end
41
-
42
- def move_to_line(line)
43
- move_to(line, @column)
44
- end
45
-
46
- def move_to_column(column)
47
- move_to(@line, column)
48
- end
49
-
50
- def move_to_eol
51
- after_last_word = current_line.index(/\s*$/)
52
- after_last_whitespace = current_line.size
53
-
54
- if @column == after_last_whitespace or @column < after_last_word
55
- move_to_column after_last_word
56
- else
57
- move_to_column after_last_whitespace
58
- end
59
- end
60
-
61
- def move_to_bol
62
- before_first_word = current_line.index(/[^\s]/) || 0
63
- if @column == 0 or @column > before_first_word
64
- move_to_column before_first_word
65
- else
66
- move_to_column 0
67
- end
68
12
  end
69
13
 
70
14
  def find(text)
71
- index = @content.index(text, cursor_index+1) || cursor_index
72
- move_to *cursor_for_index(index)
15
+ index = text_area.content.index(text, text_area.cursor_index+1) || text_area.cursor_index
16
+ move :to, *text_area.cursor_for_index(index)
73
17
  end
74
18
 
19
+ def reset;end
20
+
75
21
  def insert(text)
76
- text = tabs_to_spaces(text)
77
- insert_into_content cursor_index, text
78
- move_according_to_insert(text)
79
22
  @modified = true
23
+ text_area.insert(text)
80
24
  end
81
25
 
82
- def delete(count)
83
- if count > 0
84
- @content.slice!(cursor_index, count)
85
- else
86
- backspace(count.abs)
87
- end
26
+ def delete(*args)
27
+ text_area.delete(*args)
88
28
  @modified = true
89
29
  end
90
30
 
91
- def backspace(count)
92
- start_index = cursor_index - count
93
- if start_index < 0
94
- count += start_index
95
- start_index = 0
31
+ def delete_line
32
+ old_cursor = cursor
33
+ move :to, cursor.line, 0
34
+ delete text_area.line_length
35
+ if cursor == [0,0]
36
+ delete(1)
37
+ else
38
+ delete(-1)
96
39
  end
97
-
98
- @content.slice!(start_index, count)
99
- move_to *cursor_for_index(start_index)
100
- @modified = true
101
- end
102
-
103
- def save
104
- File.open(@file,'w'){|f| f.write(@content) }
105
- @modified = false
106
- end
107
-
108
- def cursor
109
- [cursor_line, cursor_column]
40
+ move :to, *old_cursor
110
41
  end
111
42
 
112
43
  def modified?
113
44
  @modified
114
45
  end
115
46
 
116
- private
117
-
118
- def lines
119
- @content.naive_split("\n")
120
- end
121
-
122
- def adjust_view
123
- @line = [[@line, 0].max, lines.size - 1].min
124
- @column = [[@column, 0].max, (lines[@line]||'').size].min
125
- reposition_cursor
126
- scroll_column_into_view
127
- scroll_line_into_view
128
- reposition_cursor
129
- end
130
-
131
- def scroll_column_into_view
132
- offset = [@options[:column_scrolling_offset], @options[:columns]].min
133
-
134
- if @cursor_column >= @options[:columns]
135
- @scrolled_columns = @column - @options[:columns] + offset
136
- end
137
-
138
- if @cursor_column < 0
139
- @scrolled_columns = @column - offset
140
- end
141
-
142
- @scrolled_columns = [[@scrolled_columns, 0].max, @column].min
143
- end
144
-
145
- def scroll_line_into_view
146
- offset = [@options[:line_scrolling_offset], @options[:lines]].min
147
-
148
- if @cursor_line >= @options[:lines]
149
- @scrolled_lines = @line - @options[:lines] + offset
150
- end
151
-
152
- if @cursor_line < 0
153
- @scrolled_lines = @line - offset
154
- end
155
-
156
- @scrolled_lines = [[@scrolled_lines, 0].max, @line].min
157
- end
158
-
159
- def reposition_cursor
160
- @cursor_column = @column - @scrolled_columns
161
- @cursor_line = @line - @scrolled_lines
162
- end
163
-
164
- def insert_into_content(index, text)
165
- # expand with newlines when inserting after maximum position
166
- if index > @content.size
167
- @content << "\n" * (index - @content.size)
168
- end
169
- @content.insert(index, text)
170
- end
171
-
172
- def current_line
173
- lines[@line] || ''
174
- end
175
-
176
- def cursor_index
177
- index = lines[0...@line].join("\n").size + @column
178
- index += 1 if @line > 0 # account for missing newline
179
- index
180
- end
181
-
182
- def cursor_for_index(index)
183
- jump = @content.slice(0, index).to_s.naive_split("\n")
184
- [jump.size - 1, jump.last.size]
47
+ def save
48
+ File.open(@file,'w'){|f| f.write(text_area.content) }
49
+ @modified = false
185
50
  end
186
51
 
187
- def move_according_to_insert(text)
188
- inserted_lines = text.naive_split("\n")
189
- if inserted_lines.size > 1
190
- # column position does not add up when hitting return
191
- @column = inserted_lines.last.size
192
- move(inserted_lines.size - 1, 0)
193
- else
194
- move(inserted_lines.size - 1, inserted_lines.last.size)
195
- end
196
- end
52
+ private
197
53
 
198
- def tabs_to_spaces(text)
199
- text.gsub("\t",' ' * Ruco::TAB_SIZE)
200
- end
54
+ attr_reader :text_area
201
55
  end
202
56
  end
data/lib/ruco/form.rb CHANGED
@@ -2,9 +2,10 @@ module Ruco
2
2
  class Form
3
3
  delegate :move, :delete, :to => :text_field
4
4
 
5
- def initialize(label, options)
5
+ def initialize(label, options, &submit)
6
6
  @options = options
7
7
  @label = label.strip + ' '
8
+ @submit = submit
8
9
  reset
9
10
  end
10
11
 
@@ -17,12 +18,12 @@ module Ruco
17
18
  if text.include?("\n")
18
19
  result = @text_field.value
19
20
  result = result.to_i if @options[:type] == :integer
20
- Command.new(@options[:command], result)
21
+ @submit.call(result)
21
22
  end
22
23
  end
23
24
 
24
25
  def cursor
25
- [0, @label.size + @text_field.cursor[1]]
26
+ Cursor.new 0, @label.size + @text_field.cursor.column
26
27
  end
27
28
 
28
29
  def reset
@@ -0,0 +1,181 @@
1
+ module Ruco
2
+ class TextArea
3
+ attr_reader :content
4
+
5
+ def initialize(content, options)
6
+ @content = tabs_to_spaces(content)
7
+ @options = options
8
+ @line = 0
9
+ @column = 0
10
+ @cursor_line = 0
11
+ @cursor_column = 0
12
+ @scrolled_lines = 0
13
+ @scrolled_columns = 0
14
+ @options[:line_scrolling_offset] ||= @options[:lines] / 2
15
+ @options[:column_scrolling_offset] ||= @options[:columns] / 2
16
+ end
17
+
18
+ def view
19
+ Array.new(@options[:lines]).map_with_index do |_,i|
20
+ (lines[i + @scrolled_lines] || "").slice(@scrolled_columns, @options[:columns])
21
+ end * "\n" + "\n"
22
+ end
23
+
24
+ def move(where, *args)
25
+ case where
26
+ when :relative then
27
+ @line += args.first
28
+ @column += args.last
29
+ when :to then
30
+ @line, @column = args
31
+ when :to_bol then move_to_bol(*args)
32
+ when :to_eol then move_to_eol(*args)
33
+ when :to_line then @line = args.first
34
+ when :to_column then @column = args.first
35
+ else
36
+ raise "Unknown move type #{where} with #{args.inspect}"
37
+ end
38
+ adjust_view
39
+ end
40
+
41
+ def insert(text)
42
+ text = tabs_to_spaces(text)
43
+ insert_into_content cursor_index, text
44
+ move_according_to_insert(text)
45
+ end
46
+
47
+ def delete(count)
48
+ if count > 0
49
+ @content.slice!(cursor_index, count)
50
+ else
51
+ backspace(count.abs)
52
+ end
53
+ end
54
+
55
+ def cursor
56
+ Cursor.new @cursor_line, @cursor_column
57
+ end
58
+
59
+ def cursor_index
60
+ index = lines[0...@line].join("\n").size + @column
61
+ index += 1 if @line > 0 # account for missing newline
62
+ index
63
+ end
64
+
65
+ def cursor_for_index(index)
66
+ jump = @content.slice(0, index).to_s.naive_split("\n")
67
+ [jump.size - 1, jump.last.size]
68
+ end
69
+
70
+ def line_length
71
+ lines[@line].size
72
+ end
73
+
74
+ private
75
+
76
+ def move_to_eol
77
+ after_last_word = current_line.index(/\s*$/)
78
+ after_last_whitespace = current_line.size
79
+
80
+ if @column == after_last_whitespace or @column < after_last_word
81
+ move :to_column, after_last_word
82
+ else
83
+ move :to_column, after_last_whitespace
84
+ end
85
+ end
86
+
87
+ def move_to_bol
88
+ before_first_word = current_line.index(/[^\s]/) || 0
89
+ column = if @column == 0 or @column > before_first_word
90
+ before_first_word
91
+ else
92
+ 0
93
+ end
94
+ move :to_column, column
95
+ end
96
+
97
+ def backspace(count)
98
+ start_index = cursor_index - count
99
+ if start_index < 0
100
+ count += start_index
101
+ start_index = 0
102
+ end
103
+
104
+ @content.slice!(start_index, count)
105
+ move :to, *cursor_for_index(start_index)
106
+ end
107
+
108
+ def lines
109
+ @content.naive_split("\n")
110
+ end
111
+
112
+ def adjust_view
113
+ @line = [[@line, 0].max, lines.size - 1].min
114
+ @column = [[@column, 0].max, (lines[@line]||'').size].min
115
+ reposition_cursor
116
+ scroll_column_into_view
117
+ scroll_line_into_view
118
+ reposition_cursor
119
+ end
120
+
121
+ def scroll_column_into_view
122
+ offset = [@options[:column_scrolling_offset], @options[:columns]].min
123
+
124
+ if @cursor_column >= @options[:columns]
125
+ @scrolled_columns = @column - @options[:columns] + offset
126
+ end
127
+
128
+ if @cursor_column < 0
129
+ @scrolled_columns = @column - offset
130
+ end
131
+
132
+ @scrolled_columns = [[@scrolled_columns, 0].max, @column].min
133
+ end
134
+
135
+ def scroll_line_into_view
136
+ offset = [@options[:line_scrolling_offset], @options[:lines]].min
137
+
138
+ if @cursor_line >= @options[:lines]
139
+ @scrolled_lines = @line - @options[:lines] + offset
140
+ end
141
+
142
+ if @cursor_line < 0
143
+ @scrolled_lines = @line - offset
144
+ end
145
+
146
+ @scrolled_lines = [[@scrolled_lines, 0].max, @line].min
147
+ end
148
+
149
+ def reposition_cursor
150
+ @cursor_column = @column - @scrolled_columns
151
+ @cursor_line = @line - @scrolled_lines
152
+ end
153
+
154
+ def insert_into_content(index, text)
155
+ # expand with newlines when inserting after maximum position
156
+ if index > @content.size
157
+ @content << "\n" * (index - @content.size)
158
+ end
159
+ @content.insert(index, text)
160
+ end
161
+
162
+ def current_line
163
+ lines[@line] || ''
164
+ end
165
+
166
+ def move_according_to_insert(text)
167
+ inserted_lines = text.naive_split("\n")
168
+ if inserted_lines.size > 1
169
+ # column position does not add up when hitting return
170
+ @column = inserted_lines.last.size
171
+ move(:relative, inserted_lines.size - 1, 0)
172
+ else
173
+ move(:relative, inserted_lines.size - 1, inserted_lines.last.size)
174
+ end
175
+ end
176
+
177
+ def tabs_to_spaces(text)
178
+ text.gsub("\t",' ' * Ruco::TAB_SIZE)
179
+ end
180
+ end
181
+ end
@@ -1,40 +1,15 @@
1
1
  module Ruco
2
- class TextField
2
+ class TextField < TextArea
3
3
  def initialize(options)
4
- @options = options
5
- @content = ''
6
- @column = 0
7
- end
8
-
9
- def insert(text)
10
- @content += text
11
- move(0, text.size)
12
- end
13
-
14
- def delete(count)
15
- if count > 0
16
- @content.slice!(@column, count)
17
- else
18
- delete_start = [@column - count.abs, 0].max
19
- @content[delete_start...@column] = ''
20
- @column = delete_start
21
- end
4
+ super('', options.merge(:lines => 1))
22
5
  end
23
6
 
24
7
  def view
25
- @content
8
+ super.gsub("\n",'')
26
9
  end
27
10
 
28
11
  def value
29
- @content
30
- end
31
-
32
- def move(line, column)
33
- @column = [[@column + column, 0].max, @content.size].min
34
- end
35
-
36
- def cursor
37
- [0, @column]
12
+ content.gsub("\n",'')
38
13
  end
39
14
  end
40
15
  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.5"
8
+ s.version = "0.0.6"
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-01-10}
12
+ s.date = %q{2011-01-11}
13
13
  s.default_executable = %q{ruco}
14
14
  s.email = %q{michael@grosser.it}
15
15
  s.executables = ["ruco"]
@@ -26,10 +26,11 @@ Gem::Specification.new do |s|
26
26
  "lib/ruco/core_ext/array.rb",
27
27
  "lib/ruco/core_ext/object.rb",
28
28
  "lib/ruco/core_ext/string.rb",
29
+ "lib/ruco/cursor.rb",
29
30
  "lib/ruco/editor.rb",
30
- "lib/ruco/focusable.rb",
31
31
  "lib/ruco/form.rb",
32
32
  "lib/ruco/status_bar.rb",
33
+ "lib/ruco/text_area.rb",
33
34
  "lib/ruco/text_field.rb",
34
35
  "ruco.gemspec",
35
36
  "spec/ruco/command_bar_spec.rb",
@@ -1,15 +1,16 @@
1
1
  require File.expand_path('spec/spec_helper')
2
2
 
3
3
  describe Ruco::CommandBar do
4
+ let(:default_view){ "^W Exit ^S Save ^F Find" }
4
5
  let(:bar){ Ruco::CommandBar.new(:columns => 30) }
5
6
 
6
7
  it "shows shortcuts by default" do
7
- bar.view.should == "^W Exit ^S Save ^F Find"
8
+ bar.view.should == default_view
8
9
  end
9
10
 
10
11
  it "shows less shortcuts when space is low" do
11
12
  bar = Ruco::CommandBar.new(:columns => 29)
12
- bar.view.should == "^W Exit ^S Save ^F Find"
13
+ bar.view.should == default_view
13
14
  bar = Ruco::CommandBar.new(:columns => 28)
14
15
  bar.view.should == "^W Exit ^S Save"
15
16
  end
@@ -18,14 +19,14 @@ describe Ruco::CommandBar do
18
19
  it "sets command bar into search mode" do
19
20
  bar.find
20
21
  bar.view.should == "Find: "
21
- bar.cursor_column.should == 6
22
+ bar.cursor.column.should == 6
22
23
  end
23
24
 
24
25
  it "can enter stuff" do
25
26
  bar.find
26
27
  bar.insert('abc')
27
28
  bar.view.should == "Find: abc"
28
- bar.cursor_column.should == 9
29
+ bar.cursor.column.should == 9
29
30
  end
30
31
 
31
32
  it "keeps entered stuff" do
@@ -33,7 +34,7 @@ describe Ruco::CommandBar do
33
34
  bar.insert('abc')
34
35
  bar.find
35
36
  bar.view.should == "Find: abc"
36
- bar.cursor_column.should == 9
37
+ bar.cursor.column.should == 9
37
38
  end
38
39
 
39
40
  it "can reset the search" do
@@ -42,7 +43,7 @@ describe Ruco::CommandBar do
42
43
  bar.insert("\n")
43
44
  bar.reset
44
45
 
45
- bar.view.should include("^W Exit ") # default view
46
+ bar.view.should == default_view
46
47
  bar.find
47
48
  bar.view.should == "Find: " # term removed
48
49
  end
@@ -73,23 +74,29 @@ describe Ruco::CommandBar do
73
74
  bar.move_to_line
74
75
  bar.insert('123')
75
76
  result = bar.insert("\n")
76
- result.should == Ruco::Command.new(:move_to_line, 123)
77
+ result.should == Ruco::Command.new(:move, :to_line, 123)
77
78
  end
78
79
 
79
- it "gets reset" do
80
+ it "gets reset when starting a new go to line" do
80
81
  bar.move_to_line
81
82
  bar.insert('123')
82
83
  bar.move_to_line
83
84
  bar.view.should == "Go to Line: "
84
85
  end
85
86
 
87
+ it "gets reset when submitting" do
88
+ bar.move_to_line
89
+ bar.insert("123\n")
90
+ bar.view.should == default_view
91
+ end
92
+
86
93
  it "does not reset search when resetting" do
87
94
  bar.find
88
95
  bar.insert('abc')
89
96
  bar.move_to_line
90
97
  bar.reset
91
98
 
92
- bar.view.should include("^W Exit ") # default view
99
+ bar.view.should == default_view
93
100
  bar.find
94
101
  bar.view.should == "Find: abc"
95
102
  end
@@ -26,62 +26,62 @@ describe Ruco::Editor do
26
26
  end
27
27
 
28
28
  it "can move" do
29
- editor.move(1,2)
29
+ editor.move(:relative, 1,2)
30
30
  editor.cursor.should == [1,2]
31
- editor.move(1,1)
31
+ editor.move(:relative, 1,1)
32
32
  editor.cursor.should == [2,3]
33
33
  end
34
34
 
35
35
  it "can move in empty file" do
36
36
  write("\n\n\n")
37
- editor.move(2,0)
37
+ editor.move(:relative, 2,0)
38
38
  editor.cursor.should == [2,0]
39
39
  end
40
40
 
41
41
  it "cannot move left/top off screen" do
42
- editor.move(-1,-1)
42
+ editor.move(:relative, -1,-1)
43
43
  editor.cursor.should == [0,0]
44
44
  end
45
45
 
46
46
  it "cannot move right of characters" do
47
- editor.move(2,6)
47
+ editor.move(:relative, 2,6)
48
48
  editor.cursor.should == [2,4]
49
49
  end
50
50
 
51
51
  it "stays in last line when moving past lines" do
52
52
  write(" ")
53
- editor.move(6,3)
53
+ editor.move(:relative, 6,3)
54
54
  editor.cursor.should == [0,3]
55
55
  end
56
56
 
57
57
  describe 'column scrolling' do
58
58
  it "can scroll columns" do
59
59
  write("123456789\n123")
60
- editor.move(0,4)
60
+ editor.move(:relative, 0,4)
61
61
  editor.view.should == "12345\n123\n\n"
62
- editor.cursor_column.should == 4
62
+ editor.cursor.column.should == 4
63
63
 
64
- editor.move(0,1)
64
+ editor.move(:relative, 0,1)
65
65
  editor.view.should == "6789\n\n\n"
66
- editor.cursor_column.should == 0
66
+ editor.cursor.column.should == 0
67
67
  end
68
68
 
69
69
  it "cannot scroll past the screen" do
70
70
  write('123456789')
71
- editor.move(0,4)
72
- 6.times{ editor.move(0,1) }
71
+ editor.move(:relative, 0,4)
72
+ 6.times{ editor.move(:relative, 0,1) }
73
73
  editor.view.should == "6789\n\n\n"
74
- editor.cursor_column.should == 4
74
+ editor.cursor.column.should == 4
75
75
  end
76
76
 
77
77
  it "can scroll columns backwards" do
78
78
  write('123456789')
79
- editor.move(0,5)
79
+ editor.move(:relative, 0,5)
80
80
  editor.view.should == "6789\n\n\n"
81
81
 
82
- editor.move(0,-1)
82
+ editor.move(:relative, 0,-1)
83
83
  editor.view.should == "12345\n\n\n"
84
- editor.cursor_column.should == 4
84
+ editor.cursor.column.should == 4
85
85
  end
86
86
  end
87
87
 
@@ -91,119 +91,96 @@ describe Ruco::Editor do
91
91
  end
92
92
 
93
93
  it "can scroll lines down (at maximum of screen size)" do
94
- editor.move(2,0)
94
+ editor.move(:relative, 2,0)
95
95
  editor.view.should == "1\n2\n3\n"
96
96
 
97
- editor.move(1,0)
97
+ editor.move(:relative, 1,0)
98
98
  editor.view.should == "4\n5\n6\n"
99
- editor.cursor_line.should == 0
99
+ editor.cursor.line.should == 0
100
100
  end
101
101
 
102
102
  it "can scroll till end of file" do
103
- editor.move(15,0)
103
+ editor.move(:relative, 15,0)
104
104
  editor.view.should == "9\n\n\n"
105
- editor.cursor_line.should == 0
105
+ editor.cursor.line.should == 0
106
106
  end
107
107
  end
108
- end
109
-
110
- describe :move_to do
111
- it "cannot move outside of text (bottom/right)" do
112
- write("123\n456")
113
- editor.move_to(10,10)
114
- editor.cursor.should == [1,3]
115
- end
116
-
117
- it "cannot move outside of text (top/left)" do
118
- write("123\n456")
119
- editor.move(1,1)
120
- editor.move_to(-10,-10)
121
- editor.cursor.should == [0,0]
122
- end
123
- end
124
-
125
- describe :move_to_eol do
126
- before do
127
- write("\n aa \n ")
128
- end
129
108
 
130
- it 'stays at start when line is empty' do
131
- editor.move_to_eol
132
- editor.cursor.should == [0,0]
133
- end
109
+ describe :to do
110
+ it "cannot move outside of text (bottom/right)" do
111
+ write("123\n456")
112
+ editor.move(:to, 10,10)
113
+ editor.cursor.should == [1,3]
114
+ end
134
115
 
135
- it 'moves after last word if cursor was before it' do
136
- editor.move(1,1)
137
- editor.move_to_eol
138
- editor.cursor.should == [1,3]
116
+ it "cannot move outside of text (top/left)" do
117
+ write("123\n456")
118
+ editor.move(:relative, 1,1)
119
+ editor.move(:to, -10,-10)
120
+ editor.cursor.should == [0,0]
121
+ end
139
122
  end
140
123
 
141
- it 'moves after last whitespace if cursor was after last word' do
142
- editor.move(1,3)
143
- editor.move_to_eol
144
- editor.cursor.should == [1,4]
145
- end
124
+ describe :to_eol do
125
+ before do
126
+ write("\n aa \n ")
127
+ end
146
128
 
147
- it 'moves after last work if cursor was after last whitespace' do
148
- editor.move(1,4)
149
- editor.move_to_eol
150
- editor.cursor.should == [1,3]
151
- end
152
- end
129
+ it 'stays at start when line is empty' do
130
+ editor.move :to_eol
131
+ editor.cursor.should == [0,0]
132
+ end
153
133
 
154
- describe :move_to_bol do
155
- before do
156
- write("\n aa \n ")
157
- end
134
+ it 'moves after last word if cursor was before it' do
135
+ editor.move(:relative, 1,1)
136
+ editor.move :to_eol
137
+ editor.cursor.should == [1,3]
138
+ end
158
139
 
159
- it 'stays at start when line is empty' do
160
- editor.move_to_bol
161
- editor.cursor.should == [0,0]
162
- end
140
+ it 'moves after last whitespace if cursor was after last word' do
141
+ editor.move(:relative, 1,3)
142
+ editor.move :to_eol
143
+ editor.cursor.should == [1,4]
144
+ end
163
145
 
164
- it 'moves before first work if at start of line' do
165
- editor.move(1,0)
166
- editor.move_to_bol
167
- editor.cursor.should == [1,2]
146
+ it 'moves after last work if cursor was after last whitespace' do
147
+ editor.move(:relative, 1,4)
148
+ editor.move :to_eol
149
+ editor.cursor.should == [1,3]
150
+ end
168
151
  end
169
152
 
170
- it 'moves to start of line if before first word' do
171
- editor.move(1,1)
172
- editor.move_to_bol
173
- editor.cursor.should == [1,0]
174
-
175
- editor.move(0,2)
176
- editor.move_to_bol
177
- editor.cursor.should == [1,0]
178
- end
153
+ describe :to_bol do
154
+ before do
155
+ write("\n aa \n ")
156
+ end
179
157
 
180
- it 'moves before first word if inside line' do
181
- editor.move(1,5)
182
- editor.move_to_bol
183
- editor.cursor.should == [1,2]
184
- end
185
- end
158
+ it 'stays at start when line is empty' do
159
+ editor.move :to_bol
160
+ editor.cursor.should == [0,0]
161
+ end
186
162
 
187
- describe :find do
188
- before do
189
- write("\n ab\n ab")
190
- end
163
+ it 'moves before first work if at start of line' do
164
+ editor.move(:relative, 1,0)
165
+ editor.move :to_bol
166
+ editor.cursor.should == [1,2]
167
+ end
191
168
 
192
- it "moves to first occurrence" do
193
- editor.find('ab')
194
- editor.cursor.should == [1,1]
195
- end
169
+ it 'moves to start of line if before first word' do
170
+ editor.move(:relative, 1,1)
171
+ editor.move :to_bol
172
+ editor.cursor.should == [1,0]
196
173
 
197
- it "moves to next occurrence" do
198
- editor.move(1,1)
199
- editor.find('ab')
200
- editor.cursor.should == [2,1]
201
- end
174
+ editor.move(:relative, 0,2)
175
+ editor.move :to_bol
176
+ editor.cursor.should == [1,0]
177
+ end
202
178
 
203
- it "stays in place when nothing was found" do
204
- editor.move(2,1)
205
- editor.find('ab')
206
- editor.cursor.should == [2,1]
179
+ it 'moves before first word if inside line' do
180
+ editor.move(:relative, 1,5)
181
+ editor.move :to_bol
182
+ editor.cursor.should == [1,2]
183
+ end
207
184
  end
208
185
  end
209
186
 
@@ -239,7 +216,7 @@ describe Ruco::Editor do
239
216
 
240
217
  it "can insert new chars" do
241
218
  write('123')
242
- editor.move(0,1)
219
+ editor.move(:relative, 0,1)
243
220
  editor.insert('ab')
244
221
  editor.view.should == "1ab23\n\n\n"
245
222
  editor.cursor.should == [0,3]
@@ -253,7 +230,7 @@ describe Ruco::Editor do
253
230
 
254
231
  it "jumps to correct column when inserting newline" do
255
232
  write("abc\ndefg")
256
- editor.move(1,2)
233
+ editor.move(:relative, 1,2)
257
234
  editor.insert("1\n23")
258
235
  editor.view.should == "abc\nde1\n23fg\n"
259
236
  editor.cursor.should == [2,2]
@@ -261,7 +238,7 @@ describe Ruco::Editor do
261
238
 
262
239
  it "jumps to correct column when inserting 1 newline" do
263
240
  write("abc\ndefg")
264
- editor.move(1,2)
241
+ editor.move(:relative, 1,2)
265
242
  editor.insert("\n")
266
243
  editor.view.should == "abc\nde\nfg\n"
267
244
  editor.cursor.should == [2,0]
@@ -276,7 +253,7 @@ describe Ruco::Editor do
276
253
 
277
254
  it "can add newlines to the moveable end" do
278
255
  write('abc')
279
- editor.move(0,3)
256
+ editor.move(:relative, 0,3)
280
257
  editor.insert("\n")
281
258
  editor.insert("\n")
282
259
  editor.cursor.should == [2,0]
@@ -315,7 +292,7 @@ describe Ruco::Editor do
315
292
 
316
293
  it 'removes a line' do
317
294
  write("123\n45")
318
- editor.move(0,3)
295
+ editor.move(:relative, 0,3)
319
296
  editor.delete(1)
320
297
  editor.view.should == "12345\n\n\n"
321
298
  editor.cursor.should == [0,3]
@@ -323,7 +300,7 @@ describe Ruco::Editor do
323
300
 
324
301
  it "cannot backspace over 0,0" do
325
302
  write("aa")
326
- editor.move(0,1)
303
+ editor.move(:relative, 0,1)
327
304
  editor.delete(-3)
328
305
  editor.view.should == "a\n\n\n"
329
306
  editor.cursor.should == [0,0]
@@ -331,7 +308,7 @@ describe Ruco::Editor do
331
308
 
332
309
  it 'backspaces a char' do
333
310
  write('123')
334
- editor.move(0,3)
311
+ editor.move(:relative, 0,3)
335
312
  editor.delete(-1)
336
313
  editor.view.should == "12\n\n\n"
337
314
  editor.cursor.should == [0,2]
@@ -339,7 +316,7 @@ describe Ruco::Editor do
339
316
 
340
317
  it 'backspaces a newline' do
341
318
  write("1\n234")
342
- editor.move(1,0)
319
+ editor.move(:relative, 1,0)
343
320
  editor.delete(-1)
344
321
  editor.view.should == "1234\n\n\n"
345
322
  editor.cursor.should == [0,1]
@@ -362,7 +339,7 @@ describe Ruco::Editor do
362
339
  end
363
340
 
364
341
  it "is not changed after move" do
365
- editor.move(1,1)
342
+ editor.move(:relative, 1,1)
366
343
  editor.modified?.should == false
367
344
  end
368
345
 
@@ -372,4 +349,75 @@ describe Ruco::Editor do
372
349
  editor.modified?.should == false
373
350
  end
374
351
  end
352
+
353
+ describe :find do
354
+ before do
355
+ write("\n ab\n ab")
356
+ end
357
+
358
+ it "moves to first occurrence" do
359
+ editor.find('ab')
360
+ editor.cursor.should == [1,1]
361
+ end
362
+
363
+ it "moves to next occurrence" do
364
+ editor.move(:relative, 1,1)
365
+ editor.find('ab')
366
+ editor.cursor.should == [2,1]
367
+ end
368
+
369
+ it "stays in place when nothing was found" do
370
+ editor.move(:relative, 2,1)
371
+ editor.find('ab')
372
+ editor.cursor.should == [2,1]
373
+ end
374
+ end
375
+
376
+ describe :delete_line do
377
+ before do
378
+ write("1\nlonger_than_columns\n56789")
379
+ end
380
+
381
+ it "removes the current line from first char" do
382
+ editor.move(:to, 1, 0)
383
+ editor.delete_line
384
+ editor.view.should == "1\n56789\n\n"
385
+ editor.cursor.should == [1, 0]
386
+ end
387
+
388
+ it "removes the current line from last char" do
389
+ editor.move(:to, 1, 3)
390
+ editor.delete_line
391
+ editor.view.should == "1\n56789\n\n"
392
+ editor.cursor.should == [1, 3]
393
+ end
394
+
395
+ it "can remove the first line" do
396
+ editor.delete_line
397
+ editor.view.should == "longe\n56789\n\n"
398
+ editor.cursor.should == [0, 0]
399
+ end
400
+
401
+ it "can remove the last line" do
402
+ write("aaa")
403
+ editor.delete_line
404
+ editor.view.should == "\n\n\n"
405
+ editor.cursor.should == [0, 0]
406
+ end
407
+
408
+ it "can remove the last line with lines remaining" do
409
+ write("aaa\nbbb")
410
+ editor.move(:to, 1,1)
411
+ editor.delete_line
412
+ editor.view.should == "aaa\n\n\n"
413
+ editor.cursor.should == [0, 1]
414
+ end
415
+
416
+ it "jumps to end of next lines end when put of space" do
417
+ write("1\n234\n5")
418
+ editor.move(:to, 1, 3)
419
+ editor.delete_line
420
+ editor.cursor.should == [1, 1]
421
+ end
422
+ end
375
423
  end
@@ -1,7 +1,7 @@
1
1
  require File.expand_path('spec/spec_helper')
2
2
 
3
3
  describe Ruco::Form do
4
- let(:form){ Ruco::Form.new('Test', :columns => 30, :command => :find) }
4
+ let(:form){ Ruco::Form.new('Test', :columns => 30){|value| Ruco::Command.new(:find, value) } }
5
5
 
6
6
  it "positions cursor in text field" do
7
7
  form.cursor.should == [0, 5]
@@ -26,20 +26,20 @@ describe Ruco::Form do
26
26
  describe :move do
27
27
  it "moves in text-field" do
28
28
  form.insert('abc')
29
- form.move(0, -1)
29
+ form.move(:relative, 0, -1)
30
30
  form.cursor.should == [0,7]
31
31
  end
32
32
 
33
33
  it "cannot move out of left side" do
34
- form.move(0, -3)
34
+ form.move(:relative, 0, -3)
35
35
  form.cursor.should == [0,5]
36
36
  end
37
37
 
38
38
  it "cannot move out of right side" do
39
- form.move(0, 4)
39
+ form.move(:relative, 0, 4)
40
40
  form.cursor.should == [0,5]
41
41
  form.insert('abc')
42
- form.move(0, 4)
42
+ form.move(:relative, 0, 4)
43
43
  form.cursor.should == [0,8]
44
44
  end
45
45
  end
@@ -47,21 +47,21 @@ describe Ruco::Form do
47
47
  describe :delete do
48
48
  it "removes characters forward" do
49
49
  form.insert('abc')
50
- form.move(0, -2)
50
+ form.move(:relative, 0, -2)
51
51
  form.delete(1)
52
52
  form.view.should == 'Test ac'
53
53
  end
54
54
 
55
55
  it "removes characters backward" do
56
56
  form.insert('abc')
57
- form.move(0, -1)
57
+ form.move(:relative, 0, -1)
58
58
  form.delete(-1)
59
59
  form.view.should == 'Test ac'
60
60
  end
61
61
 
62
62
  it "moves the cursor backward" do
63
63
  form.insert('abc')
64
- form.move(0, -1)
64
+ form.move(:relative, 0, -1)
65
65
  form.delete(-1)
66
66
  form.cursor.should == [0,6]
67
67
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruco
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 5
10
- version: 0.0.5
9
+ - 6
10
+ version: 0.0.6
11
11
  platform: ruby
12
12
  authors:
13
13
  - Michael Grosser
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-01-10 00:00:00 +01:00
18
+ date: 2011-01-11 00:00:00 +01:00
19
19
  default_executable: ruco
20
20
  dependencies: []
21
21
 
@@ -40,10 +40,11 @@ files:
40
40
  - lib/ruco/core_ext/array.rb
41
41
  - lib/ruco/core_ext/object.rb
42
42
  - lib/ruco/core_ext/string.rb
43
+ - lib/ruco/cursor.rb
43
44
  - lib/ruco/editor.rb
44
- - lib/ruco/focusable.rb
45
45
  - lib/ruco/form.rb
46
46
  - lib/ruco/status_bar.rb
47
+ - lib/ruco/text_area.rb
47
48
  - lib/ruco/text_field.rb
48
49
  - ruco.gemspec
49
50
  - spec/ruco/command_bar_spec.rb
@@ -1,11 +0,0 @@
1
- module Ruco
2
- # Stub so things do not explode
3
- module Focusable
4
- def reset;end
5
- def move(line, column);end
6
- def move_to_eol;end
7
- def move_to_bol;end
8
- def insert(char);end
9
- def delete(count);end
10
- end
11
- end