tty-reader 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- extend Forwardable
8
+ ANSI_MATCHER = /(\[)?\033(\[)?[;?\d]*[\dA-Za-z](\])?/
10
9
 
11
- def_delegators :@text, :size, :length, :to_s, :inspect,
12
- :slice!, :empty?
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
- attr_accessor :text
21
+ # The editable text
22
+ # @api public
23
+ attr_reader :text
15
24
 
16
- attr_accessor :cursor
25
+ # The current cursor position witin the text
26
+ # @api public
27
+ attr_reader :cursor
17
28
 
18
- def initialize(text = "")
19
- @text = text
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 == 0
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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module TTY
4
4
  class Reader
5
- VERSION = "0.1.0"
5
+ VERSION = '0.2.0'.freeze
6
6
  end # Reader
7
7
  end # TTY
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
3
 
4
- require_relative 'codes'
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 = Codes.win_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{Provides a set of methods for processing keyboard input in character, line and multiline modes.}
12
- spec.description = %q{Provides 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.}
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", "~> 10.0"
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.1.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: 2017-08-30 00:00:00.000000000 Z
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: '10.0'
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: '10.0'
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: Provides a set of methods for processing keyboard input in character,
76
- line and multiline modes. In addition it maintains history of entered input with
77
- an ability to recall and re-edit those inputs and register to listen for keystrokes.
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: '0'
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: Provides a set of methods for processing keyboard input in character, line
135
- and multiline modes.
169
+ summary: A set of methods for processing keyboard input in character, line and multiline
170
+ modes.
136
171
  test_files: []
137
- has_rdoc:
@@ -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