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.
@@ -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
@@ -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.
@@ -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
- @line = ""
189
- @pos = 0
190
- @accumulator = nil
191
-
200
+ @accumulator = nil
192
201
  @history_moved = false
202
+ @should_exit = false
193
203
 
194
- @should_exit = false
204
+ self.line = default_line
195
205
 
196
- reset_line
197
- print @prompt
206
+ render
198
207
 
199
208
  @history.index = @history.size - 1
200
209
  @history << @line
201
210
 
202
- until (char = @input.getch) == "\r"
203
- @menu.erase
211
+ @input.raw do |raw_stdin|
204
212
 
205
- handle(char)
206
- return if @should_exit
213
+ until (char = raw_stdin.read 1) == "\r"
214
+ @menu.erase
207
215
 
208
- if @history_moved
209
- @history_moved = false
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
@@ -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
@@ -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.lines.map(&:chomp)
81
+ @lines.concat @io.map(&:chomp)
82
82
  else
83
83
  @io.each do |line| # surely inefficient
84
84
  @lines << line.chomp
@@ -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)
@@ -1,3 +1,3 @@
1
1
  class Coolline
2
- Version = "0.4.0"
2
+ Version = "0.4.1"
3
3
  end
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.0
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: 2012-12-01 00:00:00.000000000 Z
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: ! 'A readline-like library that allows to change how the input
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: 1.8.23
71
+ rubygems_version: 2.0.0
76
72
  signing_key:
77
- specification_version: 3
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: