ruco 0.0.1
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/Gemfile +7 -0
- data/Gemfile.lock +28 -0
- data/Rakefile +50 -0
- data/Readme.md +28 -0
- data/VERSION +1 -0
- data/bin/ruco +52 -0
- data/lib/ruco.rb +7 -0
- data/lib/ruco/core_ext/array.rb +10 -0
- data/lib/ruco/core_ext/string.rb +14 -0
- data/lib/ruco/editor.rb +144 -0
- data/ruco.gemspec +52 -0
- data/spec/ruco/core_ext/string_spec.rb +17 -0
- data/spec/ruco_spec.rb +240 -0
- data/spec/spec_helper.rb +2 -0
- metadata +82 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
diff-lcs (1.1.2)
|
5
|
+
git (1.2.5)
|
6
|
+
jeweler (1.5.2)
|
7
|
+
bundler (~> 1.0.0)
|
8
|
+
git (>= 1.2.5)
|
9
|
+
rake
|
10
|
+
rake (0.8.7)
|
11
|
+
rspec (2.0.1)
|
12
|
+
rspec-core (~> 2.0.1)
|
13
|
+
rspec-expectations (~> 2.0.1)
|
14
|
+
rspec-mocks (~> 2.0.1)
|
15
|
+
rspec-core (2.0.1)
|
16
|
+
rspec-expectations (2.0.1)
|
17
|
+
diff-lcs (>= 1.1.2)
|
18
|
+
rspec-mocks (2.0.1)
|
19
|
+
rspec-core (~> 2.0.1)
|
20
|
+
rspec-expectations (~> 2.0.1)
|
21
|
+
|
22
|
+
PLATFORMS
|
23
|
+
ruby
|
24
|
+
|
25
|
+
DEPENDENCIES
|
26
|
+
jeweler
|
27
|
+
rake
|
28
|
+
rspec (~> 2)
|
data/Rakefile
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
task :default => :spec
|
2
|
+
require "rspec/core/rake_task"
|
3
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
4
|
+
t.rspec_opts = '--backtrace --color'
|
5
|
+
end
|
6
|
+
|
7
|
+
task :run do
|
8
|
+
file = 'spec/temp.txt'
|
9
|
+
File.open(file, 'w'){|f|f.write("12345\n1234\n#{'abcdefg'*20}\n123")}
|
10
|
+
exec "./bin/ruco #{file}"
|
11
|
+
end
|
12
|
+
|
13
|
+
task :try do
|
14
|
+
require 'curses'
|
15
|
+
Curses.setpos(0,0)
|
16
|
+
Curses.addstr("xxxxxxxx\nyyyyyyy");
|
17
|
+
Curses.getch
|
18
|
+
end
|
19
|
+
|
20
|
+
task :key do
|
21
|
+
require 'curses'
|
22
|
+
|
23
|
+
Curses.noecho
|
24
|
+
Curses.raw
|
25
|
+
Curses.stdscr.keypad(true)
|
26
|
+
|
27
|
+
count = 0
|
28
|
+
loop do
|
29
|
+
count = (count + 1) % 20
|
30
|
+
key = Curses.getch
|
31
|
+
break if key == ?\C-c
|
32
|
+
Curses.setpos(count,0)
|
33
|
+
Curses.addstr("#{key.inspect} ");
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
begin
|
38
|
+
require 'jeweler'
|
39
|
+
Jeweler::Tasks.new do |gem|
|
40
|
+
gem.name = 'ruco'
|
41
|
+
gem.summary = "Commandline editor written in ruby"
|
42
|
+
gem.email = "michael@grosser.it"
|
43
|
+
gem.homepage = "http://github.com/grosser/#{gem.name}"
|
44
|
+
gem.authors = ["Michael Grosser"]
|
45
|
+
end
|
46
|
+
|
47
|
+
Jeweler::GemcutterTasks.new
|
48
|
+
rescue LoadError
|
49
|
+
puts "Jeweler, or one of its dependencies, is not available. Install it with: gem install jeweler"
|
50
|
+
end
|
data/Readme.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
Commandline editor written in ruby
|
2
|
+
|
3
|
+
Alpha, do not use...
|
4
|
+
|
5
|
+
Finished:
|
6
|
+
- viewing / scrolling / editing / saving / creating
|
7
|
+
|
8
|
+
Install
|
9
|
+
=======
|
10
|
+
sudo gem install ruco
|
11
|
+
|
12
|
+
Usage
|
13
|
+
=====
|
14
|
+
ruco file.rb
|
15
|
+
|
16
|
+
TODO
|
17
|
+
=====
|
18
|
+
- delete key !?
|
19
|
+
- warnings / messages
|
20
|
+
- help
|
21
|
+
- syntax highlighting
|
22
|
+
|
23
|
+
|
24
|
+
Author
|
25
|
+
======
|
26
|
+
[Michael Grosser](http://grosser.it)
|
27
|
+
grosser.michael@gmail.com
|
28
|
+
Hereby placed under public domain, do what you want, just do not hold me accountable...
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/bin/ruco
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'curses'
|
3
|
+
|
4
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
5
|
+
require 'ruco'
|
6
|
+
|
7
|
+
def write(line,row,text)
|
8
|
+
Curses.setpos(line,row)
|
9
|
+
Curses.addstr(text);
|
10
|
+
end
|
11
|
+
|
12
|
+
def init_screen
|
13
|
+
Curses.noecho # do not show typed chars
|
14
|
+
Curses.init_screen
|
15
|
+
Curses.stdscr.keypad(true) # enable arrow keys
|
16
|
+
Curses.raw # give us all other keys
|
17
|
+
|
18
|
+
begin
|
19
|
+
yield
|
20
|
+
ensure
|
21
|
+
Curses.close_screen
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
editor = Ruco::Editor.new(ARGV[0], :lines => Curses.stdscr.maxy, :columns => Curses.stdscr.maxx)
|
26
|
+
|
27
|
+
init_screen do
|
28
|
+
loop do
|
29
|
+
lines = editor.view.split("\n")
|
30
|
+
Curses.stdscr.maxy.times do |i|
|
31
|
+
line = lines[i] || ''
|
32
|
+
clearer = Curses.stdscr.maxx - line.size
|
33
|
+
clearer = " " * clearer
|
34
|
+
write(i, 0, line + clearer)
|
35
|
+
end
|
36
|
+
|
37
|
+
Curses.setpos(editor.cursor_line, editor.cursor_column)
|
38
|
+
|
39
|
+
key = Curses.getch
|
40
|
+
|
41
|
+
case key
|
42
|
+
when Curses::Key::UP then editor.move(-1,0)
|
43
|
+
when Curses::Key::DOWN then editor.move(1,0)
|
44
|
+
when Curses::Key::RIGHT then editor.move(0,1)
|
45
|
+
when Curses::Key::LEFT then editor.move(0,-1)
|
46
|
+
when 32..126 then editor.insert(key.chr) # printable
|
47
|
+
when 10 then editor.insert("\n") # enter
|
48
|
+
when 263 then editor.delete(-1) # backspace
|
49
|
+
when ?\C-w, ?\C-q then break # quit
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/ruco.rb
ADDED
data/lib/ruco/editor.rb
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
module Ruco
|
2
|
+
class Editor
|
3
|
+
SCROLLING_OFFSET = 20
|
4
|
+
|
5
|
+
attr_reader :cursor_line, :cursor_column
|
6
|
+
|
7
|
+
def initialize(file, options)
|
8
|
+
@file = file
|
9
|
+
@options = options
|
10
|
+
@content = (File.exist?(@file) ? File.read(@file) : '')
|
11
|
+
@line = 0
|
12
|
+
@column = 0
|
13
|
+
@cursor_line = 0
|
14
|
+
@cursor_column = 0
|
15
|
+
@scrolled_lines = 0
|
16
|
+
@scrolled_columns = 0
|
17
|
+
@options[:line_scrolling_offset] ||= @options[:lines] / 2
|
18
|
+
@options[:column_scrolling_offset] ||= @options[:columns] / 2
|
19
|
+
end
|
20
|
+
|
21
|
+
def view
|
22
|
+
Array.new(@options[:lines]).map_with_index do |_,i|
|
23
|
+
(lines[i + @scrolled_lines] || "").slice(@scrolled_columns, @options[:columns])
|
24
|
+
end * "\n" + "\n"
|
25
|
+
end
|
26
|
+
|
27
|
+
def move(line, column)
|
28
|
+
@line = [[@line + line, 0].max, lines.size].min
|
29
|
+
@column = [[@column + column, 0].max, (lines[@line]||'').size].min
|
30
|
+
|
31
|
+
adjust_view
|
32
|
+
end
|
33
|
+
|
34
|
+
def insert(text)
|
35
|
+
insert_into_content cursor_index, text
|
36
|
+
move_according_to_insert(text)
|
37
|
+
end
|
38
|
+
|
39
|
+
def delete(count)
|
40
|
+
if count > 0
|
41
|
+
@content.slice!(cursor_index, count)
|
42
|
+
else
|
43
|
+
backspace(count.abs)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def backspace(count)
|
48
|
+
start_index = cursor_index - count
|
49
|
+
if start_index < 0
|
50
|
+
count += start_index
|
51
|
+
start_index = 0
|
52
|
+
end
|
53
|
+
|
54
|
+
@content.slice!(start_index, count)
|
55
|
+
set_cursor_to_index start_index
|
56
|
+
end
|
57
|
+
|
58
|
+
def save
|
59
|
+
File.open(@file,'w'){|f| f.write(@content) }
|
60
|
+
end
|
61
|
+
|
62
|
+
def cursor
|
63
|
+
[cursor_line, cursor_column]
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def lines
|
69
|
+
@content.naive_split("\n")
|
70
|
+
end
|
71
|
+
|
72
|
+
def adjust_view
|
73
|
+
reposition_cursor
|
74
|
+
scroll_column_into_view
|
75
|
+
scroll_line_into_view
|
76
|
+
reposition_cursor
|
77
|
+
end
|
78
|
+
|
79
|
+
def scroll_column_into_view
|
80
|
+
offset = [@options[:column_scrolling_offset], @options[:columns]].min
|
81
|
+
|
82
|
+
if @cursor_column >= @options[:columns]
|
83
|
+
@scrolled_columns = @column - @options[:columns] + offset
|
84
|
+
end
|
85
|
+
|
86
|
+
if @cursor_column < 0
|
87
|
+
@scrolled_columns = @column - offset
|
88
|
+
end
|
89
|
+
|
90
|
+
@scrolled_columns = [[@scrolled_columns, 0].max, @column].min
|
91
|
+
end
|
92
|
+
|
93
|
+
def scroll_line_into_view
|
94
|
+
offset = [@options[:line_scrolling_offset], @options[:lines]].min
|
95
|
+
|
96
|
+
if @cursor_line >= @options[:lines]
|
97
|
+
@scrolled_lines = @line - @options[:lines] + offset
|
98
|
+
end
|
99
|
+
|
100
|
+
if @cursor_line < 0
|
101
|
+
@scrolled_lines = @line - offset
|
102
|
+
end
|
103
|
+
|
104
|
+
@scrolled_lines = [[@scrolled_lines, 0].max, @line].min
|
105
|
+
end
|
106
|
+
|
107
|
+
def reposition_cursor
|
108
|
+
@cursor_column = @column - @scrolled_columns
|
109
|
+
@cursor_line = @line - @scrolled_lines
|
110
|
+
end
|
111
|
+
|
112
|
+
def insert_into_content(index, text)
|
113
|
+
# expand with newlines when inserting after maximum position
|
114
|
+
if index > @content.size
|
115
|
+
@content << "\n" * (index - @content.size)
|
116
|
+
end
|
117
|
+
@content.insert(index, text)
|
118
|
+
end
|
119
|
+
|
120
|
+
def cursor_index
|
121
|
+
insertion_point = lines[0...@line].join("\n").size + @column
|
122
|
+
insertion_point += 1 if @line > 0 # account for missing newline
|
123
|
+
insertion_point
|
124
|
+
end
|
125
|
+
|
126
|
+
def set_cursor_to_index(index)
|
127
|
+
jump = @content.slice(0, index).to_s.naive_split("\n")
|
128
|
+
@line = jump.size - 1
|
129
|
+
@column = jump.last.size
|
130
|
+
reposition_cursor
|
131
|
+
end
|
132
|
+
|
133
|
+
def move_according_to_insert(text)
|
134
|
+
inserted_lines = text.naive_split("\n")
|
135
|
+
if inserted_lines.size > 1
|
136
|
+
# column position does not add up when hitting return
|
137
|
+
@column = inserted_lines.last.size
|
138
|
+
move(inserted_lines.size - 1, 0)
|
139
|
+
else
|
140
|
+
move(inserted_lines.size - 1, inserted_lines.last.size)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
data/ruco.gemspec
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{ruco}
|
8
|
+
s.version = "0.0.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Michael Grosser"]
|
12
|
+
s.date = %q{2011-01-08}
|
13
|
+
s.default_executable = %q{ruco}
|
14
|
+
s.email = %q{michael@grosser.it}
|
15
|
+
s.executables = ["ruco"]
|
16
|
+
s.files = [
|
17
|
+
"Gemfile",
|
18
|
+
"Gemfile.lock",
|
19
|
+
"Rakefile",
|
20
|
+
"Readme.md",
|
21
|
+
"VERSION",
|
22
|
+
"bin/ruco",
|
23
|
+
"lib/ruco.rb",
|
24
|
+
"lib/ruco/core_ext/array.rb",
|
25
|
+
"lib/ruco/core_ext/string.rb",
|
26
|
+
"lib/ruco/editor.rb",
|
27
|
+
"ruco.gemspec",
|
28
|
+
"spec/ruco/core_ext/string_spec.rb",
|
29
|
+
"spec/ruco_spec.rb",
|
30
|
+
"spec/spec_helper.rb"
|
31
|
+
]
|
32
|
+
s.homepage = %q{http://github.com/grosser/ruco}
|
33
|
+
s.require_paths = ["lib"]
|
34
|
+
s.rubygems_version = %q{1.3.7}
|
35
|
+
s.summary = %q{Commandline editor written in ruby}
|
36
|
+
s.test_files = [
|
37
|
+
"spec/ruco/core_ext/string_spec.rb",
|
38
|
+
"spec/ruco_spec.rb",
|
39
|
+
"spec/spec_helper.rb"
|
40
|
+
]
|
41
|
+
|
42
|
+
if s.respond_to? :specification_version then
|
43
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
44
|
+
s.specification_version = 3
|
45
|
+
|
46
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
47
|
+
else
|
48
|
+
end
|
49
|
+
else
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.expand_path('spec/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
|
+
end
|
17
|
+
end
|
data/spec/ruco_spec.rb
ADDED
@@ -0,0 +1,240 @@
|
|
1
|
+
require File.expand_path('spec/spec_helper')
|
2
|
+
|
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
|
+
it "has a VERSION" do
|
11
|
+
Ruco::VERSION.should =~ /^\d+\.\d+\.\d+$/
|
12
|
+
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
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruco
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Michael Grosser
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-01-08 00:00:00 +01:00
|
19
|
+
default_executable: ruco
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description:
|
23
|
+
email: michael@grosser.it
|
24
|
+
executables:
|
25
|
+
- ruco
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files: []
|
29
|
+
|
30
|
+
files:
|
31
|
+
- Gemfile
|
32
|
+
- Gemfile.lock
|
33
|
+
- Rakefile
|
34
|
+
- Readme.md
|
35
|
+
- VERSION
|
36
|
+
- bin/ruco
|
37
|
+
- lib/ruco.rb
|
38
|
+
- lib/ruco/core_ext/array.rb
|
39
|
+
- lib/ruco/core_ext/string.rb
|
40
|
+
- lib/ruco/editor.rb
|
41
|
+
- ruco.gemspec
|
42
|
+
- spec/ruco/core_ext/string_spec.rb
|
43
|
+
- spec/ruco_spec.rb
|
44
|
+
- spec/spec_helper.rb
|
45
|
+
has_rdoc: true
|
46
|
+
homepage: http://github.com/grosser/ruco
|
47
|
+
licenses: []
|
48
|
+
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options: []
|
51
|
+
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 3
|
60
|
+
segments:
|
61
|
+
- 0
|
62
|
+
version: "0"
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
hash: 3
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
72
|
+
requirements: []
|
73
|
+
|
74
|
+
rubyforge_project:
|
75
|
+
rubygems_version: 1.3.7
|
76
|
+
signing_key:
|
77
|
+
specification_version: 3
|
78
|
+
summary: Commandline editor written in ruby
|
79
|
+
test_files:
|
80
|
+
- spec/ruco/core_ext/string_spec.rb
|
81
|
+
- spec/ruco_spec.rb
|
82
|
+
- spec/spec_helper.rb
|