ruco 0.2.18 → 0.2.19
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.
- checksums.yaml +7 -0
- data/MIT-LICENSE.txt +20 -0
- data/bin/ruco +24 -30
- data/lib/ruco.rb +1 -3
- data/lib/ruco/command_bar.rb +1 -1
- data/lib/ruco/core_ext/range.rb +1 -1
- data/lib/ruco/core_ext/string.rb +2 -15
- data/lib/ruco/editor/colors.rb +2 -2
- data/lib/ruco/status_bar.rb +1 -1
- data/lib/ruco/syntax_parser.rb +1 -1
- data/lib/ruco/version.rb +1 -1
- data/lib/ruco/window.rb +1 -1
- metadata +34 -64
- data/.gitignore +0 -2
- data/.travis.yml +0 -7
- data/Gemfile +0 -8
- data/Gemfile.lock +0 -39
- data/Rakefile +0 -32
- data/Readme.md +0 -164
- data/lib/ruco/keyboard.rb +0 -206
- data/lib/ruco/screen.rb +0 -148
- data/lib/ruco/style_map.rb +0 -108
- data/playground/benchmark_syntax_parser.rb +0 -23
- data/ruco.gemspec +0 -22
- data/spec/fixtures/slow.js +0 -4
- data/spec/fixtures/test.tmTheme +0 -186
- data/spec/ruco/application_spec.rb +0 -433
- data/spec/ruco/array_processor_spec.rb +0 -46
- data/spec/ruco/command_bar_spec.rb +0 -127
- data/spec/ruco/core_ext/array_spec.rb +0 -31
- data/spec/ruco/core_ext/range_spec.rb +0 -37
- data/spec/ruco/core_ext/string_spec.rb +0 -36
- data/spec/ruco/editor_spec.rb +0 -1261
- data/spec/ruco/file_store_spec.rb +0 -102
- data/spec/ruco/form_spec.rb +0 -83
- data/spec/ruco/history_spec.rb +0 -143
- data/spec/ruco/keyboard_spec.rb +0 -136
- data/spec/ruco/option_accessor_spec.rb +0 -26
- data/spec/ruco/screen_spec.rb +0 -52
- data/spec/ruco/status_bar_spec.rb +0 -49
- data/spec/ruco/style_map_spec.rb +0 -124
- data/spec/ruco/syntax_parser_spec.rb +0 -78
- data/spec/ruco/text_area_spec.rb +0 -183
- data/spec/ruco/tm_theme_spec.rb +0 -14
- data/spec/ruco/window_spec.rb +0 -170
- data/spec/ruco_spec.rb +0 -7
- data/spec/spec_helper.rb +0 -36
@@ -1,46 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Ruco::ArrayProcessor do
|
4
|
-
let(:p){ Ruco::ArrayProcessor.new }
|
5
|
-
before do
|
6
|
-
p.new_line('xxx')
|
7
|
-
end
|
8
|
-
|
9
|
-
it "is empty by default" do
|
10
|
-
p.lines.should == [[]]
|
11
|
-
end
|
12
|
-
|
13
|
-
it "parses simple syntax" do
|
14
|
-
p.open_tag('xxx',0)
|
15
|
-
p.close_tag('xxx',3)
|
16
|
-
p.lines.should == [[['xxx',0...3]]]
|
17
|
-
end
|
18
|
-
|
19
|
-
it "parses nested syntax" do
|
20
|
-
p.open_tag('xxx',0)
|
21
|
-
p.open_tag('yyy',2)
|
22
|
-
p.close_tag('yyy',3)
|
23
|
-
p.close_tag('xxx',3)
|
24
|
-
p.lines.should == [[["yyy", 2...3], ["xxx", 0...3]]]
|
25
|
-
end
|
26
|
-
|
27
|
-
it "parses multiline syntax" do
|
28
|
-
p.open_tag('xxx',0)
|
29
|
-
p.close_tag('xxx',3)
|
30
|
-
p.new_line('xxx')
|
31
|
-
p.open_tag('xxx',1)
|
32
|
-
p.close_tag('xxx',2)
|
33
|
-
p.lines.should == [
|
34
|
-
[["xxx", 0...3]],
|
35
|
-
[["xxx", 1...2]]
|
36
|
-
]
|
37
|
-
end
|
38
|
-
|
39
|
-
it "parses multiply nested syntax" do
|
40
|
-
p.open_tag('yyy',0)
|
41
|
-
p.open_tag('yyy',2)
|
42
|
-
p.close_tag('yyy',3)
|
43
|
-
p.close_tag('yyy',3)
|
44
|
-
p.lines.should == [[["yyy", 2...3], ["yyy", 0...3]]]
|
45
|
-
end
|
46
|
-
end
|
@@ -1,127 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Ruco::CommandBar do
|
4
|
-
let(:default_view){ "^W Exit ^S Save ^F Find" }
|
5
|
-
let(:bar){ Ruco::CommandBar.new(:columns => 30) }
|
6
|
-
|
7
|
-
it "shows shortcuts by default" do
|
8
|
-
bar.view.should == default_view
|
9
|
-
end
|
10
|
-
|
11
|
-
it "shows less shortcuts when space is low" do
|
12
|
-
bar = Ruco::CommandBar.new(:columns => 29)
|
13
|
-
bar.view.should == default_view
|
14
|
-
bar = Ruco::CommandBar.new(:columns => 28)
|
15
|
-
bar.view.should == "^W Exit ^S Save"
|
16
|
-
end
|
17
|
-
|
18
|
-
describe :ask do
|
19
|
-
it "sets command bar into question mode" do
|
20
|
-
bar.ask('Find: '){}
|
21
|
-
bar.view.should == "Find: "
|
22
|
-
bar.cursor.column.should == 6
|
23
|
-
end
|
24
|
-
|
25
|
-
it "can enter answer" do
|
26
|
-
bar.ask('Find: '){}
|
27
|
-
bar.insert('abc')
|
28
|
-
bar.view.should == "Find: abc"
|
29
|
-
bar.cursor.column.should == 9
|
30
|
-
end
|
31
|
-
|
32
|
-
it "gets reset when submitting" do
|
33
|
-
bar.ask('Find: '){}
|
34
|
-
bar.insert("123\n")
|
35
|
-
bar.view.should == default_view
|
36
|
-
end
|
37
|
-
|
38
|
-
it "keeps entered answer when cached" do
|
39
|
-
bar.ask('Find: ', :cache => true){}
|
40
|
-
bar.insert('abc')
|
41
|
-
bar.insert("\n")
|
42
|
-
bar.ask('Find: ', :cache => true){}
|
43
|
-
bar.view.should == "Find: abc"
|
44
|
-
bar.cursor.column.should == 9
|
45
|
-
end
|
46
|
-
|
47
|
-
it "does not keep block when cached" do
|
48
|
-
x = 0
|
49
|
-
bar.ask('Find: ', :cache => true){ x = 1 }
|
50
|
-
bar.insert("\n")
|
51
|
-
bar.ask('Find: ', :cache => true){ x = 2 }
|
52
|
-
bar.insert("\n")
|
53
|
-
x.should == 2
|
54
|
-
end
|
55
|
-
|
56
|
-
it "reset the question when cached" do
|
57
|
-
bar.ask('Find: ', :cache => true){}
|
58
|
-
bar.insert('abc')
|
59
|
-
bar.reset
|
60
|
-
|
61
|
-
bar.view.should == default_view
|
62
|
-
bar.ask('Find: ', :cache => true){}
|
63
|
-
bar.view.should == "Find: " # term removed
|
64
|
-
end
|
65
|
-
|
66
|
-
it "does not reset all cached questions" do
|
67
|
-
bar.ask('Find: ', :cache => true){}
|
68
|
-
bar.insert("abc\n")
|
69
|
-
|
70
|
-
bar.ask('Foo: ', :cache => true){}
|
71
|
-
bar.reset # clears Foo not Find
|
72
|
-
bar.view.should == default_view
|
73
|
-
|
74
|
-
bar.ask('Find: ', :cache => true){}
|
75
|
-
bar.view.should == "Find: abc"
|
76
|
-
end
|
77
|
-
|
78
|
-
it "selects last value on cache-hit so I can type for new value" do
|
79
|
-
bar.ask('Find: ', :cache => true){}
|
80
|
-
bar.insert('abc')
|
81
|
-
bar.insert("\n")
|
82
|
-
bar.ask('Find: ', :cache => true){}
|
83
|
-
bar.cursor.column.should == 9
|
84
|
-
bar.text_in_selection.should == 'abc'
|
85
|
-
end
|
86
|
-
|
87
|
-
it "can re-find when reopening the find bar" do
|
88
|
-
@results = []
|
89
|
-
bar.ask('Find: ', :cache => true){|r| @results << r }
|
90
|
-
bar.insert('abc')
|
91
|
-
bar.insert("\n")
|
92
|
-
bar.ask('Find: ', :cache => true){|r| @results << r }
|
93
|
-
bar.insert("\n")
|
94
|
-
@results.should == ["abc","abc"]
|
95
|
-
end
|
96
|
-
|
97
|
-
it "gets reset when starting a new question" do
|
98
|
-
bar.ask('Find: '){}
|
99
|
-
bar.insert('123')
|
100
|
-
bar.ask('Find: '){}
|
101
|
-
bar.view.should == "Find: "
|
102
|
-
end
|
103
|
-
|
104
|
-
it "can execute" do
|
105
|
-
bar.ask('Find: ', :cache => true){|r| @result = r }
|
106
|
-
bar.insert('abc')
|
107
|
-
bar.insert("d\n")
|
108
|
-
@result.should == 'abcd'
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
describe :style_map do
|
113
|
-
let(:bar){ Ruco::CommandBar.new(:columns => 10) }
|
114
|
-
|
115
|
-
it "is reverse" do
|
116
|
-
bar.style_map.flatten.should == [[:reverse, nil, nil, nil, nil, nil, nil, nil, nil, nil, :normal]]
|
117
|
-
end
|
118
|
-
|
119
|
-
it "has normal style for selected input field" do
|
120
|
-
bar.ask('Q'){}
|
121
|
-
bar.insert('abc')
|
122
|
-
bar.selecting{ move(:to, 0,0) }
|
123
|
-
bar.view.should == 'Q abc'
|
124
|
-
bar.style_map.flatten.should == [[:reverse, nil, :normal, nil, nil, nil, :reverse, nil, nil, nil, nil, :normal]]
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Array do
|
4
|
-
it "is bigger" do
|
5
|
-
[1].should > [0]
|
6
|
-
[1].should_not > [1]
|
7
|
-
end
|
8
|
-
|
9
|
-
it "is smaller" do
|
10
|
-
[1].should < [2]
|
11
|
-
[1].should_not < [1]
|
12
|
-
end
|
13
|
-
|
14
|
-
it "is smaller or equal" do
|
15
|
-
[1].should <= [1]
|
16
|
-
[1].should_not <= [0]
|
17
|
-
end
|
18
|
-
|
19
|
-
it "is bigger or equal" do
|
20
|
-
[1].should >= [1]
|
21
|
-
[1].should_not >= [2]
|
22
|
-
end
|
23
|
-
|
24
|
-
it "is between" do
|
25
|
-
[1].between?([1],[1]).should == true
|
26
|
-
[1].between?([1],[2]).should == true
|
27
|
-
[1].between?([0],[1]).should == true
|
28
|
-
[1].between?([0],[0]).should == false
|
29
|
-
[1].between?([2],[2]).should == false
|
30
|
-
end
|
31
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Range do
|
4
|
-
describe :last_element do
|
5
|
-
it "is the last for normal ranges" do
|
6
|
-
(1..2).last_element.should == 2
|
7
|
-
end
|
8
|
-
|
9
|
-
it "is the last for exclusive ranges" do
|
10
|
-
(1...3).last_element.should == 2
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
describe :move do
|
15
|
-
it "does not modify the original" do
|
16
|
-
a = 1..3
|
17
|
-
a.move(3)
|
18
|
-
a.should == (1..3)
|
19
|
-
end
|
20
|
-
|
21
|
-
it "can move 0" do
|
22
|
-
(1..3).move(0).should == (1..3)
|
23
|
-
end
|
24
|
-
|
25
|
-
it "can move right" do
|
26
|
-
(1..3).move(1).should == (2..4)
|
27
|
-
end
|
28
|
-
|
29
|
-
it "can move left" do
|
30
|
-
(1..3).move(-2).should == (-1..1)
|
31
|
-
end
|
32
|
-
|
33
|
-
it "can move exclusive ranges" do
|
34
|
-
(1...3).move(2).should == (3...5)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe String do
|
4
|
-
describe :naive_split do
|
5
|
-
it "splits repeated pattern" do
|
6
|
-
"aaa".naive_split('a').should == ['','','','']
|
7
|
-
end
|
8
|
-
|
9
|
-
it "splits normal stuff" do
|
10
|
-
"abacad".naive_split('a').should == ['','b','c','d']
|
11
|
-
end
|
12
|
-
|
13
|
-
it "splits empty into 1" do
|
14
|
-
"".naive_split('a').should == ['']
|
15
|
-
end
|
16
|
-
|
17
|
-
it "splits 1 into 2" do
|
18
|
-
"a".naive_split('a').should == ['','']
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
describe :surrounded_in? do
|
23
|
-
[
|
24
|
-
['aba','a',true],
|
25
|
-
['abcab','ab',true],
|
26
|
-
['acc','a',false],
|
27
|
-
['cca','a',false],
|
28
|
-
['(cca)',['(',')'],true],
|
29
|
-
['(cca',['(',')'],false],
|
30
|
-
].each do |text, word, success|
|
31
|
-
it "is #{success} for #{word} in #{text}" do
|
32
|
-
text.surrounded_in?(*[*word]).should == success
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
data/spec/ruco/editor_spec.rb
DELETED
@@ -1,1261 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Ruco::Editor do
|
4
|
-
def write(content)
|
5
|
-
File.open(@file,'wb'){|f| f.write(content) }
|
6
|
-
end
|
7
|
-
|
8
|
-
def read
|
9
|
-
File.binary_read(@file)
|
10
|
-
end
|
11
|
-
|
12
|
-
def color(c)
|
13
|
-
{
|
14
|
-
:string => ["#718C00", nil],
|
15
|
-
:keyword => ["#8959A8", nil],
|
16
|
-
:instance_variable => ["#C82829", nil],
|
17
|
-
}[c]
|
18
|
-
end
|
19
|
-
|
20
|
-
let(:language){ LanguageSniffer::Language.new(:name => 'ruby', :lexer => 'ruby') }
|
21
|
-
let(:editor){
|
22
|
-
editor = Ruco::Editor.new(@file, :lines => 3, :columns => 5, :language => language)
|
23
|
-
# only scroll when we reach end of lines/columns <-> able to test with smaller area
|
24
|
-
editor.send(:text_area).instance_eval{
|
25
|
-
@window.instance_eval{
|
26
|
-
@options[:line_scroll_threshold] = 0
|
27
|
-
@options[:line_scroll_offset] = 1
|
28
|
-
@options[:column_scroll_threshold] = 0
|
29
|
-
@options[:column_scroll_offset] = 1
|
30
|
-
}
|
31
|
-
}
|
32
|
-
editor
|
33
|
-
}
|
34
|
-
|
35
|
-
before do
|
36
|
-
`rm -rf ~/.ruco/sessions`
|
37
|
-
@file = 'spec/temp.txt'
|
38
|
-
write('')
|
39
|
-
end
|
40
|
-
|
41
|
-
describe "strange newline formats" do
|
42
|
-
it 'views \r normally' do
|
43
|
-
write("a\rb\rc\r")
|
44
|
-
editor.view.should == "a\nb\nc"
|
45
|
-
end
|
46
|
-
|
47
|
-
it 'views \r\n normally' do
|
48
|
-
write("a\r\nb\r\nc\r\n")
|
49
|
-
editor.view.should == "a\nb\nc"
|
50
|
-
end
|
51
|
-
|
52
|
-
it 'saves \r as \r' do
|
53
|
-
write("a\rb\rc\r")
|
54
|
-
editor.save
|
55
|
-
read.should == "a\rb\rc\r"
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'saves \r\n as \r\n' do
|
59
|
-
write("a\r\nb\r\nc\r\n")
|
60
|
-
editor.save
|
61
|
-
read.should == "a\r\nb\r\nc\r\n"
|
62
|
-
end
|
63
|
-
|
64
|
-
it "converts mixed formats to first" do
|
65
|
-
write("a\rb\r\nc\n")
|
66
|
-
editor.save
|
67
|
-
read.should == "a\rb\rc\r"
|
68
|
-
end
|
69
|
-
|
70
|
-
it "converts newline-free to \n" do
|
71
|
-
write("a")
|
72
|
-
editor.insert("\n")
|
73
|
-
editor.save
|
74
|
-
read.should == "\na"
|
75
|
-
end
|
76
|
-
|
77
|
-
it "is not modified after saving strange newline format" do
|
78
|
-
write("a\r\nb\r\nc\r\n")
|
79
|
-
editor.save
|
80
|
-
editor.modified?.should == false
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
describe 'blank line before end of file on save' do
|
85
|
-
it "adds a newline" do
|
86
|
-
write("aaa")
|
87
|
-
editor = Ruco::Editor.new(@file, :lines => 3, :columns => 5, :blank_line_before_eof_on_save => true)
|
88
|
-
editor.save
|
89
|
-
read.should == "aaa\n"
|
90
|
-
end
|
91
|
-
|
92
|
-
it "does not add a newline without option" do
|
93
|
-
write("aaa")
|
94
|
-
editor = Ruco::Editor.new(@file, :lines => 3, :columns => 5)
|
95
|
-
editor.save
|
96
|
-
read.should == "aaa"
|
97
|
-
end
|
98
|
-
|
99
|
-
it "adds weird newline" do
|
100
|
-
write("aaa\r\nbbb")
|
101
|
-
editor = Ruco::Editor.new(@file, :lines => 3, :columns => 5, :blank_line_before_eof_on_save => true)
|
102
|
-
editor.save
|
103
|
-
read.should == "aaa\r\nbbb\r\n"
|
104
|
-
end
|
105
|
-
|
106
|
-
it "does not add a newline for empty lines" do
|
107
|
-
write("aaa\n ")
|
108
|
-
editor = Ruco::Editor.new(@file, :lines => 3, :columns => 5, :blank_line_before_eof_on_save => true)
|
109
|
-
editor.save
|
110
|
-
read.should == "aaa\n "
|
111
|
-
end
|
112
|
-
|
113
|
-
it "does not add a newline when one is there" do
|
114
|
-
write("aaa\n")
|
115
|
-
editor = Ruco::Editor.new(@file, :lines => 3, :columns => 5, :blank_line_before_eof_on_save => true)
|
116
|
-
editor.save
|
117
|
-
read.should == "aaa\n"
|
118
|
-
end
|
119
|
-
|
120
|
-
it "does not add a weird newline when one is there" do
|
121
|
-
write("aaa\r\n")
|
122
|
-
editor = Ruco::Editor.new(@file, :lines => 3, :columns => 5, :blank_line_before_eof_on_save => true)
|
123
|
-
editor.save
|
124
|
-
read.should == "aaa\r\n"
|
125
|
-
end
|
126
|
-
|
127
|
-
it "does not add a newline when many are there" do
|
128
|
-
write("aaa\n\n")
|
129
|
-
editor = Ruco::Editor.new(@file, :lines => 3, :columns => 5, :blank_line_before_eof_on_save => true)
|
130
|
-
editor.save
|
131
|
-
read.should == "aaa\n\n"
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
describe 'convert tabs' do
|
136
|
-
before do
|
137
|
-
write("\t\ta")
|
138
|
-
end
|
139
|
-
|
140
|
-
it "reads tab as spaces when option is set" do
|
141
|
-
editor = Ruco::Editor.new(@file, :lines => 3, :columns => 5, :convert_tabs => true)
|
142
|
-
editor.view.should == " a\n\n"
|
143
|
-
end
|
144
|
-
|
145
|
-
it "reads them normally when option is not set" do
|
146
|
-
editor = Ruco::Editor.new(@file, :lines => 3, :columns => 5)
|
147
|
-
editor.view.should == "\t\ta\n\n"
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
describe 'huge-files' do
|
152
|
-
it "does not try to open huge files" do
|
153
|
-
write('a'*(1024*1024 + 1))
|
154
|
-
lambda{
|
155
|
-
Ruco::Editor.new(@file, :lines => 3, :columns => 5)
|
156
|
-
}.should raise_error
|
157
|
-
end
|
158
|
-
|
159
|
-
it "opens large files and does not take forever" do
|
160
|
-
write('a'*(1024*1024))
|
161
|
-
Time.benchmark do
|
162
|
-
editor = Ruco::Editor.new(@file, :lines => 3, :columns => 5)
|
163
|
-
editor.view
|
164
|
-
end.should < 1
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
describe :move do
|
169
|
-
before do
|
170
|
-
write(" \n \n ")
|
171
|
-
end
|
172
|
-
|
173
|
-
it "starts at 0,0" do
|
174
|
-
editor.cursor.should == [0,0]
|
175
|
-
end
|
176
|
-
|
177
|
-
it "can move" do
|
178
|
-
editor.move(:relative, 1,2)
|
179
|
-
editor.cursor.should == [1,2]
|
180
|
-
editor.move(:relative, 1,1)
|
181
|
-
editor.cursor.should == [2,3]
|
182
|
-
end
|
183
|
-
|
184
|
-
it "can move in empty file" do
|
185
|
-
write("\n\n\n")
|
186
|
-
editor.move(:relative, 2,0)
|
187
|
-
editor.cursor.should == [2,0]
|
188
|
-
end
|
189
|
-
|
190
|
-
it "cannot move left/top off screen" do
|
191
|
-
editor.move(:relative, -1,-1)
|
192
|
-
editor.cursor.should == [0,0]
|
193
|
-
end
|
194
|
-
|
195
|
-
it "does not move lines when jumping right" do
|
196
|
-
editor.move(:relative, 1, 5)
|
197
|
-
editor.cursor.should == [1,4]
|
198
|
-
end
|
199
|
-
|
200
|
-
it "does not move lines when jumping left" do
|
201
|
-
editor.move(:to, 2, 2)
|
202
|
-
editor.move(:relative, -1, -5)
|
203
|
-
editor.cursor.should == [1,0]
|
204
|
-
end
|
205
|
-
|
206
|
-
it "moves to next line when moving right of characters" do
|
207
|
-
editor.move(:relative, 0, 5)
|
208
|
-
editor.cursor.should == [1,0]
|
209
|
-
end
|
210
|
-
|
211
|
-
it "moves to prev line when moving left of characters" do
|
212
|
-
editor.move(:relative, 1, 0)
|
213
|
-
editor.move(:relative, 0, -1)
|
214
|
-
editor.cursor.should == [0,4]
|
215
|
-
end
|
216
|
-
|
217
|
-
it "stays at origin when moving left" do
|
218
|
-
editor.move(:relative, 0, -1)
|
219
|
-
editor.cursor.should == [0,0]
|
220
|
-
end
|
221
|
-
|
222
|
-
it "stays at eof when moving right" do
|
223
|
-
editor.move(:to, 2, 4)
|
224
|
-
editor.move(:relative, 0, 1)
|
225
|
-
editor.cursor.should == [2,4]
|
226
|
-
end
|
227
|
-
|
228
|
-
it "stays in last line when moving past lines" do
|
229
|
-
write(" ")
|
230
|
-
editor.move(:relative, 6,3)
|
231
|
-
editor.cursor.should == [0,3]
|
232
|
-
end
|
233
|
-
|
234
|
-
describe 'column scrolling' do
|
235
|
-
it "can scroll columns" do
|
236
|
-
write("123456789\n123")
|
237
|
-
editor.move(:relative, 0,4)
|
238
|
-
editor.view.should == "12345\n123\n"
|
239
|
-
editor.cursor.column.should == 4
|
240
|
-
|
241
|
-
editor.move(:relative, 0,1)
|
242
|
-
editor.view.should == "34567\n3\n"
|
243
|
-
editor.cursor.column.should == 3
|
244
|
-
end
|
245
|
-
|
246
|
-
it "cannot scroll past the screen" do
|
247
|
-
write('123456789')
|
248
|
-
editor.move(:relative, 0,4)
|
249
|
-
6.times{ editor.move(:relative, 0,1) }
|
250
|
-
editor.view.should == "789\n\n"
|
251
|
-
editor.cursor.column.should == 3
|
252
|
-
end
|
253
|
-
|
254
|
-
it "can scroll columns backwards" do
|
255
|
-
write('0123456789')
|
256
|
-
editor.move(:relative, 0,5)
|
257
|
-
editor.view.should == "23456\n\n"
|
258
|
-
|
259
|
-
editor.move(:relative, 0,-4)
|
260
|
-
editor.view.should == "01234\n\n"
|
261
|
-
editor.cursor.column.should == 1
|
262
|
-
end
|
263
|
-
end
|
264
|
-
|
265
|
-
describe 'line scrolling' do
|
266
|
-
before do
|
267
|
-
write("1\n2\n3\n4\n5\n6\n7\n8\n9")
|
268
|
-
end
|
269
|
-
|
270
|
-
it "can scroll lines down" do
|
271
|
-
editor.move(:relative, 2,0)
|
272
|
-
editor.view.should == "1\n2\n3"
|
273
|
-
|
274
|
-
editor.move(:relative, 1,0)
|
275
|
-
editor.view.should == "3\n4\n5"
|
276
|
-
editor.cursor.line.should == 1
|
277
|
-
end
|
278
|
-
|
279
|
-
it "can scroll till end of file" do
|
280
|
-
editor.move(:relative, 15,0)
|
281
|
-
editor.view.should == "8\n9\n"
|
282
|
-
editor.cursor.line.should == 1
|
283
|
-
end
|
284
|
-
end
|
285
|
-
|
286
|
-
describe :to do
|
287
|
-
it "cannot move outside of text (bottom/right)" do
|
288
|
-
write("123\n456")
|
289
|
-
editor.move(:to, 10,10)
|
290
|
-
editor.cursor.should == [1,3]
|
291
|
-
end
|
292
|
-
|
293
|
-
it "cannot move outside of text (top/left)" do
|
294
|
-
write("123\n456")
|
295
|
-
editor.move(:relative, 1,1)
|
296
|
-
editor.move(:to, -10,-10)
|
297
|
-
editor.cursor.should == [0,0]
|
298
|
-
end
|
299
|
-
end
|
300
|
-
|
301
|
-
describe :to_eol do
|
302
|
-
before do
|
303
|
-
write("\n aa \n ")
|
304
|
-
end
|
305
|
-
|
306
|
-
it 'stays at start when line is empty' do
|
307
|
-
editor.move :to_eol
|
308
|
-
editor.cursor.should == [0,0]
|
309
|
-
end
|
310
|
-
|
311
|
-
it 'moves after last word if cursor was before it' do
|
312
|
-
editor.move(:relative, 1,1)
|
313
|
-
editor.move :to_eol
|
314
|
-
editor.cursor.should == [1,3]
|
315
|
-
end
|
316
|
-
|
317
|
-
it 'moves after last whitespace if cursor was after last word' do
|
318
|
-
editor.move(:relative, 1,3)
|
319
|
-
editor.move :to_eol
|
320
|
-
editor.cursor.should == [1,4]
|
321
|
-
end
|
322
|
-
|
323
|
-
it 'moves after last work if cursor was after last whitespace' do
|
324
|
-
editor.move(:relative, 1,4)
|
325
|
-
editor.move :to_eol
|
326
|
-
editor.cursor.should == [1,3]
|
327
|
-
end
|
328
|
-
end
|
329
|
-
|
330
|
-
describe :to_bol do
|
331
|
-
before do
|
332
|
-
write("\n aa \n ")
|
333
|
-
end
|
334
|
-
|
335
|
-
it 'stays at start when line is empty' do
|
336
|
-
editor.move :to_bol
|
337
|
-
editor.cursor.should == [0,0]
|
338
|
-
end
|
339
|
-
|
340
|
-
it 'moves before first work if at start of line' do
|
341
|
-
editor.move(:relative, 1,0)
|
342
|
-
editor.move :to_bol
|
343
|
-
editor.cursor.should == [1,2]
|
344
|
-
end
|
345
|
-
|
346
|
-
it 'moves to start of line if before first word' do
|
347
|
-
editor.move(:relative, 1,1)
|
348
|
-
editor.move :to_bol
|
349
|
-
editor.cursor.should == [1,0]
|
350
|
-
|
351
|
-
editor.move(:relative, 0,2)
|
352
|
-
editor.move :to_bol
|
353
|
-
editor.cursor.should == [1,0]
|
354
|
-
end
|
355
|
-
|
356
|
-
it 'moves before first word if inside line' do
|
357
|
-
editor.move(:relative, 1,5)
|
358
|
-
editor.move :to_bol
|
359
|
-
editor.cursor.should == [1,2]
|
360
|
-
end
|
361
|
-
end
|
362
|
-
|
363
|
-
describe 'jumping' do
|
364
|
-
it "can jump right" do
|
365
|
-
write("abc def")
|
366
|
-
editor.move(:jump, :right)
|
367
|
-
editor.cursor.should == [0,3]
|
368
|
-
end
|
369
|
-
|
370
|
-
it "does not jump over braces" do
|
371
|
-
write("abc(def")
|
372
|
-
editor.move(:jump, :right)
|
373
|
-
editor.cursor.should == [0,3]
|
374
|
-
end
|
375
|
-
|
376
|
-
it "can jump over whitespace and newlines" do
|
377
|
-
write("abc\n 123")
|
378
|
-
editor.move(:jump, :right)
|
379
|
-
editor.cursor.should == [0,3]
|
380
|
-
editor.move(:jump, :right)
|
381
|
-
editor.cursor.should == [1,1]
|
382
|
-
end
|
383
|
-
|
384
|
-
it "can jump left" do
|
385
|
-
write("abc def")
|
386
|
-
editor.move(:relative, 0,3)
|
387
|
-
editor.move(:jump, :left)
|
388
|
-
editor.cursor.should == [0,0]
|
389
|
-
end
|
390
|
-
|
391
|
-
it "can jump to start" do
|
392
|
-
write("abc\ndef")
|
393
|
-
editor.move(:relative, 0,2)
|
394
|
-
editor.move(:jump, :left)
|
395
|
-
editor.cursor.should == [0,0]
|
396
|
-
end
|
397
|
-
|
398
|
-
it "stays at start" do
|
399
|
-
write("abc\ndef")
|
400
|
-
editor.move(:jump, :left)
|
401
|
-
editor.cursor.should == [0,0]
|
402
|
-
end
|
403
|
-
|
404
|
-
it "can jump to end" do
|
405
|
-
write("abc\ndef")
|
406
|
-
editor.move(:relative, 1,1)
|
407
|
-
editor.move(:jump, :right)
|
408
|
-
editor.cursor.should == [1,3]
|
409
|
-
end
|
410
|
-
|
411
|
-
it "stays at end" do
|
412
|
-
write("abc\ndef")
|
413
|
-
editor.move(:to, 1,3)
|
414
|
-
editor.move(:jump, :right)
|
415
|
-
editor.cursor.should == [1,3]
|
416
|
-
end
|
417
|
-
end
|
418
|
-
end
|
419
|
-
|
420
|
-
describe :move_line do
|
421
|
-
before do
|
422
|
-
write("0\n1\n2\n")
|
423
|
-
end
|
424
|
-
|
425
|
-
it "moves the line" do
|
426
|
-
editor.move_line(1)
|
427
|
-
editor.view.should == "1\n0\n2"
|
428
|
-
end
|
429
|
-
|
430
|
-
it "keeps the cursor at the moved line" do
|
431
|
-
editor.move_line(1)
|
432
|
-
editor.cursor.should == [1,0]
|
433
|
-
end
|
434
|
-
|
435
|
-
it "keeps the cursor at current column" do
|
436
|
-
editor.move(:to, 0,1)
|
437
|
-
editor.move_line(1)
|
438
|
-
editor.cursor.should == [1,1]
|
439
|
-
end
|
440
|
-
|
441
|
-
it "uses indentation of moved-to-line" do
|
442
|
-
write(" 0\n 1\n 2\n")
|
443
|
-
editor.move_line(1)
|
444
|
-
editor.view.should == " 1\n 0\n 2"
|
445
|
-
end
|
446
|
-
|
447
|
-
it "cannot move past start of file" do
|
448
|
-
editor.move_line(-1)
|
449
|
-
editor.view.should == "0\n1\n2"
|
450
|
-
end
|
451
|
-
|
452
|
-
it "cannot move past end of file" do
|
453
|
-
write("0\n1\n")
|
454
|
-
editor.move_line(1)
|
455
|
-
editor.move_line(1)
|
456
|
-
editor.move_line(1)
|
457
|
-
editor.move_line(1)
|
458
|
-
editor.view.should == "1\n\n0"
|
459
|
-
end
|
460
|
-
end
|
461
|
-
|
462
|
-
describe :selecting do
|
463
|
-
before do
|
464
|
-
write('012345678')
|
465
|
-
end
|
466
|
-
|
467
|
-
it "remembers the selection" do
|
468
|
-
editor.selecting do
|
469
|
-
move(:to, 0, 4)
|
470
|
-
end
|
471
|
-
editor.selection.should == ([0,0]..[0,4])
|
472
|
-
end
|
473
|
-
|
474
|
-
it "expands the selection" do
|
475
|
-
editor.selecting do
|
476
|
-
move(:to, 0, 4)
|
477
|
-
move(:to, 0, 6)
|
478
|
-
end
|
479
|
-
editor.selection.should == ([0,0]..[0,6])
|
480
|
-
end
|
481
|
-
|
482
|
-
it "expand an old selection" do
|
483
|
-
editor.selecting do
|
484
|
-
move(:to, 0, 4)
|
485
|
-
end
|
486
|
-
editor.selecting do
|
487
|
-
move(:relative, 0, 2)
|
488
|
-
end
|
489
|
-
editor.selection.should == ([0,0]..[0,6])
|
490
|
-
end
|
491
|
-
|
492
|
-
it "can select backwards" do
|
493
|
-
editor.move(:to, 0, 4)
|
494
|
-
editor.selecting do
|
495
|
-
move(:relative, 0, -2)
|
496
|
-
end
|
497
|
-
editor.selecting do
|
498
|
-
move(:relative, 0, -2)
|
499
|
-
end
|
500
|
-
editor.selection.should == ([0,0]..[0,4])
|
501
|
-
end
|
502
|
-
|
503
|
-
it "can select multiple lines" do
|
504
|
-
write("012\n345\n678")
|
505
|
-
editor.move(:to, 0, 2)
|
506
|
-
editor.selecting do
|
507
|
-
move(:relative, 1, 0)
|
508
|
-
end
|
509
|
-
editor.selecting do
|
510
|
-
move(:relative, 1, 0)
|
511
|
-
end
|
512
|
-
editor.selection.should == ([0,2]..[2,2])
|
513
|
-
end
|
514
|
-
|
515
|
-
it "clears the selection once I move" do
|
516
|
-
editor.selecting do
|
517
|
-
move(:to, 0, 4)
|
518
|
-
end
|
519
|
-
editor.move(:relative, 0, 2)
|
520
|
-
editor.selection.should == nil
|
521
|
-
end
|
522
|
-
|
523
|
-
it "replaces the selection with insert" do
|
524
|
-
editor.selecting do
|
525
|
-
move(:to, 0, 4)
|
526
|
-
end
|
527
|
-
editor.insert('X')
|
528
|
-
editor.selection.should == nil
|
529
|
-
editor.cursor.should == [0,1]
|
530
|
-
editor.move(:to, 0,0)
|
531
|
-
editor.view.should == "X4567\n\n"
|
532
|
-
end
|
533
|
-
|
534
|
-
it "replaces the multi-line-selection with insert" do
|
535
|
-
write("123\n456\n789")
|
536
|
-
editor.move(:to, 0,1)
|
537
|
-
editor.selecting do
|
538
|
-
move(:to, 1,2)
|
539
|
-
end
|
540
|
-
editor.insert('X')
|
541
|
-
editor.selection.should == nil
|
542
|
-
editor.cursor.should == [0,2]
|
543
|
-
editor.move(:to, 0,0)
|
544
|
-
editor.view.should == "1X6\n789\n"
|
545
|
-
end
|
546
|
-
|
547
|
-
it "deletes selection delete" do
|
548
|
-
write("123\n456\n789")
|
549
|
-
editor.move(:to, 0,1)
|
550
|
-
editor.selecting do
|
551
|
-
move(:to, 1,2)
|
552
|
-
end
|
553
|
-
editor.delete(1)
|
554
|
-
editor.cursor.should == [0,1]
|
555
|
-
editor.move(:to, 0,0)
|
556
|
-
editor.view.should == "16\n789\n"
|
557
|
-
end
|
558
|
-
end
|
559
|
-
|
560
|
-
describe :text_in_selection do
|
561
|
-
before do
|
562
|
-
write("123\n456\n789")
|
563
|
-
end
|
564
|
-
|
565
|
-
it "returns '' if nothing is selected" do
|
566
|
-
editor.selecting do
|
567
|
-
move(:to, 1,1)
|
568
|
-
end
|
569
|
-
editor.text_in_selection.should == "123\n4"
|
570
|
-
end
|
571
|
-
|
572
|
-
it "returns selected text" do
|
573
|
-
editor.text_in_selection.should == ''
|
574
|
-
end
|
575
|
-
end
|
576
|
-
|
577
|
-
describe :style_map do
|
578
|
-
it "is empty by default" do
|
579
|
-
editor.style_map.flatten.should == [nil,nil,nil]
|
580
|
-
end
|
581
|
-
|
582
|
-
it "shows one-line selection" do
|
583
|
-
write('abcdefghi')
|
584
|
-
editor.selecting do
|
585
|
-
move(:to, 0, 4)
|
586
|
-
end
|
587
|
-
editor.style_map.flatten.should == [
|
588
|
-
[:reverse, nil, nil, nil, :normal],
|
589
|
-
nil,
|
590
|
-
nil
|
591
|
-
]
|
592
|
-
end
|
593
|
-
|
594
|
-
it "shows multi-line selection" do
|
595
|
-
write("abc\nabc\nabc")
|
596
|
-
editor.move(:to, 0,1)
|
597
|
-
editor.selecting do
|
598
|
-
move(:to, 1, 1)
|
599
|
-
end
|
600
|
-
editor.style_map.flatten.should == [
|
601
|
-
[nil, :reverse, nil, nil, nil, :normal],
|
602
|
-
[:reverse, :normal],
|
603
|
-
nil
|
604
|
-
]
|
605
|
-
end
|
606
|
-
|
607
|
-
it "shows the selection from offset" do
|
608
|
-
write('abcdefghi')
|
609
|
-
editor.move(:to, 0, 2)
|
610
|
-
editor.selecting do
|
611
|
-
move(:to, 0, 4)
|
612
|
-
end
|
613
|
-
editor.style_map.flatten.should == [
|
614
|
-
[nil, nil, :reverse, nil, :normal],
|
615
|
-
nil,
|
616
|
-
nil
|
617
|
-
]
|
618
|
-
end
|
619
|
-
|
620
|
-
it "shows the selection in nth line" do
|
621
|
-
write("\nabcdefghi")
|
622
|
-
editor.move(:to, 1, 2)
|
623
|
-
editor.selecting do
|
624
|
-
move(:to, 1, 4)
|
625
|
-
end
|
626
|
-
editor.style_map.flatten.should == [
|
627
|
-
nil,
|
628
|
-
[nil, nil, :reverse, nil, :normal],
|
629
|
-
nil
|
630
|
-
]
|
631
|
-
end
|
632
|
-
|
633
|
-
it "shows multi-line selection in scrolled space" do
|
634
|
-
write("\n\n\n\n\nacdefghijk\nacdefghijk\nacdefghijk\n\n")
|
635
|
-
ta = editor.send(:text_area)
|
636
|
-
ta.send(:position=, [5,8])
|
637
|
-
ta.send(:screen_position=, [5,7])
|
638
|
-
editor.selecting do
|
639
|
-
move(:relative, 2, 1)
|
640
|
-
end
|
641
|
-
editor.view.should == "ijk\nijk\nijk"
|
642
|
-
editor.cursor.should == [2,2]
|
643
|
-
editor.style_map.flatten.should == [
|
644
|
-
[nil, :reverse, nil, nil, nil, :normal], # start to end of screen
|
645
|
-
[:reverse, nil, nil, nil, nil, :normal], # 0 to end of screen
|
646
|
-
[:reverse, nil, :normal] # 0 to end of selection
|
647
|
-
]
|
648
|
-
end
|
649
|
-
|
650
|
-
it "shows keywords" do
|
651
|
-
write("class")
|
652
|
-
editor.style_map.flatten.should == [
|
653
|
-
[color(:keyword), nil, nil, nil, nil, :normal],
|
654
|
-
nil,
|
655
|
-
nil
|
656
|
-
]
|
657
|
-
end
|
658
|
-
|
659
|
-
it "shows keywords for moved window" do
|
660
|
-
write("\n\n\n\n\n if ")
|
661
|
-
editor.move(:to, 5, 6)
|
662
|
-
editor.cursor.should == [1,3]
|
663
|
-
editor.view.should == "\n if \n"
|
664
|
-
editor.style_map.flatten.should == [
|
665
|
-
nil,
|
666
|
-
[nil, nil, color(:keyword), nil, :normal],
|
667
|
-
nil
|
668
|
-
]
|
669
|
-
end
|
670
|
-
|
671
|
-
it "shows mid-keywords for moved window" do
|
672
|
-
write("\n\n\n\n\nclass ")
|
673
|
-
editor.move(:to, 5, 6)
|
674
|
-
editor.cursor.should == [1,3]
|
675
|
-
editor.view.should == "\nss \n"
|
676
|
-
editor.style_map.flatten.should == [
|
677
|
-
nil,
|
678
|
-
[color(:keyword), nil, :normal],
|
679
|
-
nil
|
680
|
-
]
|
681
|
-
end
|
682
|
-
|
683
|
-
it "shows multiple syntax elements" do
|
684
|
-
write("if @x")
|
685
|
-
editor.style_map.flatten.should == [
|
686
|
-
[color(:keyword), nil, :normal, color(:instance_variable), nil, :normal],
|
687
|
-
nil,
|
688
|
-
nil
|
689
|
-
]
|
690
|
-
end
|
691
|
-
|
692
|
-
it "does not show keywords inside strings" do
|
693
|
-
write("'Foo'")
|
694
|
-
editor.style_map.flatten.should == [
|
695
|
-
[color(:string), nil, nil, nil, nil, :normal],
|
696
|
-
nil,
|
697
|
-
nil
|
698
|
-
]
|
699
|
-
end
|
700
|
-
|
701
|
-
xit "shows multiline comments" do
|
702
|
-
write("=begin\na\nb\n=end")
|
703
|
-
editor.move(:to, 3,0)
|
704
|
-
editor.view.should == "b\n=end\n"
|
705
|
-
editor.style_map.flatten.should == [
|
706
|
-
[["#8E908C", nil], nil, :normal],
|
707
|
-
[["#8E908C", nil], nil, nil, nil, :normal],
|
708
|
-
nil
|
709
|
-
]
|
710
|
-
end
|
711
|
-
|
712
|
-
it "shows selection on top" do
|
713
|
-
write("class")
|
714
|
-
editor.selecting do
|
715
|
-
move(:relative, 0, 3)
|
716
|
-
end
|
717
|
-
editor.style_map.flatten.should == [
|
718
|
-
[:reverse, nil, nil, ["#8959A8", nil], nil, :normal],
|
719
|
-
nil,
|
720
|
-
nil
|
721
|
-
]
|
722
|
-
end
|
723
|
-
|
724
|
-
it "times out when styling takes too long" do
|
725
|
-
STDERR.should_receive(:puts)
|
726
|
-
Timeout.should_receive(:timeout).and_raise Timeout::Error
|
727
|
-
write(File.read('lib/ruco.rb'))
|
728
|
-
editor.style_map.flatten.should == [nil,nil,nil]
|
729
|
-
end
|
730
|
-
|
731
|
-
describe 'with theme' do
|
732
|
-
before do
|
733
|
-
write("class")
|
734
|
-
`rm -rf ~/.ruco/themes`
|
735
|
-
end
|
736
|
-
|
737
|
-
it "can download a theme" do
|
738
|
-
editor = Ruco::Editor.new(@file,
|
739
|
-
:lines => 3, :columns => 5, :language => language,
|
740
|
-
:color_theme => 'https://raw.github.com/ChrisKempson/TextMate-Tomorrow-Theme/master/Tomorrow-Night-Bright.tmTheme'
|
741
|
-
)
|
742
|
-
editor.style_map.flatten.should == [
|
743
|
-
[["#C397D8", nil], nil, nil, nil, nil, :normal],
|
744
|
-
nil,
|
745
|
-
nil
|
746
|
-
]
|
747
|
-
end
|
748
|
-
|
749
|
-
it "does not fail with invalid theme url" do
|
750
|
-
STDERR.should_receive(:puts)
|
751
|
-
editor = Ruco::Editor.new(@file,
|
752
|
-
:lines => 3, :columns => 5, :language => language,
|
753
|
-
:color_theme => 'foooooo'
|
754
|
-
)
|
755
|
-
editor.style_map.flatten.should == [
|
756
|
-
[["#8959A8", nil], nil, nil, nil, nil, :normal],
|
757
|
-
nil,
|
758
|
-
nil
|
759
|
-
]
|
760
|
-
end
|
761
|
-
end
|
762
|
-
end
|
763
|
-
|
764
|
-
describe :view do
|
765
|
-
before do
|
766
|
-
write('')
|
767
|
-
end
|
768
|
-
|
769
|
-
it "displays an empty screen" do
|
770
|
-
editor.view.should == "\n\n"
|
771
|
-
end
|
772
|
-
|
773
|
-
it "displays short file content" do
|
774
|
-
write('xxx')
|
775
|
-
editor.view.should == "xxx\n\n"
|
776
|
-
end
|
777
|
-
|
778
|
-
it "displays long file content" do
|
779
|
-
write('1234567')
|
780
|
-
editor.view.should == "12345\n\n"
|
781
|
-
end
|
782
|
-
|
783
|
-
it "displays multiline-file content" do
|
784
|
-
write("xxx\nyyy\nzzz\niii")
|
785
|
-
editor.view.should == "xxx\nyyy\nzzz"
|
786
|
-
end
|
787
|
-
end
|
788
|
-
|
789
|
-
describe :insert do
|
790
|
-
before do
|
791
|
-
write('')
|
792
|
-
end
|
793
|
-
|
794
|
-
it "can insert new chars" do
|
795
|
-
write('123')
|
796
|
-
editor.move(:relative, 0,1)
|
797
|
-
editor.insert('ab')
|
798
|
-
editor.view.should == "1ab23\n\n"
|
799
|
-
editor.cursor.should == [0,3]
|
800
|
-
end
|
801
|
-
|
802
|
-
it "can insert new newlines" do
|
803
|
-
editor.insert("ab\nc")
|
804
|
-
editor.view.should == "ab\nc\n"
|
805
|
-
editor.cursor.should == [1,1]
|
806
|
-
end
|
807
|
-
|
808
|
-
it "jumps to correct column when inserting newline" do
|
809
|
-
write("abc\ndefg")
|
810
|
-
editor.move(:relative, 1,2)
|
811
|
-
editor.insert("1\n23")
|
812
|
-
editor.view.should == "abc\nde1\n23fg"
|
813
|
-
editor.cursor.should == [2,2]
|
814
|
-
end
|
815
|
-
|
816
|
-
it "jumps to correct column when inserting 1 newline" do
|
817
|
-
write("abc\ndefg")
|
818
|
-
editor.move(:relative, 1,2)
|
819
|
-
editor.insert("\n")
|
820
|
-
editor.view.should == "abc\nde\nfg"
|
821
|
-
editor.cursor.should == [2,0]
|
822
|
-
end
|
823
|
-
|
824
|
-
it "can add newlines to the end" do
|
825
|
-
write('')
|
826
|
-
editor.insert("\n")
|
827
|
-
editor.insert("\n")
|
828
|
-
editor.cursor.should == [2,0]
|
829
|
-
end
|
830
|
-
|
831
|
-
it "can add newlines to the moveable end" do
|
832
|
-
write('abc')
|
833
|
-
editor.move(:relative, 0,3)
|
834
|
-
editor.insert("\n")
|
835
|
-
editor.insert("\n")
|
836
|
-
editor.cursor.should == [2,0]
|
837
|
-
end
|
838
|
-
|
839
|
-
it "inserts tab as spaces" do
|
840
|
-
editor.insert("\t")
|
841
|
-
editor.view.should == " \n\n"
|
842
|
-
editor.cursor.should == [0,2]
|
843
|
-
end
|
844
|
-
|
845
|
-
it "keeps indentation" do
|
846
|
-
write("ab\n cd")
|
847
|
-
editor.move(:to, 1,2)
|
848
|
-
editor.insert("\n")
|
849
|
-
end
|
850
|
-
end
|
851
|
-
|
852
|
-
describe :indent do
|
853
|
-
it "indents selected lines" do
|
854
|
-
write("a\nb\nc\n")
|
855
|
-
editor.selecting{move(:to, 1,1)}
|
856
|
-
editor.indent
|
857
|
-
editor.view.should == " a\n b\nc"
|
858
|
-
end
|
859
|
-
|
860
|
-
it "moves the selection" do
|
861
|
-
write("a\nb\nc\n")
|
862
|
-
editor.selecting{move(:to, 1,1)}
|
863
|
-
editor.indent
|
864
|
-
editor.selection.should == ([0,2]..[1,3])
|
865
|
-
end
|
866
|
-
|
867
|
-
it "moves the cursor" do
|
868
|
-
write("a\nb\nc\n")
|
869
|
-
editor.selecting{move(:to, 1,1)}
|
870
|
-
editor.indent
|
871
|
-
editor.cursor.should == [1,3]
|
872
|
-
end
|
873
|
-
|
874
|
-
it "moves the cursor when selecting backward" do
|
875
|
-
write("a\nb\nc\n")
|
876
|
-
editor.move(:to, 1,1)
|
877
|
-
editor.selecting{move(:to, 0,1)}
|
878
|
-
editor.indent
|
879
|
-
editor.cursor.should == [0,3]
|
880
|
-
end
|
881
|
-
|
882
|
-
it "marks as modified" do
|
883
|
-
editor.selecting{move(:to, 0,1)}
|
884
|
-
editor.indent
|
885
|
-
editor.modified?.should == true
|
886
|
-
end
|
887
|
-
end
|
888
|
-
|
889
|
-
describe :unindent do
|
890
|
-
it "unindents single lines" do
|
891
|
-
write(" a\n\n")
|
892
|
-
editor.unindent
|
893
|
-
editor.view.should == " a\n\n"
|
894
|
-
end
|
895
|
-
|
896
|
-
it "unindents single lines by one" do
|
897
|
-
write(" a\n\n")
|
898
|
-
editor.unindent
|
899
|
-
editor.view.should == "a\n\n"
|
900
|
-
end
|
901
|
-
|
902
|
-
it "does not unindents single lines when not unindentable" do
|
903
|
-
write("a\n\n")
|
904
|
-
editor.unindent
|
905
|
-
editor.view.should == "a\n\n"
|
906
|
-
end
|
907
|
-
|
908
|
-
it "move the cursor when unindenting single line" do
|
909
|
-
write(" a\n\n")
|
910
|
-
editor.move(:to, 0,1)
|
911
|
-
editor.unindent
|
912
|
-
editor.cursor.should == [0,0]
|
913
|
-
end
|
914
|
-
|
915
|
-
it "unindents selected lines" do
|
916
|
-
write("a\n b\n c")
|
917
|
-
editor.selecting{ move(:to, 2,1) }
|
918
|
-
editor.unindent
|
919
|
-
editor.view.should == "a\nb\n c"
|
920
|
-
end
|
921
|
-
|
922
|
-
it "moves the selection" do
|
923
|
-
write(" abcd\n b\n c")
|
924
|
-
editor.move(:to, 0,3)
|
925
|
-
editor.selecting{ move(:to, 2,1) }
|
926
|
-
editor.unindent
|
927
|
-
editor.selection.should == ([0,1]..[2,0])
|
928
|
-
end
|
929
|
-
|
930
|
-
it "moves the selection when unindenting one space" do
|
931
|
-
write(" abcd\n b\n c")
|
932
|
-
editor.move(:to, 0,3)
|
933
|
-
editor.selecting{ move(:to, 2,1) }
|
934
|
-
editor.unindent
|
935
|
-
editor.selection.should == ([0,2]..[2,0])
|
936
|
-
end
|
937
|
-
|
938
|
-
it "does not move the selection when unindent is not possible" do
|
939
|
-
write("abcd\n b\n c")
|
940
|
-
editor.move(:to, 0,3)
|
941
|
-
editor.selecting{ move(:to, 2,1) }
|
942
|
-
editor.unindent
|
943
|
-
editor.selection.should == ([0,3]..[2,0])
|
944
|
-
end
|
945
|
-
|
946
|
-
it "moves the cursor when selecting forward" do
|
947
|
-
write("\n abcd\n")
|
948
|
-
editor.selecting{ move(:to, 1,3) }
|
949
|
-
editor.unindent
|
950
|
-
editor.cursor.should == [1,2]
|
951
|
-
end
|
952
|
-
|
953
|
-
it "moves the cursor when selecting backward" do
|
954
|
-
write(" x\n abcd\n")
|
955
|
-
editor.move(:to, 1,3)
|
956
|
-
editor.selecting{ move(:to, 0,1) }
|
957
|
-
editor.unindent
|
958
|
-
editor.cursor.should == [0,0]
|
959
|
-
end
|
960
|
-
end
|
961
|
-
|
962
|
-
describe 'history' do
|
963
|
-
it "does not overwrite the initial state" do
|
964
|
-
write("a")
|
965
|
-
editor.insert("b")
|
966
|
-
editor.view # trigger save point
|
967
|
-
stack = editor.history.stack
|
968
|
-
stack.length.should == 2
|
969
|
-
stack[0][:state][:content].should == "a"
|
970
|
-
stack[1][:state][:content].should == "ba"
|
971
|
-
|
972
|
-
editor.undo
|
973
|
-
editor.history.position.should == 0
|
974
|
-
|
975
|
-
editor.insert("c")
|
976
|
-
editor.view # trigger save point
|
977
|
-
stack.length.should == 2
|
978
|
-
stack[0][:state][:content].should == "a"
|
979
|
-
stack[1][:state][:content].should == "ca"
|
980
|
-
end
|
981
|
-
|
982
|
-
it "can undo an action" do
|
983
|
-
write("a")
|
984
|
-
editor.insert("b")
|
985
|
-
editor.view # trigger save point
|
986
|
-
future = Time.now + 10
|
987
|
-
Time.stub!(:now).and_return future
|
988
|
-
editor.insert("c")
|
989
|
-
editor.view # trigger save point
|
990
|
-
editor.undo
|
991
|
-
editor.view.should == "ba\n\n"
|
992
|
-
editor.cursor.should == [0,1]
|
993
|
-
end
|
994
|
-
|
995
|
-
it "removes selection on undo" do
|
996
|
-
editor.insert('a')
|
997
|
-
editor.view # trigger save point
|
998
|
-
editor.selecting{move(:to, 1,1)}
|
999
|
-
editor.selection.should_not == nil
|
1000
|
-
editor.view # trigger save point
|
1001
|
-
editor.undo
|
1002
|
-
editor.selection.should == nil
|
1003
|
-
end
|
1004
|
-
|
1005
|
-
it "sets modified on undo" do
|
1006
|
-
editor.insert('a')
|
1007
|
-
editor.save
|
1008
|
-
editor.modified?.should == false
|
1009
|
-
editor.undo
|
1010
|
-
editor.modified?.should == true
|
1011
|
-
end
|
1012
|
-
end
|
1013
|
-
|
1014
|
-
describe :save do
|
1015
|
-
it 'stores the file' do
|
1016
|
-
write('xxx')
|
1017
|
-
editor.insert('a')
|
1018
|
-
editor.save.should == true
|
1019
|
-
File.binary_read(@file).should == 'axxx'
|
1020
|
-
end
|
1021
|
-
|
1022
|
-
it 'creates the file' do
|
1023
|
-
`rm #{@file}`
|
1024
|
-
editor.insert('a')
|
1025
|
-
editor.save.should == true
|
1026
|
-
File.binary_read(@file).should == 'a'
|
1027
|
-
end
|
1028
|
-
|
1029
|
-
it 'does not crash when it cannot save a file' do
|
1030
|
-
begin
|
1031
|
-
`chmod -w #{@file}`
|
1032
|
-
editor.save.should == "Permission denied - #{@file}"
|
1033
|
-
ensure
|
1034
|
-
`chmod +w #{@file}`
|
1035
|
-
end
|
1036
|
-
end
|
1037
|
-
|
1038
|
-
describe 'remove trailing whitespace' do
|
1039
|
-
it "can remove trailing whitespace" do
|
1040
|
-
write("a \n \nb\n\n")
|
1041
|
-
editor.move(:to, 0,2)
|
1042
|
-
editor.instance_eval{@options[:remove_trailing_whitespace_on_save] = true}
|
1043
|
-
editor.save
|
1044
|
-
editor.view.should == "a\n\nb"
|
1045
|
-
editor.cursor.should == [0,1]
|
1046
|
-
end
|
1047
|
-
|
1048
|
-
it "does not affect trailing newlines" do
|
1049
|
-
write("\n\n\n")
|
1050
|
-
editor.move(:to, 2,0)
|
1051
|
-
editor.instance_eval{@options[:remove_trailing_whitespace_on_save] = true}
|
1052
|
-
editor.save
|
1053
|
-
editor.view.should == "\n\n"
|
1054
|
-
editor.cursor.should == [2,0]
|
1055
|
-
end
|
1056
|
-
|
1057
|
-
it "does not remove trailing whitespace by default" do
|
1058
|
-
write("a \n \nb\n\n")
|
1059
|
-
editor.save
|
1060
|
-
editor.view.should == "a \n \nb"
|
1061
|
-
editor.cursor.should == [0,0]
|
1062
|
-
end
|
1063
|
-
end
|
1064
|
-
end
|
1065
|
-
|
1066
|
-
describe :delete do
|
1067
|
-
it 'removes a char' do
|
1068
|
-
write('123')
|
1069
|
-
editor.delete(1)
|
1070
|
-
editor.view.should == "23\n\n"
|
1071
|
-
editor.cursor.should == [0,0]
|
1072
|
-
end
|
1073
|
-
|
1074
|
-
it 'removes a line' do
|
1075
|
-
write("123\n45")
|
1076
|
-
editor.move(:relative, 0,3)
|
1077
|
-
editor.delete(1)
|
1078
|
-
editor.view.should == "12345\n\n"
|
1079
|
-
editor.cursor.should == [0,3]
|
1080
|
-
end
|
1081
|
-
|
1082
|
-
it "cannot backspace over 0,0" do
|
1083
|
-
write("aa")
|
1084
|
-
editor.move(:relative, 0,1)
|
1085
|
-
editor.delete(-3)
|
1086
|
-
editor.view.should == "a\n\n"
|
1087
|
-
editor.cursor.should == [0,0]
|
1088
|
-
end
|
1089
|
-
|
1090
|
-
it 'backspaces a char' do
|
1091
|
-
write('123')
|
1092
|
-
editor.move(:relative, 0,3)
|
1093
|
-
editor.delete(-1)
|
1094
|
-
editor.view.should == "12\n\n"
|
1095
|
-
editor.cursor.should == [0,2]
|
1096
|
-
end
|
1097
|
-
|
1098
|
-
it 'backspaces a newline' do
|
1099
|
-
write("1\n234")
|
1100
|
-
editor.move(:relative, 1,0)
|
1101
|
-
editor.delete(-1)
|
1102
|
-
editor.view.should == "1234\n\n"
|
1103
|
-
editor.cursor.should == [0,1]
|
1104
|
-
end
|
1105
|
-
end
|
1106
|
-
|
1107
|
-
describe :modified? do
|
1108
|
-
it "is unchanged by default" do
|
1109
|
-
editor.modified?.should == false
|
1110
|
-
end
|
1111
|
-
|
1112
|
-
it "is changed after insert" do
|
1113
|
-
editor.insert('x')
|
1114
|
-
editor.modified?.should == true
|
1115
|
-
end
|
1116
|
-
|
1117
|
-
it "is changed after delete" do
|
1118
|
-
write("abc")
|
1119
|
-
editor.delete(1)
|
1120
|
-
editor.modified?.should == true
|
1121
|
-
end
|
1122
|
-
|
1123
|
-
it "is not changed after move" do
|
1124
|
-
editor.move(:relative, 1,1)
|
1125
|
-
editor.modified?.should == false
|
1126
|
-
end
|
1127
|
-
|
1128
|
-
it "is unchanged after save" do
|
1129
|
-
editor.insert('x')
|
1130
|
-
editor.save
|
1131
|
-
editor.modified?.should == false
|
1132
|
-
end
|
1133
|
-
|
1134
|
-
it "is changed after delete_line" do
|
1135
|
-
write("\n\n\n")
|
1136
|
-
editor.delete_line
|
1137
|
-
editor.modified?.should == true
|
1138
|
-
end
|
1139
|
-
end
|
1140
|
-
|
1141
|
-
describe :find do
|
1142
|
-
before do
|
1143
|
-
write("\n ab\n ab")
|
1144
|
-
end
|
1145
|
-
|
1146
|
-
it "moves to first occurrence" do
|
1147
|
-
editor.find('ab')
|
1148
|
-
editor.cursor.should == [1,1]
|
1149
|
-
end
|
1150
|
-
|
1151
|
-
it "moves to next occurrence" do
|
1152
|
-
editor.move(:relative, 1,1)
|
1153
|
-
editor.find('ab')
|
1154
|
-
editor.cursor.should == [2,1]
|
1155
|
-
end
|
1156
|
-
|
1157
|
-
it "stays in place when nothing was found" do
|
1158
|
-
editor.move(:relative, 2,1)
|
1159
|
-
editor.find('ab')
|
1160
|
-
editor.cursor.should == [2,1]
|
1161
|
-
end
|
1162
|
-
|
1163
|
-
it "selects the occurrence" do
|
1164
|
-
editor.find('ab')
|
1165
|
-
editor.selection.should == ([1, 1]..[1, 3])
|
1166
|
-
end
|
1167
|
-
end
|
1168
|
-
|
1169
|
-
describe :delete_line do
|
1170
|
-
before do
|
1171
|
-
write("1\nlonger_than_columns\n56789")
|
1172
|
-
end
|
1173
|
-
|
1174
|
-
it "removes the current line from first char" do
|
1175
|
-
editor.move(:to, 1, 0)
|
1176
|
-
editor.delete_line
|
1177
|
-
editor.view.should == "1\n56789\n"
|
1178
|
-
editor.cursor.should == [1, 0]
|
1179
|
-
end
|
1180
|
-
|
1181
|
-
it "removes the current line from last char" do
|
1182
|
-
editor.move(:to, 1, 3)
|
1183
|
-
editor.delete_line
|
1184
|
-
editor.view.should == "1\n56789\n"
|
1185
|
-
editor.cursor.should == [1, 3]
|
1186
|
-
end
|
1187
|
-
|
1188
|
-
it "can remove the first line" do
|
1189
|
-
editor.delete_line
|
1190
|
-
editor.view.should == "longe\n56789\n"
|
1191
|
-
editor.cursor.should == [0, 0]
|
1192
|
-
end
|
1193
|
-
|
1194
|
-
it "can remove the last line" do
|
1195
|
-
write("aaa")
|
1196
|
-
editor.delete_line
|
1197
|
-
editor.view.should == "\n\n"
|
1198
|
-
editor.cursor.should == [0, 0]
|
1199
|
-
end
|
1200
|
-
|
1201
|
-
it "can remove the last line with lines remaining" do
|
1202
|
-
write("aaa\nbbb")
|
1203
|
-
editor.move(:to, 1,1)
|
1204
|
-
editor.delete_line
|
1205
|
-
editor.view.should == "aaa\n\n"
|
1206
|
-
editor.cursor.should == [0, 1]
|
1207
|
-
end
|
1208
|
-
|
1209
|
-
it "jumps to end of next lines end when put of space" do
|
1210
|
-
write("1\n234\n5")
|
1211
|
-
editor.move(:to, 1, 3)
|
1212
|
-
editor.delete_line
|
1213
|
-
editor.cursor.should == [1, 1]
|
1214
|
-
end
|
1215
|
-
|
1216
|
-
it "can remove lines outside of initial screen" do
|
1217
|
-
write("0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n")
|
1218
|
-
editor.move(:to, 5, 0)
|
1219
|
-
editor.move(:to, 6, 1)
|
1220
|
-
editor.delete_line
|
1221
|
-
editor.view.should == "5\n7\n8"
|
1222
|
-
editor.cursor.should == [1, 1]
|
1223
|
-
end
|
1224
|
-
|
1225
|
-
it "can remove the last line" do
|
1226
|
-
write('xxx')
|
1227
|
-
editor.delete_line
|
1228
|
-
editor.insert('yyy')
|
1229
|
-
editor.view.should == "yyy\n\n"
|
1230
|
-
end
|
1231
|
-
end
|
1232
|
-
|
1233
|
-
describe 'with line_numbers' do
|
1234
|
-
let(:editor){ Ruco::Editor.new(@file, :lines => 5, :columns => 10, :line_numbers => true) }
|
1235
|
-
|
1236
|
-
before do
|
1237
|
-
write("a\nb\nc\nd\ne\nf\ng\nh\n")
|
1238
|
-
end
|
1239
|
-
|
1240
|
-
it "adds numbers to view" do
|
1241
|
-
editor.view.should == " 1 a\n 2 b\n 3 c\n 4 d\n 5 e"
|
1242
|
-
end
|
1243
|
-
|
1244
|
-
it "does not show numbers for empty lines" do
|
1245
|
-
editor.move(:to, 10,0)
|
1246
|
-
editor.view.should == " 6 f\n 7 g\n 8 h\n 9 \n "
|
1247
|
-
end
|
1248
|
-
|
1249
|
-
it "adjusts the cursor" do
|
1250
|
-
editor.cursor.should == [0,5]
|
1251
|
-
end
|
1252
|
-
|
1253
|
-
it "adjusts the style map" do
|
1254
|
-
editor.selecting{ move(:to, 0,1) }
|
1255
|
-
editor.style_map.flatten.should == [
|
1256
|
-
[nil, nil, nil, nil, nil, :reverse, nil, :normal],
|
1257
|
-
nil, nil, nil, nil
|
1258
|
-
]
|
1259
|
-
end
|
1260
|
-
end
|
1261
|
-
end
|