typr 1.1.2 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/curses.rb CHANGED
@@ -1,8 +1,6 @@
1
- #!/usr/bin/ruby
2
-
3
1
  require 'ncursesw'
4
2
  require_relative 'frontend'
5
-
3
+
6
4
  module Visuals
7
5
 
8
6
  include Ncurses
@@ -11,142 +9,115 @@ module Visuals
11
9
  KEY_TAB = 9
12
10
  KEY_PAGEDOWN = KEY_NPAGE
13
11
  KEY_PAGEUP = KEY_PPAGE
14
- KEY_INSERT = KEY_IC
15
- KEY_DELETE = KEY_DC
16
-
12
+
17
13
  $colors = COLORS.keys
18
14
  $pairs = []
19
- # COLORS = %w[ black red green yellow blue magenta cyan white grey]
20
- # KEY_TAB = 9
21
- # HEIGHT,WIDTH = IO.console.winsize
22
15
 
23
- %w[color pair].each{ |name| method = <<STR
24
- def %s_for obj; #return unless obj
16
+ %w[color pair].each{ |name| method = <<STR
17
+ def %s_for obj;
25
18
  if id = $%ss.index( obj ) then return id
26
19
  else last = ( $%ss << obj.dup ).count - 1
27
- Ncurses.init_%s( last, *obj )
20
+ Ncurses.init_%s( last, *obj )
28
21
  return last
29
22
  end
30
23
  end
31
24
  STR
32
25
  eval( method % ([name]*4) )
33
26
  }
34
-
27
+
35
28
  def self.width; Ncurses.COLS end
36
29
  def self.height; Ncurses.LINES end
37
- def self.row; Ncurses.getcury $creen end
38
- def self.column; Ncurses.getcurx $creen end
39
-
30
+ def self.row; Ncurses.getcury $screen end
31
+ def self.column; Ncurses.getcurx $screen end
32
+
40
33
  def self.exit
41
34
  Ncurses.echo
42
35
  Ncurses.nocbreak
43
36
  Ncurses.nl
44
37
  Ncurses.endwin
45
- # system "reset"
46
38
  end
47
39
 
48
- def read input
40
+ def read input
49
41
  case input
50
42
  when :key
51
- key = Ncurses.getch
52
- key = key.chr if key.between? 32, 126
43
+ key = Ncurses.getch
44
+ key = key.chr if key.between? 32, 126
53
45
  return key
54
- when :line #string
55
- Ncurses.echo
56
- Ncurses.curs_set 1
57
- # Ncurses.getstr str=""
58
- str = Readline.readline
59
- Ncurses.curs_set 0
60
- Ncurses.noecho
46
+ when :line
47
+ str = ''
48
+ until (key = Ncurses.getch) == KEY_RETURN
49
+ return nil if key == KEY_ESCAPE
50
+ if [KEY_BACKSPACE, 127, 8].include? key
51
+ str.chop!
52
+ else
53
+ str << key.chr if key.between? 32, 126
54
+ end
55
+ end
61
56
  return str
62
57
  end
63
58
  end
64
59
 
65
60
  def move x=0,y=0; Ncurses.move y, x end
66
61
  def refresh; Ncurses.refresh end
67
- def enable attr; Ncurses.attron attr end
68
- def disable attr; Ncurses.attroff attr end
69
- def clear type=:screen;
70
- case type
62
+ def clear type=:screen;
63
+ case type
71
64
  when :screen; Ncurses.erase
72
65
  when :line; Ncurses.clrtoeol
73
66
  when :down; Ncurses.clrtobot
74
- end
67
+ end
75
68
  end
76
69
  def change; Ncurses.color_set pair_for( $color ), 0 end
77
- def show string; Ncurses.addstr string.to_s end
70
+ def draw string; Ncurses.addstr string.to_s end
78
71
 
79
72
  def get_background; $color[1] end
80
73
  def get_foreground; $color[0] end
81
- def background color;
82
- $color[1] = (color ? color_for( color ) : $default[1]); change
74
+ def background color;
75
+ $color[1] = (color ? color_for( color ) : $default[1]); change
83
76
  end
84
- def foreground color;
85
- $color[0] = (color ? color_for( color ) : $default[0]); change
77
+ def foreground color;
78
+ $color[0] = (color ? color_for( color ) : $default[0]); change
86
79
  end
87
80
 
88
81
  def color c
89
82
  c = [c] unless c.is_a? Array and c.count == 2
90
- foreground c[0] if c[0]
91
- background c[1] if c[1]
83
+ foreground c[0] if c[0]
84
+ background c[1] if c[1]
92
85
  end
93
86
 
94
- # def color_pair pair
95
- # if id = $color_pairs.index( pair ) return id
96
- # else last = ( $color_pairs << c ).count - 1
97
- # Ncurses.init_pair( last, *pair )
98
- # return last
99
- # end
100
- # pair = p.map{ |col|
101
- # unless id = $colors.index( col )
102
- # id = ($colors << col).count - 1
103
- # Ncurses.init_color id, *col
104
- # end
105
- # id
106
- # }
107
- # unless ( id = $color_pairs.index( pair ) )
108
- # id = ( $color_pairs << pair ).count - 1
109
- # Ncurses.init_pair id, *pair
110
- # end
111
- # id
112
- # end
113
-
114
- def self.init args={}
115
- # SCREEN = Ncurses.initscr
87
+ def self.init args={}
116
88
  $creen = Ncurses.initscr
117
- Ncurses.cbreak # provide unbuffered input
118
- Ncurses.noecho # turn on input echoing
119
- Ncurses.nl # turn on newline translation
120
- # Ncurses.nonl # turn off newline translation
89
+ Ncurses.cbreak
90
+ Ncurses.noecho
91
+ Ncurses.nl
121
92
  Ncurses.curs_set 0
122
93
  Ncurses.start_color
123
- Ncurses.stdscr.intrflush(false) # turn off flush-on-interrupt
124
- Ncurses.stdscr.keypad(true) # turn on keypad mode
94
+ Ncurses.stdscr.intrflush(false)
95
+ Ncurses.stdscr.keypad(true)
125
96
 
126
- $default = [
127
- color_for( args[:foreground] || :grey80 ),
97
+ $default = [
98
+ color_for( args[:foreground] || :grey80 ),
128
99
  color_for( args[:background] || :grey10 ) ]
129
100
  $color = $default.dup
130
101
 
131
- COLORS.each_with_index{ |c,i|
132
- $pairs << [ i, $default[1] ]
133
- Ncurses.init_color i, *c[1]
102
+ COLORS.each_with_index{ |c,i|
103
+ $pairs << [ i, $default[1] ]
104
+ Ncurses.init_color i, *c[1]
134
105
  Ncurses.init_pair i, i, $default[1] }
135
-
106
+
136
107
  Ncurses.bkgd Ncurses::COLOR_PAIR( pair_for $default )
137
108
 
138
- end
109
+ end
139
110
 
140
111
  end
141
112
 
142
113
  if __FILE__ == $0
143
114
  include Visuals
144
- Visuals.init #background: :blue
115
+ Visuals.init
145
116
  characters = (32..126).map(&:chr).join
146
117
  loop do
147
118
  clear
148
- $colors.each_with_index{ |c,i|
149
- foreground c; move 0,i; show characters }
119
+ $colors.each_with_index{ |c,i|
120
+ foreground c; move 0,i; draw characters }
150
121
  refresh
151
122
  exit if read(:key) == KEY_ESCAPE
152
123
  end
data/lib/frontend.rb CHANGED
@@ -1,19 +1,6 @@
1
- require 'readline'
2
-
3
1
  module Visuals
4
2
 
5
- # COLORS = {
6
- # black: [ 0, 0, 0],
7
- # red: [ 700, 400, 400],
8
- # green: [ 400, 700, 400],
9
- # yellow: [ 700, 700, 400],
10
- # blue: [ 400, 400, 700],
11
- # magenta: [ 700, 400, 700],
12
- # cyan: [ 400, 700, 700],
13
- # white: [ 999, 999, 999],
14
- # grey: [ 618, 618, 618] }
15
-
16
- COLORS = {
3
+ COLORS = {
17
4
  black: [ 0, 0, 0],
18
5
  red: [ 180, 100, 100],
19
6
  green: [ 100, 180, 100],
@@ -22,12 +9,15 @@ module Visuals
22
9
  magenta: [ 180, 100, 180],
23
10
  cyan: [ 100, 180, 180],
24
11
  white: [ 255, 255, 255],
25
- grey: [ 158, 158, 158] }
26
-
27
- COLORS.merge! 1.upto(9).map{ |i|
28
- ["grey#{ i*10 }".to_sym, [i*25]*3 ] }.to_h
12
+ grey: [ 158, 158, 158],
13
+ dark_red: [ 90, 30, 30],
14
+ dark_green: [ 30, 90, 30],
15
+ dark_yellow: [ 90, 80, 30],
16
+ dark_blue: [ 30, 30, 90],
17
+ dark_magenta: [ 90, 30, 90],
18
+ dark_cyan: [ 30, 80, 80] }
29
19
 
30
- # COLORS.merge! 1.upto(9).map{ |i|
31
- # ["grey#{ i*10 }".to_sym, [i*100]*3 ] }.to_h
20
+ COLORS.merge! 1.upto(9).map{ |i|
21
+ ["grey#{ i*10 }".to_sym, [i*25]*3 ] }.to_h
32
22
 
33
23
  end
data/lib/graphical.rb CHANGED
@@ -1,22 +1,16 @@
1
- #!/usr/bin/ruby
2
1
  require 'sdl2'
3
- #require 'io/console'
4
- #require 'readline'
5
2
  require_relative 'frontend'
6
-
3
+
7
4
  module Visuals
8
5
  include SDL2
9
6
 
10
- public
11
- i=-1
12
- # SDL2.init(SDL2::INIT_EVERYTHING)
13
7
  SDL2.init(SDL2::INIT_VIDEO)
14
8
  TTF.init
15
- WINDOW = Window.create("visuals",
16
- Window::POS_CENTERED, #POS_UNDEFINED,
17
- Window::POS_CENTERED, #POS_UNDEFINED,
9
+ WINDOW = Window.create("visuals",
10
+ Window::POS_CENTERED,
11
+ Window::POS_CENTERED,
18
12
  1324, 768, 0)
19
- GO = WINDOW.create_renderer(-1,
13
+ GO = WINDOW.create_renderer(-1,
20
14
  Renderer::Flags::ACCELERATED|Renderer::Flags::TARGETTEXTURE)
21
15
  Key.constants.each{ |c| c = c.to_s
22
16
  eval 'KEY_'+c.upcase+'=Key::'+c }
@@ -27,8 +21,7 @@ public
27
21
  def self.column; $col end
28
22
  def self.x; $x end
29
23
  def self.y; $y end
30
-
31
-
24
+
32
25
  def color_for c
33
26
  return unless c
34
27
  c = COLORS[c] if c.is_a?( Symbol )
@@ -39,136 +32,90 @@ public
39
32
  def get_foreground; $color[0] end
40
33
  def background color; return unless color
41
34
  $color[1] = color_for( color ) end
42
- def foreground color;
35
+ def foreground color;
43
36
  $color[0] = (color ? color_for( color ) : $default[0]) end
44
37
 
45
- def color c
46
- c = [c] unless c.is_a? Array and c.count == 2 #.flatten
38
+ def color c
39
+ c = [c] unless c.is_a? Array and c.count == 2
47
40
  foreground c[0]
48
41
  background c[1]
49
- # $letters[c] = (32.upto 126).map{ |n| n = n.chr
50
- # [n, $font.render_blended( n, c )] }.to_h unless $letters[c]
51
42
  end
52
43
 
53
44
  def move col, row
54
- $x = ($col = col) * $charsize[1] #width
55
- $y = ($row = row) * $charsize[0] #$height
45
+ $x = ($col = col) * $charsize[1]
46
+ $y = ($row = row) * $charsize[0]
56
47
  end
57
48
 
58
- def clear type = :screen #bg=
59
- GO.draw_color = $default[1] #bg
60
- case type
61
- # when Array; GO.fill_rect Rect.new()
62
- when :screen; GO.fill_rect Rect.new(0, 0, *WINDOW.size)
49
+ def clear type = :screen
50
+ GO.draw_color = $default[1]
51
+ case type
52
+ when :screen; GO.fill_rect Rect.new(0, 0, *WINDOW.size)
63
53
  when :line; GO.fill_rect Rect.new(
64
54
  Visuals.x, Visuals.y, WINDOW.size[0], Visuals.y+$charsize[0])
65
55
  when :down; GO.fill_rect Rect.new(
66
56
  0, Visuals.y, *WINDOW.size)
67
57
  end
68
58
  end
69
-
70
- def show( str ) #solid_blended_shaded(
59
+
60
+ def draw( str )
71
61
  return unless str
72
- # chars = str.chars.map{ |char| $letters[foreground][char] }
73
- # width = chars.map( &:w ).sum
74
- # if $color[1] != $default[1] #get_background
75
62
  if get_background
76
63
  GO.draw_color = get_background
77
- GO.fill_rect Rect.new($x, $y, str.size*$charsize[1], $charsize[0])
64
+ GO.fill_rect Rect.new($x, $y, str.size*$charsize[1], $charsize[0])
78
65
  end
79
- # GO.fill_rect Rect.new($x, $y, width, $charsize[0])
80
- # text = Surface.new( width, $charsize[0], 32, 0, 0, 0, 0 )
81
- # x=0
82
- # for char in chars #.each{|c|
83
- # Surface.blit char, nil, text, Rect.new( x, 0, char.w, char.h )
84
- # x += char.w
85
- # end
86
- # GO.copy GO.create_texture_from(text),nil,Rect.new($x, $y, width, $charsize[0])
87
66
  text = str.rstrip
88
67
  unless text.empty?
89
68
  image = $font.render_blended( text, get_foreground )
90
69
  GO.copy GO.create_texture_from( image ), nil,
91
- Rect.new($x, $y, image.w, $charsize[0])
92
- end
70
+ Rect.new($x, $y, image.w, $charsize[0])
71
+ end
93
72
  move $col+str.size, $row
94
73
  end
95
74
 
96
75
  def refresh; GO.present end
97
76
 
98
- def read input
77
+ def read input
99
78
  case input
100
79
  when :event then e = Event.poll until e
101
- when :key then
80
+ when :key then
102
81
  e = Event.poll until e.is_a? Event::KeyDown
103
- return e.sym.between?(32, 126) ? e.sym.chr : e.sym
104
- when :line#; line = ''
105
- # File.mkfifo( 'input' ) unless File.exist? 'input'
106
- # Readline.output=input=open('input')
107
- # Readline.output=input=StringIO.new
108
- # fork{ Readline.readline }
109
- x, y = Visuals.row, Visuals.column
110
- listen = Thread.new{
111
- # until (char = input.read) == $/
112
- # until (line = Readline.line_buffer)[-1] == $/
113
- loop do
114
- move x, y
115
- show line
116
- sleep 0.1
117
- end
118
- }
119
- line = Readline.readline
120
- listen.terminate
121
- # until input.string[-1]==$/
122
- return line
123
- # until (key = read :key) == KEY_RETURN
124
- # str << key if key.is_a? String
125
- # end
126
- #
127
- # text = ""
128
- # TextInput.start
129
- # loop do
130
- ## ev = Event.poll
131
- # case ev = read( :event )
132
- # when Event::KeyDown
133
- # if ev.sym == KEY_RETURN
134
- # TextInput.stop
135
- # return text
136
- # end
137
- # when Event::TextInput
138
- # text += ev.text
139
- # show ev.text
140
- # p ev.text
141
- # end
142
- # end
82
+ return e.sym.between?(32, 126) ? e.sym.chr : e.sym
83
+ when :line
84
+ str = ''
85
+ loop do
86
+ e = Event.poll
87
+ next unless e.is_a? Event::KeyDown
88
+ return nil if e.sym == KEY_ESCAPE
89
+ return str if e.sym == KEY_RETURN
90
+ str << e.sym.chr if e.sym.between? 32, 126
91
+ end
143
92
  end
144
93
  end
145
94
 
146
95
  def self.exit
147
96
  end
148
97
 
149
- def self.init args={}
150
- $default = [
151
- color_for( args[:foreground] || :grey80 ),
98
+ def self.init args={}
99
+ $default = [
100
+ color_for( args[:foreground] || :grey80 ),
152
101
  color_for( args[:background] || :grey10 ) ]
153
102
  $color = $default.dup
154
103
  $charsize = args[:charsize] || [18,11]
155
104
  $font = TTF.open( args[:font] || "/usr/share/fonts/X11/TTF/VeraMono.ttf", $charsize[0] )
156
105
  move 0, 0
157
106
  end
158
-
107
+
159
108
  end
160
109
 
161
110
  if __FILE__ == $0
162
- # require_relative 'base'
163
111
  include Visuals
164
- Visuals.init font:ARGV[0] #[[200,200,200],[20,20,20]], [80,50]
112
+ Visuals.init font:ARGV[0]
165
113
  characters = (32..126).map(&:chr).join
166
114
  loop do
167
115
  clear
168
- COLORS.keys.each_with_index{ |c,i|
169
- foreground c; move 0,i; show characters }
116
+ COLORS.keys.each_with_index{ |c,i|
117
+ foreground c; move 0,i; draw characters }
170
118
  refresh
171
- # GO.present
172
119
  exit if read(:key) == KEY_ESCAPE
173
120
  end
174
121
  end
data/lib/grid.rb CHANGED
@@ -1,7 +1,3 @@
1
- #!/usr/bin/env ruby
2
- # coding: utf-8
3
- # frozen_string_literal: true
4
-
5
1
  require_relative 'space.rb'
6
2
 
7
3
  module Typr
@@ -13,16 +9,16 @@ module Typr
13
9
  # input: [ ["Alice", 30], ["Bob", 25] ],
14
10
  # header: [:name, :age],
15
11
  # format: [:max, :right]
16
- # )
17
- # grid.draw
18
- #
12
+ # )
13
+ # grid.show
14
+ #
19
15
  # Column format tokens: +Integer+ (fixed width), +:min+ (auto), +:max+ (fill remaining).
20
16
  #
21
17
  # Built-in procs: +:filetree+, +:datetime+, +:magnitudes+, +:convert+.
22
18
 
23
19
  class Grid < Stack # Table
24
20
  attr_accessor :format, :procs, :filters, :data, :map
25
- attr_accessor :align, :rawsort, :rawfilter
21
+ attr_accessor :align, :rawsort, :rawfilter, :reverse
26
22
  attr_writer :sequence
27
23
 
28
24
  ##
@@ -127,8 +123,9 @@ module Typr
127
123
  # @param h [Array<String, Symbol>]
128
124
 
129
125
  def header=( h ); super
130
- h.each_with_index{ |h,i| Typr.module_eval h.upcase+?=+i.to_s } if
131
- h.is_a? Array
126
+ h.each_with_index{ |h,i|
127
+ Typr.const_set(h.upcase, i) unless Typr.const_defined?(h.upcase)
128
+ } if h.is_a? Array
132
129
  end
133
130
 
134
131
  ##
@@ -143,7 +140,7 @@ module Typr
143
140
  def reset type=:all
144
141
  case type
145
142
  when :display; @map = nil; @sort = nil; @filters.clear
146
- when :format; @widths.clear; @maxed = false
143
+ when :format; @widths.clear
147
144
  when :all; reset [:display, :format]
148
145
  end
149
146
  super
@@ -180,10 +177,11 @@ module Typr
180
177
  end
181
178
 
182
179
  ##
183
- # Add a column filter (substring or regex).
180
+ # Add a column filter (substring or regex). +:all+ matches any column.
184
181
  #
185
182
  # grid.add_filter(0, "Ali") # name contains "Ali"
186
183
  # grid.add_filter(1, /^\d{2}$/) # age matches regex
184
+ # grid.add_filter(:all, "ip") # any column contains "ip"
187
185
  #
188
186
  # @param column [Integer, Symbol]
189
187
  # @param query [String, Regexp]
@@ -205,8 +203,10 @@ module Typr
205
203
 
206
204
  def check row
207
205
  @filters.reject{ |column,query|
208
- ( (@procs[column] and not @rawfilter[column]) ?
209
- @layer : @data )[row][column].to_s[query] }.empty?
206
+ cols = column == :all ? @data[row].each_index.to_a : [column]
207
+ cols.any?{ |col|
208
+ ( (@procs[col] and not @rawfilter[col]) ?
209
+ @layer : @data )[row][col].to_s[query] } }.empty?
210
210
  end
211
211
 
212
212
  ##
@@ -240,6 +240,57 @@ module Typr
240
240
 
241
241
  def sorted_by name=false; (name and @sort) ? @header[@sort] : @sort end
242
242
 
243
+ ##
244
+ # Pick a row with live-filtering.
245
+ #
246
+ # When column is given, `Grid` overrides `Stack#pick` to add interactive
247
+ # text filtering of rows by the given column. Filter text is shown at the
248
+ # bottom of the grid. Passes through to `super` for all other types or
249
+ # when no column is given.
250
+ #
251
+ # grid.pick :row, 0, column: :name
252
+ # grid.pick :row, 0, column: :all # match any column
253
+ #
254
+ # @param type [Symbol] type is ignored (always :row); passed to super otherwise
255
+ # @param column [Symbol, String] column name to filter on, or :all (default nil)
256
+
257
+ def pick type = :row, row=0, column: nil
258
+ return super(type, row) unless column
259
+
260
+ saved = [@filters.dup, @map, @start]
261
+ base = @map || ids
262
+ @filters = [[column, '']]
263
+ @map = base.select{ |id| check id }
264
+ @start = 0
265
+ show
266
+ draw_hints
267
+ result = Typr.read_line '/', left: left, top: self.bottom + 1,
268
+ &->(key, query, _) {
269
+ if key.is_a?(String) and idx = @hints[0..height-@hints_start-1].index(key)
270
+ return page.to_a[idx + @hints_start]
271
+ end
272
+ if key.is_a?(String) and !key.each_char.all?{ |c| c.ord.between?(32, 126) } and
273
+ @keymap.values.include?(key) and ![KEY_BACKSPACE, "\b"].include?(key)
274
+ send key
275
+ else
276
+ @filters = [[column, query]]
277
+ @map = base.select{ |id| check id }
278
+ @start = 0
279
+ end
280
+ show
281
+ draw_hints
282
+ nil
283
+ }
284
+ case result
285
+ when nil; @filters, @map, @start = saved
286
+ when Integer; return result
287
+ else
288
+ @filters = result.empty? ? saved[0] : saved[0] + [[column, result]]
289
+ filter :all
290
+ end
291
+ return
292
+ end
293
+
243
294
  ##
244
295
  # Sort by column (toggle direction on repeat).
245
296
  #
@@ -263,8 +314,9 @@ module Typr
263
314
  def sort
264
315
  return false unless @sort
265
316
  data = (@procs[@sort] and not @rawsort[@sort]) ? @layer : @data
266
- @map = ids.sort{ |a,b| (data[a][@sort] <=> data[b][@sort]) || 0 }
317
+ @map = (0...@data.size).to_a.sort{ |a,b| (data[a][@sort] <=> data[b][@sort]) || 0 }
267
318
  @map.reverse! if @reverse
319
+ @map = @map.select{ |id| check id } unless @filters.empty?
268
320
  return
269
321
  end
270
322
 
@@ -296,11 +348,11 @@ module Typr
296
348
  ##
297
349
  # Compute column widths from visible data and render the grid.
298
350
  #
299
- # grid.draw
351
+ # grid.show
300
352
  #
301
353
  # @return [void]
302
354
 
303
- def draw
355
+ def show
304
356
  if not @data or @data.empty? or ( @map and @map.empty? )
305
357
  @widths = [ width/columns ] * columns if @widths.count < columns
306
358
  @rest = 0
@@ -352,20 +404,20 @@ module Typr
352
404
  def print row=nil
353
405
  return super unless row
354
406
  header = ( row == :header )
355
- return show @header[0..width-1].ljust(width) if
407
+ return draw @header[0..width-1].ljust(width) if
356
408
  header and @header.is_a? String
357
409
  fields = (header ? @header : @data[row] ).dup
358
410
  @layer[row].each{ |col,value| fields[col] = value } if
359
411
  @layer[row] if @layer unless header
360
412
  for col,id in sequence.each_with_index
361
- show @separator unless id == 0
413
+ draw @separator unless id == 0
362
414
  select = ( @selected[:columns].include? col or
363
415
  @selected[:fields].include? [row,col] ) unless
364
416
  @selected[:rows].include?(row) or header
365
417
  color( @colors[:fields][[row,col]] ||
366
418
  @colors[:columns][col] || @colors[:default] ) unless header
367
419
  background @colors[:selected] if select
368
- show prepare( fields[col].to_s, width_for( id ), @align[col] )
420
+ draw prepare( fields[col].to_s, width_for( id ), @align[col] )
369
421
  background @colors[:default][1] if select
370
422
  end
371
423
  end
@@ -404,22 +456,17 @@ module Typr
404
456
  @columns,@functions = 0,{}
405
457
  @ignore,@rawfilter,@rawsort,@reverse = [],[],[],false
406
458
  @filters,@procs = [],{}
407
- @align,@format,@widths,@totals = [],[],[],[]
408
- super #args
459
+ @align,@format,@widths = [],[],[]
460
+ super
409
461
  @colors = { columns: [], fields: {} }.merge ( @colors )
410
462
  @selected = { fields:[], columns:[] }.merge @selected
411
463
  @functions = {
412
- filetree: Proc.new{ |f| f.gsub /.*\/[^$]/, ' ' },
464
+ filetree: Proc.new{ |f| ' ' * [(d = f.count('/') - 1), 0].max + '└' + File.basename(f) },
413
465
  datetime: Proc.new{|sec|Time.at(sec).strftime"%y-%m-%d %H:%M" rescue ??},
414
466
  magnitudes: Proc.new{ |size| mag = (size.to_s.length-1) / 3
415
467
  mag>0 ? (size.to_s.insert -(mag*3+1), ?.)[0..4] + %w[B K M G T][mag] :
416
468
  size rescue size },
417
- convert: Proc.new{ |value|
418
- case value.to_s
419
- when /^[\d]+$/ then value.to_s.to_i
420
- when /^\d*[\.\,]\d+$/ then value.to_s.to_f
421
- else value
422
- end } }
469
+ convert: Proc.new{ |value| coerce_type value } }
423
470
 
424
471
  if @input
425
472
  self << @input