Module: Print
- Defined in:
- lib/imsg-grep/dev/print_query.rb
Class Method Summary collapse
- .c256(c, s) ⇒ Object
- .clr ⇒ Object
- .mark(s) ⇒ Object
- .query(q, *args, title: nil, db: Messages.db) ⇒ Object
- .sep(s) ⇒ Object
- .table(table, title: nil) ⇒ Object
Class Method Details
.c256(c, s) ⇒ Object
11 |
# File 'lib/imsg-grep/dev/print_query.rb', line 11 def self.c256(c, s) = "\e[38;5;#{c}m#{s}\e[39m" |
.clr ⇒ Object
14 |
# File 'lib/imsg-grep/dev/print_query.rb', line 14 def self.clr = "\e[0m" |
.mark(s) ⇒ Object
12 |
# File 'lib/imsg-grep/dev/print_query.rb', line 12 def self.mark(s) = "\e[38;5;178m#{s}\e[39m" |
.query(q, *args, title: nil, db: Messages.db) ⇒ Object
16 17 18 |
# File 'lib/imsg-grep/dev/print_query.rb', line 16 def self.query(q, *args, title: nil, db: Messages.db) table db.execute2(q, *args), title: end |
.sep(s) ⇒ Object
13 |
# File 'lib/imsg-grep/dev/print_query.rb', line 13 def self.sep(s) = "\e[30m#{s}\e[39m" |
.table(table, title: nil) ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/imsg-grep/dev/print_query.rb', line 20 def self.table(table, title: nil) bg1 = "\e[48;5;4m" bga = ["\e[48;5;235m", "\e[48;5;238m"] bg = ->{ bg1 ? (bg1.tap{bg1=nil}) : bga.rotate!.first } # puts "\n#{'=' * 80}" hrow, *rows = table # max lengths for each col, but capping the header rows at 5 so big headers with short content don't take up space lens = [hrow.map{it[0,5]}].concat(rows).transpose.map{|col|col.map{it.to_s.size}.max||0} # is each column number? used for aligning them right nums = rows.transpose.map{|col| col.compact.all?{ Numeric===it }} hex = rows.transpose.map{|col| col.compact.all?{ String===it && it !~ /\H/ }} hex.zip(0..).each{|h,i| lens[i] = 20 if h } # hex cols start short # available term width for all cols excluding separators colsw = @term_width - hrow.size + 1 # max width per col; start with an even col width then redistribute next maxcw = colsw / hrow.size # begin redistributing bigs = lens taken = 0 while true smalls, bigs = bigs.partition{ it <= maxcw } # partition cols under/at max col width break if bigs.empty? || smalls.empty? # can't redistribute if all on either side taken += smalls.sum # accumulate used up width maxcw = (colsw - taken) / bigs.size # max for remaining bigs: split even end lens.map!{ [it, maxcw].min } # expand col header width while fits; those we capped earlier trunc_headers = lens.zip(hrow.map{it.size}, 0..).filter_map{|l,hl,i| [i,hl] if l<hl } # [col index, full header length] while lens.sum < colsw && trunc_headers.any? # while still fits and any left to widen i, hl = trunc_headers.first # take first next trunc_headers.shift if lens[i] >= hl # drop and nove on if wide enough lens[i] += 1 # widen trunc_headers.rotate! # move on to next index end total_width = lens.sum + hrow.size - 1 # full width table will take row_count = "(#{rows.size} row#{?s if rows.size != 1})" title = [title, row_count].join(" ") puts "\e[48;5;18m" + title.ljust(total_width) + "\e[49m" lines = table.map do |row| line = row.zip(lens, nums).map do |val, len, num| just = ->s{ s.send(num ? :rjust : :ljust, len) } next c256(244, just[?∅]) if val.nil? # special handling for nil next c256(112, just["1"]) if val == 1 # color 1 bool true next c256(9, just["0"]) if val == 0 # color 0 bool false s ||= val.to_s s = s.gsub(/\p{Extended_Pictographic}/, "•").gsub(/\R/, "␍").gsub(/\t/, ' ') # remove emojis, nl, tabs (better chance of not mangling columns) s = s[0, len-1] + mark(?›) if s.size > len # ellipsis just[s] end bg[] + line*sep(?│) + clr end puts lines puts "\e[48;5;18m" + row_count.ljust(total_width) + "\e[49m" puts end |