Class: Manager

Inherits:
Object
  • Object
show all
Defined in:
lib/cless/cless.rb

Defined Under Namespace

Classes: Error

Constant Summary collapse

Commands =
{
  "scroll_forward_line" => :scroll_forward_line,
  "scroll_backward_line" => :scroll_backward_line,
  "scroll_forward_half_screen" => :scroll_forward_half_screen,
  "scroll_backward_half_screen" => :scroll_backward_half_screen,
  "scroll_right" => :scroll_right,
  "scroll_left" => :scroll_left,
  "hide_columns" => :hide_columns_prompt,
  "unhide_columns" => :unhide_columns,
  "toggle_hide_ignored" => :toggle_hide_ignored,
  "toggle_headers" => :show_hide_headers,
  "change_headers_to_line" => :change_headers_to_line_content_prompt,
  "toggle_line_highlight" => :toggle_line_highlight,
  "toggle_column_highlight" => :toggle_column_highlight,
  "shift_line_highlight" => :shift_line_highlight,
  "shift_column_highlight" => :shift_column_highlight,
  "regexp_line_highlight" => :regexp_line_highlight_prompt,
  "column_align_left" => :column_align_left,
  "column_align_right" => :column_align_right,
  "column_align_center" => :column_align_center,
  "column_align_auto" => :column_align_auto,
  "right_align_regexp" => :right_align_regexp_prompt,
  "column_width" => :column_width_prompt,
  "forward_search" => :forward_search,
  "backward_search" => :backward_search,
  "repeat_search" => :repeat_search,
  "save_to_file" => :save_file_prompt,
  "goto_position" => :goto_position_prompt,
  "format_column" => :column_format_prompt,
  "column_start_index" => :change_column_start_prompt,
  "ignore_line" => :ignore_line_prompt,
  "remove_ignore_line" => :ignore_line_remove_prompt,
  "split_regexp" => :change_split_pattern_prompt,
  "separator_character" => :change_separator_prompt,
  "separator_padding" => :change_padding_prompt,
  "export" => :export_prompt,
  "help" => :display_help,
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data, display, db) ⇒ Manager

Returns a new instance of Manager.



93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/cless/cless.rb', line 93

def initialize(data, display, db)
  @data = data
  @display = display
  @db = db
  @done = false
  @status = ""
  @prebuff = ""
  @half_screen_lines = nil
  @full_screen_lines = nil
  @scroll_columns = nil
  @interrupt = false
  @search_history = []
  @max_search_history = 100
end

Instance Attribute Details

#max_search_historyObject

Returns the value of attribute max_search_history.



92
93
94
# File 'lib/cless/cless.rb', line 92

def max_search_history
  @max_search_history
end

#search_historyObject

Returns the value of attribute search_history.



92
93
94
# File 'lib/cless/cless.rb', line 92

def search_history
  @search_history
end

Instance Method Details

#backward_searchObject



523
# File 'lib/cless/cless.rb', line 523

def backward_search; search_prompt(:backward); end

#change_column_start_promptObject



661
662
663
664
665
666
667
# File 'lib/cless/cless.rb', line 661

def change_column_start_prompt
  s = prebuff
  s = @display.prompt("First column: ") unless s
  return nil unless s
  @display.col_start = s.to_i
  true
end

#change_headers_to_line(i) ⇒ Object

Raises:



506
507
508
509
510
511
512
513
514
515
516
517
518
519
# File 'lib/cless/cless.rb', line 506

def change_headers_to_line(i)
  raise Error, "Bad line number #{i}" if i < 1
  i_bak = @data.line + 1
  @data.goto_line(i)
  @data.cache_fill(1)
  line = nil
  @data.lines(1) { |l| line = l }
  @data.goto_line(i_bak)     # Go back
  raise Error, "No such line" unless line
  raise Error, "Ignored line: can't use" if line.kind_of?(IgnoredLine)
  @display.col_headers = line.onl_at(0..-1)
  @display.col_names = true
  true
end

#change_headers_to_line_content_promptObject



459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
# File 'lib/cless/cless.rb', line 459

