kv 0.6.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 70b1f3af205a0cc4e0654de74a8d9e31e023719c8cf04cd6fbb9e43d96b14be4
4
- data.tar.gz: 5265f5930278a1f39f5d00f6a6f3265e436bcdce233b7350f8f791d7f0752fee
3
+ metadata.gz: 510d5e2565cf1d662da48e3c4af89799375377b594469132319f5475ff53b8ce
4
+ data.tar.gz: '09136cab7d1f49371444949e563d5ec58225881b6ab7f781711314ea176f4401'
5
5
  SHA512:
6
- metadata.gz: 935613e6eb8be95f504d75b777b83a864bab18a34ccbdc4694df5e82c8b2312d270e9f4f4f5da7ef07ed360cc083281705b61ff62a329aa7004da289e989909f
7
- data.tar.gz: 7fb6b11b84f0c014c956cf0f0e223a74ce88426860f65919ef2e351028b957876c72a255fba10c2ed2e65dac0dbf701691cf10817745f7ec231a42de76ff7ed4
6
+ metadata.gz: e3e76a17edc990f59d1a999cb16d75619852503beafd05c9009c3efb697ccd2712203eeec6e6627614e71cce676f516972e17384588ecc9a24bd0f4acb8c2ae5
7
+ data.tar.gz: ad6c7de4f61931c05a867554ae47998d0f19f72548fbf76cfb3336fdebca7b06f111e828b17ac21011dd95defa5adb588d70c157b9043b3b897ad612fda7f4b3
@@ -0,0 +1,3 @@
1
+ # These are supported funding model platforms
2
+
3
+ github: [ko1]
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.6.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'
@@ -20,7 +20,8 @@ end
20
20
  class Screen
21
21
  RenderStatus = Struct.new(
22
22
  :c_cols, :c_lines, :x, :y, :last_lineno,
23
- :search, :goto, :line_mode, :ts_mode, :wrapping,
23
+ :search, :goto, :wrapping,
24
+ :line_mode, :ts_mode, :separation_mode,
24
25
  )
25
26
  class RenderStatus
26
27
  def to_s
@@ -29,9 +30,18 @@ class Screen
29
30
  end
30
31
 
31
32
  def initialize input, lines: [],
32
- name: nil, search: nil, first_line: 0,
33
- following_mode: false, line_mode: false, separation_mode: false,
34
- 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
+
35
45
  @rs = RenderStatus.new
36
46
  @last_rs = nil
37
47
  @rs.y = first_line
@@ -42,18 +52,21 @@ class Screen
42
52
  @rs.search = search
43
53
  @rs.wrapping = false
44
54
  @rs.ts_mode = false
55
+ @rs.separation_mode = separation_mode
45
56
 
46
57
  @name = name
47
58
  @filename = @name if @name && File.exist?(@name)
59
+ @filter_command = @filename && filter_command
48
60
 
49
61
  @time_stamp = time_stamp
50
62
  @ext_input = ext_input
51
63
  @fifo_file = fifo_file
52
- @separation_mode = separation_mode
53
64
 
54
65
  @lines = lines
55
66
  @mode = :screen
56
67
 
68
+ @watch_mode = watch
69
+
57
70
  @following = following_mode
58
71
  @apos = 0
59
72
 
@@ -70,11 +83,23 @@ class Screen
70
83
  end
71
84
 
72
85
  @prev_render = {}
86
+ input = open_file if @filename
73
87
  @meta = input.respond_to?(:meta) ? input.meta : nil
74
-
75
88
  read_async input if input
76
89
  end
77
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
+
78
103
  def setup_line line
79
104
  line = line.chomp
80
105
  line.instance_variable_set(:@time_stamp, Time.now.strftime('%H:%M:%S')) if @time_stamp
@@ -117,7 +142,7 @@ class Screen
117
142
  ensure
118
143
  if @filename
119
144
  @file_mtime = File.mtime(@filename)
120
- @file_lastpos = input.tell
145
+ @file_lastpos = input.tell unless @filter_command
121
146
  elsif @fifo_file
122
147
  input = open(@fifo_file)
123
148
  log(input)
@@ -184,9 +209,9 @@ class Screen
184
209
 
185
210
 
186
211
  def standout
187
- Curses.standout
188
- yield
189
- Curses.standend
212
+ cattr Curses::A_STANDOUT do
213
+ yield
214
+ end
190
215
  end
191
216
 
192
217
  def cattr attr
@@ -222,11 +247,11 @@ class Screen
222
247
 
223
248
  Curses.clear
224
249
 
225
- if @separation_mode && (lines = @lines[self.y ... (self.y + c_lines - 1)])
226
- max_cols = []
250
+ if @rs.separation_mode && (lines = @lines[self.y ... (self.y + c_lines - 1)])
251
+ @max_cols = [] unless defined? @max_cols
227
252
  lines.each.with_index{|line, ln|
228
253
  line.split("\t").each_with_index{|w, i|
229
- 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
230
255
  }
231
256
  }
