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

Sign up to get free protection for your applications and to get access to all the features.
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