coolline 0.4.0 → 0.4.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.
- checksums.yaml +7 -0
- data/README.md +84 -0
- data/lib/coolline/coolline.rb +37 -16
- data/lib/coolline/editor.rb +9 -0
- data/lib/coolline/history.rb +2 -2
- data/lib/coolline/menu.rb +7 -2
- data/lib/coolline/version.rb +1 -1
- metadata +14 -18
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a631331d045151d7db8be33880ea8413a598baa6
|
4
|
+
data.tar.gz: 942e4f6bb3305e997484937c5e609a59527c8fae
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cbe233557703c272040dda7fe812792e19f5202f80a1853737e0b2909df6c575125a9ba02a0258fe0ee71f550c9b2f3c23bfd13ac242e1e1dccfd3eb684ceb31
|
7
|
+
data.tar.gz: 32223264af4ad742569de556e23881229daf728845da0333240363a169644caac0de66a0f51b29a29cacca87569d2d5b9839b1d18329248e0ffadbbb98abd08e
|
data/README.md
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
Coolline
|
2
|
+
========
|
3
|
+
|
4
|
+
Coolline is a readline-like library written in pure Ruby.
|
5
|
+
|
6
|
+
It offers all of the core readline features, but with a cleaner, simpler
|
7
|
+
implementation, and the ability to easily customize its behaviour.
|
8
|
+
|
9
|
+
Customizations include: modifying all key bindings, binding keys custom functions,
|
10
|
+
full control over history and tab completion, and control over what's displayed
|
11
|
+
to the user (transforms).
|
12
|
+
|
13
|
+
Usage
|
14
|
+
=====
|
15
|
+
|
16
|
+
If you don't need anything fancy, it can work like Ruby's built-in `Readline.readline`:
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
result = Coolline.readline
|
20
|
+
```
|
21
|
+
|
22
|
+
But, of course you want something fancy, otherwise you'd be using `readline`!
|
23
|
+
Here's how to create a simple REPL with live syntax highlighting and tab completion:
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
require 'coolline'
|
27
|
+
require 'coderay'
|
28
|
+
require 'pp'
|
29
|
+
|
30
|
+
cool = Coolline.new do |c|
|
31
|
+
|
32
|
+
# Before the line is displayed, it gets passed through this proc,
|
33
|
+
# which performs syntax highlighting.
|
34
|
+
c.transform_proc = proc do
|
35
|
+
CodeRay.scan(c.line, :ruby).term
|
36
|
+
end
|
37
|
+
|
38
|
+
# Add tab completion for constants (and classes)
|
39
|
+
c.completion_proc = proc do
|
40
|
+
word = c.completed_word
|
41
|
+
Object.constants.map(&:to_s).select { |w| w.start_with? word }
|
42
|
+
end
|
43
|
+
|
44
|
+
# Alt-R should reverse the line, because we like to look at our code in the mirror
|
45
|
+
c.bind "\er" do |cool|
|
46
|
+
cool.line.reverse!
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
loop do
|
52
|
+
# READ
|
53
|
+
line = cool.readline
|
54
|
+
|
55
|
+
# EVAL
|
56
|
+
obj = eval(line)
|
57
|
+
|
58
|
+
# PRINT
|
59
|
+
print "=> "
|
60
|
+
pp obj
|
61
|
+
|
62
|
+
# LOOP
|
63
|
+
end
|
64
|
+
```
|
65
|
+
|
66
|
+
Configuration
|
67
|
+
=============
|
68
|
+
|
69
|
+
Coolline automatically loads a config file before starting, which allows adding
|
70
|
+
new key bindings to it. The file is just a chunk of arbitrary ruby code located
|
71
|
+
at ``$XDG_CONFIG_HOME/coolline/coolline.rb``.
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
Coolline.bind "\C-z" do |cool|
|
75
|
+
puts "Testing key binding with #{cool}!"
|
76
|
+
end
|
77
|
+
```
|
78
|
+
|
79
|
+
Installation
|
80
|
+
============
|
81
|
+
|
82
|
+
gem install coolline
|
83
|
+
|
84
|
+
Note: If your Ruby version is less than 1.9.3, you also need to install the `io-console` gem.
|
data/lib/coolline/coolline.rb
CHANGED
@@ -62,6 +62,9 @@ class Coolline
|
|
62
62
|
Handler.new("\e[D", &:backward_char),
|
63
63
|
Handler.new("\e[F", &:end_of_line),
|
64
64
|
Handler.new("\e[H", &:beginning_of_line),
|
65
|
+
Handler.new("\eOH", &:beginning_of_line),
|
66
|
+
Handler.new("\eOF", &:end_of_line),
|
67
|
+
Handler.new("\ed", &:kill_forward_word),
|
65
68
|
Handler.new("\et", &:transpose_words),
|
66
69
|
Handler.new("\ec", &:capitalize_word),
|
67
70
|
Handler.new("\eu", &:uppercase_word),
|
@@ -107,6 +110,10 @@ class Coolline
|
|
107
110
|
Coolline::Settings[:handlers].unshift Coolline::Handler.new(key, &action)
|
108
111
|
end
|
109
112
|
|
113
|
+
def bind(key, &action)
|
114
|
+
handlers.unshift Coolline::Handler.new(key, &action)
|
115
|
+
end
|
116
|
+
|
110
117
|
# Creates a new cool line.
|
111
118
|
#
|
112
119
|
# @yieldparam [Coolline] self
|
@@ -178,38 +185,44 @@ class Coolline
|
|
178
185
|
# @return [Menu]
|
179
186
|
attr_accessor :menu
|
180
187
|
|
188
|
+
# Perform a quick, one-off readline (equivalent to `Coolline.new.readline(...)`)
|
189
|
+
def self.readline(*args)
|
190
|
+
new.readline(*args)
|
191
|
+
end
|
192
|
+
|
181
193
|
# Reads a line from the terminal
|
182
194
|
# @param [String] prompt Characters to print before each line
|
183
|
-
def readline(prompt = ">> ")
|
195
|
+
def readline(prompt = ">> ", default_line = "")
|
184
196
|
@prompt = prompt
|
185
197
|
|
186
198
|
@history.delete_empty
|
187
199
|
|
188
|
-
@
|
189
|
-
@pos = 0
|
190
|
-
@accumulator = nil
|
191
|
-
|
200
|
+
@accumulator = nil
|
192
201
|
@history_moved = false
|
202
|
+
@should_exit = false
|
193
203
|
|
194
|
-
|
204
|
+
self.line = default_line
|
195
205
|
|
196
|
-
|
197
|
-
print @prompt
|
206
|
+
render
|
198
207
|
|
199
208
|
@history.index = @history.size - 1
|
200
209
|
@history << @line
|
201
210
|
|
202
|
-
|
203
|
-
@menu.erase
|
211
|
+
@input.raw do |raw_stdin|
|
204
212
|
|
205
|
-
|
206
|
-
|
213
|
+
until (char = raw_stdin.read 1) == "\r"
|
214
|
+
@menu.erase
|
207
215
|
|
208
|
-
|
209
|
-
|
216
|
+
handle(char)
|
217
|
+
return if @should_exit
|
218
|
+
|
219
|
+
if @history_moved
|
220
|
+
@history_moved = false
|
221
|
+
end
|
222
|
+
|
223
|
+
render
|
210
224
|
end
|
211
225
|
|
212
|
-
render
|
213
226
|
end
|
214
227
|
|
215
228
|
@menu.erase
|
@@ -400,6 +413,13 @@ class Coolline
|
|
400
413
|
char =~ word_boundaries_regexp
|
401
414
|
end
|
402
415
|
|
416
|
+
def line=(new_line)
|
417
|
+
@line = new_line.dup
|
418
|
+
@pos = new_line.size
|
419
|
+
|
420
|
+
render
|
421
|
+
end
|
422
|
+
|
403
423
|
private
|
404
424
|
def transform(line)
|
405
425
|
@transform_proc.call(line)
|
@@ -427,7 +447,8 @@ class Coolline
|
|
427
447
|
def handle_escape(char)
|
428
448
|
if char == "[" && @accumulator =~ /\A\e?\e\z/ or
|
429
449
|
char =~ /\d/ && @accumulator =~ /\A\e?\e\[\d*\z/ or
|
430
|
-
char == "\e" && @accumulator == "\e"
|
450
|
+
char == "\e" && @accumulator == "\e" or
|
451
|
+
char == "O" && @accumulator == "\e"
|
431
452
|
@accumulator << char
|
432
453
|
nil
|
433
454
|
else
|
data/lib/coolline/editor.rb
CHANGED
@@ -110,6 +110,15 @@ class Coolline
|
|
110
110
|
end
|
111
111
|
end
|
112
112
|
|
113
|
+
# Removes the next word
|
114
|
+
def kill_forward_word
|
115
|
+
if pos != line.size
|
116
|
+
ending = word_end_after(pos)
|
117
|
+
|
118
|
+
line[pos..ending] = ""
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
113
122
|
# Removes the previous character
|
114
123
|
def kill_backward_char
|
115
124
|
if pos > 0
|
data/lib/coolline/history.rb
CHANGED
@@ -57,7 +57,7 @@ class Coolline
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def []=(id, val)
|
60
|
-
@lines[id] = val
|
60
|
+
@lines[id] = val.dup
|
61
61
|
end
|
62
62
|
|
63
63
|
def save_line
|
@@ -78,7 +78,7 @@ class Coolline
|
|
78
78
|
@io.rewind
|
79
79
|
|
80
80
|
if line_count < @max_size
|
81
|
-
@lines.concat @io.
|
81
|
+
@lines.concat @io.map(&:chomp)
|
82
82
|
else
|
83
83
|
@io.each do |line| # surely inefficient
|
84
84
|
@lines << line.chomp
|
data/lib/coolline/menu.rb
CHANGED
@@ -20,13 +20,18 @@ class Coolline
|
|
20
20
|
|
21
21
|
# Sets the menu's string to a list of items, formatted in columns.
|
22
22
|
#
|
23
|
+
# If some items are to wide to be showed, they will be excluded from the
|
24
|
+
# list.
|
25
|
+
#
|
23
26
|
# @param [Array<String>] items
|
24
27
|
def list=(items)
|
28
|
+
height, width = @input.winsize
|
29
|
+
|
30
|
+
items = items.reject { |s| ansi_length(s) > width }
|
31
|
+
|
25
32
|
if items.empty?
|
26
33
|
self.string = ""
|
27
34
|
else
|
28
|
-
height, width = @input.winsize
|
29
|
-
|
30
35
|
col_width = items.map { |s| ansi_length(s) }.max
|
31
36
|
col_count = width / col_width
|
32
37
|
item_count = col_count * (height - 1)
|
data/lib/coolline/version.rb
CHANGED
metadata
CHANGED
@@ -1,41 +1,37 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: coolline
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
5
|
-
prerelease:
|
4
|
+
version: 0.4.1
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Mon ouie
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2013-04-04 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: riot
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
|
-
description:
|
31
|
-
|
27
|
+
description: |
|
28
|
+
A readline-like library that allows to change how the input
|
32
29
|
is displayed.
|
33
|
-
|
34
|
-
'
|
35
30
|
email: mon.ouie@gmail.com
|
36
31
|
executables: []
|
37
32
|
extensions: []
|
38
|
-
extra_rdoc_files:
|
33
|
+
extra_rdoc_files:
|
34
|
+
- README.md
|
39
35
|
files:
|
40
36
|
- lib/coolline/editor.rb
|
41
37
|
- lib/coolline/ansi.rb
|
@@ -52,29 +48,29 @@ files:
|
|
52
48
|
- test/run_all.rb
|
53
49
|
- repl.rb
|
54
50
|
- .gemtest
|
51
|
+
- README.md
|
55
52
|
homepage: http://github.com/Mon-Ouie/coolline
|
56
53
|
licenses: []
|
54
|
+
metadata: {}
|
57
55
|
post_install_message:
|
58
56
|
rdoc_options: []
|
59
57
|
require_paths:
|
60
58
|
- lib
|
61
59
|
required_ruby_version: !ruby/object:Gem::Requirement
|
62
|
-
none: false
|
63
60
|
requirements:
|
64
|
-
- -
|
61
|
+
- - '>='
|
65
62
|
- !ruby/object:Gem::Version
|
66
63
|
version: '0'
|
67
64
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
|
-
none: false
|
69
65
|
requirements:
|
70
|
-
- -
|
66
|
+
- - '>='
|
71
67
|
- !ruby/object:Gem::Version
|
72
68
|
version: '0'
|
73
69
|
requirements: []
|
74
70
|
rubyforge_project:
|
75
|
-
rubygems_version:
|
71
|
+
rubygems_version: 2.0.0
|
76
72
|
signing_key:
|
77
|
-
specification_version:
|
73
|
+
specification_version: 4
|
78
74
|
summary: Sounds like readline, smells like readline, but isn't readline
|
79
75
|
test_files: []
|
80
76
|
has_rdoc:
|