kv 0.8.0 → 0.9.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.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/exe/kv +1 -1
  3. data/lib/kv/version.rb +1 -1
  4. data/lib/kv.rb +81 -34
  5. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 88a03848ba99241da0e03e0947b101f10f3377b2b86324a5d2221ebe5173da45
4
- data.tar.gz: 381798ca027176bca1c4dcc6f62eba469b59a64bfd9fe8d1c3431791f7671d28
3
+ metadata.gz: 510d5e2565cf1d662da48e3c4af89799375377b594469132319f5475ff53b8ce
4
+ data.tar.gz: '09136cab7d1f49371444949e563d5ec58225881b6ab7f781711314ea176f4401'
5
5
  SHA512:
6
- metadata.gz: abe415462dbed0bb96d4cc816c6a2c6b909662c7daf08bc575b748af6a15a803be27ac19dc8bb071d555cc273c7552517d18fc18a70f64623fcb3fc7e5274d1b
7
- data.tar.gz: cc247a3f2488489a6023987e94aa346fdbb2f84dd581c552d4ab4e8554396bb1c510fa4a7a2528afdc221e618be9868bca9b6331dc647644d81d5e20664cead3
6
+ metadata.gz: e3e76a17edc990f59d1a999cb16d75619852503beafd05c9009c3efb697ccd2712203eeec6e6627614e71cce676f516972e17384588ecc9a24bd0f4acb8c2ae5
7
+ data.tar.gz: ad6c7de4f61931c05a867554ae47998d0f19f72548fbf76cfb3336fdebca7b06f111e828b17ac21011dd95defa5adb588d70c157b9043b3b897ad612fda7f4b3
data/exe/kv CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  begin
4
4
  require 'kv'
5
- rescue LoadError
5
+ rescue
6
6
  $:.unshift File.join(__dir__, '../lib')
7
7
  require 'kv'
8
8
  end
data/lib/kv/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module KV
2
- VERSION = "0.8.0"
2
+ VERSION = "0.9.0"
3
3
  end
data/lib/kv.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "kv/version"
3
+ require_relative "kv/version"
4
4
  require "curses"
5
5
  require 'stringio'
6
6
  require 'optparse'
@@ -30,9 +30,18 @@ class Screen
30
30
  end
31
31
 
32
32
  def initialize input, lines: [],
33
- name: nil, search: nil, first_line: 0,
34
- following_mode: false, line_mode: false, separation_mode: false,
35
- time_stamp: nil, ext_input: nil, fifo_file: nil
33
+ name: nil,
34
+ search: nil,
35
+ first_line: 0,
36
+ following_mode: false,
37
+ line_mode: false,
38
+ separation_mode: false,
39
+ time_stamp: nil,
40
+ ext_input: nil,
41
+ fifo_file: nil,
42
+ watch: false,
43
+ filter_command: nil
44
+
36
45
  @rs = RenderStatus.new
37
46
  @last_rs = nil
38
47
  @rs.y = first_line
@@ -47,6 +56,7 @@ class Screen
47
56
 
48
57
  @name = name
49
58
  @filename = @name if @name && File.exist?(@name)
59
+ @filter_command = @filename && filter_command
50
60
 
51
61
  @time_stamp = time_stamp
52
62
  @ext_input = ext_input
@@ -55,6 +65,8 @@ class Screen
55
65
  @lines = lines
56
66
  @mode = :screen
57
67
 
68
+ @watch_mode = watch
69
+
58
70
  @following = following_mode
59
71
  @apos = 0
60
72
 
@@ -71,11 +83,23 @@ class Screen
71
83
  end
72
84
 
73
85
  @prev_render = {}
86
+ input = open_file if @filename
74
87
  @meta = input.respond_to?(:meta) ? input.meta : nil
75
-
76
88
  read_async input if input
77
89
  end
78
90
 
91
+ def open_file
92
+ input = open(@filename)
93
+ @rs.last_lineno = 0
94
+
95
+ if @filter_command
96
+ io = IO.popen("#{@filter_command} #{@filename}", err: '/dev/null')
97
+ # io.close_write
98
+ input = io
99
+ end
100
+ input
101
+ end
102
+
79
103
  def setup_line line
80
104
  line = line.chomp
81
105
  line.instance_variable_set(:@time_stamp, Time.now.strftime('%H:%M:%S')) if @time_stamp
@@ -118,7 +142,7 @@ class Screen
118
142
  ensure
119
143
  if @filename
120
144
  @file_mtime = File.mtime(@filename)
121
- @file_lastpos = input.tell
145
+ @file_lastpos = input.tell unless @filter_command
122
146
  elsif @fifo_file
123
147
  input = open(@fifo_file)
124
148
  log(input)
@@ -185,9 +209,9 @@ class Screen
185
209
 
186
210
 
187
211
  def standout
188
- Curses.standout
189
- yield
190
- Curses.standend
212
+ cattr Curses::A_STANDOUT do
213
+ yield
214
+ end
191
215
  end
192
216
 
193
217
  def cattr attr
@@ -224,10 +248,10 @@ class Screen
224
248
  Curses.clear
225
249
 
226
250
  if @rs.separation_mode && (lines = @lines[self.y ... (self.y + c_lines - 1)])
