malysz87-highline 1.5.5 → 1.5.6

Sign up to get free protection for your applications and to get access to all the features.
data/examples/password.rb DELETED
@@ -1,7 +0,0 @@
1
- #!/usr/local/bin/ruby -w
2
-
3
- require "rubygems"
4
- require "highline/import"
5
-
6
- pass = ask("Enter your password: ") { |q| q.echo = false }
7
- puts "Your password is #{pass}!"
@@ -1,22 +0,0 @@
1
- #!/usr/local/bin/ruby -w
2
-
3
- # trapping_eof.rb
4
- #
5
- # Created by James Edward Gray II on 2006-02-20.
6
- # Copyright 2006 Gray Productions. All rights reserved.
7
-
8
- require "rubygems"
9
- require "highline/import"
10
-
11
- loop do
12
- begin
13
- name = ask("What's your name?")
14
- break if name == "exit"
15
- puts "Hello, #{name}!"
16
- rescue EOFError # HighLine throws this if @input.eof?
17
- break
18
- end
19
- end
20
-
21
- puts "Goodbye, dear friend."
22
- exit
@@ -1,17 +0,0 @@
1
- #!/usr/local/bin/ruby -w
2
-
3
- # using_readline.rb
4
- #
5
- # Created by James Edward Gray II on 2005-07-06.
6
- # Copyright 2005 Gray Productions. All rights reserved.
7
-
8
- require "rubygems"
9
- require "highline/import"
10
-
11
- loop do
12
- cmd = ask("Enter command: ", %w{save load reset quit}) do |q|
13
- q.readline = true
14
- end
15
- say("Executing \"#{cmd}\"...")
16
- break if cmd == "quit"
17
- end
data/lib/highline.rb DELETED
@@ -1,757 +0,0 @@
1
- #!/usr/local/bin/ruby -w
2
-
3
- # highline.rb
4
- #
5
- # Created by James Edward Gray II on 2005-04-26.
6
- # Copyright 2005 Gray Productions. All rights reserved.
7
- #
8
- # See HighLine for documentation.
9
- #
10
- # This is Free Software. See LICENSE and COPYING for details.
11
-
12
- require "highline/system_extensions"
13
- require "highline/question"
14
- require "highline/menu"
15
- require "highline/color_scheme"
16
- require "erb"
17
- require "optparse"
18
- require "stringio"
19
- require "abbrev"
20
-
21
- #
22
- # A HighLine object is a "high-level line oriented" shell over an input and an
23
- # output stream. HighLine simplifies common console interaction, effectively
24
- # replacing puts() and gets(). User code can simply specify the question to ask
25
- # and any details about user interaction, then leave the rest of the work to
26
- # HighLine. When HighLine.ask() returns, you'll have the answer you requested,
27
- # even if HighLine had to ask many times, validate results, perform range
28
- # checking, convert types, etc.
29
- #
30
- class HighLine
31
- # The version of the installed library.
32
- VERSION = "1.5.0".freeze
33
-
34
- # An internal HighLine error. User code does not need to trap this.
35
- class QuestionError < StandardError
36
- # do nothing, just creating a unique error type
37
- end
38
-
39
- # The setting used to disable color output.
40
- @@use_color = true
41
-
42
- # Pass +false+ to _setting_ to turn off HighLine's color escapes.
43
- def self.use_color=( setting )
44
- @@use_color = setting
45
- end
46
-
47
- # Returns true if HighLine is currently using color escapes.
48
- def self.use_color?
49
- @@use_color
50
- end
51
-
52
- # The setting used to disable EOF tracking.
53
- @@track_eof = true
54
-
55
- # Pass +false+ to _setting_ to turn off HighLine's EOF tracking.
56
- def self.track_eof=( setting )
57
- @@track_eof = setting
58
- end
59
-
60
- # Returns true if HighLine is currently tracking EOF for input.
61
- def self.track_eof?
62
- @@track_eof
63
- end
64
-
65
- # The setting used to control color schemes.
66
- @@color_scheme = nil
67
-
68
- # Pass ColorScheme to _setting_ to turn set a HighLine color scheme.
69
- def self.color_scheme=( setting )
70
- @@color_scheme = setting
71
- end
72
-
73
- # Returns the current color scheme.
74
- def self.color_scheme
75
- @@color_scheme
76
- end
77
-
78
- # Returns +true+ if HighLine is currently using a color scheme.
79
- def self.using_color_scheme?
80
- not @@color_scheme.nil?
81
- end
82
-
83
- #
84
- # Embed in a String to clear all previous ANSI sequences. This *MUST* be
85
- # done before the program exits!
86
- #
87
- CLEAR = "\e[0m"
88
- # An alias for CLEAR.
89
- RESET = CLEAR
90
- # Erase the current line of terminal output.
91
- ERASE_LINE = "\e[K"
92
- # Erase the character under the cursor.
93
- ERASE_CHAR = "\e[P"
94
- # The start of an ANSI bold sequence.
95
- BOLD = "\e[1m"
96
- # The start of an ANSI dark sequence. (Terminal support uncommon.)
97
- DARK = "\e[2m"
98
- # The start of an ANSI underline sequence.
99
- UNDERLINE = "\e[4m"
100
- # An alias for UNDERLINE.
101
- UNDERSCORE = UNDERLINE
102
- # The start of an ANSI blink sequence. (Terminal support uncommon.)
103
- BLINK = "\e[5m"
104
- # The start of an ANSI reverse sequence.
105
- REVERSE = "\e[7m"
106
- # The start of an ANSI concealed sequence. (Terminal support uncommon.)
107
- CONCEALED = "\e[8m"
108
-
109
- # Set the terminal's foreground ANSI color to black.
110
- BLACK = "\e[30m"
111
- # Set the terminal's foreground ANSI color to red.
112
- RED = "\e[31m"
113
- # Set the terminal's foreground ANSI color to green.
114
- GREEN = "\e[32m"
115
- # Set the terminal's foreground ANSI color to yellow.
116
- YELLOW = "\e[33m"
117
- # Set the terminal's foreground ANSI color to blue.
118
- BLUE = "\e[34m"
119
- # Set the terminal's foreground ANSI color to magenta.
120
- MAGENTA = "\e[35m"
121
- # Set the terminal's foreground ANSI color to cyan.
122
- CYAN = "\e[36m"
123
- # Set the terminal's foreground ANSI color to white.
124
- WHITE = "\e[37m"
125
-
126
- # Set the terminal's background ANSI color to black.
127
- ON_BLACK = "\e[40m"
128
- # Set the terminal's background ANSI color to red.
129
- ON_RED = "\e[41m"
130
- # Set the terminal's background ANSI color to green.
131
- ON_GREEN = "\e[42m"
132
- # Set the terminal's background ANSI color to yellow.
133
- ON_YELLOW = "\e[43m"
134
- # Set the terminal's background ANSI color to blue.
135
- ON_BLUE = "\e[44m"
136
- # Set the terminal's background ANSI color to magenta.
137
- ON_MAGENTA = "\e[45m"
138
- # Set the terminal's background ANSI color to cyan.
139
- ON_CYAN = "\e[46m"
140
- # Set the terminal's background ANSI color to white.
141
- ON_WHITE = "\e[47m"
142
-
143
- #
144
- # Create an instance of HighLine, connected to the streams _input_
145
- # and _output_.
146
- #
147
- def initialize( input = $stdin, output = $stdout,
148
- wrap_at = nil, page_at = nil )
149
- @input = input
150
- @output = output
151
-
152
- self.wrap_at = wrap_at
153
- self.page_at = page_at
154
-
155
- @question = nil
156
- @answer = nil
157
- @menu = nil
158
- @header = nil
159
- @prompt = nil
160
- @gather = nil
161
- @answers = nil
162
- @key = nil
163
- end
164
-
165
- include HighLine::SystemExtensions
166
-
167
- # The current column setting for wrapping output.
168
- attr_reader :wrap_at
169
- # The current row setting for paging output.
170
- attr_reader :page_at
171
-
172
- #
173
- # A shortcut to HighLine.ask() a question that only accepts "yes" or "no"
174
- # answers ("y" and "n" are allowed) and returns +true+ or +false+
175
- # (+true+ for "yes"). If provided a +true+ value, _character_ will cause
176
- # HighLine to fetch a single character response. A block can be provided
177
- # to further configure the question as in HighLine.ask()
178
- #
179
- # Raises EOFError if input is exhausted.
180
- #
181
- def agree( yes_or_no_question, character = nil )
182
- ask(yes_or_no_question, lambda { |yn| yn.downcase[0] == ?y}) do |q|
183
- q.validate = /\Ay(?:es)?|no?\Z/i
184
- q.responses[:not_valid] = 'Please enter "yes" or "no".'
185
- q.responses[:ask_on_error] = :question
186
- q.character = character
187
-
188
- yield q if block_given?
189
- end
190
- end
191
-
192
- #
193
- # This method is the primary interface for user input. Just provide a
194
- # _question_ to ask the user, the _answer_type_ you want returned, and
195
- # optionally a code block setting up details of how you want the question
196
- # handled. See HighLine.say() for details on the format of _question_, and
197
- # HighLine::Question for more information about _answer_type_ and what's
198
- # valid in the code block.
199
- #
200
- # If <tt>@question</tt> is set before ask() is called, parameters are
201
- # ignored and that object (must be a HighLine::Question) is used to drive
202
- # the process instead.
203
- #
204
- # Raises EOFError if input is exhausted.
205
- #
206
- def ask( question, answer_type = String, &details ) # :yields: question
207
- @question ||= Question.new(question, answer_type, &details)
208
-
209
- return gather if @question.gather
210
-
211
- # readline() needs to handle it's own output, but readline only supports
212
- # full line reading. Therefore if @question.echo is anything but true,
213
- # the prompt will not be issued. And we have to account for that now.
214
- say(@question) unless (@question.readline and @question.echo == true)
215
- begin
216
- @answer = @question.answer_or_default(get_response)
217
- unless @question.valid_answer?(@answer)
218
- explain_error(:not_valid)
219
- raise QuestionError
220
- end
221
-
222
- @answer = @question.convert(@answer)
223
-
224
- if @question.in_range?(@answer)
225
- if @question.confirm
226
- # need to add a layer of scope to ask a question inside a
227
- # question, without destroying instance data
228
- context_change = self.class.new(@input, @output, @wrap_at, @page_at)
229
- if @question.confirm == true
230
- confirm_question = "Are you sure? "
231
- else
232
- # evaluate ERb under initial scope, so it will have
233
- # access to @question and @answer
234
- template = ERB.new(@question.confirm, nil, "%")
235
- confirm_question = template.result(binding)
236
- end
237
- unless context_change.agree(confirm_question)
238
- explain_error(nil)
239
- raise QuestionError
240
- end
241
- end
242
-
243
- @answer
244
- else
245
- explain_error(:not_in_range)
246
- raise QuestionError
247
- end
248
- rescue QuestionError
249
- retry
250
- rescue ArgumentError
251
- explain_error(:invalid_type)
252
- retry
253
- rescue Question::NoAutoCompleteMatch
254
- explain_error(:no_completion)
255
- retry
256
- rescue Question::NotEnoughAnswers
257
- explain_error(:not_enough_answers)
258
- retry
259
- rescue NameError
260
- raise if $!.is_a?(NoMethodError)
261
- explain_error(:ambiguous_completion)
262
- retry
263
- ensure
264
- @question = nil # Reset Question object.
265
- end
266
- end
267
-
268
- #
269
- # This method is HighLine's menu handler. For simple usage, you can just
270
- # pass all the menu items you wish to display. At that point, choose() will
271
- # build and display a menu, walk the user through selection, and return
272
- # their choice amoung the provided items. You might use this in a case
273
- # statement for quick and dirty menus.
274
- #
275
- # However, choose() is capable of much more. If provided, a block will be
276
- # passed a HighLine::Menu object to configure. Using this method, you can
277
- # customize all the details of menu handling from index display, to building
278
- # a complete shell-like menuing system. See HighLine::Menu for all the
279
- # methods it responds to.
280
- #
281
- # Raises EOFError if input is exhausted.
282
- #
283
- def choose( *items, &details )
284
- @menu = @question = Menu.new(&details)
285
- @menu.choices(*items) unless items.empty?
286
-
287
- # Set _answer_type_ so we can double as the Question for ask().
288
- @menu.answer_type = if @menu.shell
289
- lambda do |command| # shell-style selection
290
- first_word = command.to_s.split.first || ""
291
-
292
- options = @menu.options
293
- options.extend(OptionParser::Completion)
294
- answer = options.complete(first_word)
295
-
296
- if answer.nil?
297
- raise Question::NoAutoCompleteMatch
298
- end
299
-
300
- [answer.last, command.sub(/^\s*#{first_word}\s*/, "")]
301
- end
302
- else
303
- @menu.options # normal menu selection, by index or name
304
- end
305
-
306
- # Provide hooks for ERb layouts.
307
- @header = @menu.header
308
- @prompt = @menu.prompt
309
-
310
- if @menu.shell
311
- selected = ask("Ignored", @menu.answer_type)
312
- @menu.select(self, *selected)
313
- else
314
- selected = ask("Ignored", @menu.answer_type)
315
- @menu.select(self, selected)
316
- end
317
- end
318
-
319
- #
320
- # This method provides easy access to ANSI color sequences, without the user
321
- # needing to remember to CLEAR at the end of each sequence. Just pass the
322
- # _string_ to color, followed by a list of _colors_ you would like it to be
323
- # affected by. The _colors_ can be HighLine class constants, or symbols
324
- # (:blue for BLUE, for example). A CLEAR will automatically be embedded to
325
- # the end of the returned String.
326
- #
327
- # This method returns the original _string_ unchanged if HighLine::use_color?
328
- # is +false+.
329
- #
330
- def color( string, *colors )
331
- return string unless self.class.use_color?
332
-
333
- colors.map! do |c|
334
- if self.class.using_color_scheme? and self.class.color_scheme.include? c
335
- self.class.color_scheme[c]
336
- elsif c.is_a? Symbol
337
- self.class.const_get(c.to_s.upcase)
338
- else
339
- c
340
- end
341
- end
342
- "#{colors.flatten.join}#{string}#{CLEAR}"
343
- end
344
-
345
- #
346
- # This method is a utility for quickly and easily laying out lists. It can
347
- # be accessed within ERb replacements of any text that will be sent to the
348
- # user.
349
- #
350
- # The only required parameter is _items_, which should be the Array of items
351
- # to list. A specified _mode_ controls how that list is formed and _option_
352
- # has different effects, depending on the _mode_. Recognized modes are:
353
- #
354
- # <tt>:columns_across</tt>:: _items_ will be placed in columns, flowing
355
- # from left to right. If given, _option_ is the
356
- # number of columns to be used. When absent,
357
- # columns will be determined based on _wrap_at_
358
- # or a default of 80 characters.
359
- # <tt>:columns_down</tt>:: Identical to <tt>:columns_across</tt>, save
360
- # flow goes down.
361
- # <tt>:inline</tt>:: All _items_ are placed on a single line. The
362
- # last two _items_ are separated by _option_ or
363
- # a default of " or ". All other _items_ are
364
- # separated by ", ".
365
- # <tt>:rows</tt>:: The default mode. Each of the _items_ is
366
- # placed on it's own line. The _option_
367
- # parameter is ignored in this mode.
368
- #
369
- # Each member of the _items_ Array is passed through ERb and thus can contain
370
- # their own expansions. Color escape expansions do not contribute to the
371
- # final field width.
372
- #
373
- def list( items, mode = :rows, option = nil )
374
- items = items.to_ary.map do |item|
375
- ERB.new(item, nil, "%").result(binding)
376
- end
377
-
378
- case mode
379
- when :inline
380
- option = " or " if option.nil?
381
-
382
- case items.size
383
- when 0
384
- ""
385
- when 1
386
- items.first
387
- when 2
388
- "#{items.first}#{option}#{items.last}"
389
- else
390
- items[0..-2].join(", ") + "#{option}#{items.last}"
391
- end
392
- when :columns_across, :columns_down
393
- max_length = actual_length(
394
- items.max { |a, b| actual_length(a) <=> actual_length(b) }
395
- )
396
-
397
- if option.nil?
398
- limit = @wrap_at || 80
399
- option = (limit + 2) / (max_length + 2)
400
- end
401
-
402
- items = items.map do |item|
403
- pad = max_length + (item.length - actual_length(item))
404
- "%-#{pad}s" % item
405
- end
406
- row_count = (items.size / option.to_f).ceil
407
-
408
- if mode == :columns_across
409
- rows = Array.new(row_count) { Array.new }
410
- items.each_with_index do |item, index|
411
- rows[index / option] << item
412
- end
413
-
414
- rows.map { |row| row.join(" ") + "\n" }.join
415
- else
416
- columns = Array.new(option) { Array.new }
417
- items.each_with_index do |item, index|
418
- columns[index / row_count] << item
419
- end
420
-
421
- list = ""
422
- columns.first.size.times do |index|
423
- list << columns.map { |column| column[index] }.
424
- compact.join(" ") + "\n"
425
- end
426
- list
427
- end
428
- else
429
- items.map { |i| "#{i}\n" }.join
430
- end
431
- end
432
-
433
- #
434
- # The basic output method for HighLine objects. If the provided _statement_
435
- # ends with a space or tab character, a newline will not be appended (output
436
- # will be flush()ed). All other cases are passed straight to Kernel.puts().
437
- #
438
- # The _statement_ parameter is processed as an ERb template, supporting
439
- # embedded Ruby code. The template is evaluated with a binding inside
440
- # the HighLine instance, providing easy access to the ANSI color constants
441
- # and the HighLine.color() method.
442
- #
443
- def say( statement )
444
- statement = statement.to_str
445
- return unless statement.length > 0
446
-
447
- template = ERB.new(statement, nil, "%")
448
- statement = template.result(binding)
449
-
450
- statement = wrap(statement) unless @wrap_at.nil?
451
- statement = page_print(statement) unless @page_at.nil?
452
-
453
- if statement[-1, 1] == " " or statement[-1, 1] == "\t"
454
- @output.print(statement)
455
- @output.flush
456
- else
457
- @output.puts(statement)
458
- end
459
- end
460
-
461
- #
462
- # Set to an integer value to cause HighLine to wrap output lines at the
463
- # indicated character limit. When +nil+, the default, no wrapping occurs. If
464
- # set to <tt>:auto</tt>, HighLine will attempt to determing the columns
465
- # available for the <tt>@output</tt> or use a sensible default.
466
- #
467
- def wrap_at=( setting )
468
- @wrap_at = setting == :auto ? output_cols : setting
469
- end
470
-
471
- #
472
- # Set to an integer value to cause HighLine to page output lines over the
473
- # indicated line limit. When +nil+, the default, no paging occurs. If
474
- # set to <tt>:auto</tt>, HighLine will attempt to determing the rows available
475
- # for the <tt>@output</tt> or use a sensible default.
476
- #
477
- def page_at=( setting )
478
- @page_at = setting == :auto ? output_rows : setting
479
- end
480
-
481
- #
482
- # Returns the number of columns for the console, or a default it they cannot
483
- # be determined.
484
- #
485
- def output_cols
486
- return 80 unless @output.tty?
487
- terminal_size.first
488
- rescue
489
- return 80
490
- end
491
-
492
- #
493
- # Returns the number of rows for the console, or a default if they cannot be
494
- # determined.
495
- #
496
- def output_rows
497
- return 24 unless @output.tty?
498
- terminal_size.last
499
- rescue
500
- return 24
501
- end
502
-
503
- private
504
-
505
- #
506
- # A helper method for sending the output stream and error and repeat
507
- # of the question.
508
- #
509
- def explain_error( error )
510
- say(@question.responses[error]) unless error.nil?
511
- if @question.responses[:ask_on_error] == :question
512
- say(@question)
513
- elsif @question.responses[:ask_on_error]
514
- say(@question.responses[:ask_on_error])
515
- end
516
- end
517
-
518
- #
519
- # Collects an Array/Hash full of answers as described in
520
- # HighLine::Question.gather().
521
- #
522
- # Raises EOFError if input is exhausted.
523
- #
524
- def gather( )
525
- @gather = @question.gather
526
- @answers = [ ]
527
- original_question = @question
528
-
529
- @question.gather = false
530
-
531
- case @gather
532
- when Integer
533
- @answers << ask(@question)
534
- @gather -= 1
535
-
536
- original_question.question = ""
537
- until @gather.zero?
538
- @question = original_question
539
- @answers << ask(@question)
540
- @gather -= 1
541
- end
542
- when String, Regexp
543
- @answers << ask(@question)
544
-
545
- original_question.question = ""
546
- until (@gather.is_a?(String) and @answers.last.to_s == @gather) or
547
- (@gather.is_a?(Regexp) and @answers.last.to_s =~ @gather)
548
- @question = original_question
549
- @answers << ask(@question)
550
- end
551
-
552
- @answers.pop
553
- when Hash
554
- @answers = { }
555
- @gather.keys.sort.each do |key|
556
- @question = original_question
557
- @key = key
558
- @answers[key] = ask(@question)
559
- end
560
- end
561
-
562
- @answers
563
- end
564
-
565
- #
566
- # Read a line of input from the input stream and process whitespace as
567
- # requested by the Question object.
568
- #
569
- # If Question's _readline_ property is set, that library will be used to
570
- # fetch input. *WARNING*: This ignores the currently set input stream.
571
- #
572
- # Raises EOFError if input is exhausted.
573
- #
574
- def get_line( )
575
- if @question.readline
576
- require "readline" # load only if needed
577
-
578
- # capture say()'s work in a String to feed to readline()
579
- old_output = @output
580
- @output = StringIO.new
581
- say(@question)
582
- question = @output.string
583
- @output = old_output
584
-
585
- # prep auto-completion
586
- # I found this version in plugin
587
- # The previous version wasn`t warking properly, readline wasn`t
588
- # showing possible answers if you push tab 2 times
589
- Readline.completion_proc = lambda do |string|
590
- @question.selection.grep(/\A#{Regexp.escape(string)}/)
591
- end
592
-
593
-
594
-
595
-
596
- # work-around ugly readline() warnings
597
- old_verbose = $VERBOSE
598
- $VERBOSE = nil
599
- answer = @question.change_case(
600
- @question.remove_whitespace(
601
- Readline.readline(question, true) ) )
602
- $VERBOSE = old_verbose
603
-
604
- answer
605
- else
606
- raise EOFError, "The input stream is exhausted." if @@track_eof and
607
- @input.eof?
608
-
609
- @question.change_case(@question.remove_whitespace(@input.gets))
610
- end
611
- end
612
-
613
- #
614
- # Return a line or character of input, as requested for this question.
615
- # Character input will be returned as a single character String,
616
- # not an Integer.
617
- #
618
- # This question's _first_answer_ will be returned instead of input, if set.
619
- #
620
- # Raises EOFError if input is exhausted.
621
- #
622
- def get_response( )
623
- return @question.first_answer if @question.first_answer?
624
-
625
- if @question.character.nil?
626
- if @question.echo == true and @question.limit.nil?
627
- get_line
628
- else
629
- raw_no_echo_mode if stty = CHARACTER_MODE == "stty"
630
-
631
- line = ""
632
- backspace_limit = 0
633
- begin
634
-
635
- while character = (stty ? @input.getc : get_character(@input))
636
- # honor backspace and delete
637
- if character == 127 or character == 8
638
- line.slice!(-1, 1)
639
- backspace_limit -= 1
640
- else
641
- line << character.chr
642
- backspace_limit = line.size
643
- end
644
- # looking for carriage return (decimal 13) or
645
- # newline (decimal 10) in raw input
646
- break if character == 13 or character == 10 or
647
- (@question.limit and line.size == @question.limit)
648
- if @question.echo != false
649
- if character == 127 or character == 8
650
- # only backspace if we have characters on the line to
651
- # eliminate, otherwise we'll tromp over the prompt
652
- if backspace_limit >= 0 then
653
- @output.print("\b#{ERASE_CHAR}")
654
- else
655
- # do nothing
656
- end
657
- else
658
- @output.print(@question.echo)
659
- end
660
- @output.flush
661
- end
662
- end
663
- ensure
664
- restore_mode if stty
665
- end
666
- if @question.overwrite
667
- @output.print("\r#{ERASE_LINE}")
668
- @output.flush
669
- else
670
- say("\n")
671
- end
672
-
673
- @question.change_case(@question.remove_whitespace(line))
674
- end
675
- elsif @question.character == :getc
676
- @question.change_case(@input.getc.chr)
677
- else
678
- response = get_character(@input).chr
679
- if @question.overwrite
680
- @output.print("\r#{ERASE_LINE}")
681
- @output.flush
682
- else
683
- echo = if @question.echo == true
684
- response
685
- elsif @question.echo != false
686
- @question.echo
687
- else
688
- ""
689
- end
690
- say("#{echo}\n")
691
- end
692
- @question.change_case(response)
693
- end
694
- end
695
-
696
- #
697
- # Page print a series of at most _page_at_ lines for _output_. After each
698
- # page is printed, HighLine will pause until the user presses enter/return
699
- # then display the next page of data.
700
- #
701
- # Note that the final page of _output_ is *not* printed, but returned
702
- # instead. This is to support any special handling for the final sequence.
703
- #
704
- def page_print( output )
705
- lines = output.scan(/[^\n]*\n?/)
706
- while lines.size > @page_at
707
- @output.puts lines.slice!(0...@page_at).join
708
- @output.puts
709
- # Return last line if user wants to abort paging
710
- return (["...\n"] + lines.slice(-2,1)).join unless continue_paging?
711
- end
712
- return lines.join
713
- end
714
-
715
- #
716
- # Ask user if they wish to continue paging output. Allows them to type "q" to
717
- # cancel the paging process.
718
- #
719
- def continue_paging?
720
- command = HighLine.new(@input, @output).ask(
721
- "-- press enter/return to continue or q to stop -- "
722
- ) { |q| q.character = true }
723
- command !~ /\A[qQ]\Z/ # Only continue paging if Q was not hit.
724
- end
725
-
726
- #
727
- # Wrap a sequence of _lines_ at _wrap_at_ characters per line. Existing
728
- # newlines will not be affected by this process, but additional newlines
729
- # may be added.
730
- #
731
- def wrap( lines )
732
- wrapped = [ ]
733
- lines.each do |line|
734
- while line =~ /([^\n]{#{@wrap_at + 1},})/
735
- search = $1.dup
736
- replace = $1.dup
737
- if index = replace.rindex(" ", @wrap_at)
738
- replace[index, 1] = "\n"
739
- replace.sub!(/\n[ \t]+/, "\n")
740
- line.sub!(search, replace)
741
- else
742
- line[@wrap_at, 0] = "\n"
743
- end
744
- end
745
- wrapped << line
746
- end
747
- return wrapped.join
748
- end
749
-
750
- #
751
- # Returns the length of the passed +string_with_escapes+, minus and color
752
- # sequence escapes.
753
- #
754
- def actual_length( string_with_escapes )
755
- string_with_escapes.gsub(/\e\[\d{1,2}m/, "").length
756
- end
757
- end