def change_headers_to_line_content_prompt
  i = prebuff
  if i.nil?
    i = @data.line + 1
    s = @display.prompt("Header line: ", :init => i.to_s) or return nil
    s.strip!
    return "Bad line number #{s}" unless s =~ /^\d+$/
    i = s.to_i
  end
  begin
    change_headers_to_line(i)
  rescue => e
    return e.message
  end
  true
end

#change_padding_promptObject



784
785
786
787
788
# File 'lib/cless/cless.rb', line 784

def change_padding_prompt
  s = @display.prompt("Padding: ") or return nil
  @display.padding = s
  true
end

#change_separator_promptObject



778
779
780
781
782
# File 'lib/cless/cless.rb', line 778

def change_separator_prompt
  s = @display.prompt("Separator: ") or return nil
  @display.separator = s
  true
end

#change_split_pattern_promptObject



726
727
728
729
730
731
732
733
734
735
736
737
# File 'lib/cless/cless.rb', line 726

def change_split_pattern_prompt
  s = @display.prompt("Split regexp(/#{@data.split_regexp}/): ")
  return "Not changed" if !s
  begin
    s.gsub!(%r{^/|/$}, '')
    regexp = s.empty? ? nil : Regexp.new(s)
  rescue => e
    return "Invalid regexp /#{s}/: #{e.message}"
  end
  @data.split_regexp = regexp
  "New split regexp: /#{regexp}/"
end

#color_descrObject



565
566
567
568
569
# File 'lib/cless/cless.rb', line 565

def color_descr
  descr = @display.attr_names
  "Color: F %s B %s A %s" % 
    [descr[:foreground] || "-", descr[:background] || "-", descr[:attribute] || "-"]
end

#column_align_autoObject



423
# File 'lib/cless/cless.rb', line 423

def column_align_auto; column_alignment(nil); end

#column_align_centerObject



422
# File 'lib/cless/cless.rb', line 422

def column_align_center; column_alignment(:center); end

#column_align_leftObject



420
# File 'lib/cless/cless.rb', line 420

def column_align_left; column_alignment(:left); end

#column_align_rightObject



421
# File 'lib/cless/cless.rb', line 421

def column_align_right; column_alignment(:right); end

#column_alignment(align) ⇒ Object



424
425
426
427
428
429
# File 'lib/cless/cless.rb', line 424

def column_alignment(align)
  i = prebuff
  a = i ? [i] : range_prompt("Columns to #{align || "auto"} align: ") or return nil
  return if a.empty?
  @display.col_align(align, a)
end

#column_format(cols, fmt) ⇒ Object



645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
# File 'lib/cless/cless.rb', line 645

def column_format(cols, fmt)
  inc = @display.col_start
  if cols
    cols = cols.map { |x| x.to_i - inc }
    cols.delete_if { |x| x < 0 }
    if fmt && !fmt.empty?
      @data.set_format_column(fmt, *cols)
    else
      cols.each { |c| @data.unset_format_column(c) }
    end
    @data.refresh
  end
  cols = @data.formatted_column_list.sort.collect { |x| x + inc }
  "Formatted: " + cols.join(" ")
end

#column_format_inline(str) ⇒ Object



639
640
641
642
643
# File 'lib/cless/cless.rb', line 639

def column_format_inline(str)
  cols, fmt = str.split(/:/, 2)
  cols = str_to_range(cols)
  column_format(cols, fmt)
end

#column_format_promptObject



629
630
631
632
633
634
635
636
637
# File 'lib/cless/cless.rb', line 629

def column_format_prompt
  i = prebuff
  cols = i ? [i] : range_prompt("Format columns: ") or return nil
  fmt = @display.prompt("Format string: ") or return nil
  fmt.strip!
  column_format(cols, fmt)
rescue => e
  return e.message
end

#column_offset_endObject



380
381
382
383
384
385
386
387
# File 'lib/cless/cless.rb', line 380

