coolline 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/coolline.rb +2 -0
- data/lib/coolline/ansi.rb +98 -0
- data/lib/coolline/coolline.rb +66 -69
- data/lib/coolline/editor.rb +6 -0
- data/lib/coolline/menu.rb +107 -0
- data/lib/coolline/version.rb +1 -1
- data/repl.rb +1 -1
- data/test/editor_test.rb +49 -0
- metadata +16 -9
data/lib/coolline.rb
CHANGED
@@ -0,0 +1,98 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
class Coolline
|
4
|
+
# Mixin that allows to manipulate strings that contain ANSI color codes:
|
5
|
+
# getting their length, printing their n first characters, etc.
|
6
|
+
#
|
7
|
+
# Additionally, it can output certain commonly needed sequences — using the
|
8
|
+
# {#print} method to write to the output.
|
9
|
+
module ANSI
|
10
|
+
Code = %r{(\e\[\??\d+(?:[;\d]*)\w)}
|
11
|
+
|
12
|
+
# @return [Integer] Amount of characters within the string, disregarding
|
13
|
+
# color codes.
|
14
|
+
def ansi_length(string)
|
15
|
+
strip_ansi_codes(string).length
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return [String] The initial string without ANSI codes.
|
19
|
+
def strip_ansi_codes(string)
|
20
|
+
string.gsub(Code, "")
|
21
|
+
end
|
22
|
+
|
23
|
+
# @return [Boolean] True if the beginning of the string is an ANSI code.
|
24
|
+
def start_with_ansi_code?(string)
|
25
|
+
(string =~ Code) == 0
|
26
|
+
end
|
27
|
+
|
28
|
+
# Prints a slice of a string containing ANSI color codes. This allows to
|
29
|
+
# print a string of a fixed width, while still keeping the right colors,
|
30
|
+
# etc.
|
31
|
+
#
|
32
|
+
# @param [String] string
|
33
|
+
# @param [Integer] start
|
34
|
+
# @param [Integer] stop Stop index, excluded from the range.
|
35
|
+
def ansi_print(string, start, stop)
|
36
|
+
i = 0
|
37
|
+
string.split(Code).each do |str|
|
38
|
+
if start_with_ansi_code? str
|
39
|
+
print str
|
40
|
+
else
|
41
|
+
if i >= start
|
42
|
+
print str[0..(stop - i - 1)]
|
43
|
+
elsif i < start && i + str.size >= start
|
44
|
+
print str[(start - i), stop - start - 1]
|
45
|
+
end
|
46
|
+
|
47
|
+
i += str.size
|
48
|
+
break if i >= stop
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Clears the current line and resets the select graphics settings.
|
54
|
+
def reset_line
|
55
|
+
print "\r\e[0m\e[0K"
|
56
|
+
end
|
57
|
+
|
58
|
+
# Clears the screen and moves the cursor to the top-left corner.
|
59
|
+
def clear_screen
|
60
|
+
print "\e[2J"
|
61
|
+
go_to(1, 1)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Moves the cursor to (x, y), where x is the colmun and y the line
|
65
|
+
# number. Both are 1-indexed. The origin is the top-left corner.
|
66
|
+
#
|
67
|
+
# @param [Integer] x
|
68
|
+
# @param [Integer] y
|
69
|
+
def go_to(x, y)
|
70
|
+
print "\e[#{y};#{x}H"
|
71
|
+
end
|
72
|
+
|
73
|
+
# Moves the cursor to the given (1-indexed) column number.
|
74
|
+
def go_to_col(x)
|
75
|
+
print "\e[#{x}G"
|
76
|
+
end
|
77
|
+
|
78
|
+
# Resets the current ansi color codes.
|
79
|
+
def reset_color
|
80
|
+
print "\e[0m"
|
81
|
+
end
|
82
|
+
|
83
|
+
# Erases the current line.
|
84
|
+
def erase_line
|
85
|
+
print "\e[0K"
|
86
|
+
end
|
87
|
+
|
88
|
+
# Moves to the beginning of the next line.
|
89
|
+
def go_to_next_line
|
90
|
+
print "\e[E"
|
91
|
+
end
|
92
|
+
|
93
|
+
# Moves to the beginning of the previous line.
|
94
|
+
def go_to_previous_line
|
95
|
+
print "\e[F"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
data/lib/coolline/coolline.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'io/console'
|
2
2
|
|
3
3
|
class Coolline
|
4
|
+
include ANSI
|
5
|
+
|
4
6
|
if config_home = ENV["XDG_CONFIG_HOME"] and !config_home.empty?
|
5
7
|
ConfigDir = File.join(config_home, "coolline")
|
6
8
|
else
|
@@ -22,8 +24,6 @@ class Coolline
|
|
22
24
|
"/dev/null"
|
23
25
|
end
|
24
26
|
|
25
|
-
AnsiCode = %r{(\e\[\??\d+(?:[;\d]*)\w)}
|
26
|
-
|
27
27
|
# @return [Hash] All the defaults settings
|
28
28
|
Settings = {
|
29
29
|
:word_boundaries => [" ", "-", "_"],
|
@@ -34,7 +34,7 @@ class Coolline
|
|
34
34
|
Handler.new(?\C-a, &:beginning_of_line),
|
35
35
|
Handler.new(?\C-e, &:end_of_line),
|
36
36
|
Handler.new(?\C-k, &:kill_line),
|
37
|
-
Handler.new(?\C-u, &:
|
37
|
+
Handler.new(?\C-u, &:kill_beginning_of_line),
|
38
38
|
Handler.new(?\C-f, &:forward_char),
|
39
39
|
Handler.new(?\C-b, &:backward_char),
|
40
40
|
Handler.new(?\C-d, &:kill_current_char_or_leave),
|
@@ -73,7 +73,7 @@ class Coolline
|
|
73
73
|
],
|
74
74
|
|
75
75
|
:unknown_char_proc => :insert_string.to_proc,
|
76
|
-
:transform_proc =>
|
76
|
+
:transform_proc => proc { |line| line },
|
77
77
|
:completion_proc => proc { |cool| [] },
|
78
78
|
|
79
79
|
:history_file => HistoryFile,
|
@@ -127,6 +127,8 @@ class Coolline
|
|
127
127
|
yield self if block_given?
|
128
128
|
|
129
129
|
@history ||= History.new(@history_file, @history_size)
|
130
|
+
|
131
|
+
@menu = Menu.new(@input, @output)
|
130
132
|
end
|
131
133
|
|
132
134
|
# @return [IO]
|
@@ -173,6 +175,9 @@ class Coolline
|
|
173
175
|
# @return [String] Current prompt
|
174
176
|
attr_accessor :prompt
|
175
177
|
|
178
|
+
# @return [Menu]
|
179
|
+
attr_accessor :menu
|
180
|
+
|
176
181
|
# Reads a line from the terminal
|
177
182
|
# @param [String] prompt Characters to print before each line
|
178
183
|
def readline(prompt = ">> ")
|
@@ -188,13 +193,15 @@ class Coolline
|
|
188
193
|
|
189
194
|
@should_exit = false
|
190
195
|
|
191
|
-
|
196
|
+
reset_line
|
192
197
|
print @prompt
|
193
198
|
|
194
199
|
@history.index = @history.size - 1
|
195
200
|
@history << @line
|
196
201
|
|
197
202
|
until (char = @input.getch) == "\r"
|
203
|
+
@menu.erase
|
204
|
+
|
198
205
|
handle(char)
|
199
206
|
return if @should_exit
|
200
207
|
|
@@ -202,49 +209,11 @@ class Coolline
|
|
202
209
|
@history_moved = false
|
203
210
|
end
|
204
211
|
|
205
|
-
|
206
|
-
prompt_size = strip_ansi_codes(@prompt).size
|
207
|
-
line = transform(@line)
|
208
|
-
|
209
|
-
stripped_line_width = strip_ansi_codes(line).size
|
210
|
-
line << " " * [width - stripped_line_width - prompt_size, 0].max
|
211
|
-
|
212
|
-
# reset the color, and kill the line
|
213
|
-
print "\r\e[0m\e[0K"
|
214
|
-
|
215
|
-
if strip_ansi_codes(@prompt + line).size <= width
|
216
|
-
print @prompt + line
|
217
|
-
print "\e[#{prompt_size + @pos + 1}G"
|
218
|
-
else
|
219
|
-
print @prompt
|
220
|
-
|
221
|
-
left_width = width - prompt_size
|
222
|
-
|
223
|
-
start_index = [@pos - left_width + 1, 0].max
|
224
|
-
end_index = start_index + left_width - 1
|
225
|
-
|
226
|
-
i = 0
|
227
|
-
line.split(AnsiCode).each do |str|
|
228
|
-
if start_with_ansi_code? str
|
229
|
-
# always print ansi codes to ensure the color is right
|
230
|
-
print str
|
231
|
-
else
|
232
|
-
if i >= start_index
|
233
|
-
print str[0..(end_index - i)]
|
234
|
-
elsif i < start_index && i + str.size >= start_index
|
235
|
-
print str[(start_index - i), left_width]
|
236
|
-
end
|
237
|
-
|
238
|
-
i += str.size
|
239
|
-
break if i >= end_index
|
240
|
-
end
|
241
|
-
end
|
242
|
-
if @pos < left_width + 1
|
243
|
-
print "\e[#{prompt_size + @pos + 1}G"
|
244
|
-
end
|
245
|
-
end
|
212
|
+
render
|
246
213
|
end
|
247
214
|
|
215
|
+
@menu.erase
|
216
|
+
|
248
217
|
print "\n"
|
249
218
|
|
250
219
|
@history[-1] = @line if @history.size != 0
|
@@ -252,7 +221,35 @@ class Coolline
|
|
252
221
|
|
253
222
|
@history.save_line
|
254
223
|
|
255
|
-
@line
|
224
|
+
@line
|
225
|
+
end
|
226
|
+
|
227
|
+
# Displays the current code on the terminal
|
228
|
+
def render
|
229
|
+
width = @input.winsize[1]
|
230
|
+
prompt_size = ansi_length(@prompt)
|
231
|
+
line = transform(@line)
|
232
|
+
|
233
|
+
stripped_line_width = ansi_length(line)
|
234
|
+
line += " " * [width - stripped_line_width - prompt_size, 0].max
|
235
|
+
|
236
|
+
reset_line
|
237
|
+
|
238
|
+
if ansi_length(@prompt + line) <= width
|
239
|
+
print @prompt + line
|
240
|
+
else
|
241
|
+
print @prompt
|
242
|
+
|
243
|
+
left_width = width - prompt_size
|
244
|
+
|
245
|
+
start_index = [@pos - left_width + 1, 0].max
|
246
|
+
end_index = start_index + left_width
|
247
|
+
|
248
|
+
ansi_print(line, start_index, end_index)
|
249
|
+
end
|
250
|
+
|
251
|
+
@menu.display
|
252
|
+
go_to_col [prompt_size + @pos + 1, width].min
|
256
253
|
end
|
257
254
|
|
258
255
|
# Reads a line with no prompt
|
@@ -367,40 +364,40 @@ class Coolline
|
|
367
364
|
line[word_beginning_before(pos)...pos]
|
368
365
|
end
|
369
366
|
|
370
|
-
#
|
371
|
-
def
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
367
|
+
# Sets the word at point, and moves the cursor to after the end of said word.
|
368
|
+
def completed_word=(string)
|
369
|
+
beg = word_beginning_before(pos)
|
370
|
+
line[beg...pos] = string
|
371
|
+
self.pos = beg + string.size
|
372
|
+
end
|
376
373
|
|
377
|
-
|
374
|
+
# @param [Array<String>] candidates
|
375
|
+
# @return [String] The common part between all completion candidates
|
376
|
+
def common_beginning(candidates)
|
377
|
+
candidates.inject do |common, el|
|
378
378
|
i = 0
|
379
379
|
i += 1 while common[i] == el[i]
|
380
380
|
|
381
381
|
el[0...i]
|
382
382
|
end
|
383
|
-
|
384
|
-
beg = word_beginning_before(pos)
|
385
|
-
line[beg...pos] = result
|
386
|
-
self.pos = beg + result.size
|
387
383
|
end
|
388
384
|
|
389
|
-
|
390
|
-
|
391
|
-
|
385
|
+
# Tries to complete the current word
|
386
|
+
def complete
|
387
|
+
return if word_boundary? line[pos - 1]
|
392
388
|
|
393
|
-
|
394
|
-
string.gsub(AnsiCode, "")
|
395
|
-
end
|
389
|
+
completions = @completion_proc.call(self)
|
396
390
|
|
397
|
-
|
398
|
-
|
391
|
+
if completions.empty?
|
392
|
+
menu.string = "(No completions found)"
|
393
|
+
else
|
394
|
+
menu.list = completions
|
395
|
+
self.completed_word = common_beginning(completions)
|
396
|
+
end
|
399
397
|
end
|
400
398
|
|
401
|
-
def
|
402
|
-
|
403
|
-
print "\e[0;0H" # goto 0, 0
|
399
|
+
def word_boundary?(char)
|
400
|
+
char =~ word_boundaries_regexp
|
404
401
|
end
|
405
402
|
|
406
403
|
private
|
data/lib/coolline/editor.rb
CHANGED
@@ -128,6 +128,12 @@ class Coolline
|
|
128
128
|
line[pos..-1] = ""
|
129
129
|
end
|
130
130
|
|
131
|
+
# Removes everything up to the current character
|
132
|
+
def kill_beginning_of_line
|
133
|
+
line[0...pos] = ""
|
134
|
+
self.pos = 0
|
135
|
+
end
|
136
|
+
|
131
137
|
# Removes all the characters in the line
|
132
138
|
def clear_line
|
133
139
|
line.clear
|
@@ -0,0 +1,107 @@
|
|
1
|
+
class Coolline
|
2
|
+
# A menu allows to display some information on a rectangle below the cursor.
|
3
|
+
#
|
4
|
+
# It displays a string or a list of strings until the user presses another
|
5
|
+
# key.
|
6
|
+
class Menu
|
7
|
+
include ANSI
|
8
|
+
|
9
|
+
def initialize(input, output)
|
10
|
+
@input = input
|
11
|
+
@output = output
|
12
|
+
|
13
|
+
@string = ""
|
14
|
+
|
15
|
+
@last_line_count = 0
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return [String] Information to be displayed
|
19
|
+
attr_accessor :string
|
20
|
+
|
21
|
+
# Sets the menu's string to a list of items, formatted in columns.
|
22
|
+
#
|
23
|
+
# @param [Array<String>] items
|
24
|
+
def list=(items)
|
25
|
+
if items.empty?
|
26
|
+
self.string = ""
|
27
|
+
else
|
28
|
+
height, width = @input.winsize
|
29
|
+
|
30
|
+
col_width = items.map { |s| ansi_length(s) }.max
|
31
|
+
col_count = width / col_width
|
32
|
+
item_count = col_count * (height - 1)
|
33
|
+
|
34
|
+
self.string = format_columns(items[0, item_count], col_count, col_width)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Renders the menu below the current line.
|
39
|
+
#
|
40
|
+
# This will ensure not to draw to much, so that the line currently being
|
41
|
+
# edited will always stay visible.
|
42
|
+
#
|
43
|
+
# Once the menu is drawn, the cursor returns to the correct line.
|
44
|
+
def display
|
45
|
+
# An empty string shouldn't be treated like a 1-line string.
|
46
|
+
return if @string.empty?
|
47
|
+
|
48
|
+
height, width = @input.winsize
|
49
|
+
|
50
|
+
lines = @string.lines.to_a
|
51
|
+
|
52
|
+
lines[0, height - 1].each do |line|
|
53
|
+
print "\n\r"
|
54
|
+
ansi_print(line.chomp, 0, width)
|
55
|
+
end
|
56
|
+
reset_color
|
57
|
+
|
58
|
+
[lines.size, height].min.times { go_to_previous_line }
|
59
|
+
|
60
|
+
@last_line_count = [height - 1, lines.size].min
|
61
|
+
end
|
62
|
+
|
63
|
+
# Erases anything that had been written by the menu.
|
64
|
+
#
|
65
|
+
# This allows to hide the menu once it is no longer relevant.
|
66
|
+
#
|
67
|
+
# Notice it can only work by knowing how many lines the menu drew on the
|
68
|
+
# screen last time it was called, and assuming the terminal size didn't
|
69
|
+
# change.
|
70
|
+
def erase
|
71
|
+
return if @last_line_count.zero?
|
72
|
+
|
73
|
+
self.string = ""
|
74
|
+
|
75
|
+
@last_line_count.times do
|
76
|
+
go_to_next_line
|
77
|
+
erase_line
|
78
|
+
end
|
79
|
+
reset_color
|
80
|
+
|
81
|
+
@last_line_count.times { go_to_previous_line }
|
82
|
+
|
83
|
+
@last_line_count = 0
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
# @param [Array<String>] items Items to show
|
89
|
+
# @param [Integer] col_count Amount of columns to show
|
90
|
+
# @param [Integer] col_width Width of each column
|
91
|
+
#
|
92
|
+
# @return [String] Items formatted appropriately
|
93
|
+
def format_columns(items, col_count, col_width)
|
94
|
+
string = ""
|
95
|
+
|
96
|
+
items.each_slice(col_count) do |line|
|
97
|
+
string << line.map { |s| s.ljust(col_width - 1) } * " " << "\n"
|
98
|
+
end
|
99
|
+
|
100
|
+
string
|
101
|
+
end
|
102
|
+
|
103
|
+
def print(*objs)
|
104
|
+
@output.print(*objs)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
data/lib/coolline/version.rb
CHANGED
data/repl.rb
CHANGED
data/test/editor_test.rb
CHANGED
@@ -63,6 +63,13 @@ context "editor of an empty line" do
|
|
63
63
|
asserts(:line).equals ""
|
64
64
|
end
|
65
65
|
|
66
|
+
context "after killing the beginning of the line" do
|
67
|
+
hookup { topic.kill_beginning_of_line }
|
68
|
+
|
69
|
+
asserts(:pos).equals 0
|
70
|
+
asserts(:line).equals ""
|
71
|
+
end
|
72
|
+
|
66
73
|
context "after transposing words" do
|
67
74
|
hookup { topic.transpose_words }
|
68
75
|
|
@@ -142,6 +149,13 @@ context "editor before many words" do
|
|
142
149
|
asserts(:line).equals ""
|
143
150
|
end
|
144
151
|
|
152
|
+
context "after killing the beginning of the line" do
|
153
|
+
hookup { topic.kill_beginning_of_line }
|
154
|
+
|
155
|
+
asserts(:pos).equals 0
|
156
|
+
asserts(:line).equals "a lovely dragon"
|
157
|
+
end
|
158
|
+
|
145
159
|
context "after transposing words" do
|
146
160
|
hookup { topic.transpose_words }
|
147
161
|
|
@@ -216,6 +230,13 @@ context "editor between two words" do
|
|
216
230
|
asserts(:line).equals "foo "
|
217
231
|
end
|
218
232
|
|
233
|
+
context "after killing the beginning of the line" do
|
234
|
+
hookup { topic.kill_beginning_of_line }
|
235
|
+
|
236
|
+
asserts(:pos).equals 0
|
237
|
+
asserts(:line).equals " bar"
|
238
|
+
end
|
239
|
+
|
219
240
|
context "after transposing words" do
|
220
241
|
hookup { topic.transpose_words }
|
221
242
|
|
@@ -318,6 +339,13 @@ context "editor between two out of three words" do
|
|
318
339
|
asserts(:line).equals "foo bar"
|
319
340
|
end
|
320
341
|
|
342
|
+
context "after killing the beginning of the line" do
|
343
|
+
hookup { topic.kill_beginning_of_line }
|
344
|
+
|
345
|
+
asserts(:pos).equals 0
|
346
|
+
asserts(:line).equals " baz"
|
347
|
+
end
|
348
|
+
|
321
349
|
context "after transposing words" do
|
322
350
|
hookup { topic.transpose_words }
|
323
351
|
|
@@ -425,6 +453,13 @@ context "editor at the end of a line" do
|
|
425
453
|
asserts(:line).equals "a lovely dragon"
|
426
454
|
end
|
427
455
|
|
456
|
+
context "after killing the beginning of the line" do
|
457
|
+
hookup { topic.kill_beginning_of_line }
|
458
|
+
|
459
|
+
asserts(:pos).equals 0
|
460
|
+
asserts(:line).equals ""
|
461
|
+
end
|
462
|
+
|
428
463
|
context "after transposing words" do
|
429
464
|
hookup { topic.transpose_words }
|
430
465
|
|
@@ -537,6 +572,13 @@ context "editor in the middle of a sentence" do
|
|
537
572
|
asserts(:line).equals "foo bar "
|
538
573
|
end
|
539
574
|
|
575
|
+
context "after killing the beginning of the line" do
|
576
|
+
hookup { topic.kill_beginning_of_line }
|
577
|
+
|
578
|
+
asserts(:pos).equals 0
|
579
|
+
asserts(:line).equals "baz qux"
|
580
|
+
end
|
581
|
+
|
540
582
|
context "after transposing words" do
|
541
583
|
hookup { topic.transpose_words }
|
542
584
|
|
@@ -649,6 +691,13 @@ context "editor in the middle of a word" do
|
|
649
691
|
asserts(:line).equals "foo bar b"
|
650
692
|
end
|
651
693
|
|
694
|
+
context "after killing the beginning of the line" do
|
695
|
+
hookup { topic.kill_beginning_of_line }
|
696
|
+
|
697
|
+
asserts(:pos).equals 0
|
698
|
+
asserts(:line).equals "az qux"
|
699
|
+
end
|
700
|
+
|
652
701
|
context "after transposing words" do
|
653
702
|
hookup { topic.transpose_words }
|
654
703
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: coolline
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-12-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: riot
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,12 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
25
30
|
description: ! 'A readline-like library that allows to change how the input
|
26
31
|
|
27
32
|
is displayed.
|
@@ -32,17 +37,19 @@ executables: []
|
|
32
37
|
extensions: []
|
33
38
|
extra_rdoc_files: []
|
34
39
|
files:
|
40
|
+
- lib/coolline/editor.rb
|
41
|
+
- lib/coolline/ansi.rb
|
42
|
+
- lib/coolline/version.rb
|
43
|
+
- lib/coolline/menu.rb
|
35
44
|
- lib/coolline/handler.rb
|
36
45
|
- lib/coolline/history.rb
|
37
|
-
- lib/coolline/editor.rb
|
38
46
|
- lib/coolline/coolline.rb
|
39
|
-
- lib/coolline/version.rb
|
40
47
|
- lib/coolline.rb
|
41
48
|
- test/helpers.rb
|
42
|
-
- test/editor_test.rb
|
43
49
|
- test/coolline_test.rb
|
44
|
-
- test/run_all.rb
|
45
50
|
- test/history_test.rb
|
51
|
+
- test/editor_test.rb
|
52
|
+
- test/run_all.rb
|
46
53
|
- repl.rb
|
47
54
|
- .gemtest
|
48
55
|
homepage: http://github.com/Mon-Ouie/coolline
|
@@ -65,7 +72,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
65
72
|
version: '0'
|
66
73
|
requirements: []
|
67
74
|
rubyforge_project:
|
68
|
-
rubygems_version: 1.8.
|
75
|
+
rubygems_version: 1.8.23
|
69
76
|
signing_key:
|
70
77
|
specification_version: 3
|
71
78
|
summary: Sounds like readline, smells like readline, but isn't readline
|