highline 1.7.10 → 2.0.0.pre.develop.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.simplecov +5 -0
  4. data/.travis.yml +11 -6
  5. data/Changelog.md +112 -20
  6. data/Gemfile +8 -7
  7. data/README.rdoc +3 -0
  8. data/Rakefile +7 -2
  9. data/appveyor.yml +19 -0
  10. data/examples/asking_for_arrays.rb +3 -0
  11. data/examples/basic_usage.rb +3 -0
  12. data/examples/get_character.rb +3 -0
  13. data/examples/limit.rb +3 -0
  14. data/examples/menus.rb +3 -0
  15. data/examples/overwrite.rb +3 -0
  16. data/examples/password.rb +3 -0
  17. data/examples/repeat_entry.rb +4 -1
  18. data/lib/highline.rb +182 -704
  19. data/lib/highline/builtin_styles.rb +109 -0
  20. data/lib/highline/color_scheme.rb +4 -1
  21. data/lib/highline/compatibility.rb +2 -0
  22. data/lib/highline/custom_errors.rb +19 -0
  23. data/lib/highline/import.rb +4 -2
  24. data/lib/highline/list.rb +93 -0
  25. data/lib/highline/list_renderer.rb +232 -0
  26. data/lib/highline/menu.rb +20 -20
  27. data/lib/highline/paginator.rb +43 -0
  28. data/lib/highline/question.rb +157 -97
  29. data/lib/highline/question/answer_converter.rb +84 -0
  30. data/lib/highline/question_asker.rb +147 -0
  31. data/lib/highline/simulate.rb +5 -1
  32. data/lib/highline/statement.rb +58 -0
  33. data/lib/highline/string.rb +34 -0
  34. data/lib/highline/string_extensions.rb +3 -28
  35. data/lib/highline/style.rb +18 -8
  36. data/lib/highline/template_renderer.rb +38 -0
  37. data/lib/highline/terminal.rb +78 -0
  38. data/lib/highline/terminal/io_console.rb +98 -0
  39. data/lib/highline/terminal/ncurses.rb +38 -0
  40. data/lib/highline/terminal/unix_stty.rb +94 -0
  41. data/lib/highline/version.rb +3 -1
  42. data/lib/highline/wrapper.rb +43 -0
  43. data/test/acceptance/acceptance.rb +62 -0
  44. data/test/acceptance/acceptance_test.rb +69 -0
  45. data/test/acceptance/at_color_output_using_erb_templates.rb +17 -0
  46. data/test/acceptance/at_echo_false.rb +23 -0
  47. data/test/acceptance/at_readline.rb +37 -0
  48. data/test/io_console_compatible.rb +37 -0
  49. data/test/string_methods.rb +3 -0
  50. data/test/test_answer_converter.rb +26 -0
  51. data/test/{tc_color_scheme.rb → test_color_scheme.rb} +7 -9
  52. data/test/test_helper.rb +26 -0
  53. data/test/{tc_highline.rb → test_highline.rb} +193 -136
  54. data/test/{tc_import.rb → test_import.rb} +5 -2
  55. data/test/test_list.rb +60 -0
  56. data/test/{tc_menu.rb → test_menu.rb} +6 -3
  57. data/test/test_paginator.rb +73 -0
  58. data/test/test_question_asker.rb +20 -0
  59. data/test/test_simulator.rb +24 -0
  60. data/test/test_string_extension.rb +72 -0
  61. data/test/{tc_string_highline.rb → test_string_highline.rb} +7 -3
  62. data/test/{tc_style.rb → test_style.rb} +70 -35
  63. data/test/test_wrapper.rb +188 -0
  64. metadata +57 -22
  65. data/lib/highline/system_extensions.rb +0 -254
  66. data/test/tc_simulator.rb +0 -33
  67. data/test/tc_string_extension.rb +0 -33
