highline 1.7.10 → 2.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +5 -0
- data/.rubocop.yml +84 -0
- data/.simplecov +5 -0
- data/.travis.yml +35 -9
- data/Changelog.md +214 -15
- data/Gemfile +16 -5
- data/README.md +202 -0
- data/Rakefile +8 -20
- data/appveyor.yml +37 -0
- data/examples/ansi_colors.rb +6 -11
- data/examples/asking_for_arrays.rb +6 -2
- data/examples/basic_usage.rb +31 -21
- data/examples/color_scheme.rb +11 -10
- data/examples/get_character.rb +8 -4
- data/examples/limit.rb +4 -0
- data/examples/menus.rb +16 -10
- data/examples/overwrite.rb +9 -5
- data/examples/page_and_wrap.rb +5 -4
- data/examples/password.rb +4 -0
- data/examples/repeat_entry.rb +10 -5
- data/examples/trapping_eof.rb +2 -1
- data/examples/using_readline.rb +2 -1
- data/highline.gemspec +25 -27
- data/lib/highline/builtin_styles.rb +129 -0
- data/lib/highline/color_scheme.rb +49 -32
- data/lib/highline/compatibility.rb +11 -4
- data/lib/highline/custom_errors.rb +57 -0
- data/lib/highline/import.rb +19 -12
- data/lib/highline/io_console_compatible.rb +37 -0
- data/lib/highline/list.rb +177 -0
- data/lib/highline/list_renderer.rb +261 -0
- data/lib/highline/menu/item.rb +32 -0
- data/lib/highline/menu.rb +306 -111
- data/lib/highline/paginator.rb +52 -0
- data/lib/highline/question/answer_converter.rb +103 -0
- data/lib/highline/question.rb +281 -131
- data/lib/highline/question_asker.rb +150 -0
- data/lib/highline/simulate.rb +24 -13
- data/lib/highline/statement.rb +88 -0
- data/lib/highline/string.rb +36 -0
- data/lib/highline/string_extensions.rb +83 -64
- data/lib/highline/style.rb +196 -63
- data/lib/highline/template_renderer.rb +62 -0
- data/lib/highline/terminal/io_console.rb +36 -0
- data/lib/highline/terminal/ncurses.rb +38 -0
- data/lib/highline/terminal/unix_stty.rb +51 -0
- data/lib/highline/terminal.rb +190 -0
- data/lib/highline/version.rb +3 -1
- data/lib/highline/wrapper.rb +53 -0
- data/lib/highline.rb +390 -788
- metadata +56 -35
- data/INSTALL +0 -59
- data/README.rdoc +0 -74
- data/lib/highline/system_extensions.rb +0 -254
- data/setup.rb +0 -1360
- data/test/string_methods.rb +0 -32
- data/test/tc_color_scheme.rb +0 -96
- data/test/tc_highline.rb +0 -1402
- data/test/tc_import.rb +0 -52
- data/test/tc_menu.rb +0 -439
- data/test/tc_simulator.rb +0 -33
- data/test/tc_string_extension.rb +0 -33
- data/test/tc_string_highline.rb +0 -38
- data/test/tc_style.rb +0 -578
data/appveyor.yml
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
version: 2.0.{build}-{branch}
|
2
|
+
|
3
|
+
cache:
|
4
|
+
- vendor/bundle
|
5
|
+
|
6
|
+
environment:
|
7
|
+
matrix:
|
8
|
+
- RUBY_VERSION: "193"
|
9
|
+
- RUBY_VERSION: "200"
|
10
|
+
- RUBY_VERSION: "200-x64"
|
11
|
+
- RUBY_VERSION: "21"
|
12
|
+
- RUBY_VERSION: "21-x64"
|
13
|
+
- RUBY_VERSION: "22"
|
14
|
+
- RUBY_VERSION: "22-x64"
|
15
|
+
- RUBY_VERSION: "23"
|
16
|
+
- RUBY_VERSION: "23-x64"
|
17
|
+
- RUBY_VERSION: "24"
|
18
|
+
- RUBY_VERSION: "24-x64"
|
19
|
+
|
20
|
+
matrix:
|
21
|
+
allow_failures:
|
22
|
+
- RUBY_VERSION: "193"
|
23
|
+
|
24
|
+
install:
|
25
|
+
- set PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH%
|
26
|
+
- bundle config --local path vendor/bundle
|
27
|
+
- bundle install --retry=3 --without code_quality
|
28
|
+
|
29
|
+
build: off
|
30
|
+
|
31
|
+
before_test:
|
32
|
+
- ruby -v
|
33
|
+
- gem -v
|
34
|
+
- bundle -v
|
35
|
+
|
36
|
+
test_script:
|
37
|
+
- bundle exec rake
|
data/examples/ansi_colors.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
2
3
|
|
3
4
|
# ansi_colors.rb
|
4
5
|
#
|
@@ -9,19 +10,13 @@ require "rubygems"
|
|
9
10
|
require "highline/import"
|
10
11
|
|
11
12
|
# Supported color sequences.
|
12
|
-
colors = %w
|
13
|
+
colors = %w[black red green yellow blue magenta cyan white]
|
13
14
|
|
14
15
|
# Using color() with symbols.
|
15
16
|
colors.each_with_index do |c, i|
|
16
17
|
say("This should be <%= color('#{c}', :#{c}) %>!")
|
17
|
-
|
18
|
-
|
19
|
-
"<%= color('white on #{c}', :white, :on_#{c}) %>!")
|
20
|
-
else
|
21
|
-
say( "This should be " +
|
22
|
-
"<%= color( '#{colors[i - 1]} on #{c}',
|
23
|
-
:#{colors[i - 1]}, :on_#{c} ) %>!")
|
24
|
-
end
|
18
|
+
say("This should be <%= color('#{colors[i - 1]} on #{c}', \
|
19
|
+
:#{colors[i - 1]}, :on_#{c} ) %>!")
|
25
20
|
end
|
26
21
|
|
27
22
|
# Using color with constants.
|
@@ -32,7 +27,7 @@ say("This should be <%= color('underlined', UNDERLINE) %>!")
|
|
32
27
|
say("This might even <%= BLINK %>blink<%= CLEAR %>!")
|
33
28
|
|
34
29
|
# It even works with list wrapping.
|
35
|
-
erb_digits = %w
|
30
|
+
erb_digits = %w[Zero One Two Three Four] +
|
36
31
|
["<%= color('Five', :blue) %%>"] +
|
37
|
-
%w
|
32
|
+
%w[Six Seven Eight Nine]
|
38
33
|
say("<%= list(#{erb_digits.inspect}, :columns_down, 3) %>")
|
@@ -1,4 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
2
3
|
|
3
4
|
# asking_for_arrays.rb
|
4
5
|
#
|
@@ -9,8 +10,11 @@ require "rubygems"
|
|
9
10
|
require "highline/import"
|
10
11
|
require "pp"
|
11
12
|
|
12
|
-
|
13
|
-
|
13
|
+
puts "Using: #{HighLine.default_instance.class}"
|
14
|
+
puts
|
15
|
+
|
16
|
+
grades = ask("Enter test scores (or a blank line to quit):",
|
17
|
+
->(ans) { ans =~ /^-?\d+$/ ? Integer(ans) : ans }) do |q|
|
14
18
|
q.gather = ""
|
15
19
|
end
|
16
20
|
|
data/examples/basic_usage.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
2
3
|
|
3
4
|
# basic_usage.rb
|
4
5
|
#
|
@@ -9,32 +10,38 @@ require "rubygems"
|
|
9
10
|
require "highline/import"
|
10
11
|
require "yaml"
|
11
12
|
|
12
|
-
|
13
|
+
puts "Using: #{HighLine.default_instance.terminal.class}"
|
14
|
+
puts
|
13
15
|
|
16
|
+
contacts = []
|
17
|
+
|
18
|
+
# Just define a parse class method and use the class
|
19
|
+
# as a parser for HighLine#ask
|
20
|
+
#
|
14
21
|
class NameClass
|
15
|
-
def self.parse(
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
22
|
+
def self.parse(string)
|
23
|
+
raise ArgumentError, "Invalid name format." unless
|
24
|
+
string =~ /^\s*(\w+),\s*(\w+)\s*$/
|
25
|
+
|
26
|
+
new(Regexp.last_match(2), Regexp.last_match(1))
|
21
27
|
end
|
22
28
|
|
23
29
|
def initialize(first, last)
|
24
|
-
@first
|
30
|
+
@first = first
|
31
|
+
@last = last
|
25
32
|
end
|
26
33
|
|
27
34
|
attr_reader :first, :last
|
28
35
|
end
|
29
36
|
|
30
|
-
|
31
|
-
entry =
|
37
|
+
loop do
|
38
|
+
entry = {}
|
32
39
|
|
33
40
|
# basic output
|
34
41
|
say("Enter a contact:")
|
35
42
|
|
36
43
|
# basic input
|
37
|
-
entry[:name]
|
44
|
+
entry[:name] = ask("Name? (last, first) ", NameClass) do |q|
|
38
45
|
q.validate = /\A\w+, ?\w+\Z/
|
39
46
|
end
|
40
47
|
entry[:company] = ask("Company? ") { |q| q.default = "none" }
|
@@ -44,27 +51,30 @@ begin
|
|
44
51
|
q.case = :up
|
45
52
|
q.validate = /\A[A-Z]{2}\Z/
|
46
53
|
end
|
47
|
-
entry[:zip]
|
54
|
+
entry[:zip] = ask("Zip? ") do |q|
|
48
55
|
q.validate = /\A\d{5}(?:-?\d{4})?\Z/
|
49
56
|
end
|
50
|
-
entry[:phone]
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
57
|
+
entry[:phone] = ask("Phone? ",
|
58
|
+
lambda { |p|
|
59
|
+
p.delete("^0-9").
|
60
|
+
sub(/\A(\d{3})/, '(\1) ').
|
61
|
+
sub(/(\d{4})\Z/, '-\1')
|
62
|
+
}) do |q|
|
63
|
+
q.validate = ->(p) { p.delete("^0-9").length == 10 }
|
55
64
|
q.responses[:not_valid] = "Enter a phone numer with area code."
|
56
65
|
end
|
57
66
|
entry[:age] = ask("Age? ", Integer) { |q| q.in = 0..105 }
|
58
67
|
entry[:birthday] = ask("Birthday? ", Date)
|
59
|
-
entry[:interests] = ask(
|
60
|
-
|
68
|
+
entry[:interests] = ask("Interests? (comma separated list) ",
|
69
|
+
->(str) { str.split(/,\s*/) })
|
61
70
|
entry[:description] = ask("Enter a description for this contact.") do |q|
|
62
71
|
q.whitespace = :strip_and_collapse
|
63
72
|
end
|
64
73
|
|
65
74
|
contacts << entry
|
66
|
-
# shortcut for yes and no questions
|
67
|
-
|
75
|
+
# shortcut for yes and no questions
|
76
|
+
break unless agree("Enter another contact? ", true)
|
77
|
+
end
|
68
78
|
|
69
79
|
if agree("Save these contacts? ", true)
|
70
80
|
file_name = ask("Enter a file name: ") do |q|
|
data/examples/color_scheme.rb
CHANGED
@@ -1,20 +1,21 @@
|
|
1
1
|
#!/usr/bin/env ruby -w
|
2
|
+
# encoding: utf-8
|
2
3
|
|
3
4
|
# color_scheme.rb
|
4
5
|
#
|
5
6
|
# Created by Jeremy Hinegardner on 2007-01-24
|
6
7
|
# Copyright 2007 Jeremy Hinegardner. All rights reserved
|
7
8
|
|
8
|
-
require
|
9
|
-
require
|
9
|
+
require "rubygems"
|
10
|
+
require "highline/import"
|
10
11
|
|
11
12
|
# Create a color scheme, naming color patterns with symbol names.
|
12
13
|
ft = HighLine::ColorScheme.new do |cs|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
cs[:headline] = [:bold, :yellow, :on_black]
|
15
|
+
cs[:horizontal_line] = [:bold, :white, :on_blue]
|
16
|
+
cs[:even_row] = [:green]
|
17
|
+
cs[:odd_row] = [:magenta]
|
18
|
+
end
|
18
19
|
|
19
20
|
# Assign that color scheme to HighLine...
|
20
21
|
HighLine.color_scheme = ft
|
@@ -26,7 +27,7 @@ say("<%= color('-'*20, :horizontal_line) %>")
|
|
26
27
|
# Setup a toggle for rows.
|
27
28
|
i = true
|
28
29
|
("A".."D").each do |row|
|
29
|
-
|
30
|
-
|
31
|
-
|
30
|
+
row_color = i ? :even_row : :odd_row
|
31
|
+
say("<%= color('#{row}', '#{row_color}') %>")
|
32
|
+
i = !i
|
32
33
|
end
|
data/examples/get_character.rb
CHANGED
@@ -1,12 +1,16 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
2
3
|
|
3
4
|
require "rubygems"
|
4
5
|
require "highline/import"
|
5
6
|
|
7
|
+
puts "Using: #{HighLine.default_instance.terminal.class}"
|
8
|
+
puts
|
9
|
+
|
6
10
|
choices = "ynaq"
|
7
11
|
answer = ask("Your choice [#{choices}]? ") do |q|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
+
q.echo = false
|
13
|
+
q.character = true
|
14
|
+
q.validate = /\A[#{choices}]\Z/
|
15
|
+
end
|
12
16
|
say("Your choice: #{answer}")
|
data/examples/limit.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby -w
|
2
|
+
# encoding: utf-8
|
2
3
|
|
3
4
|
# limit.rb
|
4
5
|
#
|
@@ -8,5 +9,8 @@
|
|
8
9
|
require "rubygems"
|
9
10
|
require "highline/import"
|
10
11
|
|
12
|
+
puts "Using: #{HighLine.default_instance.terminal.class}"
|
13
|
+
puts
|
14
|
+
|
11
15
|
text = ask("Enter text (max 10 chars): ") { |q| q.limit = 10 }
|
12
16
|
puts "You entered: #{text}!"
|
data/examples/menus.rb
CHANGED
@@ -1,10 +1,14 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
2
3
|
|
3
4
|
require "rubygems"
|
4
5
|
require "highline/import"
|
5
6
|
|
7
|
+
puts "Using: #{HighLine.default_instance.terminal.class}"
|
8
|
+
puts
|
9
|
+
|
6
10
|
# The old way, using ask() and say()...
|
7
|
-
choices = %w
|
11
|
+
choices = %w[ruby python perl]
|
8
12
|
say("This is the old way using ask() and say()...")
|
9
13
|
say("Please choose your favorite programming language:")
|
10
14
|
say(choices.map { |c| " #{c}\n" }.join)
|
@@ -21,19 +25,21 @@ say("\nThis is the new mode (default)...")
|
|
21
25
|
choose do |menu|
|
22
26
|
menu.prompt = "Please choose your favorite programming language? "
|
23
27
|
|
24
|
-
menu.choice
|
25
|
-
menu.choices(:python, :perl)
|
28
|
+
menu.choice(:ruby) { say("Good choice!") }
|
29
|
+
menu.choices(:python, :perl) { say("Not from around here, are you?") }
|
30
|
+
|
31
|
+
menu.default = :ruby
|
26
32
|
end
|
27
33
|
|
28
34
|
say("\nThis is letter indexing...")
|
29
35
|
choose do |menu|
|
30
|
-
menu.index = :letter
|
36
|
+
menu.index = :letter # Use :capital_letter for uppercase
|
31
37
|
menu.index_suffix = ") "
|
32
38
|
|
33
39
|
menu.prompt = "Please choose your favorite programming language? "
|
34
40
|
|
35
|
-
menu.choice
|
36
|
-
menu.choices(:python, :perl)
|
41
|
+
menu.choice(:ruby) { say("Good choice!") }
|
42
|
+
menu.choices(:python, :perl) { say("Not from around here, are you?") }
|
37
43
|
end
|
38
44
|
|
39
45
|
say("\nThis is with a different layout...")
|
@@ -43,8 +49,8 @@ choose do |menu|
|
|
43
49
|
menu.header = "Languages"
|
44
50
|
menu.prompt = "Favorite? "
|
45
51
|
|
46
|
-
menu.choice
|
47
|
-
menu.choices(:python, :perl)
|
52
|
+
menu.choice(:ruby) { say("Good choice!") }
|
53
|
+
menu.choices(:python, :perl) { say("Not from around here, are you?") }
|
48
54
|
end
|
49
55
|
|
50
56
|
say("\nYou can even build shells...")
|
@@ -54,10 +60,10 @@ loop do
|
|
54
60
|
|
55
61
|
menu.shell = true
|
56
62
|
|
57
|
-
menu.choice(:load, "Load a file.") do |
|
63
|
+
menu.choice(:load, "Load a file.") do |_command, details|
|
58
64
|
say("Loading file with options: #{details}...")
|
59
65
|
end
|
60
|
-
menu.choice(:save, "Save a file.") do |
|
66
|
+
menu.choice(:save, "Save a file.") do |_command, details|
|
61
67
|
say("Saving file with options: #{details}...")
|
62
68
|
end
|
63
69
|
menu.choice(:quit, "Exit program.") { exit }
|
data/examples/overwrite.rb
CHANGED
@@ -1,19 +1,23 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
2
3
|
|
3
4
|
# overwrite.rb
|
4
5
|
#
|
5
6
|
# Created by Jeremy Hinegardner on 2007-01-24
|
6
7
|
# Copyright 2007 Jeremy Hinegardner. All rights reserved
|
7
8
|
|
8
|
-
require
|
9
|
-
require
|
9
|
+
require "rubygems"
|
10
|
+
require "highline/import"
|
11
|
+
|
12
|
+
puts "Using: #{HighLine.default_instance.terminal.class}"
|
13
|
+
puts
|
10
14
|
|
11
15
|
prompt = "here is your password:"
|
12
16
|
ask(
|
13
17
|
"#{prompt} <%= color('mypassword', RED, BOLD) %> (Press Any Key to blank) "
|
14
18
|
) do |q|
|
15
|
-
|
16
|
-
|
17
|
-
|
19
|
+
q.overwrite = true
|
20
|
+
q.echo = false # overwrite works best when echo is false.
|
21
|
+
q.character = true # if this is set to :getc then overwrite does not work
|
18
22
|
end
|
19
23
|
say("<%= color('Look! blanked out!', GREEN) %>")
|
data/examples/page_and_wrap.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
2
3
|
|
3
4
|
# page_and_wrap.rb
|
4
5
|
#
|
@@ -8,10 +9,10 @@
|
|
8
9
|
require "rubygems"
|
9
10
|
require "highline/import"
|
10
11
|
|
11
|
-
|
12
|
-
|
12
|
+
HighLine.default_instance.wrap_at = 80
|
13
|
+
HighLine.default_instance.page_at = 22
|
13
14
|
|
14
|
-
say(<<
|
15
|
+
say(<<CONSTITUTION)
|
15
16
|
THE UNITED STATES CONSTITUTION
|
16
17
|
|
17
18
|
We the People of the United States, in Order to form a more perfect Union, establish Justice, insure domestic Tranquility, provide for the common defence, promote the general Welfare, and secure the Blessings of Liberty to ourselves and our Posterity, do ordain and establish this Constitution for the United States of America.
|
@@ -319,4 +320,4 @@ James Wilson.
|
|
319
320
|
Gouv Morris
|
320
321
|
|
321
322
|
Attest William Jackson Secretary
|
322
|
-
|
323
|
+
CONSTITUTION
|
data/examples/password.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
2
3
|
|
3
4
|
require "rubygems"
|
4
5
|
require "highline/import"
|
5
6
|
|
7
|
+
puts "Using: #{HighLine.default_instance.terminal.class}"
|
8
|
+
puts
|
9
|
+
|
6
10
|
pass = ask("Enter your password: ") { |q| q.echo = false }
|
7
11
|
puts "Your password is #{pass}!"
|
data/examples/repeat_entry.rb
CHANGED
@@ -1,9 +1,14 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
2
3
|
|
3
4
|
require "rubygems"
|
4
5
|
require "highline/import"
|
5
6
|
|
6
|
-
|
7
|
+
puts "Using: #{HighLine.default_instance.terminal.class}"
|
8
|
+
puts
|
9
|
+
|
10
|
+
# tounge_twister
|
11
|
+
ask("... try saying that three times fast") do |q|
|
7
12
|
q.gather = 3
|
8
13
|
q.verify_match = true
|
9
14
|
q.responses[:mismatch] = "Nope, those don't match. Try again."
|
@@ -11,11 +16,11 @@ end
|
|
11
16
|
|
12
17
|
puts "Ok, you did it."
|
13
18
|
|
14
|
-
pass = ask("<%=
|
15
|
-
q.echo =
|
19
|
+
pass = ask("<%= key %>: ") do |q|
|
20
|
+
q.echo = "*"
|
16
21
|
q.verify_match = true
|
17
|
-
q.gather = {"Enter a password" =>
|
18
|
-
|
22
|
+
q.gather = { "Enter a password" => "",
|
23
|
+
"Please type it again for verification" => "" }
|
19
24
|
end
|
20
25
|
|
21
26
|
puts "Your password is now #{pass}!"
|
data/examples/trapping_eof.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
2
3
|
|
3
4
|
# trapping_eof.rb
|
4
5
|
#
|
@@ -13,7 +14,7 @@ loop do
|
|
13
14
|
name = ask("What's your name?")
|
14
15
|
break if name == "exit"
|
15
16
|
puts "Hello, #{name}!"
|
16
|
-
rescue EOFError
|
17
|
+
rescue EOFError # HighLine throws this if @input.eof?
|
17
18
|
break
|
18
19
|
end
|
19
20
|
end
|
data/examples/using_readline.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
2
3
|
|
3
4
|
# using_readline.rb
|
4
5
|
#
|
@@ -9,7 +10,7 @@ require "rubygems"
|
|
9
10
|
require "highline/import"
|
10
11
|
|
11
12
|
loop do
|
12
|
-
cmd = ask("Enter command: ", %w
|
13
|
+
cmd = ask("Enter command: ", %w[save sample load reset quit]) do |q|
|
13
14
|
q.readline = true
|
14
15
|
end
|
15
16
|
say("Executing \"#{cmd}\"...")
|
data/highline.gemspec
CHANGED
@@ -1,37 +1,35 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'highline/version'
|
5
|
-
|
6
|
-
GEM_VERSION = HighLine::VERSION
|
7
2
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
spec.platform = Gem::Platform::RUBY
|
12
|
-
spec.summary = "HighLine is a high-level command-line IO library."
|
13
|
-
spec.files = `git ls-files`.split("\n")
|
14
|
-
|
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'
|
3
|
+
lib = File.expand_path("../lib", __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require "highline/version"
|
20
6
|
|
21
|
-
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = "highline"
|
9
|
+
spec.version = HighLine::VERSION
|
10
|
+
spec.author = "James Edward Gray II"
|
11
|
+
spec.email = "james@graysoftinc.com"
|
22
12
|
|
23
|
-
spec.
|
24
|
-
spec.
|
25
|
-
spec.rubyforge_project = "highline"
|
26
|
-
spec.homepage = "https://github.com/JEG2/highline"
|
27
|
-
spec.license = "Ruby"
|
28
|
-
spec.description = <<END_DESC
|
13
|
+
spec.summary = "HighLine is a high-level command-line IO library."
|
14
|
+
spec.description = <<DESCRIPTION
|
29
15
|
A high-level IO library that provides validation, type conversion, and more for
|
30
16
|
command-line interfaces. HighLine also includes a complete menu system that can
|
31
17
|
crank out anything from simple list selection to complete shells with just
|
32
18
|
minutes of work.
|
33
|
-
|
19
|
+
DESCRIPTION
|
20
|
+
spec.homepage = "https://github.com/JEG2/highline"
|
21
|
+
spec.license = "Ruby"
|
22
|
+
|
23
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
24
|
+
f.match(%r{^(test|spec|features)/})
|
25
|
+
end
|
26
|
+
spec.require_paths = ["lib"]
|
27
|
+
|
28
|
+
spec.extra_rdoc_files = %w[README.md TODO Changelog.md LICENSE]
|
29
|
+
|
30
|
+
spec.required_ruby_version = ">= 1.9.3"
|
34
31
|
|
35
|
-
spec.add_development_dependency "
|
36
|
-
spec.
|
32
|
+
spec.add_development_dependency "bundler"
|
33
|
+
spec.add_development_dependency "rake"
|
34
|
+
spec.add_development_dependency "minitest"
|
37
35
|
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
class HighLine
|
4
|
+
# Builtin Styles that are included at HighLine initialization.
|
5
|
+
# It has the basic styles like :bold and :underline.
|
6
|
+
module BuiltinStyles
|
7
|
+
# Included callback
|
8
|
+
# @param base [Class, Module] base class
|
9
|
+
def self.included(base)
|
10
|
+
base.extend ClassMethods
|
11
|
+
end
|
12
|
+
|
13
|
+
# Basic styles' ANSI escape codes like :bold => "\e[1m"
|
14
|
+
STYLE_LIST = {
|
15
|
+
erase_line: "\e[K",
|
16
|
+
erase_char: "\e[P",
|
17
|
+
clear: "\e[0m",
|
18
|
+
reset: "\e[0m",
|
19
|
+
bold: "\e[1m",
|
20
|
+
dark: "\e[2m",
|
21
|
+
underline: "\e[4m",
|
22
|
+
underscore: "\e[4m",
|
23
|
+
blink: "\e[5m",
|
24
|
+
reverse: "\e[7m",
|
25
|
+
concealed: "\e[8m"
|
26
|
+
}.freeze
|
27
|
+
|
28
|
+
STYLE_LIST.each do |style_name, code|
|
29
|
+
style = String(style_name).upcase
|
30
|
+
|
31
|
+
const_set style, code
|
32
|
+
const_set style + "_STYLE",
|
33
|
+
Style.new(name: style_name, code: code, builtin: true)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Basic Style names like CLEAR, BOLD, UNDERLINE
|
37
|
+
STYLES = %w[CLEAR RESET BOLD DARK UNDERLINE
|
38
|
+
UNDERSCORE BLINK REVERSE CONCEALED].freeze
|
39
|
+
|
40
|
+
# A Hash with the basic colors an their ANSI escape codes.
|
41
|
+
COLOR_LIST = {
|
42
|
+
black: { code: "\e[30m", rgb: [0, 0, 0] },
|
43
|
+
red: { code: "\e[31m", rgb: [128, 0, 0] },
|
44
|
+
green: { code: "\e[32m", rgb: [0, 128, 0] },
|
45
|
+
blue: { code: "\e[34m", rgb: [0, 0, 128] },
|
46
|
+
yellow: { code: "\e[33m", rgb: [128, 128, 0] },
|
47
|
+
magenta: { code: "\e[35m", rgb: [128, 0, 128] },
|
48
|
+
cyan: { code: "\e[36m", rgb: [0, 128, 128] },
|
49
|
+
white: { code: "\e[37m", rgb: [192, 192, 192] },
|
50
|
+
gray: { code: "\e[37m", rgb: [192, 192, 192] },
|
51
|
+
grey: { code: "\e[37m", rgb: [192, 192, 192] },
|
52
|
+
none: { code: "\e[38m", rgb: [0, 0, 0] }
|
53
|
+
}.freeze
|
54
|
+
|
55
|
+
COLOR_LIST.each do |color_name, attributes|
|
56
|
+
color = String(color_name).upcase
|
57
|
+
|
58
|
+
style = Style.new(
|
59
|
+
name: color_name,
|
60
|
+
code: attributes[:code],
|
61
|
+
rgb: attributes[:rgb],
|
62
|
+
builtin: true
|
63
|
+
)
|
64
|
+
|
65
|
+
const_set color + "_STYLE", style
|
66
|
+
end
|
67
|
+
|
68
|
+
# The builtin styles basic colors like black, red, green.
|
69
|
+
BASIC_COLORS =
|
70
|
+
%w[BLACK RED GREEN YELLOW BLUE
|
71
|
+
MAGENTA CYAN WHITE GRAY GREY NONE].freeze
|
72
|
+
|
73
|
+
colors = BASIC_COLORS.dup
|
74
|
+
BASIC_COLORS.each do |color|
|
75
|
+
bright_color = "BRIGHT_#{color}"
|
76
|
+
colors << bright_color
|
77
|
+
const_set bright_color + "_STYLE", const_get(color + "_STYLE").bright
|
78
|
+
|
79
|
+
light_color = "LIGHT_#{color}"
|
80
|
+
colors << light_color
|
81
|
+
const_set light_color + "_STYLE", const_get(color + "_STYLE").light
|
82
|
+
end
|
83
|
+
|
84
|
+
# The builtin styles' colors like LIGHT_RED and BRIGHT_BLUE.
|
85
|
+
COLORS = colors
|
86
|
+
|
87
|
+
colors.each do |color|
|
88
|
+
const_set color, const_get("#{color}_STYLE").code
|
89
|
+
const_set "ON_#{color}_STYLE", const_get("#{color}_STYLE").on
|
90
|
+
const_set "ON_#{color}", const_get("ON_#{color}_STYLE").code
|
91
|
+
end
|
92
|
+
|
93
|
+
ON_NONE_STYLE.rgb = [255, 255, 255] # Override; white background
|
94
|
+
|
95
|
+
# BuiltinStyles class methods to be extended.
|
96
|
+
module ClassMethods
|
97
|
+
# Regexp to match against RGB style constant names.
|
98
|
+
RGB_COLOR_PATTERN = /^(ON_)?(RGB_)([A-F0-9]{6})(_STYLE)?$/
|
99
|
+
|
100
|
+
# const_missing callback for automatically respond to
|
101
|
+
# builtin constants (without explicitly defining them)
|
102
|
+
# @param name [Symbol] missing constant name
|
103
|
+
def const_missing(name)
|
104
|
+
raise NameError, "Bad color or uninitialized constant #{name}" unless
|
105
|
+
name.to_s =~ RGB_COLOR_PATTERN
|
106
|
+
|
107
|
+
on = Regexp.last_match(1)
|
108
|
+
suffix = Regexp.last_match(4)
|
109
|
+
|
110
|
+
code_name = if suffix
|
111
|
+
Regexp.last_match(1).to_s +
|
112
|
+
Regexp.last_match(2) +
|
113
|
+
Regexp.last_match(3)
|
114
|
+
else
|
115
|
+
name.to_s
|
116
|
+
end
|
117
|
+
|
118
|
+
style_name = code_name + "_STYLE"
|
119
|
+
style = Style.rgb(Regexp.last_match(3))
|
120
|
+
style = style.on if on
|
121
|
+
|
122
|
+
const_set(style_name, style)
|
123
|
+
const_set(code_name, style.code)
|
124
|
+
|
125
|
+
suffix ? style : style.code
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|