class MapData
Constants
- BIGINT_PROC
- FLOAT_PROC
- FLOAT_REGEXP
- FMT_LETTERS
- FMT_REGEXP
- INT_PROC
- INT_REGEXP
- PERCENTAGE_PROC
Attributes
line[R]
line2[R]
pattern[R]
sizes[R]
split_regexp[R]
Public Class Methods
new(str, split_regexp = nil)
click to toggle source
# File lib/cless/data.rb, line 276 def initialize(str, split_regexp = nil) @str = str @line = @line2 = 0 @off = @off2 = 0 # @off = first character of first line in cache # @off2 = first character of first line past cache @cache = [] @sizes = [] @pattern = nil # search pattern @formats = nil # formating strings. When not nil, a hash. @ignores = nil # line ignored index or pattern. @split_regexp = split_regexp # split pattern @highlight_regexp = nil # highlight pattern @need_more = false # true if last cache_fill needs data end
Public Instance Methods
add_ignore(pattern)
click to toggle source
# File lib/cless/data.rb, line 483 def add_ignore(pattern) return nil unless [Integer, Range, Regexp].any? { |c| c === pattern } (@ignored ||= []) << pattern true end
cache_fill(n)
click to toggle source
# File lib/cless/data.rb, line 422 def cache_fill(n) @need_more = @cache.size < n cache_forward(n - @cache.size) if @need_more end
clear_cache()
click to toggle source
# File lib/cless/data.rb, line 427 def clear_cache @cache.clear @line2 = @line @off2 = @off @sizes.clear end
file_path()
click to toggle source
# File lib/cless/data.rb, line 291 def file_path; @str.file_path; end
formatted_column_list()
click to toggle source
# File lib/cless/data.rb, line 481 def formatted_column_list; @formats ? @formats.keys : []; end
get_format_column(col)
click to toggle source
# File lib/cless/data.rb, line 476 def get_format_column(col) return nil unless @formats @formats[col] end
goto_end()
click to toggle source
# File lib/cless/data.rb, line 334 def goto_end old_line = @line2 @line2 = @str.lines return false if @line2 == old_line @line = @line2 @off2 = @off = @str.size cache_size = @cache.size @cache.clear scroll(-cache_size) return true end
goto_line(nb)
click to toggle source
# File lib/cless/data.rb, line 346 def goto_line(nb) delta = nb - @line - 1 scroll(delta) end
goto_offset(off)
click to toggle source
# File lib/cless/data.rb, line 359 def goto_offset(off) @str.lines(nil, off) if off > @str.size off -= 1 if @str[off] == ?\n && off > 0 @off = @off2 = (@str.rindex("\n", off) || -1) + 1 @line = @line2 = @str.count_lines_upto(@off) @cache.clear end
goto_percent(percent)
click to toggle source
# File lib/cless/data.rb, line 351 def goto_percent(percent) percent = 0.0 if percent < 0.0 percent = 100.0 if percent > 100.0 percent = percent.to_f line = (@str.lines * percent / 100).round goto_line(line) end
goto_start()
click to toggle source
# File lib/cless/data.rb, line 326 def goto_start return false if @line == 0 @line = @line2 = 0 @off = @off2 = 0 @cache.clear return true end
highlight_regexp=(regexp)
click to toggle source
# File lib/cless/data.rb, line 494 def highlight_regexp=(regexp) @highlight_regexp = regexp clear_cache end
ignore_pattern_list()
click to toggle source
# File lib/cless/data.rb, line 510 def ignore_pattern_list; @ignored ? @ignored : []; end
lines(n) { |l| ... }
click to toggle source
yield n lines with length len to be displayed
# File lib/cless/data.rb, line 319 def lines(n) @cache.each_with_index { |l, i| break if i >= n yield l } end
max_offset()
click to toggle source
Returns the maximum line offset of all lines in cache
# File lib/cless/data.rb, line 513 def max_offset @cache.collect { |l| l.off }.max end
refresh()
click to toggle source
# File lib/cless/data.rb, line 434 def refresh size = @cache.size clear_cache cache_fill(size) end
remove_ignore(pattern)
click to toggle source
# File lib/cless/data.rb, line 499 def remove_ignore(pattern) if pattern.nil? r, @ignored = @ignored, nil return r end return nil unless [Integer, Range, Regexp].any? { |c| c === pattern } r = @ignored.delete(pattern) @ignored = nil if @ignored.empty? r end
repeat_search(dir = :forward)
click to toggle source
# File lib/cless/data.rb, line 384 def repeat_search(dir = :forward) first_line = nil cache = (dir == :forward) ? @cache : @cache.reverse cache[1..-1].each_with_index { |l, i| if l.has_match first_line = i break end } if first_line scroll((dir == :forward) ? first_line + 1 : -first_line - 1) return true else return search_next(dir) end end
scroll(delta)
click to toggle source
delta > for scrolling down (forward in file)
# File lib/cless/data.rb, line 407 def scroll(delta) return if delta == 0 cache_size = @cache.size if delta > 0 skipped = skip_forward(delta) @cache.slice!(0, skipped) cache_forward([cache_size, skipped].min) else skipped = skip_backward(-delta) delta = -@cache.size if -delta > @cache.size @cache.slice!((delta..-1)) cache_backward([cache_size, skipped].min) end end
search(pattern, dir = :forward)
click to toggle source
Return true if pattern found, false otherwise
# File lib/cless/data.rb, line 368 def search(pattern, dir = :forward) search_clear if @pattern @pattern = pattern first_line = nil cache = (dir == :forward) ? @cache : @cache.reverse cache.each_with_index { |l, i| l.match(@pattern) and first_line ||= i } if first_line scroll((dir == :forward) ? first_line : -first_line) return true else return search_next(dir) end end
search_clear()
click to toggle source
# File lib/cless/data.rb, line 401 def search_clear @pattern = nil @cache.each { |l| l.clear_match } end
select_fd(n)
click to toggle source
Return a file descriptor to listen on (select) if there is less than n lines in the cache, or nil if not needed, or file is memory mapped and no listening is necessary.
# File lib/cless/data.rb, line 308 def select_fd(n) @cache.size < n ? @str.more_fd : nil end
set_format_column(fmt, *cols)
click to toggle source
# File lib/cless/data.rb, line 455 def set_format_column(fmt, *cols) if fmt =~ FMT_REGEXP a = case $3 when "b", "c", "d", "i", "o", "u", "X", "x"; [fmt, INT_REGEXP, INT_PROC] when "E", "e", "f", "G", "g"; [fmt, FLOAT_REGEXP, FLOAT_PROC] when "I"; ["#{$`}#{$1}#{$2}s#{$'}", FLOAT_REGEXP, BIGINT_PROC] when "p"; ["#{$`}#{$1}#{$2}f%#{$'}", FLOAT_REGEXP, PERCENTAGE_PROC] end end @formats ||= {} cols.each { |c| @formats[c] = a } true end
split_regexp=(regexp)
click to toggle source
# File lib/cless/data.rb, line 489 def split_regexp=(regexp) @split_regexp = regexp clear_cache end
unset_format_column(col)
click to toggle source
# File lib/cless/data.rb, line 469 def unset_format_column(col) return nil unless @formats r = @formats.delete(col) @formats = nil if @formats.empty? r end
write_to(fd)
click to toggle source
# File lib/cless/data.rb, line 292 def write_to(fd) @str.lines # Make sure we have all the data block = 64*1024 (@str.size / block).times do |i| fd.syswrite(@str[i*block, block]) end if (r = @str.size % block) > 0 fd.syswrite(@str[@str.size - r, r]) end @str.size end
Private Instance Methods
cache_backward(n)
click to toggle source
# File lib/cless/data.rb, line 589 def cache_backward(n) lnb = @line - 1 n.times do |i| break if @off == 0 ooff = @off @off = search_backward_to_new_line(@off) @cache.unshift(line_massage(@str[@off, ooff - @off - 1], lnb - i, @off)) end @line = @line2 - @cache.size end
cache_forward(n)
click to toggle source
# File lib/cless/data.rb, line 579 def cache_forward(n) lnb = @line + @cache.size n.times do |i| noff2 = @str.index("\n", @off2) or break @cache << line_massage(@str[@off2, noff2 - @off2], lnb + i, @off2) @off2 = noff2 + 1 end @line2 = @line + @cache.size end
line_ignore?(str, i)
click to toggle source
# File lib/cless/data.rb, line 553 def line_ignore?(str, i) @ignored.any? do |pat| case pat when Range, Integer; pat === i when Regexp; pat === str else false end end end
line_massage(str, i, off)
click to toggle source
str = line i = line number
# File lib/cless/data.rb, line 565 def line_massage(str, i, off) if @ignored && line_ignore?(str, i) l = IgnoredLine.new(str, off) else onl, nl = nil, str.split(@split_regexp) onl = reformat(nl) if @formats @sizes.max_update(nl.collect { |x| x.size }) l = Line.new(nl, onl, off) end l.match(@pattern) if @pattern l.highlight = @highlight_regexp && (@highlight_regexp =~ str) l end
reformat(nl)
click to toggle source
# File lib/cless/data.rb, line 541 def reformat(nl) onl = nl.dup @formats.each do |i, f| s = nl[i] or next fmt, cond, proc = *f cond =~ s or next s = proc[s] if proc nl[i] = fmt % s rescue "###" end onl end
search_backward_to_new_line(start)
click to toggle source
# File lib/cless/data.rb, line 600 def search_backward_to_new_line(start) return 0 if start < 2 npos = @str.rindex("\n", start - 2) return npos ? npos + 1 : 0 end
search_next(dir = :forward)
click to toggle source
# File lib/cless/data.rb, line 518 def search_next(dir = :forward) if dir == :forward m = @str.search_index(@pattern, @off2) else m = @str.search_rindex(@pattern, @off) end return false if !m if dir == :forward old_off2, old_line2 = @off2, @line2 @off = @off2 = (@str.rindex("\n", m) || -1) + 1 @line = @line2 = old_line2 + @str[old_off2..@off2].count("\n") @cache.clear else old_off, old_line = @off, @line @off = @off2 = (@str.rindex("\n", m) || -1) + 1 @line = @line2 = old_line - @str[@off..old_off].count("\n") cache_size = @cache.size @cache.clear scroll(-cache_size+1) end return true end
skip_backward(n)
click to toggle source
Move @off2 back by n lines. Make sure that @off <= @off2
# File lib/cless/data.rb, line 621 def skip_backward(n) i = 0 n.times do break if @off2 == 0 @off2 = search_backward_to_new_line(@off2) i += 1 end @off = @off2 if @off > @off2 @line2 -= i @line = @line2 if @line2 < @line i end
skip_forward(n)
click to toggle source
Move @off by n lines. Make sure that @off2 >= @off
# File lib/cless/data.rb, line 607 def skip_forward(n) i = 0 n.times do noff = @str.search_index("\n", @off) or break @off = noff + 1 i += 1 end @off2 = @off if @off2 < @off @line += i @line2 = @line if @line > @line2 i end