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 +4 -4
- data/Changelog.md +28 -0
- data/README.md +188 -0
- data/Rakefile +0 -11
- data/highline.gemspec +2 -4
- data/lib/highline.rb +170 -73
- data/lib/highline/builtin_styles.rb +18 -2
- data/lib/highline/color_scheme.rb +15 -5
- data/lib/highline/compatibility.rb +6 -1
- data/lib/highline/custom_errors.rb +43 -6
- data/lib/highline/import.rb +10 -3
- data/lib/highline/list.rb +95 -7
- data/lib/highline/list_renderer.rb +36 -17
- data/lib/highline/menu.rb +73 -18
- data/lib/highline/paginator.rb +10 -0
- data/lib/highline/question.rb +98 -41
- data/lib/highline/question/answer_converter.rb +19 -0
- data/lib/highline/question_asker.rb +21 -17
- data/lib/highline/simulate.rb +10 -1
- data/lib/highline/statement.rb +62 -38
- data/lib/highline/string.rb +26 -25
- data/lib/highline/string_extensions.rb +60 -32
- data/lib/highline/style.rb +125 -25
- data/lib/highline/template_renderer.rb +25 -1
- data/lib/highline/terminal.rb +124 -1
- data/lib/highline/terminal/io_console.rb +6 -75
- data/lib/highline/terminal/ncurses.rb +7 -8
- data/lib/highline/terminal/unix_stty.rb +35 -81
- data/lib/highline/version.rb +1 -1
- data/lib/highline/wrapper.rb +9 -0
- data/test/test_highline.rb +1 -1
- metadata +6 -13
- data/INSTALL +0 -59
- data/README.rdoc +0 -77
- data/setup.rb +0 -1360
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe7f4a2acbc139058d22c6e720cf45f3d8807278
|
4
|
+
data.tar.gz: 4a2e208bb898d2498f5911efaa695095341cb43c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f276ad26eb858d757254770be10c6a007b0c4032078ef7f750b677499ed19c43315b0518d802480fd3cb9b8f2804286bdfd255ea647a85f5209be312dd8ab90
|
7
|
+
data.tar.gz: ab6323e8a8a16a5912328700cb207ca9009a60f05772102bf643db3ca8dd4b21dc7a527d79aad8113cbb32f2d6a1ed66297220d3faf86c3ca43d8befa85a8034
|
data/Changelog.md
CHANGED
@@ -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)
|
data/README.md
ADDED
@@ -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
|
data/highline.gemspec
CHANGED
@@ -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 =
|
17
|
-
spec.extra_rdoc_files = %w[README.
|
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
|
|
data/lib/highline.rb
CHANGED
@@ -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
|
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
|
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
|
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
|
-
|
147
|
+
|
148
|
+
# @return [Integer] The current row setting for paging output.
|
134
149
|
attr_reader :page_at
|
135
|
-
|
150
|
+
|
151
|
+
# @return [Boolean] Indentation over multiple lines
|
136
152
|
attr_accessor :multi_indent
|
137
|
-
|
153
|
+
|
154
|
+
# @return [Integer] The indentation size in characters
|
138
155
|
attr_accessor :indent_size
|
139
|
-
|
156
|
+
|
157
|
+
# @return [Integer] The indentation level
|
140
158
|
attr_accessor :indent_level
|
141
159
|
|
142
|
-
|
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
|
176
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
265
|
-
|
266
|
-
|
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
|
-
#
|
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
|
443
|
-
|
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
|
-
|
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
|
-
|
472
|
-
|
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
|
-
|
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 =
|
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
|
|