ruco 0.0.1 → 0.0.2
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 +6 -3
- data/VERSION +1 -1
- data/bin/ruco +46 -11
- data/lib/ruco.rb +1 -0
- data/lib/ruco/editor.rb +10 -1
- data/lib/ruco/status_bar.rb +27 -0
- data/ruco.gemspec +6 -1
- data/spec/ruco/editor_spec.rb +263 -0
- data/spec/ruco/status_bar_spec.rb +35 -0
- data/spec/ruco_spec.rb +0 -233
- metadata +8 -3
data/Readme.md
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
Commandline editor written in ruby
|
2
2
|
|
3
|
-
Alpha,
|
3
|
+
Alpha, lets see if this works...
|
4
4
|
|
5
5
|
Finished:
|
6
|
+
|
6
7
|
- viewing / scrolling / editing / saving / creating
|
8
|
+
- change-indicator
|
9
|
+
- writeable indicator
|
10
|
+
- backspace
|
7
11
|
|
8
12
|
Install
|
9
13
|
=======
|
@@ -15,12 +19,11 @@ Usage
|
|
15
19
|
|
16
20
|
TODO
|
17
21
|
=====
|
22
|
+
- indentation + paste support
|
18
23
|
- delete key !?
|
19
24
|
- warnings / messages
|
20
|
-
- help
|
21
25
|
- syntax highlighting
|
22
26
|
|
23
|
-
|
24
27
|
Author
|
25
28
|
======
|
26
29
|
[Michael Grosser](http://grosser.it)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.2
|
data/bin/ruco
CHANGED
@@ -1,8 +1,31 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
require 'curses'
|
3
|
-
|
3
|
+
require 'optparse'
|
4
4
|
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
5
|
-
|
5
|
+
|
6
|
+
def parse_options
|
7
|
+
options = OptionParser.new do |opts|
|
8
|
+
opts.banner = <<BANNER
|
9
|
+
[Ru]by [Co]mmandline editor
|
10
|
+
|
11
|
+
Shortcuts:
|
12
|
+
Ctrl+w/q Exit
|
13
|
+
Ctrl+s Save
|
14
|
+
|
15
|
+
Usage:
|
16
|
+
ruco FILE
|
17
|
+
|
18
|
+
Options:
|
19
|
+
BANNER
|
20
|
+
opts.on("-h", "--help","Show this.") { puts opts; exit }
|
21
|
+
end
|
22
|
+
options.parse!
|
23
|
+
|
24
|
+
if ARGV.empty?
|
25
|
+
puts options
|
26
|
+
exit
|
27
|
+
end
|
28
|
+
end
|
6
29
|
|
7
30
|
def write(line,row,text)
|
8
31
|
Curses.setpos(line,row)
|
@@ -22,19 +45,30 @@ def init_screen
|
|
22
45
|
end
|
23
46
|
end
|
24
47
|
|
25
|
-
|
48
|
+
def display(widget, offset, color)
|
49
|
+
Curses.attrset color
|
50
|
+
lines = widget.view.naive_split("\n")
|
51
|
+
Curses.stdscr.maxy.times do |i|
|
52
|
+
line = lines[i] || ''
|
53
|
+
clearer = Curses.stdscr.maxx - line.size
|
54
|
+
clearer = " " * clearer
|
55
|
+
write(i + offset, 0, line + clearer)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
parse_options
|
60
|
+
|
61
|
+
require 'ruco'
|
62
|
+
editor_offset = 1
|
63
|
+
editor = Ruco::Editor.new(ARGV[0], :lines => Curses.stdscr.maxy - editor_offset, :columns => Curses.stdscr.maxx)
|
64
|
+
status = Ruco::StatusBar.new(editor, :columns => Curses.stdscr.maxx)
|
26
65
|
|
27
66
|
init_screen do
|
28
67
|
loop do
|
29
|
-
|
30
|
-
|
31
|
-
line = lines[i] || ''
|
32
|
-
clearer = Curses.stdscr.maxx - line.size
|
33
|
-
clearer = " " * clearer
|
34
|
-
write(i, 0, line + clearer)
|
35
|
-
end
|
68
|
+
display status, 0, Curses::A_REVERSE
|
69
|
+
display editor, editor_offset, Curses::A_NORMAL
|
36
70
|
|
37
|
-
Curses.setpos(editor.cursor_line, editor.cursor_column)
|
71
|
+
Curses.setpos(editor.cursor_line + editor_offset, editor.cursor_column)
|
38
72
|
|
39
73
|
key = Curses.getch
|
40
74
|
|
@@ -46,6 +80,7 @@ init_screen do
|
|
46
80
|
when 32..126 then editor.insert(key.chr) # printable
|
47
81
|
when 10 then editor.insert("\n") # enter
|
48
82
|
when 263 then editor.delete(-1) # backspace
|
83
|
+
when ?\C-s then editor.save
|
49
84
|
when ?\C-w, ?\C-q then break # quit
|
50
85
|
end
|
51
86
|
end
|
data/lib/ruco.rb
CHANGED
data/lib/ruco/editor.rb
CHANGED
@@ -2,7 +2,7 @@ module Ruco
|
|
2
2
|
class Editor
|
3
3
|
SCROLLING_OFFSET = 20
|
4
4
|
|
5
|
-
attr_reader :cursor_line, :cursor_column
|
5
|
+
attr_reader :cursor_line, :cursor_column, :file
|
6
6
|
|
7
7
|
def initialize(file, options)
|
8
8
|
@file = file
|
@@ -14,6 +14,7 @@ module Ruco
|
|
14
14
|
@cursor_column = 0
|
15
15
|
@scrolled_lines = 0
|
16
16
|
@scrolled_columns = 0
|
17
|
+
@modified = false
|
17
18
|
@options[:line_scrolling_offset] ||= @options[:lines] / 2
|
18
19
|
@options[:column_scrolling_offset] ||= @options[:columns] / 2
|
19
20
|
end
|
@@ -34,6 +35,7 @@ module Ruco
|
|
34
35
|
def insert(text)
|
35
36
|
insert_into_content cursor_index, text
|
36
37
|
move_according_to_insert(text)
|
38
|
+
@modified = true
|
37
39
|
end
|
38
40
|
|
39
41
|
def delete(count)
|
@@ -42,6 +44,7 @@ module Ruco
|
|
42
44
|
else
|
43
45
|
backspace(count.abs)
|
44
46
|
end
|
47
|
+
@modified = true
|
45
48
|
end
|
46
49
|
|
47
50
|
def backspace(count)
|
@@ -53,16 +56,22 @@ module Ruco
|
|
53
56
|
|
54
57
|
@content.slice!(start_index, count)
|
55
58
|
set_cursor_to_index start_index
|
59
|
+
@modified = true
|
56
60
|
end
|
57
61
|
|
58
62
|
def save
|
59
63
|
File.open(@file,'w'){|f| f.write(@content) }
|
64
|
+
@modified = false
|
60
65
|
end
|
61
66
|
|
62
67
|
def cursor
|
63
68
|
[cursor_line, cursor_column]
|
64
69
|
end
|
65
70
|
|
71
|
+
def modified?
|
72
|
+
@modified
|
73
|
+
end
|
74
|
+
|
66
75
|
private
|
67
76
|
|
68
77
|
def lines
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Ruco
|
2
|
+
class StatusBar
|
3
|
+
def initialize(editor, options)
|
4
|
+
@editor = editor
|
5
|
+
@options = options
|
6
|
+
end
|
7
|
+
|
8
|
+
def view
|
9
|
+
"Ruco #{Ruco::VERSION} -- #{@editor.file}#{change_indicator}#{writable_indicator}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def format
|
13
|
+
Curses::A_REVERSE
|
14
|
+
end
|
15
|
+
|
16
|
+
def change_indicator
|
17
|
+
@editor.modified? ? '*' : ' '
|
18
|
+
end
|
19
|
+
|
20
|
+
def writable_indicator
|
21
|
+
@writeable ||= begin
|
22
|
+
writable = (not File.exist?(@editor.file) or system("test -w #{@editor.file}"))
|
23
|
+
writable ? ' ' : '!'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/ruco.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
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.2"
|
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"]
|
@@ -24,8 +24,11 @@ Gem::Specification.new do |s|
|
|
24
24
|
"lib/ruco/core_ext/array.rb",
|
25
25
|
"lib/ruco/core_ext/string.rb",
|
26
26
|
"lib/ruco/editor.rb",
|
27
|
+
"lib/ruco/status_bar.rb",
|
27
28
|
"ruco.gemspec",
|
28
29
|
"spec/ruco/core_ext/string_spec.rb",
|
30
|
+
"spec/ruco/editor_spec.rb",
|
31
|
+
"spec/ruco/status_bar_spec.rb",
|
29
32
|
"spec/ruco_spec.rb",
|
30
33
|
"spec/spec_helper.rb"
|
31
34
|
]
|
@@ -35,6 +38,8 @@ Gem::Specification.new do |s|
|
|
35
38
|
s.summary = %q{Commandline editor written in ruby}
|
36
39
|
s.test_files = [
|
37
40
|
"spec/ruco/core_ext/string_spec.rb",
|
41
|
+
"spec/ruco/editor_spec.rb",
|
42
|
+
"spec/ruco/status_bar_spec.rb",
|
38
43
|
"spec/ruco_spec.rb",
|
39
44
|
"spec/spec_helper.rb"
|
40
45
|
]
|
@@ -0,0 +1,263 @@
|
|
1
|
+
require File.expand_path('spec/spec_helper')
|
2
|
+
|
3
|
+
describe Ruco::Editor do
|
4
|
+
def write(content)
|
5
|
+
File.open(@file,'w'){|f| f.write(content) }
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:editor){ Ruco::Editor.new(@file, :lines => 3, :columns => 5, :line_scrolling_offset => 5, :column_scrolling_offset => 5) }
|
9
|
+
|
10
|
+
before do
|
11
|
+
@file = 'spec/temp.txt'
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'moving' do
|
15
|
+
before do
|
16
|
+
write(" \n \n ")
|
17
|
+
end
|
18
|
+
|
19
|
+
it "starts at 0,0" do
|
20
|
+
editor.cursor.should == [0,0]
|
21
|
+
end
|
22
|
+
|
23
|
+
it "can move" do
|
24
|
+
editor.move(1,2)
|
25
|
+
editor.cursor.should == [1,2]
|
26
|
+
editor.move(1,1)
|
27
|
+
editor.cursor.should == [2,3]
|
28
|
+
end
|
29
|
+
|
30
|
+
it "can move in empty file" do
|
31
|
+
write("\n\n\n")
|
32
|
+
editor.move(2,0)
|
33
|
+
editor.cursor.should == [2,0]
|
34
|
+
end
|
35
|
+
|
36
|
+
it "cannot move left/top off screen" do
|
37
|
+
editor.move(-1,-1)
|
38
|
+
editor.cursor.should == [0,0]
|
39
|
+
end
|
40
|
+
|
41
|
+
it "cannot move right of characters" do
|
42
|
+
editor.move(2,6)
|
43
|
+
editor.cursor.should == [2,4]
|
44
|
+
end
|
45
|
+
|
46
|
+
it "gets reset to empty line when moving past lines" do
|
47
|
+
write(" ")
|
48
|
+
editor.move(6,3)
|
49
|
+
editor.cursor.should == [1,0]
|
50
|
+
end
|
51
|
+
|
52
|
+
describe 'column scrolling' do
|
53
|
+
it "can scroll columns" do
|
54
|
+
write("123456789\n123")
|
55
|
+
editor.move(0,4)
|
56
|
+
editor.view.should == "12345\n123\n\n"
|
57
|
+
editor.cursor_column.should == 4
|
58
|
+
|
59
|
+
editor.move(0,1)
|
60
|
+
editor.view.should == "6789\n\n\n"
|
61
|
+
editor.cursor_column.should == 0
|
62
|
+
end
|
63
|
+
|
64
|
+
it "cannot scroll past the screen" do
|
65
|
+
write('123456789')
|
66
|
+
editor.move(0,4)
|
67
|
+
6.times{ editor.move(0,1) }
|
68
|
+
editor.view.should == "6789\n\n\n"
|
69
|
+
editor.cursor_column.should == 4
|
70
|
+
end
|
71
|
+
|
72
|
+
it "can scroll columns backwards" do
|
73
|
+
write('123456789')
|
74
|
+
editor.move(0,5)
|
75
|
+
editor.view.should == "6789\n\n\n"
|
76
|
+
|
77
|
+
editor.move(0,-1)
|
78
|
+
editor.view.should == "12345\n\n\n"
|
79
|
+
editor.cursor_column.should == 4
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe 'line scrolling' do
|
84
|
+
before do
|
85
|
+
write("1\n2\n3\n4\n5\n6\n7\n8\n9")
|
86
|
+
end
|
87
|
+
|
88
|
+
it "can scroll lines down (at maximum of screen size)" do
|
89
|
+
editor.move(2,0)
|
90
|
+
editor.view.should == "1\n2\n3\n"
|
91
|
+
|
92
|
+
editor.move(1,0)
|
93
|
+
editor.view.should == "4\n5\n6\n"
|
94
|
+
editor.cursor_line.should == 0
|
95
|
+
end
|
96
|
+
|
97
|
+
it "can scroll till end of file" do
|
98
|
+
editor.move(15,0)
|
99
|
+
editor.view.should == "\n\n\n"
|
100
|
+
editor.cursor_line.should == 0
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe 'viewing' do
|
106
|
+
before do
|
107
|
+
write('')
|
108
|
+
end
|
109
|
+
|
110
|
+
it "displays an empty screen" do
|
111
|
+
editor.view.should == "\n\n\n"
|
112
|
+
end
|
113
|
+
|
114
|
+
it "displays short file content" do
|
115
|
+
write('xxx')
|
116
|
+
editor.view.should == "xxx\n\n\n"
|
117
|
+
end
|
118
|
+
|
119
|
+
it "displays long file content" do
|
120
|
+
write('1234567')
|
121
|
+
editor.view.should == "12345\n\n\n"
|
122
|
+
end
|
123
|
+
|
124
|
+
it "displays multiline-file content" do
|
125
|
+
write("xxx\nyyy\nzzz\niii")
|
126
|
+
editor.view.should == "xxx\nyyy\nzzz\n"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe 'inserting' do
|
131
|
+
before do
|
132
|
+
write('')
|
133
|
+
end
|
134
|
+
|
135
|
+
it "can insert new chars" do
|
136
|
+
write('123')
|
137
|
+
editor.move(0,1)
|
138
|
+
editor.insert('ab')
|
139
|
+
editor.view.should == "1ab23\n\n\n"
|
140
|
+
editor.cursor.should == [0,3]
|
141
|
+
end
|
142
|
+
|
143
|
+
it "can insert new newlines" do
|
144
|
+
editor.insert("ab\nc")
|
145
|
+
editor.view.should == "ab\nc\n\n"
|
146
|
+
editor.cursor.should == [1,1]
|
147
|
+
end
|
148
|
+
|
149
|
+
it "jumps to correct column when inserting newline" do
|
150
|
+
write("abc\ndefg")
|
151
|
+
editor.move(1,2)
|
152
|
+
editor.insert("1\n23")
|
153
|
+
editor.view.should == "abc\nde1\n23fg\n"
|
154
|
+
editor.cursor.should == [2,2]
|
155
|
+
end
|
156
|
+
|
157
|
+
it "jumps to correct column when inserting 1 newline" do
|
158
|
+
write("abc\ndefg")
|
159
|
+
editor.move(1,2)
|
160
|
+
editor.insert("\n")
|
161
|
+
editor.view.should == "abc\nde\nfg\n"
|
162
|
+
editor.cursor.should == [2,0]
|
163
|
+
end
|
164
|
+
|
165
|
+
it "can add newlines to the end" do
|
166
|
+
write('')
|
167
|
+
editor.insert("\n")
|
168
|
+
editor.insert("\n")
|
169
|
+
editor.cursor.should == [2,0]
|
170
|
+
end
|
171
|
+
|
172
|
+
it "can add newlines to the moveable end" do
|
173
|
+
write('')
|
174
|
+
editor.move(1,0)
|
175
|
+
editor.insert("\n")
|
176
|
+
editor.cursor.should == [2,0]
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
describe 'save' do
|
181
|
+
it 'stores the file' do
|
182
|
+
write('xxx')
|
183
|
+
editor.insert('a')
|
184
|
+
editor.save
|
185
|
+
File.read(@file).should == 'axxx'
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'creates the file' do
|
189
|
+
`rm #{@file}`
|
190
|
+
editor.insert('a')
|
191
|
+
editor.save
|
192
|
+
File.read(@file).should == 'a'
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
describe 'delete' do
|
197
|
+
it 'removes a char' do
|
198
|
+
write('123')
|
199
|
+
editor.delete(1)
|
200
|
+
editor.view.should == "23\n\n\n"
|
201
|
+
editor.cursor.should == [0,0]
|
202
|
+
end
|
203
|
+
|
204
|
+
it 'removes a line' do
|
205
|
+
write("123\n45")
|
206
|
+
editor.move(0,3)
|
207
|
+
editor.delete(1)
|
208
|
+
editor.view.should == "12345\n\n\n"
|
209
|
+
editor.cursor.should == [0,3]
|
210
|
+
end
|
211
|
+
|
212
|
+
it "cannot backspace over 0,0" do
|
213
|
+
write("aa")
|
214
|
+
editor.move(0,1)
|
215
|
+
editor.delete(-3)
|
216
|
+
editor.view.should == "a\n\n\n"
|
217
|
+
editor.cursor.should == [0,0]
|
218
|
+
end
|
219
|
+
|
220
|
+
it 'backspaces a char' do
|
221
|
+
write('123')
|
222
|
+
editor.move(0,3)
|
223
|
+
editor.delete(-1)
|
224
|
+
editor.view.should == "12\n\n\n"
|
225
|
+
editor.cursor.should == [0,2]
|
226
|
+
end
|
227
|
+
|
228
|
+
it 'backspaces a newline' do
|
229
|
+
write("1\n234")
|
230
|
+
editor.move(1,0)
|
231
|
+
editor.delete(-1)
|
232
|
+
editor.view.should == "1234\n\n\n"
|
233
|
+
editor.cursor.should == [0,1]
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
describe :changes? do
|
238
|
+
it "is unchanged by default" do
|
239
|
+
editor.modified?.should == false
|
240
|
+
end
|
241
|
+
|
242
|
+
it "is changed after insert" do
|
243
|
+
editor.insert('x')
|
244
|
+
editor.modified?.should == true
|
245
|
+
end
|
246
|
+
|
247
|
+
it "is changed after delete" do
|
248
|
+
editor.delete(1)
|
249
|
+
editor.modified?.should == true
|
250
|
+
end
|
251
|
+
|
252
|
+
it "is not changed after move" do
|
253
|
+
editor.move(1,1)
|
254
|
+
editor.modified?.should == false
|
255
|
+
end
|
256
|
+
|
257
|
+
it "is unchanged after save" do
|
258
|
+
editor.insert('x')
|
259
|
+
editor.save
|
260
|
+
editor.modified?.should == false
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.expand_path('spec/spec_helper')
|
2
|
+
|
3
|
+
describe Ruco::StatusBar do
|
4
|
+
let(:file){ 'spec/temp.txt' }
|
5
|
+
let(:editor){ Ruco::Editor.new(file, :lines => 5, :columns => 10) }
|
6
|
+
let(:bar){ Ruco::StatusBar.new(editor, :columns => 10) }
|
7
|
+
|
8
|
+
it "shows name and version" do
|
9
|
+
bar.view.should include("Ruco #{Ruco::VERSION}")
|
10
|
+
end
|
11
|
+
|
12
|
+
it "shows the file" do
|
13
|
+
bar.view.should include(file)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "indicates modified" do
|
17
|
+
bar.view.should_not include('*')
|
18
|
+
editor.insert('x')
|
19
|
+
bar.view.should include('*')
|
20
|
+
end
|
21
|
+
|
22
|
+
it "indicates writable" do
|
23
|
+
bar.view.should_not include('!')
|
24
|
+
end
|
25
|
+
|
26
|
+
it "indicates writable if file is missing" do
|
27
|
+
editor.stub!(:file).and_return '/gradasadadsds'
|
28
|
+
bar.view.should_not include('!')
|
29
|
+
end
|
30
|
+
|
31
|
+
it "indicates not writable" do
|
32
|
+
editor.stub!(:file).and_return '/etc/sudoers'
|
33
|
+
bar.view.should include('!')
|
34
|
+
end
|
35
|
+
end
|
data/spec/ruco_spec.rb
CHANGED
@@ -1,240 +1,7 @@
|
|
1
1
|
require File.expand_path('spec/spec_helper')
|
2
2
|
|
3
3
|
describe Ruco do
|
4
|
-
def write(content)
|
5
|
-
File.open(@file,'w'){|f| f.write(content) }
|
6
|
-
end
|
7
|
-
|
8
|
-
let(:editor){ Ruco::Editor.new(@file, :lines => 3, :columns => 5, :line_scrolling_offset => 5, :column_scrolling_offset => 5) }
|
9
|
-
|
10
4
|
it "has a VERSION" do
|
11
5
|
Ruco::VERSION.should =~ /^\d+\.\d+\.\d+$/
|
12
6
|
end
|
13
|
-
|
14
|
-
before do
|
15
|
-
@file = 'spec/temp.txt'
|
16
|
-
end
|
17
|
-
|
18
|
-
describe 'moving' do
|
19
|
-
before do
|
20
|
-
write(" \n \n ")
|
21
|
-
end
|
22
|
-
|
23
|
-
it "starts at 0,0" do
|
24
|
-
editor.cursor.should == [0,0]
|
25
|
-
end
|
26
|
-
|
27
|
-
it "can move" do
|
28
|
-
editor.move(1,2)
|
29
|
-
editor.cursor.should == [1,2]
|
30
|
-
editor.move(1,1)
|
31
|
-
editor.cursor.should == [2,3]
|
32
|
-
end
|
33
|
-
|
34
|
-
it "can move in empty file" do
|
35
|
-
write("\n\n\n")
|
36
|
-
editor.move(2,0)
|
37
|
-
editor.cursor.should == [2,0]
|
38
|
-
end
|
39
|
-
|
40
|
-
it "cannot move left/top off screen" do
|
41
|
-
editor.move(-1,-1)
|
42
|
-
editor.cursor.should == [0,0]
|
43
|
-
end
|
44
|
-
|
45
|
-
it "cannot move right of characters" do
|
46
|
-
editor.move(2,6)
|
47
|
-
editor.cursor.should == [2,4]
|
48
|
-
end
|
49
|
-
|
50
|
-
it "gets reset to empty line when moving past lines" do
|
51
|
-
write(" ")
|
52
|
-
editor.move(6,3)
|
53
|
-
editor.cursor.should == [1,0]
|
54
|
-
end
|
55
|
-
|
56
|
-
describe 'column scrolling' do
|
57
|
-
it "can scroll columns" do
|
58
|
-
write("123456789\n123")
|
59
|
-
editor.move(0,4)
|
60
|
-
editor.view.should == "12345\n123\n\n"
|
61
|
-
editor.cursor_column.should == 4
|
62
|
-
|
63
|
-
editor.move(0,1)
|
64
|
-
editor.view.should == "6789\n\n\n"
|
65
|
-
editor.cursor_column.should == 0
|
66
|
-
end
|
67
|
-
|
68
|
-
it "cannot scroll past the screen" do
|
69
|
-
write('123456789')
|
70
|
-
editor.move(0,4)
|
71
|
-
6.times{ editor.move(0,1) }
|
72
|
-
editor.view.should == "6789\n\n\n"
|
73
|
-
editor.cursor_column.should == 4
|
74
|
-
end
|
75
|
-
|
76
|
-
it "can scroll columns backwards" do
|
77
|
-
write('123456789')
|
78
|
-
editor.move(0,5)
|
79
|
-
editor.view.should == "6789\n\n\n"
|
80
|
-
|
81
|
-
editor.move(0,-1)
|
82
|
-
editor.view.should == "12345\n\n\n"
|
83
|
-
editor.cursor_column.should == 4
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
describe 'line scrolling' do
|
88
|
-
before do
|
89
|
-
write("1\n2\n3\n4\n5\n6\n7\n8\n9")
|
90
|
-
end
|
91
|
-
|
92
|
-
it "can scroll lines down (at maximum of screen size)" do
|
93
|
-
editor.move(2,0)
|
94
|
-
editor.view.should == "1\n2\n3\n"
|
95
|
-
|
96
|
-
editor.move(1,0)
|
97
|
-
editor.view.should == "4\n5\n6\n"
|
98
|
-
editor.cursor_line.should == 0
|
99
|
-
end
|
100
|
-
|
101
|
-
it "can scroll till end of file" do
|
102
|
-
editor.move(15,0)
|
103
|
-
editor.view.should == "\n\n\n"
|
104
|
-
editor.cursor_line.should == 0
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
describe 'viewing' do
|
110
|
-
before do
|
111
|
-
write('')
|
112
|
-
end
|
113
|
-
|
114
|
-
it "displays an empty screen" do
|
115
|
-
editor.view.should == "\n\n\n"
|
116
|
-
end
|
117
|
-
|
118
|
-
it "displays short file content" do
|
119
|
-
write('xxx')
|
120
|
-
editor.view.should == "xxx\n\n\n"
|
121
|
-
end
|
122
|
-
|
123
|
-
it "displays long file content" do
|
124
|
-
write('1234567')
|
125
|
-
editor.view.should == "12345\n\n\n"
|
126
|
-
end
|
127
|
-
|
128
|
-
it "displays multiline-file content" do
|
129
|
-
write("xxx\nyyy\nzzz\niii")
|
130
|
-
editor.view.should == "xxx\nyyy\nzzz\n"
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
describe 'inserting' do
|
135
|
-
before do
|
136
|
-
write('')
|
137
|
-
end
|
138
|
-
|
139
|
-
it "can insert new chars" do
|
140
|
-
write('123')
|
141
|
-
editor.move(0,1)
|
142
|
-
editor.insert('ab')
|
143
|
-
editor.view.should == "1ab23\n\n\n"
|
144
|
-
editor.cursor.should == [0,3]
|
145
|
-
end
|
146
|
-
|
147
|
-
it "can insert new newlines" do
|
148
|
-
editor.insert("ab\nc")
|
149
|
-
editor.view.should == "ab\nc\n\n"
|
150
|
-
editor.cursor.should == [1,1]
|
151
|
-
end
|
152
|
-
|
153
|
-
it "jumps to correct column when inserting newline" do
|
154
|
-
write("abc\ndefg")
|
155
|
-
editor.move(1,2)
|
156
|
-
editor.insert("1\n23")
|
157
|
-
editor.view.should == "abc\nde1\n23fg\n"
|
158
|
-
editor.cursor.should == [2,2]
|
159
|
-
end
|
160
|
-
|
161
|
-
it "jumps to correct column when inserting 1 newline" do
|
162
|
-
write("abc\ndefg")
|
163
|
-
editor.move(1,2)
|
164
|
-
editor.insert("\n")
|
165
|
-
editor.view.should == "abc\nde\nfg\n"
|
166
|
-
editor.cursor.should == [2,0]
|
167
|
-
end
|
168
|
-
|
169
|
-
it "can add newlines to the end" do
|
170
|
-
write('')
|
171
|
-
editor.insert("\n")
|
172
|
-
editor.insert("\n")
|
173
|
-
editor.cursor.should == [2,0]
|
174
|
-
end
|
175
|
-
|
176
|
-
it "can add newlines to the moveable end" do
|
177
|
-
write('')
|
178
|
-
editor.move(1,0)
|
179
|
-
editor.insert("\n")
|
180
|
-
editor.cursor.should == [2,0]
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
describe 'save' do
|
185
|
-
it 'stores the file' do
|
186
|
-
write('xxx')
|
187
|
-
editor.insert('a')
|
188
|
-
editor.save
|
189
|
-
File.read(@file).should == 'axxx'
|
190
|
-
end
|
191
|
-
|
192
|
-
it 'creates the file' do
|
193
|
-
`rm #{@file}`
|
194
|
-
editor.insert('a')
|
195
|
-
editor.save
|
196
|
-
File.read(@file).should == 'a'
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
describe 'delete' do
|
201
|
-
it 'removes a char' do
|
202
|
-
write('123')
|
203
|
-
editor.delete(1)
|
204
|
-
editor.view.should == "23\n\n\n"
|
205
|
-
editor.cursor.should == [0,0]
|
206
|
-
end
|
207
|
-
|
208
|
-
it 'removes a line' do
|
209
|
-
write("123\n45")
|
210
|
-
editor.move(0,3)
|
211
|
-
editor.delete(1)
|
212
|
-
editor.view.should == "12345\n\n\n"
|
213
|
-
editor.cursor.should == [0,3]
|
214
|
-
end
|
215
|
-
|
216
|
-
it "cannot backspace over 0,0" do
|
217
|
-
write("aa")
|
218
|
-
editor.move(0,1)
|
219
|
-
editor.delete(-3)
|
220
|
-
editor.view.should == "a\n\n\n"
|
221
|
-
editor.cursor.should == [0,0]
|
222
|
-
end
|
223
|
-
|
224
|
-
it 'backspaces a char' do
|
225
|
-
write('123')
|
226
|
-
editor.move(0,3)
|
227
|
-
editor.delete(-1)
|
228
|
-
editor.view.should == "12\n\n\n"
|
229
|
-
editor.cursor.should == [0,2]
|
230
|
-
end
|
231
|
-
|
232
|
-
it 'backspaces a newline' do
|
233
|
-
write("1\n234")
|
234
|
-
editor.move(1,0)
|
235
|
-
editor.delete(-1)
|
236
|
-
editor.view.should == "1234\n\n\n"
|
237
|
-
editor.cursor.should == [0,1]
|
238
|
-
end
|
239
|
-
end
|
240
7
|
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: 27
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Michael Grosser
|
@@ -38,8 +38,11 @@ files:
|
|
38
38
|
- lib/ruco/core_ext/array.rb
|
39
39
|
- lib/ruco/core_ext/string.rb
|
40
40
|
- lib/ruco/editor.rb
|
41
|
+
- lib/ruco/status_bar.rb
|
41
42
|
- ruco.gemspec
|
42
43
|
- spec/ruco/core_ext/string_spec.rb
|
44
|
+
- spec/ruco/editor_spec.rb
|
45
|
+
- spec/ruco/status_bar_spec.rb
|
43
46
|
- spec/ruco_spec.rb
|
44
47
|
- spec/spec_helper.rb
|
45
48
|
has_rdoc: true
|
@@ -78,5 +81,7 @@ specification_version: 3
|
|
78
81
|
summary: Commandline editor written in ruby
|
79
82
|
test_files:
|
80
83
|
- spec/ruco/core_ext/string_spec.rb
|
84
|
+
- spec/ruco/editor_spec.rb
|
85
|
+
- spec/ruco/status_bar_spec.rb
|
81
86
|
- spec/ruco_spec.rb
|
82
87
|
- spec/spec_helper.rb
|