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.
@@ -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