232
257
  end
@@ -273,29 +298,32 @@ class Screen
273
298
 
274
299
  line = line[self.x, cols] || ''
275
300
 
276
- if @separation_mode
301
+ if @rs.separation_mode
277
302
  line = line.split(/\t/).tap{|e|
278
- if (max = max_cols.size) > 0
303
+ if (max = @max_cols.size) > 0
279
304
  # fill empty columns
280
305
  e[max - 1] ||= nil
281
306
  end
282
307
  }.map.with_index{|w, i|
283
- "%-#{max_cols[i]}s" % w
308
+ "%-#{@max_cols[i]}s" % w
284
309
  }.join(' | ')
285
310
  end
286
311
 
287
- if !@rs.search || !(Regexp === @rs.search)
312
+ if !@rs.search || !(Regexp === @rs.search) ||
313
+ (parts = search_partition(line, @rs.search)).is_a?(String)
288
314
  Curses.addstr line
289
315
  else
290
- partition(line, @rs.search).each{|(matched, str)|
291
- if matched == :match
292
- 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
293
323
  Curses.addstr str
294
- }
295
- else
296
- Curses.addstr str
297
- end
298
- }
324
+ end
325
+ }
326
+ end
299
327
  end
300
328
  }
301
329
  end
@@ -361,17 +389,25 @@ class Screen
361
389
 
362
390
  def check_update
363
391
  if @loading == false
364
- if @filename && File.exist?(@filename) && File.mtime(@filename) > @file_mtime
365
- input = open(@filename)
392
+ if @filename && File.mtime(@filename) > @file_mtime
393
+ screen_status "#{@filename} is updated."
366
394
 
367
- if input.size < @file_lastpos
368
- screen_status "#{@filename} is truncated. Rewinded."
369
- pause
370
- @lineno = 0
395
+ if @watch_mode
396
+ @lines = []
397
+ input = open_file
398
+ read_async input
371
399
  else
372
- 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
373
410
  end
374
- read_async input
375
411
  end
376
412
  end
377
413
  end
@@ -658,6 +694,9 @@ class Screen
658
694
  @rs.line_mode = !@rs.line_mode
659
695
  when 'T'
660
696
  @rs.ts_mode = !@rs.ts_mode if @time_stamp
697
+ when 'S'
698
+ @rs.separation_mode = !@rs.separation_mode
699
+ @max_cols = []
661
700
  when 't'
662
701
  Curses.close_screen
663
702
  @mode = :terminal
@@ -828,6 +867,12 @@ class KV
828
867
  opts.on('-s', 'Separation mode (tsv)'){
829
868
  @opts[:separation_mode] = true
830
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
+ }
831
876
  opts.parse!(argv)
832
877
  end
833
878
 
@@ -838,7 +883,7 @@ class KV
838
883
  @screens.last.control
839
884
  rescue PopScreen
840
885
  @screens.pop
841
- @screens.last.redraw!
886
+ @screens.last.redraw! unless @screens.empty?
842
887
  rescue PushScreen => e
843
888
  @screens.push e.screen
844
889
  @screens.last.redraw!
@@ -861,18 +906,23 @@ def log obj, prefix = ''
861
906
  end
862
907
  end
863
908
 
864
- def partition str, search
909
+ def search_partition str, search
865
910
  results = []
866
911
  loop{
867
912
  r = str.match(search){|m|
868
913
  break if m.post_match == str
869
- results << [:unmatch, m.pre_match]
914
+ results << [:unmatch, m.pre_match] unless m.pre_match.empty?
870
915
  results << [:match, m.to_s]
871
916
  str = m.post_match
872
917
  }
873
918
  break unless r
874
919
  }
875
- results << [:unmatch, str]
920
+ if results.empty?
921
+ str
922
+ else
923
+ results << [:unmatch, str] unless str.empty?
924
+ results
925
+ end
876
926
  end
877
927
 
878
928
  def help_io
@@ -888,5 +938,5 @@ def help_io
888
938
  end
889
939
  }
890
940
 
891
- help_io = StringIO.new(help.join)
941
+ StringIO.new(help.join)
892
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.6.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-06-19 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
@@ -32,6 +32,7 @@ executables:
32
32
  extensions: []
33
33
  extra_rdoc_files: []
34
34
  files:
35
+ - ".github/FUNDING.yml"
35
36
  - ".gitignore"
36
37
  - LICENSE
37
38
  - README.md
@@ -61,8 +62,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
61
62
  - !ruby/object:Gem::Version
62
63
  version: '0'
63
64
  requirements: []
64
- rubyforge_project:
65
- rubygems_version: 2.7.6
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'