readline-ng 0.0.5 → 0.0.6

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,6 @@
1
+ language: ruby
2
+ gemfile: Gemfile.travis
3
+ rvm:
4
+ - 1.8.7
5
+ - 1.9.2
6
+ - 1.9.3
@@ -0,0 +1,8 @@
1
+ source :rubygems
2
+
3
+ group :test do
4
+ gem "rake"
5
+ gem "rspec"
6
+ gem "mocha"
7
+ end
8
+
@@ -0,0 +1,21 @@
1
+ ## Readline ng
2
+
3
+ [![Build Status](https://secure.travis-ci.org/richoH/readline-ng.png?branch=master)](http://travis-ci.org/richoH/readline-ng)
4
+
5
+ Readline-NG is /not/ a drop in replacement for readline.
6
+
7
+ It addresses a very specific need I had inside a twitter client, but
8
+ hopefully it's of use to someone else, too.
9
+
10
+ Readline relies on being able to poll for input often, leading to a
11
+ hideously inefficient event loop, but generally
12
+ ```ruby
13
+ reader = ReadlineNG::Reader.new
14
+ loop do
15
+ reader.tick
16
+ reader.each_line do |line|
17
+ # Handle full line of input
18
+ reader.puts_above("user input #{line}")
19
+ end
20
+ end
21
+ ```
@@ -0,0 +1,9 @@
1
+ require 'rake'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec) do |t|
5
+ t.pattern = "spec/*_spec.rb"
6
+ end
7
+
8
+ desc 'Default: run specs'
9
+ task :default => :spec
@@ -2,7 +2,7 @@ module ReadlineNG
2
2
 
3
3
  VERSION_MAJOR = 0
4
4
  VERSION_MINOR = 0
5
- VERSION_PATCH = 5
5
+ VERSION_PATCH = 6
6
6
  VERSION = "#{VERSION_MAJOR}.#{VERSION_MINOR}.#{VERSION_PATCH}"
7
7
 
8
8
  CONTROL_BS = "\x08"
@@ -13,6 +13,9 @@ module ReadlineNG
13
13
  KB_BS = "\x7F"
14
14
  KB_CR = "\x0d"
15
15
 
16
+ KB_LEFT = "\x25"
17
+ KB_RIGHT = "\x27"
18
+
16
19
  BLANK = " "
17
20
 
18
21
  class Reader
@@ -23,16 +26,18 @@ module ReadlineNG
23
26
  # make a whole lot of sense, although potentially giving out rope is not a
24
27
  # terrible idea here
25
28
 
26
- attr_accessor :lines, :visible
29
+ attr_accessor :lines, :visible, :polling_resolution
27
30
 
28
31
  # A third party dev can overload filter to implement their own actions
29
32
  def filter
30
33
  end
31
34
 
32
- def initialize(visible=true)
35
+ def initialize(visible=true, opts = {})
33
36
  @buf = ""
37
+ @index = 0
34
38
  @visible = visible
35
39
  @lines = []
40
+ @polling_resolution = opts[:polling_resolution] || 20
36
41
  if @@initialized
37
42
  STDERR.puts "A ReadlineNG reader is already instanciated, expect weirdness"
38
43
  else
@@ -45,6 +50,13 @@ module ReadlineNG
45
50
  end
46
51
  end
47
52
 
53
+ def wait(n)
54
+ (n * polling_resolution).times do
55
+ tick
56
+ sleep 1.0/polling_resolution
57
+ end
58
+ end
59
+
48
60
  def puts_above(string)
49
61
  if visible
50
62
  backspace(@buf.length)
@@ -58,14 +70,6 @@ module ReadlineNG
58
70
  t = STDIN.read_nonblock(128)
59
71
  t.each_char { |c| process(c) }
60
72
  filter # Expect a 3rd party dev to override this
61
-
62
- raise Interrupt if @buf.include?(CONTROL_INT)
63
-
64
- a = @buf.split("\r")
65
- return if a.empty? && @buf.empty?
66
- @buf = @buf[-1] == "\r" ? "" : a.pop
67
-
68
- @lines += a
69
73
  rescue Errno::EAGAIN
70
74
  nil
71
75
  end
@@ -87,16 +91,48 @@ module ReadlineNG
87
91
  private
88
92
 
89
93
  def process(c)
94
+ # TODO This method is getting monolithic, think about how to modularise it
90
95
  case c
96
+ when "\r"
97
+ @lines += [@buf]
98
+ reset
99
+ when CONTROL_INT
100
+ raise Interrupt
91
101
  when KB_BS
92
- @buf.chop!
93
- backspace
102
+ if @buf.chop!
103
+ @index -= 1
104
+ backspace
105
+ end
106
+ when KB_LEFT
107
+ if @buf and @index != 0
108
+ @index -= 1
109
+ end
110
+ when KB_RIGHT
111
+ if @buf and @index < @buf.length
112
+ @index -= 1
113
+ end
94
114
  else
95
- @buf += c
96
- _print c
115
+ @buf = @buf.insert(@index, c)
116
+ @index += 1
117
+ if @index == @buf.length
118
+ _print c
119
+ else
120
+ redraw
121
+ end
97
122
  end
98
123
  end
99
124
 
125
+ def reset
126
+ @index, @buf = 0, ""
127
+ end
128
+
129
+ def redraw
130
+ # TODO We can get away with only going back as far as index, I should
131
+ # think
132
+ backspace(@buf.length)
133
+ _print @buf
134
+ end
135
+
100
136
  def backspace(n=1)
101
137
  _print CONTROL_BS*n,BLANK*n,CONTROL_BS*n
102
138
  end
@@ -118,8 +154,6 @@ module ReadlineNG
118
154
  `stty #{@stty_saved}`
119
155
  end
120
156
 
121
-
122
-
123
157
  end
124
158
  end
125
159
 
@@ -12,6 +12,8 @@ Gem::Specification.new do |s|
12
12
  s.description = s.summary
13
13
 
14
14
  s.add_development_dependency 'rspec'
15
+ s.add_development_dependency 'mocha'
16
+ s.add_development_dependency 'rake'
15
17
 
16
18
  s.files = `git ls-files`.split("\n")
17
19
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
@@ -58,5 +58,25 @@ describe ReadlineNG do
58
58
  @reader.get_line.should == "input"
59
59
  end
60
60
 
61
+ it "should respect the left key" do
62
+ STDIN.stub(:read_nonblock).and_return("asdf", "\x25"*2, "__\r")
63
+ @reader.get_line.should == "as__df"
64
+ end
65
+
66
+ it "should not allow the user to left before an empty buffer" do
67
+ STDIN.stub(:read_nonblock).and_return("\x25"*2, "__", "\x25"*2, "\r")
68
+ @reader.get_line.should == "__"
69
+ end
70
+
71
+ it "should respect the right key" do
72
+ STDIN.stub(:read_nonblock).and_return("asdf", "\x25"*2, "__", "\x27", "++\r" )
73
+ @reader.get_line.should == "as_++_df"
74
+ end
75
+
76
+ it "should not allow the user to right after an empty buffer" do
77
+ STDIN.stub(:read_nonblock).and_return("\x27"*2, "__", "\x27"*2, "\r")
78
+ @reader.get_line.should == "__"
79
+ end
80
+
61
81
  end
62
82
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: readline-ng
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
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-02-22 00:00:00.000000000 Z
12
+ date: 2012-03-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &7211240 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,44 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *7211240
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: mocha
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
25
62
  description: Essentially, readline++
26
63
  email:
27
64
  - richo@psych0tik.net
@@ -30,8 +67,11 @@ extensions: []
30
67
  extra_rdoc_files: []
31
68
  files:
32
69
  - .rvmrc
70
+ - .travis.yml
33
71
  - Gemfile
34
- - README
72
+ - Gemfile.travis
73
+ - README.md
74
+ - Rakefile
35
75
  - lib/readline-ng.rb
36
76
  - readline-ng.gemspec
37
77
  - spec/readline-ng_spec.rb
@@ -55,7 +95,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
55
95
  version: '0'
56
96
  requirements: []
57
97
  rubyforge_project:
58
- rubygems_version: 1.8.16
98
+ rubygems_version: 1.8.19
59
99
  signing_key:
60
100
  specification_version: 3
61
101
  summary: Essentially, readline++
data/README DELETED
@@ -1,16 +0,0 @@
1
- Readline-NG is /not/ a drop in replacement for readline.
2
-
3
- It addresses a very specific need I had inside a twitter client, but
4
- hopefully it's of use to someone else, too.
5
-
6
- Readline relies on being able to poll for input often, leading to a
7
- hideously inefficient event loop, but generally
8
-
9
- reader = ReadlineNG::Reader.new
10
- loop do
11
- reader.tick
12
- reader.each_line do |line|
13
- # Handle full line of input
14
- reader.puts_above("user input #{line}")
15
- end
16
- end