def column_offset_end
  if prebuff && prebuff >= @display.col_start
    @offset_column = prebuff - @display.col_start
  end
  return if @offset_column.nil?
  @display.col_offsets[@offset_column] =
    [0, @data.sizes[@offset_column] - (@display.widths[@offset_column] || @display.col_width)].max
end

#column_offset_leftObject



371
# File 'lib/cless/cless.rb', line 371

def column_offset_left; column_offset_sideways(-1); end

#column_offset_rightObject



370
# File 'lib/cless/cless.rb', line 370

def column_offset_right; column_offset_sideways(1); end

#column_offset_sideways(dir) ⇒ Object



360
361
362
363
364
365
366
367
368
# File 'lib/cless/cless.rb', line 360

def column_offset_sideways(dir)
  if prebuff && prebuff >= @display.col_start
    @offset_column = prebuff - @display.col_start
  end
  return if @offset_column.nil?
  off = @display.col_offsets[@offset_column] || 0
  off = [off + dir, 0].max
  @display.col_offsets[@offset_column] = off
end

#column_offset_startObject



372
373
374
375
376
377
378
# File 'lib/cless/cless.rb', line 372

def column_offset_start
  if prebuff && prebuff >= @display.col_start
    @offset_column = prebuff - @display.col_start
  end
  return if @offset_column.nil?
  @display.col_offsets[@offset_column] = 0
end

#column_width_change(x) ⇒ Object



440
441
442
443
444
445
446
447
448
# File 'lib/cless/cless.rb', line 440

def column_width_change(x)
  if prebuff && prebuff >= @display.col_start
    @offset_column = prebuff - @display.col_start
  end
  return if @offset_column.nil?
  w = (@display.widths[@offset_column] || @display.col_width) + x
  w = 5 if w < 5
  @display.widths[@offset_column] = w
end

#column_width_decreaseObject



451
# File 'lib/cless/cless.rb', line 451

def column_width_decrease; column_width_change(-1); end

#column_width_increaseObject



450
# File 'lib/cless/cless.rb', line 450

def column_width_increase; column_width_change(1); end

#column_width_promptObject



431
432
433
434
435
436
437
438
# File 'lib/cless/cless.rb', line 431

def column_width_prompt
  i = prebuff
  a = i ? [i] : range_prompt("Width of columns: ") or return nil
  return nil if a.empty?
  s = @display.prompt("Max width: ") or return nil
  s = [s.to_i, 5].max
  a.map { |x| @display.widths[x] = s }
end

#display_helpObject



790
791
792
793
794
795
796
797
798
# File 'lib/cless/cless.rb', line 790

def display_help
  Ncurses.endwin
  Help.display
  true
rescue => e
  e.message
ensure
  Ncurses.refresh
end

#doneObject



108
# File 'lib/cless/cless.rb', line 108

def done; @done = true; end

#export_promptObject



800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
# File 'lib/cless/cless.rb', line 800

def export_prompt
  format = @display.prompt("Format: ") or return nil
  s = @display.prompt("Lines: ") or return nil
  ls, le = s.split.map { |x| x.to_i }
  file = @display.prompt("File: ") or return nil
  qs = Export.questions(format)
  opts = {}
  qs && qs.each { |k, pt, init|
    s = @display.prompt(pt + ": ", :init => init) or return nil
    opts[k] = s
  }
  len = Export.export(file, format, ls..le, @data, @display, opts)
  "Wrote #{len} bytes"
rescue => e
  return "Error: #{e.message}"
end

#forward_searchObject

Return a status if an error occur, otherwise, returns nil



522
# File 'lib/cless/cless.rb', line 522

def forward_search; search_prompt(:forward); end

#goto_line(l) ⇒ Object



389
390
391
392
393
394
395
396
397
398
399
400
401
402
# File 'lib/cless/cless.rb', line 389

def goto_line(l)
  if l == 0
    return @data.goto_start ? "" : "Start of file"
  elsif l < 0
      @display.start_active_status("Skipping to end of file")
      return @data.goto_end ? "" : "End of file"
  else
    @display.start_active_status("Skipping to line #{l}")
    @data.goto_line(prebuff)
  end
  true
ensure
  @display.end_active_status
