highline 2.0.0.pre.develop.2 → 2.0.0.pre.develop.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7f330e1d4093d9a373e0471827e2acdf89076eac
4
- data.tar.gz: 1bba362856956f240a80312fe26e74966790b783
3
+ metadata.gz: fe7f4a2acbc139058d22c6e720cf45f3d8807278
4
+ data.tar.gz: 4a2e208bb898d2498f5911efaa695095341cb43c
5
5
  SHA512:
6
- metadata.gz: 36049605dccd8943c87037214ca65c02feab5ead5f1ca4579ba5491b0b8b966c9a49377c40f9fb99d53bd5a63ea86ef664c55cae40158cc53bef31b4413249cf
7
- data.tar.gz: fdd91732e30725625a9197226d70d2a8bf99002c3a029094617bbed2048a3dadc93a3f95012eca5a87a0ca3f0f69ac5fb9007a3afc48cc6d253afaa81b4236d9
6
+ metadata.gz: 3f276ad26eb858d757254770be10c6a007b0c4032078ef7f750b677499ed19c43315b0518d802480fd3cb9b8f2804286bdfd255ea647a85f5209be312dd8ab90
7
+ data.tar.gz: ab6323e8a8a16a5912328700cb207ca9009a60f05772102bf643db3ca8dd4b21dc7a527d79aad8113cbb32f2d6a1ed66297220d3faf86c3ca43d8befa85a8034
@@ -2,6 +2,34 @@
2
2
 
3
3
  Below is a complete listing of changes for each revision of HighLine.
4
4
 
5
+ ### 2.0.0-develop.4 / 2015-12-14
6
+ This versions makes the code documentation 100% 'A' grade on inch.
7
+ We have used inch and http://inch-ci.org to guide the priorities
8
+ on documentation production.
9
+
10
+ The grade 'A' (on inch) number of objects on master branch was 44,22% (153/346).
11
+ After this PR we have a 100% grade 'A' (344 objects).
12
+
13
+ There's already a inch-ci.org badge on README.md. And now it's all green!
14
+
15
+ We also bring some improvement on CodeClimate scores.
16
+
17
+ #### CHANGES SUMMARY
18
+
19
+ * PR #179 - Make inch happy. Grade "A" for the whole HighLine documentation. By Abinoam Jr. (@abinoam)
20
+ * PR #178 - Improve score on Code Climate by applying some refactoring. By Abinoam Jr. (@abinoam)
21
+ * PR #172 - Initial work on documentation by Abinoam Jr. (@abinoam)
22
+ * Use yard
23
+ * Use inch
24
+ * New Readme file
25
+ * Fix #166 with PR #173 by (@matugm)
26
+
27
+
28
+ ### 2.0.0-develop.3 / 2015-10-28
29
+
30
+ This version brings some improvements on documentation (switch to Yardoc).
31
+ This is the first 2.0.0-develop.x version to be release as gem.
32
+
5
33
  ### 2.0.0-develop.2 / 2015-09-09
6
34
 
7
35
  (by Abinoam P. Marques Jr. - @abinoam)