@@ -0,0 +1,38 @@
1
+ # coding: utf-8
2
+
3
+ require 'forwardable'
4
+
5
+ class HighLine
6
+ class TemplateRenderer
7
+ extend Forwardable
8
+
9
+ def_delegators :@highline, :color, :list, :key
10
+ def_delegators :@source, :answer_type, :prompt, :header, :answer
11
+
12
+ attr_reader :template, :source, :highline
13
+
14
+ def initialize(template, source, highline)
15
+ @template = template
16
+ @source = source
17
+ @highline = highline
18
+ end
19
+
20
+ def render
21
+ template.result(binding)
22
+ end
23
+
24
+ def method_missing(method, *args)
25
+ "Method #{method} with args #{args.inspect} " +
26
+ "is not available on #{self.inspect}. " +
27
+ "Try #{methods(false).sort.inspect}"
28
+ end
29
+
30
+ def menu
31
+ source
32
+ end
33
+
34
+ def self.const_missing(name)
35
+ HighLine.const_get(name)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,78 @@
1
+ # coding: utf-8
2
+
3
+ #--
4
+ # terminal.rb
5
+ #
6
+ # Originally created by James Edward Gray II on 2006-06-14 as
7
+ # system_extensions.rb.
8
+ # Copyright 2006 Gray Productions. All rights reserved.
9
+ #
10
+ # This is Free Software. See LICENSE and COPYING for details.
11
+
12
+ require "highline/compatibility"
13
+
14
+ class HighLine
15
+ class Terminal
16
+ def self.get_terminal(input, output)
17
+ terminal = nil
18
+
19
+ # First of all, probe for io/console
20
+ begin
21
+ require "io/console"
22
+ require "highline/terminal/io_console"
23
+ terminal = HighLine::Terminal::IOConsole.new(input, output)
24
+ rescue LoadError
25
+ end
26
+
27
+ # Fall back to UnixStty
28
+ unless terminal
29
+ require 'highline/terminal/unix_stty'
30
+ terminal = HighLine::Terminal::UnixStty.new(input, output)
31
+ end
32
+
33
+ terminal.initialize_system_extensions
34
+ terminal
35
+ end
36
+
37
+ attr_reader :input, :output
38
+
39
+ def initialize(input, output)
40
+ @input = input
41
+ @output = output
42
+ end
43
+
44
+ def initialize_system_extensions
45
+ end
46
+
47
+ def terminal_size
48
+ end
49
+
50
+ def raw_no_echo_mode
51
+ end
52
+
53
+ def raw_no_echo_mode_exec
54
+ raw_no_echo_mode
55
+ yield
56
+ ensure
57
+ restore_mode
58
+ end
59
+
60
+ def restore_mode
61
+ end
62
+
63
+ def get_character
64
+ end
65
+
66
+ def jruby?
67
+ defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
68
+ end
69
+
70
+ def rubinius?
71
+ defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
72
+ end
73
+
74
+ def windows?
75
+ defined?(RUBY_PLATFORM) && (RUBY_PLATFORM =~ /mswin|mingw|cygwin/)
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,98 @@
1
+ # coding: utf-8
2
+
3
+ class HighLine
4
+ class Terminal
5
+ class IOConsole < Terminal
6
+ def terminal_size
7
+ output.winsize.reverse
8
+ end
9
+
10
+ CHARACTER_MODE = "io_console" # For Debugging purposes only.
11
+
12
+ def raw_no_echo_mode
13
+ input.echo = false
14
+ end
15
+
16
+ def restore_mode
17
+ input.echo = true
18
+ end
19
+
20
+ def get_character
21
+ input.getch # from ruby io/console
22
+ end
23
+
24
+ def character_mode
25
+ "io_console"
26
+ end
27
+
28
+ def get_line(question, highline, options={})
29
+ raw_answer =
30
+ if question.readline
31
+ get_line_with_readline(question, highline, options={})
32
+ else
33
+ get_line_default(highline)
34
+ end
35
+
36
+ question.format_answer(raw_answer)
37
+ end
38
+
39
+ def get_line_with_readline(question, highline, options={})
40
+ require "readline" # load only if needed
41
+
42
+ question_string = highline.render_statement(question)
43
+
44
+ raw_answer = readline_read(question_string, question)
45
+
46
+ if !raw_answer and highline.track_eof?
47
+ raise EOFError, "The input stream is exhausted."
48
+ end
49
+
50
+ raw_answer || ""
51
+ end
52
+
53
+ def readline_read(string, question)
54
+ # prep auto-completion
55
+ unless question.selection.empty?
56
+ Readline.completion_proc = lambda do |str|
57
+ question.selection.grep(/\A#{Regexp.escape(str)}/)
58
+ end
59
+ end
60
+
61
+ # work-around ugly readline() warnings
62
+ old_verbose = $VERBOSE
63
+ $VERBOSE = nil
64
+
65
+ raw_answer = run_preserving_stty do
66
+ Readline.readline(string, true)
67
+ end
68
+
69
+ $VERBOSE = old_verbose
70
+
71
+ raw_answer
72
+ end
73
+
74
+ def get_line_default(highline)
75
+ raise EOFError, "The input stream is exhausted." if highline.track_eof? and
76
+ highline.input.eof?
77
+ highline.input.gets
78
+ end
79
+
80
+ private
81
+
82
+ def run_preserving_stty
83
+ save_stty
84
+ yield
85
+ ensure
86
+ restore_stty
87
+ end
88
+
89
+ def save_stty
90
+ @stty_save = `stty -g`.chomp rescue nil
91
+ end
92
+
93
+ def restore_stty
94
+ system("stty", @stty_save) if @stty_save
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,38 @@
1
+ # coding: utf-8
2
+
3
+ # TODO:
4
+ # Code below to be discussed.
5
+ # Will we maintain an ncurses version of HighLine::Terminal?
6
+ # If so, port it to the new api.
7
+
8
+ class HighLine
9
+ module SystemExtensions
10
+ module NCurses
11
+ require 'ffi-ncurses'
12
+ CHARACTER_MODE = "ncurses" # For Debugging purposes only.
13
+
14
+ def raw_no_echo_mode
15
+ FFI::NCurses.initscr
16
+ FFI::NCurses.cbreak
17
+ end
18
+
19
+ def restore_mode
20
+ FFI::NCurses.endwin
21
+ end
22
+
23
+ #
24
+ # A ncurses savvy method to fetch the console columns, and rows.
25
+ #
26
+ def terminal_size
27
+ size = [80, 40]
28
+ FFI::NCurses.initscr
29
+ begin
30
+ size = FFI::NCurses.getmaxyx(FFI::NCurses.stdscr).reverse
31
+ ensure
32
+ FFI::NCurses.endwin
33
+ end
34
+ size
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,94 @@
1
+ # coding: utf-8
2
+
3
+ class HighLine
4
+ class Terminal::UnixStty < Terminal
5
+
6
+ # A Unix savvy method using stty to fetch the console columns, and rows.
7
+ # ... stty does not work in JRuby
8
+ def terminal_size
9
+ begin
10
+ require "io/console"
11
+ winsize = IO.console.winsize.reverse rescue nil
12
+ return winsize if winsize
13
+ rescue LoadError
14
+ end
15
+
16
+ if /solaris/ =~ RUBY_PLATFORM and
17
+ `stty` =~ /\brows = (\d+).*\bcolumns = (\d+)/
18
+ [$2, $1].map { |c| x.to_i }
19
+ elsif `stty size` =~ /^(\d+)\s(\d+)$/
20
+ [$2.to_i, $1.to_i]
21
+ else
22
+ [ 80, 24 ]
23
+ end
24
+ end
25
+
26
+ # *WARNING*: This requires the external "stty" program!
27
+ CHARACTER_MODE = "unix_stty" # For Debugging purposes only.
28
+
29
+ def raw_no_echo_mode
30
+ @state = `stty -g`
31
+ system "stty raw -echo -icanon isig"
32
+ end
33
+
34
+ def restore_mode
35
+ system "stty #{@state}"
36
+ print "\r"
37
+ end
38
+
39
+ def get_character( input = STDIN )
40
+ input.getc
41
+ end
42
+
43
+ def character_mode
44
+ "unix_stty"
45
+ end
46
+
47
+ def get_line(question, highline, options={})
48
+ raw_answer =
49
+ if question.readline
50
+ get_line_with_readline(question, highline, options={})
51
+ else
52
+ get_line_default(highline)
53
+ end
54
+
55
+ question.format_answer(raw_answer)
56
+ end
57
+
58
+ def get_line_with_readline(question, highline, options={})
59
+ require "readline" # load only if needed
60
+
61
+ question_string = highline.render_statement(question)
62
+
63
+ raw_answer = readline_read(question_string, question)
64
+
65
+ if !raw_answer and highline.track_eof?
66
+ raise EOFError, "The input stream is exhausted."
67
+ end
68
+
69
+ raw_answer || ""
70
+ end
71
+
72
+ def readline_read(string, question)
73
+ # prep auto-completion
74
+ Readline.completion_proc = lambda do |string|
75
+ question.selection.grep(/\A#{Regexp.escape(string)}/)
76
+ end
77
+
78
+ # work-around ugly readline() warnings
79
+ old_verbose = $VERBOSE
80
+ $VERBOSE = nil
81
+ raw_answer = Readline.readline(string, true)
82
+
83
+ $VERBOSE = old_verbose
84
+
85
+ raw_answer
86
+ end
87
+
88
+ def get_line_default(highline)
89
+ raise EOFError, "The input stream is exhausted." if highline.track_eof? and
90
+ highline.input.eof?
91
+ highline.input.gets
92
+ end
93
+ end
94
+ end
@@ -1,4 +1,6 @@
1
+ # coding: utf-8
2
+
1
3
  class HighLine
2
4
  # The version of the installed library.
3
- VERSION = "1.7.10".freeze
5
+ VERSION = "2.0.0-develop.2".freeze
4
6
  end
@@ -0,0 +1,43 @@
1
+ # coding: utf-8
2
+
3
+ class HighLine
4
+ module Wrapper
5
+
6
+ #
7
+ # Wrap a sequence of _lines_ at _wrap_at_ characters per line. Existing
8
+ # newlines will not be affected by this process, but additional newlines
9
+ # may be added.
10
+ #
11
+ def self.wrap(text, wrap_at)
12
+ return text unless wrap_at
13
+ wrap_at = Integer(wrap_at)
14
+
15
+ wrapped = [ ]
16
+ text.each_line do |line|
17
+ # take into account color escape sequences when wrapping
18
+ wrap_at = wrap_at + (line.length - actual_length(line))
19
+ while line =~ /([^\n]{#{wrap_at + 1},})/
20
+ search = $1.dup
21
+ replace = $1.dup
22
+ if index = replace.rindex(" ", wrap_at)
23
+ replace[index, 1] = "\n"
24
+ replace.sub!(/\n[ \t]+/, "\n")
25
+ line.sub!(search, replace)
26
+ else
27
+ line[$~.begin(1) + wrap_at, 0] = "\n"
28
+ end
29
+ end
30
+ wrapped << line
31
+ end
32
+ return wrapped.join
33
+ end
34
+
35
+ #
36
+ # Returns the length of the passed +string_with_escapes+, minus and color
37
+ # sequence escapes.
38
+ #
39
+ def self.actual_length( string_with_escapes )
40
+ string_with_escapes.to_s.gsub(/\e\[\d{1,2}m/, "").length
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ current_dir = File.dirname(File.expand_path(__FILE__))
5
+
6
+ # All acceptance test files begins with 'at_'
7
+ acceptance_test_files = Dir["#{current_dir}/at_*"]
8
+
9
+ # Load each acceptance test file making
10
+ # all tests to be run
11
+ acceptance_test_files.each { |file| load file }
12
+
13
+ # Print a report
14
+
15
+ report = <<EOF
16
+
17
+ ===
18
+ Well done!
19
+
20
+ Below you have a report with all the answers you gave.
21
+ It has also some environment information to help us debugging.
22
+
23
+ If any of the tests have not passed on your environment,
24
+ please copy/past the text bellow and send to us.
25
+
26
+ If you are familiar with GitHub you can report the failing test
27
+ as a GitHub issue at https://github.com/JEG2/highline/issues.
28
+ If possible, always check if your issue is already reported
29
+ by someone else. If so, just report that you are also affected
30
+ on the same alredy open issued.
31
+
32
+ If you are more confortable with e-mail, you could send it to
33
+ james@grayproductions.net
34
+
35
+ === HighLine Acceptance Tests Report
36
+ Date: #{Time.now.utc}
37
+ HighLine::VERSION: #{HighLine::VERSION}
38
+ Terminal: #{$terminal.terminal.class}
39
+ RUBY_DESCRIPTION: #{RUBY_DESCRIPTION rescue 'not available'}
40
+ Readline::VERSION: #{Readline::VERSION rescue 'not availabe'}
41
+ ENV['SHELL']: #{ENV['SHELL']}
42
+ ENV['TERM']: #{ENV['TERM']}
43
+ ENV['TERM_PROGRAM']: #{ENV['TERM_PROGRAM']}
44
+
45
+ Answers:
46
+ #{HighLine::AcceptanceTest.answers_for_report}
47
+ EOF
48
+
49
+ puts report
50
+
51
+ timestamp = Time.now.strftime('%Y%m%d%H%M%S')
52
+ filename = "highlinetests-#{timestamp}.log"
53
+
54
+ File.open "#{filename}", 'w+' do |f|
55
+ f.puts report
56
+ end
57
+
58
+ puts
59
+ puts "You can also see the above information in"
60
+ puts "a timestamped file named #{filename}"
61
+ puts "at the current directory."
62
+ puts