end

#goto_percentObject



596
597
598
599
# File 'lib/cless/cless.rb', line 596

def goto_percent
  percent = prebuff or return true
  @data.goto_percent(percent)
end

#goto_position_promptObject



601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
# File 'lib/cless/cless.rb', line 601

def goto_position_prompt
  s = prebuff || @display.prompt("Goto: ") or return nil
  s = s.to_s.strip

  case s[-1]
  when "p", "%"
    s.slice!(-1)
    f = s.to_f
    return "Invalid percentage" if f <= 0.0 || f > 100.0
    @display.start_active_status("Goto %d%%" % f.round)
    @data.goto_percent(f)
  when "o"
    s.slice!(-1)
    i = s.to_i
    return "Invalid offset" if i < 0
    @display.start_active_status("Goto offset #{i}")
    @data.goto_offset(i)
  else
    i = s.to_i
    return "Invalid line number" if i <= 0
    @display.start_active_status("Goto line #{i}")
    @data.goto_line(i)
  end
  true
ensure
  @display.end_active_status
end

#hide_columns_prompt(show = false) ⇒ Object



405
406
407
408
409
410
411
412
413
414
415
416
# File 'lib/cless/cless.rb', line 405

def hide_columns_prompt(show = false)
  i = prebuff
  a = i ? [i] : range_prompt(show ? "Show: " : "Hide: ") or return nil
  if a.empty?
    @display.col_hide_clear
  else
    show ? @display.col_show(*a) : @display.col_hide(*a)
  end
  "Hidden: #{@display.col_hidden.join(" ")}"
rescue => e
  return e.message
end

#ignore_line(str) ⇒ Object



698
699
700
701
702
703
704
705
706
# File 'lib/cless/cless.rb', line 698

def ignore_line(str)
  ignore_line_list_each(str) do |spat, opat|
    if opat.nil? || !@data.add_ignore(opat)
      return "Bad pattern #{spat}"
    end
  end
  @data.refresh
  "Ignored: " + ignore_line_list_display(@data.ignore_pattern_list).join(" ")
end

#ignore_line_list_display(a) ⇒ Object



687
688
689
690
691
692
693
694
695
696
# File 'lib/cless/cless.rb', line 687

def ignore_line_list_display(a)
  a.collect { |x|
    o = case x
        when Range; (x.begin + 1)..(x.end + 1)
        when Integer; x + 1
        else x
        end
    o.inspect
  }
end

#ignore_line_list_each(str) ⇒ Object



675
676
677
678
679
680
681
682
683
684
685
# File 'lib/cless/cless.rb', line 675

def ignore_line_list_each(str)
  a = str.split_with_quotes('\s', '\/')
  a.each do |spat|
    opat = case spat
           when /^(\d+)(?:\.{2}|-)(\d+)$/; ($1.to_i - 1)..($2.to_i - 1)
           when /^(\d+)$/; $1.to_i - 1
           else Regexp.new(spat) rescue nil
           end
    yield(spat, opat)
  end
end

#ignore_line_promptObject



669
670
671
672
673
# File 'lib/cless/cless.rb', line 669

def ignore_line_prompt
  s = @display.prompt("Ignore: ") or return nil
  s.strip!
  ignore_line(s)
end

#ignore_line_remove(str) ⇒ Object



714
715
716
717
718
719
720
721
722
723
724
# File 'lib/cless/cless.rb', line 714

def ignore_line_remove(str)
  if !str || str.empty?
    @data.remove_ignore(nil)
  else
    ignore_line_list_each(str) do |spat, opat|
      opat && @data.remove_ignore(opat)
    end
  end
  @data.refresh
  "Ignored: " + ignore_line_list_display(@data.ignore_pattern_list).join(" ")
end

#ignore_line_remove_promptObject



708
709
710
711
712
# File 'lib/cless/cless.rb', line 708

def ignore_line_remove_prompt
  s = @display.prompt("Remove ignore: ") or return nil
  s.strip!
  ignore_line_remove(s)
end

#interrupt_resetObject



110
# File 'lib/cless/cless.rb', line 110

