highline 1.7.10 → 2.0.0.pre.develop.2

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