highline 1.7.10 → 2.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +5 -0
  3. data/.rubocop.yml +84 -0
  4. data/.simplecov +5 -0
  5. data/.travis.yml +35 -9
  6. data/Changelog.md +214 -15
  7. data/Gemfile +16 -5
  8. data/README.md +202 -0
  9. data/Rakefile +8 -20
  10. data/appveyor.yml +37 -0
  11. data/examples/ansi_colors.rb +6 -11
  12. data/examples/asking_for_arrays.rb +6 -2
  13. data/examples/basic_usage.rb +31 -21
  14. data/examples/color_scheme.rb +11 -10
  15. data/examples/get_character.rb +8 -4
  16. data/examples/limit.rb +4 -0
  17. data/examples/menus.rb +16 -10
  18. data/examples/overwrite.rb +9 -5
  19. data/examples/page_and_wrap.rb +5 -4
  20. data/examples/password.rb +4 -0
  21. data/examples/repeat_entry.rb +10 -5
  22. data/examples/trapping_eof.rb +2 -1
  23. data/examples/using_readline.rb +2 -1
  24. data/highline.gemspec +25 -27
  25. data/lib/highline/builtin_styles.rb +129 -0
  26. data/lib/highline/color_scheme.rb +49 -32
  27. data/lib/highline/compatibility.rb +11 -4
  28. data/lib/highline/custom_errors.rb +57 -0
  29. data/lib/highline/import.rb +19 -12
  30. data/lib/highline/io_console_compatible.rb +37 -0
  31. data/lib/highline/list.rb +177 -0
  32. data/lib/highline/list_renderer.rb +261 -0
  33. data/lib/highline/menu/item.rb +32 -0
  34. data/lib/highline/menu.rb +306 -111
  35. data/lib/highline/paginator.rb +52 -0
  36. data/lib/highline/question/answer_converter.rb +103 -0
  37. data/lib/highline/question.rb +281 -131
  38. data/lib/highline/question_asker.rb +150 -0
  39. data/lib/highline/simulate.rb +24 -13
  40. data/lib/highline/statement.rb +88 -0
  41. data/lib/highline/string.rb +36 -0
  42. data/lib/highline/string_extensions.rb +83 -64
  43. data/lib/highline/style.rb +196 -63
  44. data/lib/highline/template_renderer.rb +62 -0
  45. data/lib/highline/terminal/io_console.rb +36 -0
  46. data/lib/highline/terminal/ncurses.rb +38 -0
  47. data/lib/highline/terminal/unix_stty.rb +51 -0
  48. data/lib/highline/terminal.rb +190 -0
  49. data/lib/highline/version.rb +3 -1
  50. data/lib/highline/wrapper.rb +53 -0
  51. data/lib/highline.rb +390 -788
  52. metadata +56 -35
  53. data/INSTALL +0 -59
  54. data/README.rdoc +0 -74
  55. data/lib/highline/system_extensions.rb +0 -254
  56. data/setup.rb +0 -1360
  57. data/test/string_methods.rb +0 -32
  58. data/test/tc_color_scheme.rb +0 -96
  59. data/test/tc_highline.rb +0 -1402
  60. data/test/tc_import.rb +0 -52
  61. data/test/tc_menu.rb +0 -439
  62. data/test/tc_simulator.rb +0 -33
  63. data/test/tc_string_extension.rb +0 -33
  64. data/test/tc_string_highline.rb +0 -38
  65. 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
@@ -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{black red green yellow blue magenta cyan white}
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
- if i == 0
18
- say( "This should be " +
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{Zero One Two Three Four} +
30
+ erb_digits = %w[Zero One Two Three Four] +
36
31
  ["<%= color('Five', :blue) %%>"] +
37
- %w{Six Seven Eight Nine}
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
- grades = ask( "Enter test scores (or a blank line to quit):",
13
- lambda { |ans| ans =~ /^-?\d+$/ ? Integer(ans) : ans} ) do |q|
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
 
@@ -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
- contacts = [ ]
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( string )
16
- if string =~ /^\s*(\w+),\s*(\w+)\s*$/
17
- self.new($2, $1)
18
- else
19
- raise ArgumentError, "Invalid name format."
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, @last = first, last
30
+ @first = first
31
+ @last = last
25
32
  end
26
33
 
27
34
  attr_reader :first, :last
28
35
  end
29
36
 
30
- begin
31
- entry = Hash.new
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] = ask("Name? (last, first) ", NameClass) do |q|
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] = ask("Zip? ") do |q|
54
+ entry[:zip] = ask("Zip? ") do |q|
48
55
  q.validate = /\A\d{5}(?:-?\d{4})?\Z/
49
56
  end
50
- entry[:phone] = ask( "Phone? ",
51
- lambda { |p| p.delete("^0-9").
52
- sub(/\A(\d{3})/, '(\1) ').
53
- sub(/(\d{4})\Z/, '-\1') } ) do |q|
54
- q.validate = lambda { |p| p.delete("^0-9").length == 10 }
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( "Interests? (comma separated list) ",
60
- lambda { |str| str.split(/,\s*/) } )
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
- end while agree("Enter another contact? ", true)
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|
@@ -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 'rubygems'
9
- require 'highline/import'
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
- cs[:headline] = [ :bold, :yellow, :on_black ]
14
- cs[:horizontal_line] = [ :bold, :white, :on_blue]
15
- cs[:even_row] = [ :green ]
16
- cs[:odd_row] = [ :magenta ]
17
- end
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
- row_color = i ? :even_row : :odd_row
30
- say("<%= color('#{row}', '#{row_color}') %>")
31
- i = !i
30
+ row_color = i ? :even_row : :odd_row
31
+ say("<%= color('#{row}', '#{row_color}') %>")
32
+ i = !i
32
33
  end
@@ -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
- q.echo = false
9
- q.character = true
10
- q.validate = /\A[#{choices}]\Z/
11
- end
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{ruby python perl}
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 :ruby do say("Good choice!") end
25
- menu.choices(:python, :perl) do say("Not from around here, are you?") end
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 :ruby do say("Good choice!") end
36
- menu.choices(:python, :perl) do say("Not from around here, are you?") end
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 :ruby do say("Good choice!") end
47
- menu.choices(:python, :perl) do say("Not from around here, are you?") end
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 |command, details|
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 |command, details|
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 }
@@ -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 'rubygems'
9
- require 'highline/import'
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
- q.overwrite = true
16
- q.echo = false # overwrite works best when echo is false.
17
- q.character = true # if this is set to :getc then overwrite does not work
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) %>")
@@ -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
- $terminal.wrap_at = 80
12
- $terminal.page_at = 22
12
+ HighLine.default_instance.wrap_at = 80
13
+ HighLine.default_instance.page_at = 22
13
14
 
14
- say(<<END)
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
- END
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}!"
@@ -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
- tounge_twister = ask("... try saying that three times fast") do |q|
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("<%= @key %>: ") do |q|
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
- "Please type it again for verification" => ''}
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}!"
@@ -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 # HighLine throws this if @input.eof?
17
+ rescue EOFError # HighLine throws this if @input.eof?
17
18
  break
18
19
  end
19
20
  end
@@ -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{save sample load reset quit}) do |q|
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
- SPEC = Gem::Specification.new do |spec|
9
- spec.name = "highline"
10
- spec.version = GEM_VERSION
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
- spec.require_path = 'lib'
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.author = "James Edward Gray II"
24
- spec.email = "james@graysoftinc.com"
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
- END_DESC
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 "code_statistics"
36
- spec.required_ruby_version = '>= 1.9.3'
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