def interrupt_reset; i, @interrupt = @interrupt, false; i; end

#interrupt_setObject



109
# File 'lib/cless/cless.rb', line 109

def interrupt_set; @interrupt = true; end

#load_history(file) ⇒ Object



123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/cless/cless.rb', line 123

def load_history(file)
  tty = ttyname
  history = File.open(file, "r") { |fd|
    fd.flock(File::LOCK_SH)
    YAML::load(fd)
  }
  history = {} unless Hash === history
  history["tty"] = {} unless Hash === history["tty"]
  tty_history = history["tty"][tty] || history["tty"][history["recent_tty"]] || {}
  @search_history = tty_history["search"] || []
rescue Errno::EACCES
rescue Errno::ENOENT
end

#long_commandObject

This is a little odd. Does it belong to display more?



267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
# File 'lib/cless/cless.rb', line 267

def long_command
  sub = CommandSubWindow.new(Commands.keys.map { |s| s.size }.max)
  old_prompt_line = ""
  sub.new_list(Commands.keys.sort)
  extra = proc {
    if old_prompt_line != @display.prompt_line
      old_prompt_line = @display.prompt_line.dup
      reg = Regexp.new(Regexp.quote(old_prompt_line))
      sub.new_list(Commands.keys.grep(reg).sort)
      Ncurses.refresh
    end
  }
  other = proc { |ch|
    r = true
    case ch
    when NC::KEY_DOWN, C::CTRL_N; sub.next_item
    when NC::KEY_UP, C::CTRL_P; sub.previous_item
    else r = false
    end
    Ncurses.refresh if r
  }
  s = @display.prompt("Filter: ", :extra => extra, :other => other)
  sub.destroy
  @display.refresh
  self.__send__(Commands[sub.item]) if s
end

#main_loopObject



158
159
160
161
162
163
164
165
166
167
# File 'lib/cless/cless.rb', line 158

def main_loop
  if @status.empty?
    @status = "Help? Press ~ or F1"
  end
  while !@done do
    @data.cache_fill(@display.nb_lines)
    @display.refresh
    wait_for_key or break
  end
end

#prebuffObject



169
# File 'lib/cless/cless.rb', line 169

def prebuff; @prebuff.empty? ? nil : @prebuff.to_i; end

#range_prompt(prompt) ⇒ Object



306
307
308
309
# File 'lib/cless/cless.rb', line 306

def range_prompt(prompt)
  s = @display.prompt(prompt) or return nil
  str_to_range(s)
end

#regexp_line_highlight_promptObject



739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
# File 'lib/cless/cless.rb', line 739

def regexp_line_highlight_prompt
  s = @display.prompt("Highlight regexp(/#{@data.split_regexp}/): ")
  s.strip! if s
  if !s || s.empty?
    @data.highlight_regexp = nil
    return "No line highlight by regexp"
  end
  begin
    s.gsub!(%r{^/|/$}, '')
    regexp = s.empty? ? nil : Regexp.new(s)
  rescue => e
    return "Invalid regexp /#{s}/: #{e.message}"
  end
  @data.highlight_regexp = regexp
  "New highlight regexp: /#{regexp}/"
end

#repeat_search(reverse = false) ⇒ Object

Return a status if an error occur, otherwise, returns nil



554
555
556
557
558
559
560
561
562
563
# File 'lib/cless/cless.rb', line 554

def repeat_search(reverse = false)
  return "No pattern" if !@data.pattern
  dir = if reverse 
          (@search_dir == :forward) ? :backward : :forward
        else 
          @search_dir
        end
  @data.repeat_search(dir) or return "Pattern not found!"
  true
end

#right_align_regexp_promptObject



756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
# File 'lib/cless/cless.rb', line 756