@@ -0,0 +1,188 @@
1
+ HighLine
2
+ ========
3
+
4
+ [![Build Status](https://travis-ci.org/JEG2/highline.svg?branch=master)](https://travis-ci.org/JEG2/highline)
5
+ [![Build status](https://ci.appveyor.com/api/projects/status/4p05fijpah77d28x/branch/master?svg=true)](https://ci.appveyor.com/project/JEG2/highline/branch/master)
6
+ [![Gem Version](https://badge.fury.io/rb/highline.svg)](https://badge.fury.io/rb/highline)
7
+ [![Code Climate](https://codeclimate.com/github/JEG2/highline/badges/gpa.svg)](https://codeclimate.com/github/JEG2/highline)
8
+ [![Test Coverage](https://codeclimate.com/github/JEG2/highline/badges/coverage.svg)](https://codeclimate.com/github/JEG2/highline/coverage)
9
+ [![Inline docs](http://inch-ci.org/github/JEG2/highline.svg?branch=master)](http://inch-ci.org/github/JEG2/highline)
10
+
11
+ Description
12
+ -----------
13
+
14
+ Welcome to HighLine.
15
+
16
+ HighLine was designed to ease the tedious tasks of doing console input and
17
+ output with low-level methods like ```gets``` and ```puts```. HighLine provides a
18
+ robust system for requesting data from a user, without needing to code all the
19
+ error checking and validation rules and without needing to convert the typed
20
+ Strings into what your program really needs. Just tell HighLine what you're
21
+ after, and let it do all the work.
22
+
23
+ Documentation
24
+ -------------
25
+
26
+ See: [Rubydoc.info for HighLine](http://www.rubydoc.info/github/JEG2/highline/master).
27
+ Specially [HighLine](http://www.rubydoc.info/github/JEG2/highline/master/HighLine) and [HighLine::Question](http://www.rubydoc.info/github/JEG2/highline/master/HighLine/Question).
28
+
29
+ Usage
30
+ -----
31
+
32
+ ```ruby
33
+
34
+ require 'highline'
35
+
36
+ # Basic usage
37
+
38
+ cli = HighLine.new
39
+ answer = cli.ask "What do you think?"
40
+ puts "You have answered: #{answer}"
41
+
42
+
43
+ # Default answer
44
+
45
+ cli.ask("Company? ") { |q| q.default = "none" }
46
+
47
+
48
+ # Validation
49
+
50
+ cli.ask("Age? ", Integer) { |q| q.in = 0..105 }
51
+ cli.ask("Name? (last, first) ") { |q| q.validate = /\A\w+, ?\w+\Z/ }
52
+
53
+
54
+ # Type conversion for answers:
55
+
56
+ cli.ask("Birthday? ", Date)
57
+ cli.ask("Interests? (comma sep list) ", lambda { |str| str.split(/,\s*/) })
58
+
59
+
60
+ # Reading passwords:
61
+
62
+ cli.ask("Enter your password: ") { |q| q.echo = false }
63
+ cli.ask("Enter your password: ") { |q| q.echo = "x" }
64
+
65
+
66
+ # ERb based output (with HighLine's ANSI color tools):
67
+
68
+ cli.say("This should be <%= color('bold', BOLD) %>!")
69
+
70
+
71
+ # Menus:
72
+
73
+ cli.choose do |menu|
74
+ menu.prompt = "Please choose your favorite programming language? "
75
+ menu.choice(:ruby) { say("Good choice!") }
76
+ menu.choices(:python, :perl) { say("Not from around here, are you?") }
77
+ end
78
+ ```
79
+
80
+ If you want to save some characters, you can inject/import HighLine methods on Kernel by doing the following. Just be sure to avoid name collisions in the top-level namespace.
81
+
82
+
83
+ ```ruby
84
+ require 'highline/import'
85
+
86
+ say "Now you can use #say directly"
87
+ ```
88
+
89
+ For more examples see the examples/ directory of this project.
90
+
91
+ Requirements
92
+ ------------
93
+
94
+ HighLine from version >= 1.7.0 requires ruby >= 1.9.3
95
+
96
+ Installing
97
+ ----------
98
+
99
+ To install HighLine, use the following command:
100
+
101
+ ```sh
102
+ $ gem install highline
103
+ ```
104
+
105
+ (Add `sudo` if you're installing under a POSIX system as root)
106
+
107
+ If you're using [Bundler](http://bundler.io/), add this to your Gemfile:
108
+
109
+ ```ruby
110
+ source "https://rubygems.org"
111
+ gem 'highline'
112
+ ```
113
+
114
+ And then run:
115
+
116
+ ```sh
117
+ $ bundle
118
+ ```
119
+
120
+ If you want to build the gem locally, use the following command from the root of the sources:
121
+
122
+ ```sh
123
+ $ rake package
124
+ ```
125
+
126
+ You can also build and install directly:
127
+
128
+ ```sh
129
+ $ rake install
130
+ ```
131
+
132
+ Contributing
133
+ ------------
134
+
135
+ 1. Open an issue
136
+ - https://github.com/JEG2/highline/issues
137
+
138
+ 2. Fork the repository
139
+ - https://github.com/JEG2/highline/fork
140
+
141
+ 3. Clone it locally
142
+ - ```git clone git@github.com:YOUR-USERNAME/highline.git```
143
+
144
+ 4. Add the main HighLine repository as the __upstream__ remote
145
+ - ```cd highline``` # to enter the cloned repository directory.
146
+ - ```git remote add -v upstream https://github.com/JEG2/highline```
147
+
148
+ 5. Keep your fork in sync with __upstream__
149
+ - ```git fetch upstream```
150
+ - ```git checkout master```
151
+ - ```git merge upstream/master```
152
+
153
+ 6. Create your feature branch
154
+ - ```git checkout -b your_branch```
155
+
156
+ 7. Hack the source code and run the tests
157
+ - ```rake test```
158
+ - ```rake acceptance```
159
+
160
+ 8. Commit your changes
161
+ - ```git commit -am "Your commit message"```
162
+
163
+ 9. Push it
164
+ - ```git push```
165
+
166
+ 10. Open a pull request
167
+ - https://github.com/JEG2/highline/pulls
168
+
169
+ Details on:
170
+
171
+ * GitHub Guide to Contributing to Open Source - https://guides.github.com/activities/contributing-to-open-source/
172
+ * GitHub issues - https://guides.github.com/features/issues/
173
+ * Forking - https://help.github.com/articles/fork-a-repo/
174
+ * Cloning - https://help.github.com/articles/cloning-a-repository/
175
+ * Adding upstream - https://help.github.com/articles/configuring-a-remote-for-a-fork/
176
+ * Syncing your fork - https://help.github.com/articles/syncing-a-fork/
177
+ * Branching - https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging
178
+ * Commiting - https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository
179
+ * Pushing - https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes
180
+
181
+ The Core HighLine Team
182
+ ----------------------
183
+
184
+ * [James Edward Gray II](https://github.com/JEG2) - Author
185
+ * [Gregory Brown](https://github.com/practicingruby) - Core contributor
186
+ * [Abinoam P. Marques Jr.](https://github.com/abinoam) - Core contributor
187
+
188
+ _For a list of people who have contributed to the codebase, see [GitHub's list of contributors](https://github.com/JEG2/highline/contributors)._
data/Rakefile CHANGED
@@ -1,4 +1,3 @@
1
- require "rdoc/task"
2
1
  require "rake/testtask"
3
2
  require "rubygems/package_task"
4
3
  require "bundler/gem_tasks"
@@ -15,16 +14,6 @@ Rake::TestTask.new do |test|
15
14
  test.test_files = FileList['test/test*.rb']
16
15
  end
17
16
 
18
- RDoc::Task.new do |rdoc|
19
- rdoc.rdoc_files.include( "README.rdoc", "INSTALL",
20
- "TODO", "Changelog.md",
21
- "AUTHORS", "COPYING",
22
- "LICENSE", "lib/**/*.rb")
23
- rdoc.main = "README.rdoc"
24
- rdoc.rdoc_dir = "doc/html"
25
- rdoc.title = "HighLine Documentation"
26
- end
27
-
28
17
  Gem::PackageTask.new(SPEC) do |package|
29
18
  # do nothing: I just need a gem but this block is required
30
19
  end
@@ -13,10 +13,8 @@ SPEC = Gem::Specification.new do |spec|
13
13
  spec.files = `git ls-files`.split("\n")
14
14
 
15
15
  spec.test_files = `git ls-files -- test/*.rb`.split("\n")
16
- spec.has_rdoc = true
17
- spec.extra_rdoc_files = %w[README.rdoc INSTALL TODO Changelog.md LICENSE]
18
- spec.rdoc_options << '--title' << 'HighLine Documentation' <<
19
- '--main' << 'README'
16
+ spec.has_rdoc = 'yard'
17
+ spec.extra_rdoc_files = %w[README.md TODO Changelog.md LICENSE]
20
18
 
21
19
  spec.require_path = 'lib'
22
20
 
@@ -29,12 +29,17 @@ require "highline/builtin_styles"
29
29
  #
30
30
  # A HighLine object is a "high-level line oriented" shell over an input and an
31
31
  # output stream. HighLine simplifies common console interaction, effectively
32
- # replacing puts() and gets(). User code can simply specify the question to ask
32
+ # replacing {Kernel#puts} and {Kernel#gets}. User code can simply specify the question to ask
33
33
  # and any details about user interaction, then leave the rest of the work to
34
- # HighLine. When HighLine.ask() returns, you'll have the answer you requested,
34
+ # HighLine. When {HighLine#ask} returns, you'll have the answer you requested,
35
35
  # even if HighLine had to ask many times, validate results, perform range
36
36
  # checking, convert types, etc.
37
37
  #
38
+ # @example Basic usage
39
+ # cli = HighLine.new
40
+ # answer = cli.ask "What do you think?"
41
+ # puts "You have answered: #{answer}"
42
+
38
43
  class HighLine
39
44
  include BuiltinStyles
40
45
  include CustomErrors
@@ -72,6 +77,7 @@ class HighLine
72
77
  @track_eof
73
78
  end
74
79
 
80
+ # (see HighLine.track_eof?)
75
81
  def track_eof?
76
82
  self.class.track_eof?
77
83
  end
@@ -101,14 +107,22 @@ class HighLine
101
107
  reset_color_scheme
102
108
  end
103
109
 
110
+ # Reset color scheme to default (+nil+)
104
111
  def self.reset_color_scheme
105
112
  self.color_scheme = nil
106
113
  end
107
114
 
108
115
  #
109
- # Create an instance of HighLine, connected to the streams _input_
110
- # and _output_.
116
+ # Create an instance of HighLine connected to the given _input_
117
+ # and _output_ streams.
111
118
  #
119
+ # @param input [IO] the default input stream for HighLine.
120
+ # @param output [IO] the default output stream for HighLine.
121
+ # @param wrap_at [Integer] all statements outputed through
122
+ # HighLine will be wrapped to this column size if set.
123
+ # @param page_at [Integer] page size and paginating.
124
+ # @param indent_size [Integer] indentation size in spaces.
125
+ # @param indent_level [Integer] how deep is indentated.
112
126
  def initialize( input = $stdin, output = $stdout,
113
127
  wrap_at = nil, page_at = nil, indent_size=3, indent_level=0 )
114
128
  @input = input
@@ -128,24 +142,38 @@ class HighLine
128
142
  @terminal = HighLine::Terminal.get_terminal(input, output)
129
143
  end
130
144
 
131
- # The current column setting for wrapping output.
145
+ # @return [Integer] The current column setting for wrapping output.
132
146
  attr_reader :wrap_at
133
- # The current row setting for paging output.
147
+
148
+ # @return [Integer] The current row setting for paging output.
134
149
  attr_reader :page_at
135
- # Indentation over multiple lines
150
+
151
+ # @return [Boolean] Indentation over multiple lines
136
152
  attr_accessor :multi_indent
137
- # The indentation size
153
+
154
+ # @return [Integer] The indentation size in characters
138
155
  attr_accessor :indent_size
139
- # The indentation level
156
+
157
+ # @return [Integer] The indentation level
140
158
  attr_accessor :indent_level
141
159
 
142
- attr_reader :input, :output
160
+ # @return [IO] the default input stream for a HighLine instance
161
+ attr_reader :input
143
162
 
163
+ # @return [IO] the default output stream for a HighLine instance
164
+ attr_reader :output
165
+
166
+ # When gathering a Hash with {QuestionAsker#gather_hash},
167
+ # it tracks the current key being asked.
168
+ #
169
+ # @todo We should probably move this into the HighLine::Question
170
+ # object.
144
171
  attr_accessor :key
145
172
 
146
173
  # System specific that responds to #initialize_system_extensions,
147
174
  # #terminal_size, #raw_no_echo_mode, #restore_mode, #get_character.
148
175
  # It polymorphically handles specific cases for different platforms.
176
+ # @return [HighLine::Terminal]
149
177
  attr_reader :terminal
150
178
 
151
179
  #
@@ -157,6 +185,9 @@ class HighLine
157
185
  #
158
186
  # Raises EOFError if input is exhausted.
159
187
  #
188
+ # @param yes_or_no_question [String] a question that accepts yes and no as answers
189
+ # @param character [Boolean, :getc] character mode to be passed to Question#character
190
+ # @see Question#character
160
191
  def agree( yes_or_no_question, character = nil )
161
192
  ask(yes_or_no_question, lambda { |yn| yn.downcase[0] == ?y}) do |q|
162
193
  q.validate = /\Ay(?:es)?|no?\Z/i
@@ -172,12 +203,14 @@ class HighLine
172
203
  # This method is the primary interface for user input. Just provide a
173
204
  # _question_ to ask the user, the _answer_type_ you want returned, and
174
205
  # optionally a code block setting up details of how you want the question
175
- # handled. See HighLine.say() for details on the format of _question_, and
176
- # HighLine::Question for more information about _answer_type_ and what's
206
+ # handled. See {#say} for details on the format of _question_, and
207
+ # {Question} for more information about _answer_type_ and what's
177
208
  # valid in the code block.
178
209
  #
179
210
  # Raises EOFError if input is exhausted.
180
211
  #
212
+ # @param (see Question.build)
213
+ # @return answer converted to the class in answer_type
181
214
  def ask(template_or_question, answer_type = nil, &details)
182
215
  question = Question.build(template_or_question, answer_type, &details)
183
216
 
@@ -203,6 +236,9 @@ class HighLine
203
236
  #
204
237
  # Raises EOFError if input is exhausted.
205
238
  #
239
+ # @param items [Array<String>]
240
+ # @param details [Proc] to be passed to Menu.new
241
+ # @return [String] answer
206
242
  def choose( *items, &details )
207
243
  menu = Menu.new(&details)
208
244
  menu.choices(*items) unless items.empty?
@@ -210,21 +246,9 @@ class HighLine
210
246
  # Set auto-completion
211
247
  menu.completion = menu.options
212
248
 
213
- shell_style_lambda = lambda do |command| # shell-style selection
214
- first_word = command.to_s.split.first || ""
215
-
216
- options = menu.options
217
- options.extend(OptionParser::Completion)
218
- answer = options.complete(first_word)
219
-
220
- raise Question::NoAutoCompleteMatch unless answer
221
-
222
- [answer.last, command.sub(/^\s*#{first_word}\s*/, "")]
223
- end
224
-
225
249
  # Set _answer_type_ so we can double as the Question for ask().
226
250
  # menu.option = normal menu selection, by index or name
227
- menu.answer_type = menu.shell ? shell_style_lambda : menu.options
251
+ menu.answer_type = menu.shell ? shell_style_lambda(menu) : menu.options
228
252
 
229
253
  selected = ask(menu)
230
254
 
@@ -235,6 +259,24 @@ class HighLine
235
259
  end
236
260
  end
237
261
 
262
+ # Convenience method to craft a lambda suitable for
263
+ # beind used in autocompletion operations by {#choose}
264
+ # @return [lambda] lambda to be used in autocompletion operations
265
+
266
+ def shell_style_lambda(menu)
267
+ lambda do |command| # shell-style selection
268
+ first_word = command.to_s.split.first || ""
269
+
270
+ options = menu.options
271
+ options.extend(OptionParser::Completion)
272
+ answer = options.complete(first_word)
273
+
274
+ raise Question::NoAutoCompleteMatch unless answer
275
+
276
+ [answer.last, command.sub(/^\s*#{first_word}\s*/, "")]
277
+ end
278
+ end
279
+
238
280
  #
239
281
  # This method provides easy access to ANSI color sequences, without the user
240
282
  # needing to remember to CLEAR at the end of each sequence. Just pass the
@@ -246,36 +288,65 @@ class HighLine
246
288
  # This method returns the original _string_ unchanged if HighLine::use_color?
247
289
  # is +false+.
248
290
  #
291
+ # @param string [String] string to be colored
292
+ # @param colors [Array<Symbol>] array of colors like [:red, :blue]
293
+ # @return [String] (ANSI escaped) colored string
294
+ # @example
295
+ # HighLine.color("Sustainable", :green, :bold)
296
+ # # => "\e[32m\e[1mSustainable\e[0m"
249
297
  def self.color( string, *colors )
250
298
  return string unless self.use_color?
251
299
  Style(*colors).color(string)
252
300
  end
253
301
 
254
- # In case you just want the color code, without the embedding and the CLEAR
302
+ # (see .color)
303
+ # Convenience instance method. It delegates to the class method.
304
+ def color(string, *colors)
305
+ self.class.color(string, *colors)
306
+ end
307
+
308
+ # In case you just want the color code, without the embedding and
309
+ # the CLEAR sequence.
310
+ #
311
+ # @param colors [Array<Symbol>]
312
+ # @return [String] ANSI escape code for the given colors.
313
+ #
314
+ # @example
315
+ # s = HighLine.Style(:red, :blue)
316
+ # s.code # => "\e[31m\e[34m"
317
+ #
318
+ # HighLine.color_code(:red, :blue) # => "\e[31m\e[34m"
319
+
255
320
  def self.color_code(*colors)
256
321
  Style(*colors).code
257
322
  end
258
323
 
259
- # Works as an instance method, same as the class method
324
+ # (see HighLine.color_code)
325
+ # Convenience instance method. It delegates to the class method.
260
326
  def color_code(*colors)
261
327
  self.class.color_code(*colors)
262
328
  end
263
329
 
264
- # Works as an instance method, same as the class method
265
- def color(*args)
266
- self.class.color(*args)
267
- end
268
-
269
- # Remove color codes from a string
330
+ # Remove color codes from a string.
331
+ # @param string [String] to be decolorized
332
+ # @return [String] without the ANSI escape sequence (colors)
270
333
  def self.uncolor(string)
271
334
  Style.uncolor(string)
272
335
  end
273
336
 
274
- # Works as an instance method, same as the class method
337
+ # (see .uncolor)
338
+ # Convenience instance method. It delegates to the class method.
339
+
275
340
  def uncolor(string)
276
341
  self.class.uncolor(string)
277
342
  end
278
343
 
344
+ # Renders a list of itens using a {ListRenderer}
345
+ # @param items [Array]
346
+ # @param mode [Symbol]
347
+ # @param option
348
+ # @return [String]
349
+ # @see ListRenderer#initialize ListRenderer#initialize for parameter details
279
350
  def list(items, mode = :rows, option = nil)
280
351
  ListRenderer.new(items, mode, option, self).render
281
352
  end
@@ -290,6 +361,7 @@ class HighLine
290
361
  # instance's binding for providing easy access to the ANSI color constants
291
362
  # and the HighLine#color() method.
292
363
  #
364
+ # @param statement [Statement, String] what to be said
293
365
  def say(statement)
294
366
  statement = render_statement(statement)
295
367
  return if statement.empty?
@@ -306,6 +378,9 @@ class HighLine
306
378
  end
307
379
  end
308
380
 
381
+ # Renders a statement using {HighLine::Statement}
382
+ # @param statement [String] any string
383
+ # @return [Statement] rendered statement
309
384
  def render_statement(statement)
310
385
  Statement.new(statement, self).to_s
311
386
  end
@@ -340,6 +415,11 @@ class HighLine
340
415
  #
341
416
  # Executes block or outputs statement with indentation
342
417
  #
418
+ # @param increase [Integer] how much to increase indentation
419
+ # @param statement [Statement, String] to be said
420
+ # @param multiline [Boolean]
421
+ # @return [void]
422
+ # @see #multi_indent
343
423
  def indent(increase=1, statement=nil, multiline=nil)
344
424
  @indent_level += increase
345
425
  multi = @multi_indent
@@ -385,6 +465,8 @@ class HighLine
385
465
  return 24
386
466
  end
387
467
 
468
+ # Call #puts on the HighLine's output stream
469
+ # @param args [String] same args for Kernel#puts
388
470
  def puts(*args)
389
471
  @output.puts(*args)
390
472
  end
@@ -426,6 +508,17 @@ class HighLine
426
508
  answers.respond_to?(:values) ? answers.values.last : answers.last
427
509
  end
428
510
 
511
+ # Get response one line at time
512
+ # @param question [Question]
513
+ # @return [String] response
514
+ def get_response_line_mode(question)
515
+ if question.echo == true and !question.limit
516
+ get_line(question)
517
+ else
518
+ get_line_raw_no_echo_mode(question)
519
+ end
520
+ end
521
+
429
522
  #
430
523
  # Read a line of input from the input stream and process whitespace as
431
524
  # requested by the Question object.
@@ -439,47 +532,58 @@ class HighLine
439
532
  terminal.get_line(question, self)
440
533
  end
441
534
 
442
- def get_response_line_mode(question)
443
- if question.echo == true and !question.limit
444
- get_line(question)
445
- else
446
- line = ""
447
-
448
- terminal.raw_no_echo_mode_exec do
449
- while character = terminal.get_character
450
- break if character == "\n" or character == "\r"
451
-
452
- # honor backspace and delete
453
- if character == "\b"
454
- chopped = line.chop!
455
- output_erase_char if chopped and question.echo
456
- else
457
- line << character
458
- @output.print(line[-1]) if question.echo == true
459
- @output.print(question.echo) if question.echo and question.echo != true
460
- end
461
-
462
- @output.flush
535
+ def get_line_raw_no_echo_mode(question)
536
+ line = ""
463
537
 
464
- break if question.limit and line.size == question.limit
538
+ terminal.raw_no_echo_mode_exec do
539
+ while character = terminal.get_character
540
+ break if ["\n", "\r"].include? character
541
+
542
+ # honor backspace and delete
543
+ if character == "\b"
544
+ chopped = line.chop!
545
+ output_erase_char if chopped and question.echo
546
+ else
547
+ line << character
548
+ say_last_char_or_echo_char(line, question)
465
549
  end
466
- end
467
550
 
468
- if question.overwrite
469
- @output.print("\r#{HighLine.Style(:erase_line).code}")
470
551
  @output.flush
471
- else
472
- say("\n")
552
+
553
+ break if line_overflow_for_question?(line, question)
473
554
  end
555
+ end
556
+
557
+ say_new_line_or_overwrite(question)
558
+
559
+ question.format_answer(line)
560
+ end
474
561
 
475
- question.format_answer(line)
562
+ def say_new_line_or_overwrite(question)
563
+ if question.overwrite
564
+ @output.print("\r#{HighLine.Style(:erase_line).code}")
565
+ @output.flush
566
+ else
567
+ say("\n")
476
568
  end
477
569
  end
478
570
 
571
+ def say_last_char_or_echo_char(line, question)
572
+ @output.print(line[-1]) if question.echo == true
573
+ @output.print(question.echo) if question.echo and question.echo != true
574
+ end
575
+
576
+ def line_overflow_for_question?(line, question)
577
+ question.limit and line.size == question.limit
578
+ end
579
+
479
580
  def output_erase_char
480
581
  @output.print("\b#{HighLine.Style(:erase_char).code}")
481
582
  end
482
583
 
584
+ # Get response using #getc
585
+ # @param question [Question]
586
+ # @return [String] response
483
587
  def get_response_getc_mode(question)
484
588
  terminal.raw_no_echo_mode_exec do
485
589
  response = @input.getc
@@ -487,13 +591,16 @@ class HighLine
487
591
  end
488
592
  end
489
593
 
594
+ # Get response each character per turn
595
+ # @param question [Question]
596
+ # @return [String] response
490
597
  def get_response_character_mode(question)
491
598
  terminal.raw_no_echo_mode_exec do
492
599
  response = terminal.get_character
493
600
  if question.overwrite
494
601
  erase_current_line
495
602
  else
496
- echo = get_echo(question, response)
603
+ echo = question.get_echo_for_response(response)
497
604
  say("#{echo}\n")
498
605
  end
499
606
  question.format_answer(response)
@@ -505,16 +612,6 @@ class HighLine
505
612
  @output.flush
506
613
  end
507
614
 
508
- def get_echo(question, response)
509
- if question.echo == true
510
- response
511
- elsif question.echo != false
512
- question.echo
513
- else
514
- ""
515
- end
516
- end
517
-
518
615
  public :get_response_character_mode, :get_response_line_mode
519
616
  public :get_response_getc_mode
520
617