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 +1 -2
- data/VERSION +1 -1
- data/bin/ruco +9 -7
- data/lib/ruco.rb +2 -1
- data/lib/ruco/command_bar.rb +11 -9
- data/lib/ruco/cursor.rb +10 -0
- data/lib/ruco/editor.rb +25 -171
- data/lib/ruco/form.rb +4 -3
- data/lib/ruco/text_area.rb +181 -0
- data/lib/ruco/text_field.rb +4 -29
- data/ruco.gemspec +4 -3
- data/spec/ruco/command_bar_spec.rb +16 -9
- data/spec/ruco/editor_spec.rb +162 -114
- data/spec/ruco/form_spec.rb +8 -8
- metadata +6 -5
- data/lib/ruco/focusable.rb +0 -11
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.
|
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.
|
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.
|
91
|
-
when Curses::KEY_HOME then focused.
|
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/
|
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
|
data/lib/ruco/command_bar.rb
CHANGED
@@ -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
|
-
@
|
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], :
|
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
|
47
|
+
def cursor
|
46
48
|
if @form
|
47
|
-
@form.cursor
|
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
|
|
data/lib/ruco/cursor.rb
ADDED
data/lib/ruco/editor.rb
CHANGED
@@ -1,202 +1,56 @@
|
|
1
1
|
module Ruco
|
2
2
|
class Editor
|
3
|
-
|
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
|
-
|
13
|
-
@
|
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 =
|
72
|
-
|
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(
|
83
|
-
|
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
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
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
|
-
|
117
|
-
|
118
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
21
|
+
@submit.call(result)
|
21
22
|
end
|
22
23
|
end
|
23
24
|
|
24
25
|
def cursor
|
25
|
-
|
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
|
data/lib/ruco/text_field.rb
CHANGED
@@ -1,40 +1,15 @@
|
|
1
1
|
module Ruco
|
2
|
-
class TextField
|
2
|
+
class TextField < TextArea
|
3
3
|
def initialize(options)
|
4
|
-
|
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
|
-
|
8
|
+
super.gsub("\n",'')
|
26
9
|
end
|
27
10
|
|
28
11
|
def value
|
29
|
-
|
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.
|
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-
|
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 ==
|
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 ==
|
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.
|
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.
|
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.
|
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
|
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(:
|
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
|
99
|
+
bar.view.should == default_view
|
93
100
|
bar.find
|
94
101
|
bar.view.should == "Find: abc"
|
95
102
|
end
|
data/spec/ruco/editor_spec.rb
CHANGED
@@ -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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
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
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
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
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
end
|
124
|
+
describe :to_eol do
|
125
|
+
before do
|
126
|
+
write("\n aa \n ")
|
127
|
+
end
|
146
128
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
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
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
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
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
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
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
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
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
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
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
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
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
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
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
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
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
end
|
174
|
+
editor.move(:relative, 0,2)
|
175
|
+
editor.move :to_bol
|
176
|
+
editor.cursor.should == [1,0]
|
177
|
+
end
|
202
178
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
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
|
data/spec/ruco/form_spec.rb
CHANGED
@@ -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
|
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:
|
4
|
+
hash: 19
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
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-
|
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
|