tty-reader 0.1.0 → 0.2.0
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 +4 -4
- data/.travis.yml +5 -5
- data/CHANGELOG.md +22 -1
- data/Gemfile +4 -5
- data/README.md +176 -27
- data/appveyor.yml +0 -4
- data/benchmarks/speed_read_char.rb +34 -0
- data/benchmarks/speed_read_line.rb +34 -0
- data/examples/keypress.rb +16 -0
- data/examples/line.rb +7 -0
- data/examples/multiline.rb +7 -0
- data/examples/noecho.rb +6 -0
- data/examples/shell.rb +12 -0
- data/lib/tty/reader.rb +121 -58
- data/lib/tty/reader/console.rb +2 -2
- data/lib/tty/reader/history.rb +6 -2
- data/lib/tty/reader/key_event.rb +4 -35
- data/lib/tty/reader/keys.rb +165 -0
- data/lib/tty/reader/line.rb +96 -9
- data/lib/tty/reader/version.rb +1 -1
- data/lib/tty/reader/win_console.rb +2 -2
- data/tty-reader.gemspec +7 -3
- metadata +46 -12
- data/lib/tty/reader/codes.rb +0 -120
data/lib/tty/reader/line.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
# frozen_string_literal: true
|
3
2
|
|
4
3
|
require 'forwardable'
|
@@ -6,28 +5,84 @@ require 'forwardable'
|
|
6
5
|
module TTY
|
7
6
|
class Reader
|
8
7
|
class Line
|
9
|
-
|
8
|
+
ANSI_MATCHER = /(\[)?\033(\[)?[;?\d]*[\dA-Za-z](\])?/
|
10
9
|
|
11
|
-
|
12
|
-
|
10
|
+
# Strip ANSI characters from the text
|
11
|
+
#
|
12
|
+
# @param [String] text
|
13
|
+
#
|
14
|
+
# @return [String]
|
15
|
+
#
|
16
|
+
# @api public
|
17
|
+
def self.sanitize(text)
|
18
|
+
text.dup.gsub(ANSI_MATCHER, '')
|
19
|
+
end
|
13
20
|
|
14
|
-
|
21
|
+
# The editable text
|
22
|
+
# @api public
|
23
|
+
attr_reader :text
|
15
24
|
|
16
|
-
|
25
|
+
# The current cursor position witin the text
|
26
|
+
# @api public
|
27
|
+
attr_reader :cursor
|
17
28
|
|
18
|
-
|
19
|
-
|
29
|
+
# The line mode
|
30
|
+
# @api public
|
31
|
+
attr_reader :mode
|
32
|
+
|
33
|
+
attr_reader :prompt
|
34
|
+
|
35
|
+
def initialize(prompt, text = '')
|
36
|
+
@prompt = prompt.dup
|
37
|
+
@text = text.dup
|
20
38
|
@cursor = [0, @text.length].max
|
39
|
+
@mode = :edit
|
21
40
|
yield self if block_given?
|
22
41
|
end
|
23
42
|
|
43
|
+
# Check if line is in edit mode
|
44
|
+
#
|
45
|
+
# @return [Boolean]
|
46
|
+
#
|
47
|
+
# @public
|
48
|
+
def editing?
|
49
|
+
@mode == :edit
|
50
|
+
end
|
51
|
+
|
52
|
+
# Enable edit mode
|
53
|
+
#
|
54
|
+
# @return [Boolean]
|
55
|
+
#
|
56
|
+
# @public
|
57
|
+
def edit_mode
|
58
|
+
@mode = :edit
|
59
|
+
end
|
60
|
+
|
61
|
+
# Check if line is in replace mode
|
62
|
+
#
|
63
|
+
# @return [Boolean]
|
64
|
+
#
|
65
|
+
# @public
|
66
|
+
def replacing?
|
67
|
+
@mode == :replace
|
68
|
+
end
|
69
|
+
|
70
|
+
# Enable replace mode
|
71
|
+
#
|
72
|
+
# @return [Boolean]
|
73
|
+
#
|
74
|
+
# @public
|
75
|
+
def replace_mode
|
76
|
+
@mode = :replace
|
77
|
+
end
|
78
|
+
|
24
79
|
# Check if cursor reached beginning of the line
|
25
80
|
#
|
26
81
|
# @return [Boolean]
|
27
82
|
#
|
28
83
|
# @api public
|
29
84
|
def start?
|
30
|
-
@cursor
|
85
|
+
@cursor.zero?
|
31
86
|
end
|
32
87
|
|
33
88
|
# Check if cursor reached end of the line
|
@@ -80,6 +135,7 @@ module TTY
|
|
80
135
|
#
|
81
136
|
# @api public
|
82
137
|
def []=(i, chars)
|
138
|
+
edit_mode
|
83
139
|
if i.is_a?(Range)
|
84
140
|
@text[i] = chars
|
85
141
|
@cursor += chars.length
|
@@ -125,6 +181,7 @@ module TTY
|
|
125
181
|
def replace(text)
|
126
182
|
@text = text
|
127
183
|
@cursor = @text.length # put cursor outside of text
|
184
|
+
replace_mode
|
128
185
|
end
|
129
186
|
|
130
187
|
# Insert char(s) at cursor position
|
@@ -156,6 +213,36 @@ module TTY
|
|
156
213
|
left
|
157
214
|
@text.slice!(@cursor, 1)
|
158
215
|
end
|
216
|
+
|
217
|
+
# Full line with prompt as string
|
218
|
+
#
|
219
|
+
# @api public
|
220
|
+
def to_s
|
221
|
+
"#{@prompt}#{@text}"
|
222
|
+
end
|
223
|
+
alias inspect to_s
|
224
|
+
|
225
|
+
# Prompt size
|
226
|
+
#
|
227
|
+
# @api public
|
228
|
+
def prompt_size
|
229
|
+
self.class.sanitize(@prompt).size
|
230
|
+
end
|
231
|
+
|
232
|
+
# Text size
|
233
|
+
#
|
234
|
+
# @api public
|
235
|
+
def text_size
|
236
|
+
self.class.sanitize(@text).size
|
237
|
+
end
|
238
|
+
|
239
|
+
# Full line size with prompt
|
240
|
+
#
|
241
|
+
# @api public
|
242
|
+
def size
|
243
|
+
prompt_size + text_size
|
244
|
+
end
|
245
|
+
alias length size
|
159
246
|
end # Line
|
160
247
|
end # Reader
|
161
248
|
end # TTY
|
data/lib/tty/reader/version.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require_relative '
|
4
|
+
require_relative 'keys'
|
5
5
|
|
6
6
|
module TTY
|
7
7
|
class Reader
|
@@ -27,7 +27,7 @@ module TTY
|
|
27
27
|
def initialize(input)
|
28
28
|
require_relative 'win_api'
|
29
29
|
@input = input
|
30
|
-
@keys =
|
30
|
+
@keys = Keys.ctrl_keys.merge(Keys.win_keys)
|
31
31
|
@escape_codes = [[NUL_HEX.ord], [ESC.ord], EXT_HEX.bytes.to_a]
|
32
32
|
end
|
33
33
|
|
data/tty-reader.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = TTY::Reader::VERSION
|
9
9
|
spec.authors = ["Piotr Murach"]
|
10
10
|
spec.email = [""]
|
11
|
-
spec.summary = %q{
|
12
|
-
spec.description = %q{
|
11
|
+
spec.summary = %q{A set of methods for processing keyboard input in character, line and multiline modes.}
|
12
|
+
spec.description = %q{A set of methods for processing keyboard input in character, line and multiline modes. In addition it maintains history of entered input with an ability to recall and re-edit those inputs and register to listen for keystrokes.}
|
13
13
|
spec.homepage = "https://piotrmurach.github.io/tty"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
@@ -20,9 +20,13 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
21
|
spec.require_paths = ["lib"]
|
22
22
|
|
23
|
+
spec.required_ruby_version = '>= 2.0.0'
|
24
|
+
|
23
25
|
spec.add_dependency "wisper", "~> 2.0.0"
|
26
|
+
spec.add_dependency "tty-screen", "~> 0.6.4"
|
27
|
+
spec.add_dependency "tty-cursor", "~> 0.5.0"
|
24
28
|
|
25
29
|
spec.add_development_dependency "bundler", ">= 1.5.0", "< 2.0"
|
26
|
-
spec.add_development_dependency "rake", "~>
|
30
|
+
spec.add_development_dependency "rake", "~> 12.0"
|
27
31
|
spec.add_development_dependency "rspec", "~> 3.0"
|
28
32
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tty-reader
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Murach
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-01-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: wisper
|
@@ -24,6 +24,34 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 2.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: tty-screen
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.6.4
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.6.4
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: tty-cursor
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.5.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.5.0
|
27
55
|
- !ruby/object:Gem::Dependency
|
28
56
|
name: bundler
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -50,14 +78,14 @@ dependencies:
|
|
50
78
|
requirements:
|
51
79
|
- - "~>"
|
52
80
|
- !ruby/object:Gem::Version
|
53
|
-
version: '
|
81
|
+
version: '12.0'
|
54
82
|
type: :development
|
55
83
|
prerelease: false
|
56
84
|
version_requirements: !ruby/object:Gem::Requirement
|
57
85
|
requirements:
|
58
86
|
- - "~>"
|
59
87
|
- !ruby/object:Gem::Version
|
60
|
-
version: '
|
88
|
+
version: '12.0'
|
61
89
|
- !ruby/object:Gem::Dependency
|
62
90
|
name: rspec
|
63
91
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,9 +100,9 @@ dependencies:
|
|
72
100
|
- - "~>"
|
73
101
|
- !ruby/object:Gem::Version
|
74
102
|
version: '3.0'
|
75
|
-
description:
|
76
|
-
|
77
|
-
|
103
|
+
description: A set of methods for processing keyboard input in character, line and
|
104
|
+
multiline modes. In addition it maintains history of entered input with an ability
|
105
|
+
to recall and re-edit those inputs and register to listen for keystrokes.
|
78
106
|
email:
|
79
107
|
- ''
|
80
108
|
executables: []
|
@@ -91,14 +119,21 @@ files:
|
|
91
119
|
- README.md
|
92
120
|
- Rakefile
|
93
121
|
- appveyor.yml
|
122
|
+
- benchmarks/speed_read_char.rb
|
123
|
+
- benchmarks/speed_read_line.rb
|
94
124
|
- bin/console
|
95
125
|
- bin/setup
|
126
|
+
- examples/keypress.rb
|
127
|
+
- examples/line.rb
|
128
|
+
- examples/multiline.rb
|
129
|
+
- examples/noecho.rb
|
130
|
+
- examples/shell.rb
|
96
131
|
- lib/tty-reader.rb
|
97
132
|
- lib/tty/reader.rb
|
98
|
-
- lib/tty/reader/codes.rb
|
99
133
|
- lib/tty/reader/console.rb
|
100
134
|
- lib/tty/reader/history.rb
|
101
135
|
- lib/tty/reader/key_event.rb
|
136
|
+
- lib/tty/reader/keys.rb
|
102
137
|
- lib/tty/reader/line.rb
|
103
138
|
- lib/tty/reader/mode.rb
|
104
139
|
- lib/tty/reader/version.rb
|
@@ -120,7 +155,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
120
155
|
requirements:
|
121
156
|
- - ">="
|
122
157
|
- !ruby/object:Gem::Version
|
123
|
-
version:
|
158
|
+
version: 2.0.0
|
124
159
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
125
160
|
requirements:
|
126
161
|
- - ">="
|
@@ -131,7 +166,6 @@ rubyforge_project:
|
|
131
166
|
rubygems_version: 2.5.1
|
132
167
|
signing_key:
|
133
168
|
specification_version: 4
|
134
|
-
summary:
|
135
|
-
|
169
|
+
summary: A set of methods for processing keyboard input in character, line and multiline
|
170
|
+
modes.
|
136
171
|
test_files: []
|
137
|
-
has_rdoc:
|
data/lib/tty/reader/codes.rb
DELETED
@@ -1,120 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
module TTY
|
5
|
-
class Reader
|
6
|
-
module Codes
|
7
|
-
def ctrl_keys
|
8
|
-
{
|
9
|
-
ctrl_a: ?\C-a,
|
10
|
-
ctrl_b: ?\C-b,
|
11
|
-
ctrl_c: ?\C-c,
|
12
|
-
ctrl_d: ?\C-d,
|
13
|
-
ctrl_e: ?\C-e,
|
14
|
-
ctrl_f: ?\C-f,
|
15
|
-
ctrl_g: ?\C-g,
|
16
|
-
ctrl_h: ?\C-h,
|
17
|
-
ctrl_i: ?\C-i,
|
18
|
-
ctrl_j: ?\C-j,
|
19
|
-
ctrl_k: ?\C-k,
|
20
|
-
ctrl_l: ?\C-l,
|
21
|
-
ctrl_m: ?\C-m,
|
22
|
-
ctrl_n: ?\C-n,
|
23
|
-
ctrl_o: ?\C-o,
|
24
|
-
ctrl_p: ?\C-p,
|
25
|
-
ctrl_q: ?\C-q,
|
26
|
-
ctrl_r: ?\C-r,
|
27
|
-
ctrl_s: ?\C-s,
|
28
|
-
ctrl_t: ?\C-t,
|
29
|
-
ctrl_u: ?\C-u,
|
30
|
-
ctrl_v: ?\C-v,
|
31
|
-
ctrl_w: ?\C-w,
|
32
|
-
ctrl_x: ?\C-x,
|
33
|
-
ctrl_y: ?\C-y,
|
34
|
-
ctrl_z: ?\C-z
|
35
|
-
}
|
36
|
-
end
|
37
|
-
module_function :ctrl_keys
|
38
|
-
|
39
|
-
def keys
|
40
|
-
{
|
41
|
-
tab: "\t",
|
42
|
-
enter: "\n",
|
43
|
-
return: "\r",
|
44
|
-
escape: "\e",
|
45
|
-
space: " ",
|
46
|
-
backspace: ?\C-?,
|
47
|
-
home: "\e[1~",
|
48
|
-
insert: "\e[2~",
|
49
|
-
delete: "\e[3~",
|
50
|
-
end: "\e[4~",
|
51
|
-
page_up: "\e[5~",
|
52
|
-
page_down: "\e[6~",
|
53
|
-
|
54
|
-
up: "\e[A",
|
55
|
-
down: "\e[B",
|
56
|
-
right: "\e[C",
|
57
|
-
left: "\e[D",
|
58
|
-
clear: "\e[E",
|
59
|
-
|
60
|
-
f1_xterm: "\eOP",
|
61
|
-
f2_xterm: "\eOQ",
|
62
|
-
f3_xterm: "\eOR",
|
63
|
-
f4_xterm: "\eOS",
|
64
|
-
|
65
|
-
f1: "\e[11~",
|
66
|
-
f2: "\e[12~",
|
67
|
-
f3: "\e[13~",
|
68
|
-
f4: "\e[14~",
|
69
|
-
f5: "\e[15~",
|
70
|
-
f6: "\e[17~",
|
71
|
-
f7: "\e[18~",
|
72
|
-
f8: "\e[19~",
|
73
|
-
f9: "\e[20~",
|
74
|
-
f10: "\e[21~",
|
75
|
-
f11: "\e[23~",
|
76
|
-
f12: "\e[24~"
|
77
|
-
}.merge(ctrl_keys)
|
78
|
-
end
|
79
|
-
module_function :keys
|
80
|
-
|
81
|
-
def win_keys
|
82
|
-
{
|
83
|
-
tab: "\t",
|
84
|
-
enter: "\r",
|
85
|
-
return: "\r",
|
86
|
-
escape: "\e",
|
87
|
-
space: " ",
|
88
|
-
backspace: "\b",
|
89
|
-
home: [224, 71].pack('U*'),
|
90
|
-
end: [224, 79].pack('U*'),
|
91
|
-
insert: [224, 82].pack('U*'),
|
92
|
-
delete: [224, 83].pack('U*'),
|
93
|
-
page_up: [224, 73].pack('U*'),
|
94
|
-
page_down: [224, 81].pack('U*'),
|
95
|
-
|
96
|
-
up: [224, 72].pack('U*'),
|
97
|
-
down: [224, 80].pack('U*'),
|
98
|
-
right: [224, 77].pack('U*'),
|
99
|
-
left: [224, 75].pack('U*'),
|
100
|
-
clear: [224, 83].pack('U*'),
|
101
|
-
|
102
|
-
f1: "\x00;",
|
103
|
-
f2: "\x00<",
|
104
|
-
f3: "\x00",
|
105
|
-
f4: "\x00=",
|
106
|
-
f5: "\x00?",
|
107
|
-
f6: "\x00@",
|
108
|
-
f7: "\x00A",
|
109
|
-
f8: "\x00B",
|
110
|
-
f9: "\x00C",
|
111
|
-
f10: "\x00D",
|
112
|
-
f11: "\x00\x85",
|
113
|
-
f12: "\x00\x86"
|
114
|
-
}.merge(ctrl_keys)
|
115
|
-
end
|
116
|
-
module_function :win_keys
|
117
|
-
|
118
|
-
end # Codes
|
119
|
-
end # Reader
|
120
|
-
end # TTY
|