def right_align_regexp_prompt
  current = @display.right_align_re == LineDisplay::ISNUM ? "number" : @display.right_align_re.to_s
  s = @display.prompt("Right align regexp(/#{current}/): ")
  s.strip! if s
  if s.nil? || s.empty?
    @display.right_align_re = LineDisplay::ISNUM
    return "Automatic right alignment of numbers"
  elsif s == "//"
    @display.right_align_re = nil
    return "No automatic right alignment"
  end

  begin
    s.gsub!(%r{^/|/$}, '')
    regexp = Regexp.new(s)
  rescue => e
    return "Invalid regexp /#{s}/: #{e.message}"
  end
  @display.right_align_re = regexp
  "Automatic right alignment regexp: /#{regexp}/"
end

#save_file_promptObject



571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
# File 'lib/cless/cless.rb', line 571

def save_file_prompt
  s = @display.prompt("Save to: ")
  return nil if !s || s.empty?
  if @data.file_path
    begin
      File.link(@data.file_path, s)
      return "Hard linked"
    rescue Errno::EXDEV => e
    rescue Exception => e
      return "Error: #{e.message}"
    end
  end

  # Got here, hard link failed. Copy by hand.
  nb_bytes = nil
  begin
    File.open(s, File::WRONLY|File::CREAT|File::EXCL) do |fd|
      nb_bytes = @data.write_to(fd)
    end
  rescue Exception => e
    return "Error: #{e.message}"
  end
  "Wrote #{nb_bytes} bytes"
end

#save_history(file) ⇒ Object



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/cless/cless.rb', line 137

def save_history(file)
  tty = ttyname
  File.open(file, File::RDWR|File::CREAT, 0644) { |fd|
    fd.flock(File::LOCK_EX)

    history = YAML::load(fd)
    history = {} unless Hash === history
    history["tty"] = {} unless Hash === history["tty"]
    history["tty"][tty] = {} unless Hash === history["tty"][tty]
    history["tty"][tty]["search"] = @search_history
    history["recent_tty"] = tty

    fd.rewind
    fd.print(history.to_yaml)
    fd.flush
    fd.truncate(fd.pos)
  }
rescue Errno::EACCES
rescue Errno::ENOENT
end

#scroll_backward_full_screen(save = false) ⇒ Object



339
340
341
342
343
# File 'lib/cless/cless.rb', line 339

def scroll_backward_full_screen(save = false)
  @full_screen_lines = prebuff if save && prebuff
  @data.scroll(-(prebuff || @full_screen_lines || (@display.nb_lines - 1)))
  true
end

#scroll_backward_half_screen(save = false) ⇒ Object



327
328
329
330
331
# File 'lib/cless/cless.rb', line 327

def scroll_backward_half_screen(save = false)
  @half_screen_lines = prebuff if save && prebuff
  @data.scroll(-(prebuff || @half_screen_lines || (@display.nb_lines / 2)))
  true
end

#scroll_backward_lineObject



316
317
318
319
# File 'lib/cless/cless.rb', line 316

def scroll_backward_line
  @data.scroll(-(prebuff || 1))
  true
end

#scroll_forward_full_screen(save = false) ⇒ Object



333
334
335
336
337
# File 'lib/cless/cless.rb', line 333

def scroll_forward_full_screen(save = false)
  @full_screen_lines = prebuff if save && prebuff
  @data.scroll(prebuff || @full_screen_lines || (@display.nb_lines - 1))
  true
end

#scroll_forward_half_screen(save = false) ⇒ Object



321
322
323
324
325
# File 'lib/cless/cless.rb', line 321

def scroll_forward_half_screen(save = false)
  @half_screen_lines = prebuff if save && prebuff
  @data.scroll(prebuff || @half_screen_lines || (@display.nb_lines / 2))
  true
end

#scroll_forward_lineObject



311
312
313
314
# File 'lib/cless/cless.rb', line 311

def scroll_forward_line
  @data.scroll(prebuff || 1)
  true
end

#scroll_leftObject



357
# File 'lib/cless/cless.rb', line 357

def scroll_left; scroll_sideways(-1); end

#scroll_rightObject



358
# File 'lib/cless/cless.rb', line 358

def scroll_right; scroll_sideways(1); end

#scroll_sideways(dir) ⇒ Object



345
346
347
348
349
350
351
352
353
354
355
# File 'lib/cless/cless.rb', line 345