227
- max_cols = []
251
+ @max_cols = [] unless defined? @max_cols
228
252
  lines.each.with_index{|line, ln|
229
253
  line.split("\t").each_with_index{|w, i|
230
- max_cols[i] = max_cols[i] ? [max_cols[i], w.size].max : w.size
254
+ @max_cols[i] = @max_cols[i] ? [@max_cols[i], w.size].max : w.size
231
255
  }
232
256
  }
233
257
  end
@@ -276,27 +300,30 @@ class Screen
276
300
 
277
301
  if @rs.separation_mode
278
302
  line = line.split(/\t/).tap{|e|
279
- if (max = max_cols.size) > 0
303
+ if (max = @max_cols.size) > 0
280
304
  # fill empty columns
281
305
  e[max - 1] ||= nil
282
306
  end
283
307
  }.map.with_index{|w, i|
284
- "%-#{max_cols[i]}s" % w
308
+ "%-#{@max_cols[i]}s" % w
285
309
  }.join(' | ')
286
310
  end
287
311
 
288
- if !@rs.search || !(Regexp === @rs.search)
312
+ if !@rs.search || !(Regexp === @rs.search) ||
313
+ (parts = search_partition(line, @rs.search)).is_a?(String)
289
314
  Curses.addstr line
290
315
  else
291
- partition(line, @rs.search).each{|(matched, str)|
292
- if matched == :match
293
- standout{
316
+ cattr Curses::A_UNDERLINE do
317
+ parts.each{|(matched, str)|
318
+ if matched == :match
319
+ standout{
320
+ Curses.addstr str
321
+ }
322
+ else
294
323
  Curses.addstr str
295
- }
296
- else
297
- Curses.addstr str
298
- end
299
- }
324
+ end
325
+ }
326
+ end
300
327
  end
301
328
  }
302
329
  end
@@ -362,17 +389,25 @@ class Screen
362
389
 
363
390
  def check_update
364
391
  if @loading == false
365
- if @filename && File.exist?(@filename) && File.mtime(@filename) > @file_mtime
366
- input = open(@filename)
392
+ if @filename && File.mtime(@filename) > @file_mtime
393
+ screen_status "#{@filename} is updated."
367
394
 
368
- if input.size < @file_lastpos
369
- screen_status "#{@filename} is truncated. Rewinded."
370
- pause
371
- @lineno = 0
395
+ if @watch_mode
396
+ @lines = []
397
+ input = open_file
398
+ read_async input
372
399
  else
373
- input.seek @file_lastpos
400
+ input = open(@filename)
401
+
402
+ if input.size < @file_lastpos
403
+ screen_status "#{@filename} is truncated. Rewinded."
404
+ pause
405
+ @lineno = 0
406
+ else
407
+ input.seek @file_lastpos
408
+ end
409
+ read_async input
374
410
  end
375
- read_async input
376
411
  end
377
412
  end
378
413
  end
@@ -661,6 +696,7 @@ class Screen
661
696
  @rs.ts_mode = !@rs.ts_mode if @time_stamp
662
697
  when 'S'
663
698
  @rs.separation_mode = !@rs.separation_mode
699
+ @max_cols = []
664
700
  when 't'
665
701
  Curses.close_screen
666
702
  @mode = :terminal
@@ -831,6 +867,12 @@ class KV
831
867
  opts.on('-s', 'Separation mode (tsv)'){
832
868
  @opts[:separation_mode] = true
833
869
  }
870
+ opts.on('-w', 'Watch mode: Reload on file changed'){
871
+ @opts[:watch] = true
872
+ }
873
+ opts.on('--filter-command=FILTER_COMMAND', 'Apply filter command'){|cmd|
874
+ @opts[:filter_command] = cmd
875
+ }
834
876
  opts.parse!(argv)
835
877
  end
836
878
 
@@ -864,18 +906,23 @@ def log obj, prefix = ''
864
906
  end
865
907
  end
866
908
 
867
- def partition str, search
909
+ def search_partition str, search
868
910
  results = []
869
911
  loop{
870
912
  r = str.match(search){|m|
871
913
  break if m.post_match == str
872
- results << [:unmatch, m.pre_match]
914
+ results << [:unmatch, m.pre_match] unless m.pre_match.empty?
873
915
  results << [:match, m.to_s]
874
916
  str = m.post_match
875
917
  }
876
918
  break unless r
877
919
  }
878
- results << [:unmatch, str]
920
+ if results.empty?
921
+ str
922
+ else
923
+ results << [:unmatch, str] unless str.empty?
924
+ results
925
+ end
879
926
  end
880
927
 
881
928
  def help_io
@@ -891,5 +938,5 @@ def help_io
891
938
  end
892
939
  }
893
940
 
894
- help_io = StringIO.new(help.join)
941
+ StringIO.new(help.join)
895
942
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kv
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Koichi Sasada
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-08-04 00:00:00.000000000 Z
11
+ date: 2022-05-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: curses
@@ -62,7 +62,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
62
62
  - !ruby/object:Gem::Version
63
63
  version: '0'
64
64
  requirements: []
65
- rubygems_version: 3.1.2
65
+ rubygems_version: 3.1.6
66
66
  signing_key:
67
67
  specification_version: 4
68
68
  summary: 'kv: A page viewer written by Ruby'