ruco 0.0.56 → 0.1.0
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 +1 -0
- data/Gemfile.lock +1 -0
- data/Rakefile +20 -1
- data/Readme.md +9 -3
- data/VERSION +1 -1
- data/bin/ruco +4 -1
- data/lib/ruco/application.rb +2 -2
- data/lib/ruco/core_ext/file.rb +13 -1
- data/lib/ruco/editor.rb +5 -3
- data/lib/ruco/editor/history.rb +4 -2
- data/lib/ruco/editor_area.rb +0 -0
- data/lib/ruco/file_store.rb +12 -5
- data/lib/ruco/history.rb +33 -16
- data/ruco.gemspec +2 -2
- data/spec/ruco/application_spec.rb +4 -4
- data/spec/ruco/editor_spec.rb +24 -5
- data/spec/ruco/file_store_spec.rb +9 -17
- data/spec/ruco/history_spec.rb +26 -0
- data/spec/ruco/status_bar_spec.rb +5 -2
- metadata +4 -4
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
data/Rakefile
CHANGED
@@ -8,7 +8,7 @@ end
|
|
8
8
|
|
9
9
|
task :run do
|
10
10
|
file = 'spec/temp.txt'
|
11
|
-
File.open(file, '
|
11
|
+
File.open(file, 'wb'){|f|f.write("12345\n1234\n#{'abcdefg'*20}\n123")}
|
12
12
|
exec "./bin/ruco #{file}"
|
13
13
|
end
|
14
14
|
|
@@ -19,6 +19,25 @@ task :try do
|
|
19
19
|
Curses.getch
|
20
20
|
end
|
21
21
|
|
22
|
+
task :try_color do
|
23
|
+
require 'curses'
|
24
|
+
if Curses::has_colors?
|
25
|
+
Curses::start_color
|
26
|
+
# initialize every color we want to use
|
27
|
+
# id, foreground, background
|
28
|
+
Curses::init_pair( Curses::COLOR_BLACK, Curses::COLOR_BLACK, Curses::COLOR_BLACK )
|
29
|
+
Curses::init_pair( Curses::COLOR_RED, Curses::COLOR_RED, Curses::COLOR_BLACK )
|
30
|
+
Curses::init_pair( Curses::COLOR_GREEN, Curses::COLOR_GREEN, Curses::COLOR_BLACK )
|
31
|
+
end
|
32
|
+
|
33
|
+
Curses.setpos(0,0)
|
34
|
+
Curses.attrset(Curses.color_pair(Curses::COLOR_RED)) # fetch color pair with the id xxx
|
35
|
+
Curses.addstr("xxxxxxxx\nyyyyyyy");
|
36
|
+
Curses.attrset(Curses.color_pair(Curses::COLOR_GREEN))
|
37
|
+
Curses.addstr("xxxxxxxx\nyyyyyyy");
|
38
|
+
Curses.getch
|
39
|
+
end
|
40
|
+
|
22
41
|
task :key do
|
23
42
|
require 'curses'
|
24
43
|
|
data/Readme.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Simple, extendable, test-driven commandline editor written in ruby.
|
1
|
+
Simple, extendable, test-driven commandline editor written in ruby, for Linux/Mac/Windows.
|
2
2
|
|
3
3
|
Features:
|
4
4
|
|
@@ -81,6 +81,7 @@ TIPS
|
|
81
81
|
|
82
82
|
TODO
|
83
83
|
=====
|
84
|
+
- slow when opening file with 10,000+ short lines -> investigate
|
84
85
|
- check writable status every x seconds (e.g. in background) -> faster while typing
|
85
86
|
- search help e.g. 'Nothing found' '#4 of 6 hits' 'no more hits, start from beginning ?'
|
86
87
|
- highlight current work when reopening search (so typing replaces it)
|
@@ -96,8 +97,13 @@ TODO
|
|
96
97
|
- add auto-confirm to 'replace?' dialog -> type s == skip, no enter needed
|
97
98
|
- 1.8: unicode support <-> already finished but unusable due to Curses (see encoding branch)
|
98
99
|
|
99
|
-
|
100
|
-
|
100
|
+
Authors
|
101
|
+
=======
|
102
|
+
|
103
|
+
### [Contributors](http://github.com/grosser/ruco/contributors)
|
104
|
+
- [AJ Palkovic](https://github.com/ajpalkovic)
|
105
|
+
|
106
|
+
|
101
107
|
[Michael Grosser](http://grosser.it)<br/>
|
102
108
|
grosser.michael@gmail.com<br/>
|
103
109
|
Hereby placed under public domain, do what you want, just do not hold me accountable...
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
0.1.0
|
data/bin/ruco
CHANGED
@@ -20,6 +20,7 @@ Usage:
|
|
20
20
|
Options:
|
21
21
|
BANNER
|
22
22
|
opts.on("-c", "--convert-tabs","Convert tabs to spaces") { options[:convert_tabs] = true }
|
23
|
+
opts.on("-u", "--undo-stack-size SIZE","Maximum size of the undo stack. 0 allows for a complete undo stack.") {|size| options[:undo_stack_size] = size.to_i }
|
23
24
|
opts.on("--debug-cache","Show caching in action") { options[:debug_cache] = true }
|
24
25
|
opts.on("--debug-keys", "Show pressed keys") { options[:debug_keys] = true }
|
25
26
|
opts.on("-v", "--version","Show Version"){
|
@@ -55,6 +56,7 @@ def init_screen
|
|
55
56
|
begin
|
56
57
|
yield
|
57
58
|
ensure
|
59
|
+
Curses.clear # needed to clear the menu/status bar on windows
|
58
60
|
Curses.close_screen
|
59
61
|
end
|
60
62
|
end
|
@@ -107,7 +109,7 @@ def debug_key(key)
|
|
107
109
|
end
|
108
110
|
|
109
111
|
def log(stuff)
|
110
|
-
File.open('ruco.log','
|
112
|
+
File.open('ruco.log','ab'){|f| f.puts stuff }
|
111
113
|
end
|
112
114
|
|
113
115
|
@options = parse_options
|
@@ -116,6 +118,7 @@ require 'ruco'
|
|
116
118
|
|
117
119
|
app = Ruco::Application.new(ARGV[0],
|
118
120
|
:convert_tabs => @options[:convert_tabs],
|
121
|
+
:undo_stack_size => @options[:undo_stack_size],
|
119
122
|
:lines => Curses.stdscr.maxy, :columns => Curses.stdscr.maxx
|
120
123
|
)
|
121
124
|
|
data/lib/ruco/application.rb
CHANGED
@@ -155,7 +155,7 @@ module Ruco
|
|
155
155
|
|
156
156
|
action :quit do
|
157
157
|
if editor.modified?
|
158
|
-
ask("
|
158
|
+
ask("Lose changes? Enter=Yes Esc=Cancel") do
|
159
159
|
editor.store_session
|
160
160
|
:quit
|
161
161
|
end
|
@@ -253,7 +253,7 @@ module Ruco
|
|
253
253
|
@status_lines = 1
|
254
254
|
|
255
255
|
editor_options = @options.slice(
|
256
|
-
:columns, :convert_tabs, :convert_newlines
|
256
|
+
:columns, :convert_tabs, :convert_newlines, :undo_stack_size
|
257
257
|
).merge(
|
258
258
|
:window => @options.nested(:window),
|
259
259
|
:history => @options.nested(:history),
|
data/lib/ruco/core_ext/file.rb
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
class File
|
2
2
|
def self.write(to, content)
|
3
|
-
File.open(to, '
|
3
|
+
File.open(to, 'wb'){|f| f.write(content) }
|
4
|
+
end
|
5
|
+
|
6
|
+
# Open files in binary mode. On linux this is ignored by ruby.
|
7
|
+
# On Windows ruby open files in text mode by default, so it replaces \r with \n,
|
8
|
+
# so the specs fail. If files are opened in binary mode, which is the only mode
|
9
|
+
# on linux, it does not replace the newlines. This thread has slightly more information:
|
10
|
+
# http://groups.google.com/group/rubyinstaller/browse_thread/thread/c7fbe346831e58cc
|
11
|
+
def self.binary_read(file)
|
12
|
+
io = File.open(file, 'rb')
|
13
|
+
content = io.read
|
14
|
+
io.close
|
15
|
+
content
|
4
16
|
end
|
5
17
|
end
|
data/lib/ruco/editor.rb
CHANGED
@@ -2,10 +2,11 @@ module Ruco
|
|
2
2
|
class Editor
|
3
3
|
attr_reader :file
|
4
4
|
attr_reader :text_area
|
5
|
+
attr_reader :history
|
5
6
|
private :text_area
|
6
7
|
delegate :view, :style_map, :cursor, :position,
|
7
8
|
:insert, :indent, :unindent, :delete, :delete_line,
|
8
|
-
:redo, :undo,
|
9
|
+
:redo, :undo, :save_state,
|
9
10
|
:selecting, :selection, :text_in_selection, :reset,
|
10
11
|
:move, :resize, :move_line,
|
11
12
|
:to => :text_area
|
@@ -19,7 +20,7 @@ module Ruco
|
|
19
20
|
raise "#{@file} is larger than 1MB, did you really want to open that with Ruco?"
|
20
21
|
end
|
21
22
|
|
22
|
-
content = (File.exist?(@file) ? File.
|
23
|
+
content = (File.exist?(@file) ? File.binary_read(@file) : '')
|
23
24
|
content.tabs_to_spaces! if @options[:convert_tabs]
|
24
25
|
|
25
26
|
# cleanup newline formats
|
@@ -29,6 +30,7 @@ module Ruco
|
|
29
30
|
|
30
31
|
@saved_content = content
|
31
32
|
@text_area = EditorArea.new(content, @options)
|
33
|
+
@history = @text_area.history
|
32
34
|
restore_session
|
33
35
|
end
|
34
36
|
|
@@ -51,7 +53,7 @@ module Ruco
|
|
51
53
|
lines << '' if @options[:blank_line_before_eof_on_save] and lines.last.to_s !~ /^\s*$/
|
52
54
|
content = lines * @newline
|
53
55
|
|
54
|
-
File.open(@file,'
|
56
|
+
File.open(@file,'wb'){|f| f.write(content) }
|
55
57
|
@saved_content = content.gsub(/\r?\n/, "\n")
|
56
58
|
|
57
59
|
true
|
data/lib/ruco/editor/history.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
module Ruco
|
2
2
|
class Editor
|
3
3
|
module History
|
4
|
+
attr_reader :history
|
5
|
+
|
4
6
|
def initialize(content, options)
|
5
7
|
super(content, options)
|
6
|
-
@history = Ruco::History.new((options[:history]||{}).reverse_merge(:state => state, :track => [:content], :entries =>
|
8
|
+
@history = Ruco::History.new((options[:history]||{}).reverse_merge(:state => state, :track => [:content], :entries => options[:undo_stack_size], :timeout => 2))
|
7
9
|
end
|
8
10
|
|
9
11
|
def undo
|
@@ -15,7 +17,7 @@ module Ruco
|
|
15
17
|
@history.redo
|
16
18
|
self.state = @history.state
|
17
19
|
end
|
18
|
-
|
20
|
+
|
19
21
|
def view
|
20
22
|
@history.add(state)
|
21
23
|
super
|
data/lib/ruco/editor_area.rb
CHANGED
File without changes
|
data/lib/ruco/file_store.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "digest/md5"
|
2
|
+
require "fileutils"
|
2
3
|
|
3
4
|
module Ruco
|
4
5
|
class FileStore
|
@@ -8,21 +9,27 @@ module Ruco
|
|
8
9
|
end
|
9
10
|
|
10
11
|
def set(key, value)
|
11
|
-
|
12
|
+
FileUtils.mkdir_p @folder unless File.exist? @folder
|
12
13
|
File.write(file(key), serialize(value))
|
13
14
|
cleanup
|
14
15
|
end
|
15
16
|
|
16
17
|
def get(key)
|
17
18
|
file = file(key)
|
18
|
-
deserialize File.
|
19
|
+
deserialize File.binary_read(file) if File.exist?(file)
|
19
20
|
end
|
20
21
|
|
21
22
|
private
|
22
23
|
|
24
|
+
def entries
|
25
|
+
(Dir.entries(@folder) - ['.','..']).
|
26
|
+
map{|entry| File.join(@folder, entry) }.
|
27
|
+
sort_by{|file| File.mtime(file) }
|
28
|
+
end
|
29
|
+
|
23
30
|
def cleanup
|
24
|
-
delete =
|
25
|
-
delete.each{|f| File.delete(
|
31
|
+
delete = entries[0...-@options[:keep]] || []
|
32
|
+
delete.each{|f| File.delete(f) }
|
26
33
|
end
|
27
34
|
|
28
35
|
def file(key)
|
@@ -37,4 +44,4 @@ module Ruco
|
|
37
44
|
Marshal.load(value)
|
38
45
|
end
|
39
46
|
end
|
40
|
-
end
|
47
|
+
end
|
data/lib/ruco/history.rb
CHANGED
@@ -1,41 +1,65 @@
|
|
1
1
|
module Ruco
|
2
2
|
class History
|
3
3
|
attr_accessor :timeout
|
4
|
+
attr_reader :stack, :position
|
4
5
|
|
5
6
|
def initialize(options)
|
6
7
|
@options = options
|
7
|
-
@
|
8
|
+
@options[:entries] ||= 100
|
8
9
|
@timeout = options.delete(:timeout) || 0
|
9
|
-
|
10
|
+
|
11
|
+
@stack = [{:mutable => false, :created_at => 0, :type => :initial, :state => @options.delete(:state)}]
|
10
12
|
@position = 0
|
11
13
|
end
|
12
14
|
|
13
15
|
def state
|
14
|
-
@stack[@position]
|
16
|
+
@stack[@position][:state]
|
15
17
|
end
|
16
18
|
|
17
19
|
def add(state)
|
18
20
|
return unless tracked_field_changes?(state)
|
19
21
|
remove_undone_states
|
20
|
-
|
22
|
+
unless merge? state
|
23
|
+
# can no longer modify previous states
|
24
|
+
@stack[@position][:mutable] = false
|
25
|
+
|
26
|
+
state_type = type(state)
|
21
27
|
@position += 1
|
22
|
-
@
|
28
|
+
@stack[@position] = {:mutable => true, :type => state_type, :created_at => Time.now.to_f}
|
23
29
|
end
|
24
|
-
@stack[@position] = state
|
30
|
+
@stack[@position][:state] = state
|
25
31
|
limit_stack
|
26
32
|
end
|
27
33
|
|
28
34
|
def undo
|
29
|
-
timeout!
|
30
35
|
@position = [@position - 1, 0].max
|
31
36
|
end
|
32
37
|
|
33
38
|
def redo
|
34
|
-
timeout!
|
35
39
|
@position = [@position + 1, @stack.size - 1].min
|
36
40
|
end
|
37
41
|
|
38
42
|
private
|
43
|
+
def type(state)
|
44
|
+
@options[:track].each do |field|
|
45
|
+
if state[field].is_a?(String) && @stack[@position][:state][field].is_a?(String)
|
46
|
+
diff = state[field].length - @stack[@position][:state][field].length
|
47
|
+
if diff > 0
|
48
|
+
return :insert
|
49
|
+
elsif diff < 0
|
50
|
+
return :delete
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
nil
|
55
|
+
end
|
56
|
+
|
57
|
+
def merge?(state)
|
58
|
+
top = @stack[@position]
|
59
|
+
top[:mutable] &&
|
60
|
+
top[:type] == type(state) &&
|
61
|
+
top[:created_at]+@timeout > Time.now.to_f
|
62
|
+
end
|
39
63
|
|
40
64
|
def remove_undone_states
|
41
65
|
@stack.slice!(@position + 1, 9999999)
|
@@ -48,18 +72,11 @@ module Ruco
|
|
48
72
|
end
|
49
73
|
|
50
74
|
def limit_stack
|
75
|
+
return if @options[:entries] == 0
|
51
76
|
to_remove = @stack.size - @options[:entries]
|
52
77
|
return if to_remove < 1
|
53
78
|
@stack.slice!(0, to_remove)
|
54
79
|
@position -= to_remove
|
55
80
|
end
|
56
|
-
|
57
|
-
def timeout!
|
58
|
-
@last_merge = 0
|
59
|
-
end
|
60
|
-
|
61
|
-
def merge_timeout?
|
62
|
-
(Time.now.to_f - @last_merge) > @timeout
|
63
|
-
end
|
64
81
|
end
|
65
82
|
end
|
data/ruco.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{ruco}
|
8
|
-
s.version = "0.0
|
8
|
+
s.version = "0.1.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Michael Grosser"]
|
12
|
-
s.date = %q{2011-05-
|
12
|
+
s.date = %q{2011-05-20}
|
13
13
|
s.default_executable = %q{ruco}
|
14
14
|
s.email = %q{michael@grosser.it}
|
15
15
|
s.executables = ["ruco"]
|
@@ -15,11 +15,11 @@ describe Ruco::Application do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def write(content)
|
18
|
-
File.open(@file,'
|
18
|
+
File.open(@file,'wb'){|f| f.write(content) }
|
19
19
|
end
|
20
20
|
|
21
21
|
def read
|
22
|
-
File.
|
22
|
+
File.binary_read(@file)
|
23
23
|
end
|
24
24
|
|
25
25
|
def editor_part(view)
|
@@ -110,7 +110,7 @@ describe Ruco::Application do
|
|
110
110
|
it "asks before closing changed file -- escape == no" do
|
111
111
|
app.key('a')
|
112
112
|
app.key(:"Ctrl+w")
|
113
|
-
app.view.split("\n").last.should include("
|
113
|
+
app.view.split("\n").last.should include("Lose changes")
|
114
114
|
app.key(:escape).should_not == :quit
|
115
115
|
app.key("\n").should_not == :quit
|
116
116
|
end
|
@@ -118,7 +118,7 @@ describe Ruco::Application do
|
|
118
118
|
it "asks before closing changed file -- enter == yes" do
|
119
119
|
app.key('a')
|
120
120
|
app.key(:"Ctrl+w")
|
121
|
-
app.view.split("\n").last.should include("
|
121
|
+
app.view.split("\n").last.should include("Lose changes")
|
122
122
|
app.key(:enter).should == :quit
|
123
123
|
end
|
124
124
|
end
|
data/spec/ruco/editor_spec.rb
CHANGED
@@ -2,11 +2,11 @@ require File.expand_path('spec/spec_helper')
|
|
2
2
|
|
3
3
|
describe Ruco::Editor do
|
4
4
|
def write(content)
|
5
|
-
File.open(@file,'
|
5
|
+
File.open(@file,'wb'){|f| f.write(content) }
|
6
6
|
end
|
7
7
|
|
8
8
|
def read
|
9
|
-
File.
|
9
|
+
File.binary_read(@file)
|
10
10
|
end
|
11
11
|
|
12
12
|
let(:editor){
|
@@ -753,6 +753,25 @@ describe Ruco::Editor do
|
|
753
753
|
end
|
754
754
|
|
755
755
|
describe 'history' do
|
756
|
+
it "does not overwrite the initial state" do
|
757
|
+
write("a")
|
758
|
+
editor.insert("b")
|
759
|
+
editor.view # trigger save point
|
760
|
+
stack = editor.history.stack
|
761
|
+
stack.length.should == 2
|
762
|
+
stack[0][:state][:content].should == "a"
|
763
|
+
stack[1][:state][:content].should == "ba"
|
764
|
+
|
765
|
+
editor.undo
|
766
|
+
editor.history.position.should == 0
|
767
|
+
|
768
|
+
editor.insert("c")
|
769
|
+
editor.view # trigger save point
|
770
|
+
stack.length.should == 2
|
771
|
+
stack[0][:state][:content].should == "a"
|
772
|
+
stack[1][:state][:content].should == "ca"
|
773
|
+
end
|
774
|
+
|
756
775
|
it "can undo an action" do
|
757
776
|
write("a")
|
758
777
|
editor.insert("b")
|
@@ -768,6 +787,7 @@ describe Ruco::Editor do
|
|
768
787
|
|
769
788
|
it "removes selection on undo" do
|
770
789
|
editor.insert('a')
|
790
|
+
editor.view # trigger save point
|
771
791
|
editor.selecting{move(:to, 1,1)}
|
772
792
|
editor.selection.should_not == nil
|
773
793
|
editor.view # trigger save point
|
@@ -777,7 +797,6 @@ describe Ruco::Editor do
|
|
777
797
|
|
778
798
|
it "sets modified on undo" do
|
779
799
|
editor.insert('a')
|
780
|
-
editor.view # trigger save point
|
781
800
|
editor.save
|
782
801
|
editor.modified?.should == false
|
783
802
|
editor.undo
|
@@ -790,14 +809,14 @@ describe Ruco::Editor do
|
|
790
809
|
write('xxx')
|
791
810
|
editor.insert('a')
|
792
811
|
editor.save.should == true
|
793
|
-
File.
|
812
|
+
File.binary_read(@file).should == 'axxx'
|
794
813
|
end
|
795
814
|
|
796
815
|
it 'creates the file' do
|
797
816
|
`rm #{@file}`
|
798
817
|
editor.insert('a')
|
799
818
|
editor.save.should == true
|
800
|
-
File.
|
819
|
+
File.binary_read(@file).should == 'a'
|
801
820
|
end
|
802
821
|
|
803
822
|
it 'does not crash when it cannot save a file' do
|
@@ -1,6 +1,10 @@
|
|
1
1
|
require File.expand_path('spec/spec_helper')
|
2
2
|
|
3
3
|
describe Ruco::FileStore do
|
4
|
+
def mark_all_as_old
|
5
|
+
store.send(:entries).each{|e| File.utime(1,1,e) }
|
6
|
+
end
|
7
|
+
|
4
8
|
before do
|
5
9
|
@folder = 'spec/sessions'
|
6
10
|
`rm -rf #{@folder}`
|
@@ -21,23 +25,10 @@ describe Ruco::FileStore do
|
|
21
25
|
store.set('xxx', 1)
|
22
26
|
store.set('yyy', 1)
|
23
27
|
store.set('zzz', 1)
|
24
|
-
|
25
|
-
store.
|
26
|
-
|
27
|
-
|
28
|
-
it "drops least recently used key" do
|
29
|
-
store.set('xxx', 1)
|
30
|
-
sleep(0.1)
|
31
|
-
store.set('yyy', 1)
|
32
|
-
sleep(0.1)
|
33
|
-
store.set('xxx', 1)
|
34
|
-
sleep(0.1)
|
35
|
-
store.set('zzz', 1)
|
36
|
-
sleep(0.1)
|
37
|
-
store.set('aaa', 1)
|
38
|
-
sleep(0.1)
|
39
|
-
store.get('xxx').should == 1
|
40
|
-
store.get('yyy').should == nil
|
28
|
+
mark_all_as_old
|
29
|
+
store.set('aaa', 2)
|
30
|
+
store.get('aaa').should == 2
|
31
|
+
['xxx','yyy','zzz'].map{|f| store.get(f) }.should =~ [1,1,nil]
|
41
32
|
end
|
42
33
|
|
43
34
|
it "does not drop if used multiple times" do
|
@@ -45,6 +36,7 @@ describe Ruco::FileStore do
|
|
45
36
|
store.set('yyy', 1)
|
46
37
|
store.set('zzz', 1)
|
47
38
|
store.set('zzz', 1)
|
39
|
+
mark_all_as_old
|
48
40
|
store.set('zzz', 1)
|
49
41
|
store.set('zzz', 1)
|
50
42
|
store.get('xxx').should == 1
|
data/spec/ruco/history_spec.rb
CHANGED
@@ -74,6 +74,20 @@ describe Ruco::History do
|
|
74
74
|
history.undo
|
75
75
|
history.state.should == {:x => 3}
|
76
76
|
end
|
77
|
+
|
78
|
+
describe 'with strings' do
|
79
|
+
let(:history){ Ruco::History.new(:state => {:x => 'a'}, :track => [:x], :timeout => 0.1) }
|
80
|
+
|
81
|
+
it "triggers a new state on insertion and deletion" do
|
82
|
+
%w{ab abc ab a a}.each{|state| history.add(:x => state)}
|
83
|
+
|
84
|
+
history.undo
|
85
|
+
history.state.should == {:x => "abc"}
|
86
|
+
|
87
|
+
history.undo
|
88
|
+
history.state.should == {:x => "a"}
|
89
|
+
end
|
90
|
+
end
|
77
91
|
|
78
92
|
describe 'with timeout' do
|
79
93
|
let(:history){ Ruco::History.new(:state => {:x => 1}, :track => [:x], :entries => 3, :timeout => 0.1) }
|
@@ -114,4 +128,16 @@ describe Ruco::History do
|
|
114
128
|
history.state.should == {:x => 3}
|
115
129
|
end
|
116
130
|
end
|
131
|
+
|
132
|
+
describe 'with no entry limit' do
|
133
|
+
let(:history){ Ruco::History.new(:state => {:x => 1}, :track => [:x], :entries => 0, :timeout => 0) }
|
134
|
+
|
135
|
+
it "should track unlimited states" do
|
136
|
+
200.times do |i|
|
137
|
+
history.add(:x => i+5)
|
138
|
+
end
|
139
|
+
history.stack.length.should == 201
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
117
143
|
end
|
@@ -29,8 +29,11 @@ describe Ruco::StatusBar do
|
|
29
29
|
end
|
30
30
|
|
31
31
|
it "indicates not writable" do
|
32
|
-
|
33
|
-
|
32
|
+
# this test will always fail on Windows with cygwin because of how cygwin sets up permissions
|
33
|
+
unless RUBY_PLATFORM =~ /mingw/
|
34
|
+
editor.stub!(:file).and_return '/etc/sudoers'
|
35
|
+
bar.view.should include('!')
|
36
|
+
end
|
34
37
|
end
|
35
38
|
|
36
39
|
it "shows line and column and right side" do
|
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:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 0.0.56
|
10
|
+
version: 0.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Michael Grosser
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-05-
|
18
|
+
date: 2011-05-20 00:00:00 +02:00
|
19
19
|
default_executable: ruco
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|