def scroll_sideways(dir)
  @scroll_columns = prebuff if prebuff
  to_scroll = @scroll_columns || 1
  st_col = @display.st_col
  to_scroll.times { |i|
    st_col += dir
    redo if @display.col_hidden(false).index(st_col)
  }
  @display.st_col = st_col
  true
end

#search_prompt(dir = :forward) ⇒ Object



524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
# File 'lib/cless/cless.rb', line 524

def search_prompt(dir = :forward)
  s = @display.prompt("%s Search: " % 
                        [(dir == :forward) ? "Forward" : "Backward"],
                      { :history => @search_history })
  s or return nil
  if s =~ /^\s*$/
    @data.search_clear
  else
    begin
      @display.start_active_status("Searching '#{s}'")

      hist_index = @search_history.index(s)
      @search_history.slice!(hist_index) if hist_index
      @search_history.unshift(s)
      @search_history = @search_history[0, @max_search_history]
      begin
        @search_dir = dir
        pattern = Regexp.new(s)
        @data.search(pattern, dir) or return "Pattern not found!"
      rescue RegexpError => e
      return "Bad attr_reader :egexp: #{e.message}"
      end
    ensure
      @display.end_active_status
    end
  end
  true
end

#shift_column_highlightObject



498
499
500
501
502
503
504
# File 'lib/cless/cless.rb', line 498

def shift_column_highlight
  if i = prebuff
    @display.col_highlight_shift = i
  else
    @display.col_highlight_shift += 1
  end
end

#shift_line_highlightObject



490
491
492
493
494
495
496
# File 'lib/cless/cless.rb', line 490

def shift_line_highlight
  if i = prebuff
    @display.line_highlight_shift = i
  else
    @display.line_highlight_shift += 1
  end
end

#show_hide_headersObject



453
454
455
456
457
# File 'lib/cless/cless.rb', line 453

def show_hide_headers
  return "No names defined" if !@display.col_names && !@display.col_headers
  @display.col_names = !@display.col_names
  true
end

#str_to_range(str) ⇒ Object



294
295
296
297
298
299
300
301
302
303
304
# File 'lib/cless/cless.rb', line 294

def str_to_range(str)
  str.split_with_quotes().map { |r|
    case r
    when /^(\d+)$/
      $1.to_i
    when /^(\d+)(?:\.{2,3}|-)(\d+)$/
      (($1.to_i)..($2.to_i)).to_a
    else raise "Invalid range: #{r}"
    end
  }.flatten
end

#toggle_column_highlightObject



483
484
485
486
487
488
# File 'lib/cless/cless.rb', line 483

def toggle_column_highlight
  i = prebuff
  @display.col_highlight = !@display.col_highlight
  @display.col_highlight_period = i if i
  true
end

#toggle_hide_ignoredObject



418
# File 'lib/cless/cless.rb', line 418

def toggle_hide_ignored; @display.hide_ignored = !@display.hide_ignored; end

#toggle_line_highlightObject



476
477
478
479
480
481
# File 'lib/cless/cless.rb', line 476

def toggle_line_highlight
  i = prebuff
  @display.line_highlight = !@display.line_highlight
  @display.line_highlight_period = i if i
  true
end

#ttynameObject



112
113
114
115
116
117
118
119
120
121
# File 'lib/cless/cless.rb', line 112

def ttyname
  [Proc.new { File.readlink("/proc/self/fd/0") },
   Proc.new { `tty`.chomp }].each { |m|
    begin
      return m.call
    rescue Errno::ENOENT
    end
  }
  return "/dev/unknown"
end

#unhide_columnsObject



404
# File 'lib/cless/cless.rb', line 404

def unhide_columns; hide_columns_prompt(true); end

#wait_for_keyObject



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/cless/cless.rb', line 171

