ruco 0.0.43 → 0.0.44
Sign up to get free protection for your applications and to get access to all the features.
- data/Readme.md +6 -0
- data/VERSION +1 -1
- data/lib/ruco.rb +1 -0
- data/lib/ruco/application.rb +17 -8
- data/lib/ruco/core_ext/hash.rb +5 -1
- data/lib/ruco/editor_area.rb +1 -1
- data/lib/ruco/keyboard.rb +21 -23
- data/lib/ruco/option_accessor.rb +25 -0
- data/lib/ruco/text_area.rb +2 -2
- data/ruco.gemspec +7 -3
- data/spec/ruco/application_spec.rb +32 -14
- data/spec/ruco/editor_spec.rb +6 -0
- data/spec/ruco/option_accessor_spec.rb +26 -0
- metadata +11 -11
data/Readme.md
CHANGED
@@ -26,6 +26,11 @@ Customize
|
|
26
26
|
|
27
27
|
# ~/.ruco.rb
|
28
28
|
Ruco.configure do
|
29
|
+
# set options
|
30
|
+
options.window_line_scroll_offset = 5 # default 1
|
31
|
+
options.history_entries = 10 # default 100
|
32
|
+
...
|
33
|
+
|
29
34
|
# bind a key
|
30
35
|
# - you can use Integers and Symbols
|
31
36
|
# - use "ruco --debug-keys foo" to see which keys are possible
|
@@ -65,6 +70,7 @@ TIPS
|
|
65
70
|
|
66
71
|
TODO
|
67
72
|
=====
|
73
|
+
- align soft-tabs
|
68
74
|
- strip whitespace after content / whitespace only lines, without removing intentional whitespace e.g. from markdown
|
69
75
|
- handle \\r and \\r\\n nicely <-> breaks curses output
|
70
76
|
- highlight tabs (e.g. strange character or reverse/underline/color)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.44
|
data/lib/ruco.rb
CHANGED
data/lib/ruco/application.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
module Ruco
|
2
2
|
class Application
|
3
|
+
attr_reader :editor, :status, :command, :options
|
4
|
+
|
3
5
|
def initialize(file, options)
|
4
6
|
@file = file
|
5
|
-
@options = options
|
7
|
+
@options = OptionAccessor.new(options)
|
6
8
|
|
7
9
|
setup_actions
|
8
10
|
setup_keys
|
@@ -123,8 +125,6 @@ module Ruco
|
|
123
125
|
|
124
126
|
private
|
125
127
|
|
126
|
-
attr_reader :editor, :status, :command
|
127
|
-
|
128
128
|
def setup_actions
|
129
129
|
@actions = {}
|
130
130
|
|
@@ -228,22 +228,31 @@ module Ruco
|
|
228
228
|
|
229
229
|
def load_user_config
|
230
230
|
Ruco.application = self
|
231
|
-
config = File.expand_path("~/.ruco.rb")
|
231
|
+
config = File.expand_path(@options[:rc] || "~/.ruco.rb")
|
232
232
|
load config if File.exist?(config)
|
233
233
|
end
|
234
234
|
|
235
235
|
def create_components
|
236
236
|
@status_lines = 1
|
237
|
-
|
238
|
-
|
239
|
-
|
237
|
+
|
238
|
+
editor_options = @options.slice(
|
239
|
+
:columns, :convert_tabs, :convert_newlines
|
240
|
+
).merge(
|
241
|
+
:window => @options.nested(:window),
|
242
|
+
:history => @options.nested(:history),
|
243
|
+
:lines => editor_lines
|
244
|
+
).merge(@options.nested(:editor))
|
245
|
+
|
246
|
+
@editor ||= Ruco::Editor.new(@file, editor_options)
|
247
|
+
@status = Ruco::StatusBar.new(@editor, @options.nested(:status_bar).merge(:columns => options[:columns]))
|
248
|
+
@command = Ruco::CommandBar.new(@options.nested(:command_bar).merge(:columns => options[:columns]))
|
240
249
|
command.cursor_line = editor_lines
|
241
250
|
@focused = @editor
|
242
251
|
end
|
243
252
|
|
244
253
|
def editor_lines
|
245
254
|
command_lines = 1
|
246
|
-
|
255
|
+
@options[:lines] - @status_lines - command_lines
|
247
256
|
end
|
248
257
|
end
|
249
258
|
end
|
data/lib/ruco/core_ext/hash.rb
CHANGED
data/lib/ruco/editor_area.rb
CHANGED
@@ -4,7 +4,7 @@ module Ruco
|
|
4
4
|
class EditorArea < TextArea
|
5
5
|
def initialize(*args)
|
6
6
|
super(*args)
|
7
|
-
@history = History.new(:state => state, :track => [:content], :entries => 100, :timeout => 2)
|
7
|
+
@history = History.new((args.last[:history]||{}).reverse_merge(:state => state, :track => [:content], :entries => 100, :timeout => 2))
|
8
8
|
end
|
9
9
|
|
10
10
|
def undo
|
data/lib/ruco/keyboard.rb
CHANGED
@@ -38,16 +38,16 @@ class Keyboard
|
|
38
38
|
when Curses::Key::DOWN then :down
|
39
39
|
when Curses::Key::RIGHT then :right
|
40
40
|
when Curses::Key::LEFT then :left
|
41
|
-
when
|
42
|
-
when
|
43
|
-
when 555 then :"Ctrl+Shift+right"
|
44
|
-
when
|
45
|
-
when
|
46
|
-
when 540 then :"Ctrl+Shift+left"
|
47
|
-
when
|
48
|
-
when
|
49
|
-
when
|
50
|
-
when
|
41
|
+
when 402, '^[1;2C' then :"Shift+right"
|
42
|
+
when 554, '^[1;5C' then :"Ctrl+right"
|
43
|
+
when 555, '^[1;6C' then :"Ctrl+Shift+right"
|
44
|
+
when 393, '^[1;2D' then :"Shift+left"
|
45
|
+
when 539, '^[1;5D' then :"Ctrl+left"
|
46
|
+
when 540, '^[1;6D' then :"Ctrl+Shift+left"
|
47
|
+
when 337, '^[1;2A' then :"Shift+up"
|
48
|
+
when 560, '^[1;5A' then :"Ctrl+up"
|
49
|
+
when 336, '^[1;2B' then :"Shift+down"
|
50
|
+
when 519, '^[1;5B' then :"Ctrl+down"
|
51
51
|
when Curses::KEY_END then :end
|
52
52
|
when Curses::KEY_HOME then :home
|
53
53
|
when Curses::KEY_NPAGE then :page_down
|
@@ -68,7 +68,13 @@ class Keyboard
|
|
68
68
|
when ESCAPE then :escape
|
69
69
|
when Curses::KEY_RESIZE then :resize
|
70
70
|
else
|
71
|
-
key
|
71
|
+
if key.is_a? Fixnum
|
72
|
+
key > MAX_CHAR ? key : key.chr
|
73
|
+
elsif is_alt_key_code?(key)
|
74
|
+
:"Alt+#{key.slice(1,1)}"
|
75
|
+
else
|
76
|
+
key
|
77
|
+
end
|
72
78
|
end
|
73
79
|
end
|
74
80
|
|
@@ -133,7 +139,8 @@ class Keyboard
|
|
133
139
|
else
|
134
140
|
# when connected via ssh escape sequences are used
|
135
141
|
if escape_sequence?(sequence)
|
136
|
-
|
142
|
+
stringified = bytes_to_string(sequence).sub("\e",'^').sub('[[','[')
|
143
|
+
[translate_key_to_code(stringified)]
|
137
144
|
else
|
138
145
|
bytes_to_key_codes(sequence)
|
139
146
|
end
|
@@ -144,16 +151,7 @@ class Keyboard
|
|
144
151
|
sequence[0] == ESCAPE and sequence.size.between?(2,6) # Esc
|
145
152
|
end
|
146
153
|
|
147
|
-
def self.
|
148
|
-
|
149
|
-
when [ESCAPE, 91, 49, 59, 50, 65] then :"Shift+up"
|
150
|
-
when [ESCAPE, 91, 49, 59, 50, 66] then :"Shift+down"
|
151
|
-
else
|
152
|
-
if sequence.size == 2
|
153
|
-
:"Alt+#{sequence[1].chr}"
|
154
|
-
else
|
155
|
-
bytes_to_string(sequence)
|
156
|
-
end
|
157
|
-
end
|
154
|
+
def self.is_alt_key_code?(key)
|
155
|
+
key.slice(0,1) == "^" and key.size == 2
|
158
156
|
end
|
159
157
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Ruco
|
2
|
+
# Can be used like a hash, but also allows .key access
|
3
|
+
class OptionAccessor
|
4
|
+
attr_reader :wrapped
|
5
|
+
delegate :[], :[]=, :slice, :to => :wrapped
|
6
|
+
|
7
|
+
def initialize(wrapped={})
|
8
|
+
@wrapped = wrapped
|
9
|
+
end
|
10
|
+
|
11
|
+
def nested(key)
|
12
|
+
Hash[wrapped.map do |k,v|
|
13
|
+
if k.to_s =~ /^#{key}_(.*)$/
|
14
|
+
[$1.to_sym,v]
|
15
|
+
end
|
16
|
+
end.compact]
|
17
|
+
end
|
18
|
+
|
19
|
+
def method_missing(method, *args)
|
20
|
+
base = method.to_s.sub('=','').to_sym
|
21
|
+
raise if args.size != 1
|
22
|
+
@wrapped[base] = args.first
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/ruco/text_area.rb
CHANGED
@@ -7,7 +7,7 @@ module Ruco
|
|
7
7
|
@options = options.dup
|
8
8
|
@column = 0
|
9
9
|
@line = 0
|
10
|
-
@window = Window.new(@options.delete(:lines), @options.delete(:columns))
|
10
|
+
@window = Window.new(@options.delete(:lines), @options.delete(:columns), @options[:window]||{})
|
11
11
|
adjust_window
|
12
12
|
end
|
13
13
|
|
@@ -80,7 +80,7 @@ module Ruco
|
|
80
80
|
delete_content_in_selection if @selection
|
81
81
|
|
82
82
|
text.tabs_to_spaces!
|
83
|
-
if text == "\n" and @column >=
|
83
|
+
if text == "\n" and @column >= current_line.leading_whitespace.size
|
84
84
|
current_whitespace = current_line.leading_whitespace
|
85
85
|
next_whitespace = lines[line+1].to_s.leading_whitespace
|
86
86
|
text = text + [current_whitespace, next_whitespace].max
|
data/ruco.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{ruco}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.44"
|
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-02-
|
12
|
+
s.date = %q{2011-02-09}
|
13
13
|
s.default_executable = %q{ruco}
|
14
14
|
s.email = %q{michael@grosser.it}
|
15
15
|
s.executables = ["ruco"]
|
@@ -35,6 +35,7 @@ Gem::Specification.new do |s|
|
|
35
35
|
"lib/ruco/form.rb",
|
36
36
|
"lib/ruco/history.rb",
|
37
37
|
"lib/ruco/keyboard.rb",
|
38
|
+
"lib/ruco/option_accessor.rb",
|
38
39
|
"lib/ruco/position.rb",
|
39
40
|
"lib/ruco/status_bar.rb",
|
40
41
|
"lib/ruco/style_map.rb",
|
@@ -52,6 +53,7 @@ Gem::Specification.new do |s|
|
|
52
53
|
"spec/ruco/form_spec.rb",
|
53
54
|
"spec/ruco/history_spec.rb",
|
54
55
|
"spec/ruco/keyboard_spec.rb",
|
56
|
+
"spec/ruco/option_accessor_spec.rb",
|
55
57
|
"spec/ruco/status_bar_spec.rb",
|
56
58
|
"spec/ruco/style_map_spec.rb",
|
57
59
|
"spec/ruco/text_area_spec.rb",
|
@@ -61,7 +63,7 @@ Gem::Specification.new do |s|
|
|
61
63
|
]
|
62
64
|
s.homepage = %q{http://github.com/grosser/ruco}
|
63
65
|
s.require_paths = ["lib"]
|
64
|
-
s.rubygems_version = %q{1.
|
66
|
+
s.rubygems_version = %q{1.3.7}
|
65
67
|
s.summary = %q{Commandline editor written in ruby}
|
66
68
|
s.test_files = [
|
67
69
|
"spec/ruco/application_spec.rb",
|
@@ -73,6 +75,7 @@ Gem::Specification.new do |s|
|
|
73
75
|
"spec/ruco/form_spec.rb",
|
74
76
|
"spec/ruco/history_spec.rb",
|
75
77
|
"spec/ruco/keyboard_spec.rb",
|
78
|
+
"spec/ruco/option_accessor_spec.rb",
|
76
79
|
"spec/ruco/status_bar_spec.rb",
|
77
80
|
"spec/ruco/style_map_spec.rb",
|
78
81
|
"spec/ruco/text_area_spec.rb",
|
@@ -82,6 +85,7 @@ Gem::Specification.new do |s|
|
|
82
85
|
]
|
83
86
|
|
84
87
|
if s.respond_to? :specification_version then
|
88
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
85
89
|
s.specification_version = 3
|
86
90
|
|
87
91
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
@@ -4,10 +4,15 @@ require File.expand_path('spec/spec_helper')
|
|
4
4
|
describe Ruco::Application do
|
5
5
|
before do
|
6
6
|
`rm -rf ~/.ruco/sessions`
|
7
|
+
`rm #{rucorc} 2>&1`
|
7
8
|
@file = 'spec/temp.txt'
|
8
9
|
write('')
|
9
10
|
end
|
10
11
|
|
12
|
+
after do
|
13
|
+
`rm #{rucorc} 2>&1`
|
14
|
+
end
|
15
|
+
|
11
16
|
def write(content)
|
12
17
|
File.open(@file,'w'){|f| f.write(content) }
|
13
18
|
end
|
@@ -24,7 +29,8 @@ describe Ruco::Application do
|
|
24
29
|
keys.each{|k| app.key k }
|
25
30
|
end
|
26
31
|
|
27
|
-
let(:
|
32
|
+
let(:rucorc){ 'spec/.ruco.rb' }
|
33
|
+
let(:app){ Ruco::Application.new(@file, :lines => 5, :columns => 10, :rc => rucorc) }
|
28
34
|
let(:status){ "Ruco #{Ruco::VERSION} -- spec/temp.txt \n" }
|
29
35
|
let(:command){ "^W Exit" }
|
30
36
|
|
@@ -239,12 +245,16 @@ describe Ruco::Application do
|
|
239
245
|
editor_part(app.view).should == "a\n c\n b"
|
240
246
|
end
|
241
247
|
|
242
|
-
it "
|
248
|
+
it "indents when inside line and next line has more whitespace" do
|
243
249
|
write("ab\n b\n")
|
244
|
-
|
245
|
-
app.
|
246
|
-
|
247
|
-
|
250
|
+
type :right, :enter, 'c'
|
251
|
+
editor_part(app.view).should == "a\n cb\n b"
|
252
|
+
end
|
253
|
+
|
254
|
+
it "indents when inside indented line" do
|
255
|
+
write(" ab\nc\n")
|
256
|
+
type :right, :right, :right, :enter, 'd'
|
257
|
+
editor_part(app.view).should == " a\n db\nc"
|
248
258
|
end
|
249
259
|
|
250
260
|
it "indents when tabbing on selection" do
|
@@ -262,19 +272,27 @@ describe Ruco::Application do
|
|
262
272
|
end
|
263
273
|
|
264
274
|
describe '.ruco.rb' do
|
265
|
-
around do |block|
|
266
|
-
rucorc = File.expand_path('~/.ruco.rb')
|
267
|
-
`mv #{rucorc} #{rucorc}.backup 2>&1`
|
268
|
-
File.write(rucorc, "Ruco.configure{ bind(:'Ctrl+e'){ @editor.insert('TEST') } }")
|
269
|
-
block.call
|
270
|
-
`rm #{rucorc} && mv #{rucorc}.backup #{rucorc} 2>&1`
|
271
|
-
end
|
272
|
-
|
273
275
|
it "loads it and can use the bound keys" do
|
276
|
+
File.write(rucorc, "Ruco.configure{ bind(:'Ctrl+e'){ @editor.insert('TEST') } }")
|
274
277
|
app.view.should_not include('TEST')
|
275
278
|
app.key(:"Ctrl+e")
|
276
279
|
app.view.should include("TEST")
|
277
280
|
end
|
281
|
+
|
282
|
+
it "uses settings" do
|
283
|
+
File.write(rucorc, "Ruco.configure{ options.convert_tabs = true }")
|
284
|
+
app.options[:convert_tabs].should == true
|
285
|
+
end
|
286
|
+
|
287
|
+
it "passes settings to the window" do
|
288
|
+
File.write(rucorc, "Ruco.configure{ options.window_line_scroll_offset = 10 }")
|
289
|
+
app.send(:editor).send(:text_area).instance_eval{@window}.instance_eval{@options[:line_scroll_offset]}.should == 10
|
290
|
+
end
|
291
|
+
|
292
|
+
it "passes settings to history" do
|
293
|
+
File.write(rucorc, "Ruco.configure{ options.history_entries = 10 }")
|
294
|
+
app.send(:editor).send(:text_area).instance_eval{@history}.instance_eval{@options[:entries]}.should == 10
|
295
|
+
end
|
278
296
|
end
|
279
297
|
|
280
298
|
describe :save do
|
data/spec/ruco/editor_spec.rb
CHANGED
@@ -517,6 +517,12 @@ describe Ruco::Editor do
|
|
517
517
|
editor.view.should == " \n\n\n"
|
518
518
|
editor.cursor.should == [0,2]
|
519
519
|
end
|
520
|
+
|
521
|
+
it "keeps indentation" do
|
522
|
+
write("ab\n cd")
|
523
|
+
editor.move(:to, 1,2)
|
524
|
+
editor.insert("\n")
|
525
|
+
end
|
520
526
|
end
|
521
527
|
|
522
528
|
describe :indent do
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require File.expand_path('spec/spec_helper')
|
2
|
+
|
3
|
+
describe Ruco::OptionAccessor do
|
4
|
+
let(:options){ Ruco::OptionAccessor.new }
|
5
|
+
|
6
|
+
it "can be accessed like a hash" do
|
7
|
+
options[:xx].should == nil
|
8
|
+
options[:xx] = 1
|
9
|
+
options[:xx].should == 1
|
10
|
+
end
|
11
|
+
|
12
|
+
it "can be written" do
|
13
|
+
options.foo = true
|
14
|
+
options[:foo].should == true
|
15
|
+
end
|
16
|
+
|
17
|
+
it "can access nested keys" do
|
18
|
+
options.foo_bar = 1
|
19
|
+
options.history_size = 1
|
20
|
+
options.nested(:history).should == {:size => 1}
|
21
|
+
end
|
22
|
+
|
23
|
+
it "has empty hash for nested key" do
|
24
|
+
options.nested(:history).should == {}
|
25
|
+
end
|
26
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruco
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
4
|
+
prerelease: false
|
6
5
|
segments:
|
7
6
|
- 0
|
8
7
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
8
|
+
- 44
|
9
|
+
version: 0.0.44
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Michael Grosser
|
@@ -15,25 +14,24 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date: 2011-02-
|
17
|
+
date: 2011-02-09 00:00:00 +01:00
|
19
18
|
default_executable: ruco
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
21
|
+
name: clipboard
|
22
22
|
requirement: &id001 !ruby/object:Gem::Requirement
|
23
23
|
none: false
|
24
24
|
requirements:
|
25
25
|
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
hash: 51
|
28
27
|
segments:
|
29
28
|
- 0
|
30
29
|
- 9
|
31
30
|
- 4
|
32
31
|
version: 0.9.4
|
32
|
+
type: :runtime
|
33
33
|
prerelease: false
|
34
34
|
version_requirements: *id001
|
35
|
-
type: :runtime
|
36
|
-
name: clipboard
|
37
35
|
description:
|
38
36
|
email: michael@grosser.it
|
39
37
|
executables:
|
@@ -64,6 +62,7 @@ files:
|
|
64
62
|
- lib/ruco/form.rb
|
65
63
|
- lib/ruco/history.rb
|
66
64
|
- lib/ruco/keyboard.rb
|
65
|
+
- lib/ruco/option_accessor.rb
|
67
66
|
- lib/ruco/position.rb
|
68
67
|
- lib/ruco/status_bar.rb
|
69
68
|
- lib/ruco/style_map.rb
|
@@ -81,6 +80,7 @@ files:
|
|
81
80
|
- spec/ruco/form_spec.rb
|
82
81
|
- spec/ruco/history_spec.rb
|
83
82
|
- spec/ruco/keyboard_spec.rb
|
83
|
+
- spec/ruco/option_accessor_spec.rb
|
84
84
|
- spec/ruco/status_bar_spec.rb
|
85
85
|
- spec/ruco/style_map_spec.rb
|
86
86
|
- spec/ruco/text_area_spec.rb
|
@@ -101,7 +101,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
101
101
|
requirements:
|
102
102
|
- - ">="
|
103
103
|
- !ruby/object:Gem::Version
|
104
|
-
hash:
|
104
|
+
hash: -55157123
|
105
105
|
segments:
|
106
106
|
- 0
|
107
107
|
version: "0"
|
@@ -110,14 +110,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
110
110
|
requirements:
|
111
111
|
- - ">="
|
112
112
|
- !ruby/object:Gem::Version
|
113
|
-
hash: 3
|
114
113
|
segments:
|
115
114
|
- 0
|
116
115
|
version: "0"
|
117
116
|
requirements: []
|
118
117
|
|
119
118
|
rubyforge_project:
|
120
|
-
rubygems_version: 1.
|
119
|
+
rubygems_version: 1.3.7
|
121
120
|
signing_key:
|
122
121
|
specification_version: 3
|
123
122
|
summary: Commandline editor written in ruby
|
@@ -131,6 +130,7 @@ test_files:
|
|
131
130
|
- spec/ruco/form_spec.rb
|
132
131
|
- spec/ruco/history_spec.rb
|
133
132
|
- spec/ruco/keyboard_spec.rb
|
133
|
+
- spec/ruco/option_accessor_spec.rb
|
134
134
|
- spec/ruco/status_bar_spec.rb
|
135
135
|
- spec/ruco/style_map_spec.rb
|
136
136
|
- spec/ruco/text_area_spec.rb
|