def wait_for_key
  status = nil
  esc = false
  while !@done do
    nc = false        # Set to true if no data change
    data_fd = @data.select_fd(@display.nb_lines)
    prompt = data_fd ? "+:" : ":"
    @display.wait_status(@status, prompt + @prebuff)
    if data_fd
      @display.flush
      in_fds = select([$stdin, data_fd])
      if in_fds[0].include?(data_fd)
        status = :more
        nc = true
        break
      end
    end

    k = Ncurses.getch
    status = 
      case k
      when NC::KEY_DOWN, NC::KEY_ENTER, C::CTRL_N, ?e.ord, C::CTRL_E, ?j.ord, C::CTRL_J, ?\n.ord, ?\r.ord
        scroll_forward_line
      when NC::KEY_UP, ?y.ord, C::CTRL_Y, C::CTRL_P, ?k.ord, C::CTRL_K
        scroll_backward_line
      when ?d.ord, C::CTRL_D; scroll_forward_half_screen(true)
      when ?u.ord, C::CTRL_U; scroll_backward_half_screen(true)
      when C::SPACE, NC::KEY_NPAGE, C::CTRL_V, ?f.ord, C::CTRL_F; scroll_forward_full_screen
      when ?z.ord; scroll_forward_full_screen(true)
      when NC::KEY_PPAGE, ?b.ord, C::CTRL_B; scroll_backward_full_screen
      when ?w.ord; scroll_backward_full_screen(true)
      when NC::KEY_HOME, ?g.ord, ?<.ord; goto_line(0)
      when NC::KEY_END, ?G.ord, ?>.ord; goto_line(-1)
      when NC::KEY_LEFT; scroll_left
      when NC::KEY_RIGHT; scroll_right
      when ?+.ord; @display.col_space += 1; true
      when ?-.ord; @display.col_space -= 1; true
      when ?F.ord; goto_position_prompt
      when ?v.ord; column_format_prompt
      when ?i.ord; ignore_line_prompt
      when ?I.ord; ignore_line_remove_prompt
      when ?o.ord; toggle_line_highlight
      when ?O.ord; toggle_column_highlight
      when ?m.ord; shift_line_highlight
      when ?M.ord; shift_column_highlight
      when ?c.ord; @display.column = !@display.column; true
      when ?l.ord; @display.line = !@display.line; true
      when ?L.ord; @display.line_offset = !@display.line_offset; true
      when ?h.ord; hide_columns_prompt
      when ?H.ord; hide_columns_prompt(:show)
      when ?A.ord; column_alignment(:right)
      when ?a.ord; column_alignment(:left)
      when ?`.ord; change_column_start_prompt
      when ?).ord; esc ? scroll_right : column_width_increase
      when ?(.ord; esc ? scroll_left : column_width_decrease
      when ?/.ord; search_prompt(:forward)
      when ??.ord; search_prompt(:backward)
      when ?n.ord; repeat_search
      when ?N.ord; repeat_search(true)
      when ?s.ord; save_file_prompt
      when ?S.ord; change_split_pattern_prompt
      when ?E.ord; export_prompt
      when ?t.ord; show_hide_headers
      when ?p.ord, ?%.ord; goto_percent
      when ?|.ord; change_separator_prompt
      when ?\\.ord; change_padding_prompt
      when ?^.ord; change_headers_to_line_content_prompt
      when ?r.ord, ?R.ord, C::CTRL_R, C::CTRL_L; @data.clear_cache; NC::endwin; NC::doupdate
      when NC::KEY_RESIZE; nc = true # Will break to refresh display
      when NC::KEY_F1, ?~.ord; display_help
      when (?0.ord)..(?9.ord); @prebuff += k.chr; next
      when NC::KEY_BACKSPACE, ?\b.ord; esc ? @prebuff = "" : @prebuff.chop!; next
      when ?:.ord; long_command
      when ?q.ord; return nil
      when C::ESC; esc = true; next
      when NC::KEY_SLEFT, ?[.ord; column_offset_left
      when NC::KEY_SRIGHT, ?].ord; column_offset_right
      when ?{.ord; column_offset_start
      when ?}.ord; column_offset_end
      else next
      end
    break
  end
  
  @prebuff = "" unless nc
  @status = 
    case status
    when String; status
    when nil; "Cancelled"
    when :more; @status
    else ""
    end
  return true
end