linecache-tf 0.45 → 1.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 (3) hide show
  1. data/lib/linecache.rb +123 -66
  2. data/lib/tracelines.rb +5 -4
  3. metadata +28 -28
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
- # Copyright (C) 2007, 2008, 2009, 2010 Rocky Bernstein <rockyb@rubyforge.net>
2
+ # Copyright (C) 2007, 2008, 2009, 2010, 2011 Rocky Bernstein
3
+ # <rockyb@rubyforge.net>
3
4
  #
4
5
  # This program is free software; you can redistribute it and/or modify
5
6
  # it under the terms of the GNU General Public License as published by
@@ -66,7 +67,7 @@ require_relative 'tracelines'
66
67
  # = module LineCache
67
68
  # A module to read and cache lines of a Ruby program.
68
69
  module LineCache
69
- VERSION = '0.45'
70
+ VERSION = '1.0'
70
71
  LineCacheInfo = Struct.new(:stat, :line_numbers, :lines, :path, :sha1) unless
71
72
  defined?(LineCacheInfo)
72
73
 
@@ -75,6 +76,9 @@ module LineCache
75
76
  @@file_cache = {}
76
77
  @@iseq_cache = {}
77
78
 
79
+ # Used for CodeRay syntax highlighting
80
+ @@ruby_highlighter = nil
81
+
78
82
  # Maps a string filename (a String) to a key in @@file_cache (a
79
83
  # String).
80
84
  #
@@ -92,22 +96,41 @@ module LineCache
92
96
 
93
97
  @@iseq2file = {}
94
98
 
99
+ module_function
100
+
95
101
  def remove_iseq_temps
96
102
  @@iseq2file.values.each do |filename|
97
- File.unlink(filename)
103
+ File.unlink(filename) if File.exist?(filename)
98
104
  end
99
105
  end
100
- module_function :remove_iseq_temps
101
106
  at_exit { remove_iseq_temps }
102
107
 
103
108
 
109
+ # Remove syntax-formatted lines in the cache. Use this
110
+ # when you change the CodeRay syntax or Token formatting
111
+ # and want to redo how files may have previously been
112
+ # syntax marked.
113
+ def clear_file_format_cache
114
+ @@file_cache.each_pair do |fname, cache_info|
115
+ cache_info.lines.each_pair do |format, lines|
116
+ next if :plain == format
117
+ @@file_cache[fname].lines[format] = nil
118
+ end
119
+ end
120
+ end
121
+
104
122
  # Clear the file cache entirely.
105
- def clear_file_cache()
106
- @@file_cache = {}
107
- @@file2file_remap = {}
108
- @@file2file_remap_lines = {}
123
+ def clear_file_cache(filename=nil)
124
+ if filename
125
+ if @@file_cache[filename]
126
+ @@file_cache.delete(filename)
127
+ end
128
+ else
129
+ @@file_cache = {}
130
+ @@file2file_remap = {}
131
+ @@file2file_remap_lines = {}
132
+ end
109
133
  end
110
- module_function :clear_file_cache
111
134
 
112
135
  # Clear the iseq cache entirely.
113
136
  def clear_iseq_cache()
@@ -119,7 +142,6 @@ module LineCache
119
142
  def cached_files()
120
143
  @@file_cache.keys
121
144
  end
122
- module_function :cached_files
123
145
 
124
146
  # Discard cache entries that are out of date. If +filename+ is +nil+
125
147
  # all entries in the file cache +@@file_cache+ are checked.
@@ -127,7 +149,7 @@ module LineCache
127
149
  # if the file was read from __SCRIPT_LINES but no corresponding file
128
150
  # is found, it will be kept. Return a list of invalidated filenames.
129
151
  # nil is returned if a filename was given but not found cached.
130
- def checkcache(filename=nil, use_script_lines=false)
152
+ def checkcache(filename=nil, opts={})
131
153
 
132
154
  if !filename
133
155
  filenames = @@file_cache.keys()
@@ -148,26 +170,24 @@ module LineCache
148
170
  if stat &&
149
171
  (cache_info.size != stat.size or cache_info.mtime != stat.mtime)
150
172
  result << filename
151
- update_cache(filename, use_script_lines)
173
+ update_cache(filename, opts)
152
174
  end
153
175
  else
154
176
  result << filename
155
- update_cache(filename, use_script_lines)
177
+ update_cache(filename, opts)
156
178
  end
157
179
  end
158
180
  end
159
181
  return result
160
182
  end
161
- module_function :checkcache
162
183
 
163
184
  # Cache iseq if it's not already cached.
164
- def cache_iseq(iseq, string=nil, sha1=nil)
185
+ def cache_iseq(iseq, opts={})
165
186
  if !@@iseq_cache.member?(iseq)
166
- update_iseq_cache(iseq, string, sha1)
187
+ update_iseq_cache(iseq, opts)
167
188
  end
168
189
  iseq
169
190
  end
170
- module_function :cache_iseq
171
191
 
172
192
  # Cache file name or iseq object if it's not already cached.
173
193
  # Return the expanded filename for it in the cache if a filename,
@@ -184,11 +204,12 @@ module LineCache
184
204
  # Cache filename if it's not already cached.
185
205
  # Return the expanded filename for it in the cache
186
206
  # or nil if we can't find the file.
187
- def cache_file(filename, reload_on_change=false)
207
+ def cache_file(filename, reload_on_change=false, opts={})
188
208
  if @@file_cache.member?(filename)
189
209
  checkcache(filename) if reload_on_change
190
210
  else
191
- update_cache(filename, true)
211
+ opts[:use_script_lines] = true
212
+ update_cache(filename, opts)
192
213
  end
193
214
  if @@file_cache.member?(filename)
194
215
  @@file_cache[filename].path
@@ -196,7 +217,6 @@ module LineCache
196
217
  nil
197
218
  end
198
219
  end
199
- module_function :cache_file
200
220
 
201
221
  # Return true if file_or_iseq is cached
202
222
  def cached?(file_or_iseq)
@@ -230,12 +250,12 @@ module LineCache
230
250
  # $: << '/tmp'
231
251
  # lines = LineCache.getlines('myfile.rb')
232
252
  #
233
- def getline(file_or_iseq, line_number, reload_on_change=true)
253
+ def getline(file_or_iseq, line_number, opts={})
234
254
  lines =
235
255
  if file_or_iseq.kind_of?(String)
236
256
  filename = map_file(file_or_iseq)
237
257
  filename, line_number = map_file_line(filename, line_number)
238
- getlines(filename, reload_on_change)
258
+ getlines(filename, opts)
239
259
  else
240
260
  iseq_getlines(file_or_iseq)
241
261
  end
@@ -245,43 +265,68 @@ module LineCache
245
265
  return nil
246
266
  end
247
267
  end
248
- module_function :getline
249
268
 
250
269
  # Read lines of +iseq+ and cache the results. However +iseq+ was
251
270
  # previously cached use the results from the cache. Return nil
252
271
  # if we can't get lines
253
- def iseq_getlines(iseq)
254
- if @@iseq_cache.member?(iseq)
255
- return @@iseq_cache[iseq].lines
256
- else
257
- update_iseq_cache(iseq)
272
+ def iseq_getlines(iseq, opts={})
273
+ return nil unless iseq.kind_of? RubyVM::InstructionSequence
274
+ format = opts[:output] || :plain
275
+ line_formats =
258
276
  if @@iseq_cache.member?(iseq)
259
- return @@iseq_cache[iseq].lines
277
+ @@iseq_cache[iseq].lines
260
278
  else
261
- return nil
279
+ update_iseq_cache(iseq, opts)
280
+ if @@iseq_cache.member?(iseq)
281
+ @@iseq_cache[iseq].lines
282
+ else
283
+ nil
284
+ end
262
285
  end
286
+ return nil unless line_formats
287
+ if format != :plain && !line_formats[format]
288
+ highlight_string(line_formats[:plain].join('')).split(/\n/)
289
+ else
290
+ line_formats[format]
263
291
  end
264
292
  end
265
- module_function :iseq_getlines
266
293
 
267
294
  # Read lines of +filename+ and cache the results. However +filename+ was
268
295
  # previously cached use the results from the cache. Return nil
269
296
  # if we can't get lines
270
- def getlines(filename, reload_on_change=false)
297
+ def getlines(filename, opts={})
271
298
  filename = map_file(filename)
272
- checkcache(filename) if reload_on_change
299
+ checkcache(filename) if opts[:reload_on_change]
300
+ format = opts[:output] || :plain
273
301
  if @@file_cache.member?(filename)
274
- return @@file_cache[filename].lines
302
+ lines = @@file_cache[filename].lines
303
+ if opts[:output] && !lines[format]
304
+ lines[format] =
305
+ highlight_string(lines[:plain].join(''), format).split(/\n/)
306
+ end
307
+ return lines[format]
275
308
  else
276
- update_cache(filename, true)
309
+ opts[:use_script_lines] = true
310
+ update_cache(filename, opts)
277
311
  if @@file_cache.member?(filename)
278
- return @@file_cache[filename].lines
312
+ return @@file_cache[filename].lines[format]
279
313
  else
280
314
  return nil
281
315
  end
282
316
  end
283
317
  end
284
- module_function :getlines
318
+
319
+ def highlight_string(string, output_type)
320
+ require 'rubygems'
321
+ begin
322
+ require 'coderay'
323
+ require 'term/ansicolor'
324
+ rescue LoadError
325
+ return string
326
+ end
327
+ @@ruby_highlighter ||= CodeRay::Duo[:ruby, output_type]
328
+ @@ruby_highlighter.encode(string)
329
+ end
285
330
 
286
331
  # Return full filename path for filename
287
332
  def path(filename)
@@ -290,12 +335,10 @@ module LineCache
290
335
  return nil unless @@file_cache.member?(filename)
291
336
  @@file_cache[filename].path
292
337
  end
293
- module_function :path
294
338
 
295
339
  def remap_file(to_file, from_file)
296
340
  @@file2file_remap[to_file] = from_file
297
341
  end
298
- module_function :remap_file
299
342
 
300
343
  def remap_file_lines(from_file, to_file, range, start)
301
344
  range = (range..range) if range.kind_of?(Fixnum)
@@ -308,7 +351,6 @@ module LineCache
308
351
  @@file2file_remap_lines[to_file] = [[from_file, range, start]]
309
352
  end
310
353
  end
311
- module_function :remap_file_lines
312
354
 
313
355
  # Return SHA1 of filename.
314
356
  def sha1(filename)
@@ -317,13 +359,12 @@ module LineCache
317
359
  return @@file_cache[filename].sha1.hexdigest if
318
360
  @@file_cache[filename].sha1
319
361
  sha1 = Digest::SHA1.new
320
- @@file_cache[filename].lines.each do |line|
362
+ @@file_cache[filename].lines[:plain].each do |line|
321
363
  sha1 << line + "\n"
322
364
  end
323
365
  @@file_cache[filename].sha1 = sha1
324
366
  sha1.hexdigest
325
367
  end
326
- module_function :sha1
327
368
 
328
369
  # Return the number of lines in filename
329
370
  def size(file_or_iseq)
@@ -331,13 +372,13 @@ module LineCache
331
372
  if file_or_iseq.kind_of?(String)
332
373
  file_or_iseq = map_file(file_or_iseq)
333
374
  return nil unless @@file_cache.member?(file_or_iseq)
334
- @@file_cache[file_or_iseq].lines.length
375
+ @@file_cache[file_or_iseq].lines[:plain].length
335
376
  else
336
377
  return nil unless @@iseq_cache.member?(file_or_iseq)
337
378
  @@iseq_cache[file_or_iseq].lines.length
379
+ @@script_cache[file_or_iseq].lines[:plain].length
338
380
  end
339
381
  end
340
- module_function :size
341
382
 
342
383
  # Return File.stat in the cache for filename.
343
384
  def stat(filename)
@@ -356,17 +397,15 @@ module LineCache
356
397
  e = @@file_cache[filename]
357
398
  unless e.line_numbers
358
399
  e.line_numbers =
359
- TraceLineNumbers.lnums_for_str_array(e.lines)
400
+ TraceLineNumbers.lnums_for_str_array(e.lines[:plain])
360
401
  e.line_numbers = false unless e.line_numbers
361
402
  end
362
403
  e.line_numbers
363
404
  end
364
- module_function :trace_line_numbers
365
405
 
366
406
  def map_file(file)
367
407
  @@file2file_remap[file] ? @@file2file_remap[file] : file
368
408
  end
369
- module_function :map_file
370
409
 
371
410
  def map_iseq(iseq)
372
411
  if @@iseq2file[iseq]
@@ -375,17 +414,15 @@ module LineCache
375
414
  # Doc says there's new takes an optional string parameter
376
415
  # But it doesn't work for me
377
416
  sha1 = Digest::SHA1.new
378
- string = iseq.source
379
- sha1 << iseq.source
417
+ string = iseq.eval_source
418
+ sha1 << iseq.eval_source
380
419
  tempfile = Tempfile.new(["eval-#{sha1.hexdigest[0...7]}-", '.rb'])
381
420
  tempfile.open.puts(string)
382
421
  tempfile.close
383
- # cache_iseq(iseq, string, sha1.hexdigest)
384
422
  @@iseq2file[iseq] = tempfile.path
385
423
  tempfile.path
386
424
  end
387
425
  end
388
- module_function :map_iseq
389
426
 
390
427
  def map_file_line(file, line)
391
428
  if @@file2file_remap_lines[file]
@@ -401,26 +438,28 @@ module LineCache
401
438
  module_function :map_file_line
402
439
 
403
440
  def iseq_is_eval?(iseq)
404
- !!iseq.source
441
+ !!iseq.eval_source
405
442
  end
406
443
  module_function :iseq_is_eval?
407
444
 
408
445
  # Update a cache entry. If something is wrong, return nil. Return
409
446
  # true if the cache was updated and false if not.
410
- def update_iseq_cache(iseq, string=nil, sha1=nil)
447
+ def update_iseq_cache(iseq, opts)
411
448
  return false unless iseq_is_eval?(iseq)
412
- string = iseq.source unless string
449
+ string = opts[:string] || iseq.eval_source
450
+ lines = {:plain => string.split(/\n/)}
451
+ lines[opts[:output]] = highlight_string(string, opts[:output]) if
452
+ opts[:output]
413
453
  @@iseq_cache[iseq] =
414
- LineCacheInfo.new(nil, nil, string.split(/\n/), nil, sha1)
454
+ LineCacheInfo.new(nil, nil, lines, nil, opts[:sha1])
415
455
  return true
416
456
  end
417
- module_function :update_iseq_cache
418
457
 
419
- # Update a cache entry. If something's
420
- # wrong, return nil. Return true if the cache was updated and false
421
- # if not. If use_script_lines is true, use that as the source for the
458
+ # Update a cache entry. If something's wrong, return nil. Return
459
+ # true if the cache was updated and false if not. If
460
+ # opts[:use_script_lines] is true, use that as the source for the
422
461
  # lines of the file
423
- def update_cache(filename, use_script_lines=false)
462
+ def update_cache(filename, opts={})
424
463
 
425
464
  return nil unless filename
426
465
 
@@ -443,8 +482,13 @@ module LineCache
443
482
  end
444
483
  begin
445
484
  fp = File.open(path, 'r')
446
- lines = fp.readlines()
485
+ raw_string = fp.read
486
+ fp.rewind
487
+ lines = {:plain => fp.readlines}
447
488
  fp.close()
489
+ lines[opts[:output]] =
490
+ highlight_string(raw_string, opts[:output]).split(/\n/) if
491
+ opts[:output]
448
492
  rescue
449
493
  ## print '*** cannot open', path, ':', msg
450
494
  return nil
@@ -454,8 +498,6 @@ module LineCache
454
498
  @@file2file_remap[path] = filename
455
499
  return true
456
500
  end
457
-
458
- module_function :update_cache
459
501
  end
460
502
 
461
503
  # example usage
@@ -494,7 +536,22 @@ if __FILE__ == $0
494
536
  puts "Remapped 10th line of test2 is\n#{line}"
495
537
  require 'thread_frame'
496
538
  puts eval("x=1
497
- LineCache::getline(RubyVM::ThreadFrame.current.iseq, 1)")
498
- puts eval("x=2
499
- LineCache::getline(RubyVM::ThreadFrame.current.iseq, 2)")
539
+ LineCache::getline(RubyVM::ThreadFrame.current.iseq, 1)")
540
+ puts eval("x=2
541
+ LineCache::getline(RubyVM::ThreadFrame.current.iseq, 2)")
542
+
543
+ # # Try new ANSI Terminal syntax coloring
544
+ LineCache::clear_file_cache(__FILE__)
545
+ LineCache::update_cache(__FILE__, :output => :term)
546
+ 50.upto(60) do |i|
547
+ line = LineCache::getline(__FILE__, i, :output => :term)
548
+ # puts line.inspect
549
+ puts line
550
+ end
551
+ puts '-' * 20
552
+ 50.upto(60) do |i|
553
+ line = LineCache::getline(__FILE__, i)
554
+ # puts line.inspect
555
+ puts line
556
+ end
500
557
  end
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
- # $Id: tracelines.rb 182 2009-10-18 23:47:37Z rockyb $
3
- # Copyright (C) 2007, 2008, 2009 Rocky Bernstein <rockyb@rubyforge.net>
2
+ # $Id: tracelines.rb 233 2010-12-18 23:12:20Z rockyb $
3
+ # Copyright (C) 2007, 2008, 2009, 2010
4
+ # Rocky Bernstein <rockyb@rubyforge.net>
4
5
  #
5
6
  # This program is free software; you can redistribute it and/or modify
6
7
  # it under the terms of the GNU General Public License as published by
@@ -20,8 +21,8 @@ require 'thread_frame'
20
21
 
21
22
  module TraceLineNumbers
22
23
 
23
- def lnums_for_iseq(iseq, uniq=true)
24
- lnums = iseq.child_iseqs.map { |iseq|
24
+ def lnums_for_iseq(orig_iseq, uniq=true)
25
+ lnums = orig_iseq.child_iseqs.map { |iseq|
25
26
  iseq.offsetlines.values.flatten
26
27
  }.flatten.sort
27
28
  uniq ? lnums.uniq : lnums
metadata CHANGED
@@ -3,9 +3,9 @@ name: linecache-tf
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
+ - 1
6
7
  - 0
7
- - 45
8
- version: "0.45"
8
+ version: "1.0"
9
9
  platform: ruby
10
10
  authors:
11
11
  - R. Bernstein
@@ -13,7 +13,7 @@ autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
15
 
16
- date: 2010-12-10 00:00:00 -05:00
16
+ date: 2011-02-01 00:00:00 -05:00
17
17
  default_executable:
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
@@ -52,41 +52,41 @@ files:
52
52
  - NEWS
53
53
  - README
54
54
  - Rakefile
55
- - lib/tracelines.rb
56
55
  - lib/linecache.rb
56
+ - lib/tracelines.rb
57
+ - test/test-lnum.rb
58
+ - test/test-tracelines.rb
57
59
  - test/parse-show.rb
60
+ - test/test-linecache.rb
58
61
  - test/lnum-diag.rb
59
62
  - test/rcov-bug.rb
60
- - test/test-lnum.rb
61
- - test/test-linecache.rb
62
- - test/test-tracelines.rb
63
- - test/data/if1.rb
64
- - test/data/comments1.rb
65
- - test/data/not-lit.rb
66
- - test/data/begin2.rb
67
- - test/data/block2.rb
68
- - test/data/if6.rb
63
+ - test/data/if4.rb
69
64
  - test/data/end.rb
65
+ - test/data/if6.rb
66
+ - test/data/begin3.rb
67
+ - test/data/if3.rb
68
+ - test/data/block2.rb
69
+ - test/data/case2.rb
70
+ - test/data/begin2.rb
71
+ - test/data/each1.rb
72
+ - test/data/if2.rb
70
73
  - test/data/case4.rb
71
- - test/data/begin1.rb
72
- - test/data/for1.rb
74
+ - test/data/if5.rb
75
+ - test/data/if7.rb
73
76
  - test/data/match.rb
77
+ - test/data/def1.rb
78
+ - test/data/case1.rb
79
+ - test/data/case3.rb
74
80
  - test/data/match3a.rb
81
+ - test/data/for1.rb
75
82
  - test/data/class1.rb
76
- - test/data/if3.rb
77
- - test/data/if5.rb
78
- - test/data/case1.rb
79
- - test/data/def1.rb
80
- - test/data/if7.rb
83
+ - test/data/not-lit.rb
84
+ - test/data/comments1.rb
85
+ - test/data/if1.rb
81
86
  - test/data/block1.rb
82
- - test/data/begin3.rb
83
- - test/data/case3.rb
84
- - test/data/case2.rb
85
- - test/data/each1.rb
86
- - test/data/if2.rb
87
- - test/data/match3.rb
88
- - test/data/if4.rb
89
87
  - test/data/case5.rb
88
+ - test/data/match3.rb
89
+ - test/data/begin1.rb
90
90
  - test/short-file
91
91
  has_rdoc: true
92
92
  homepage: http://rubyforge.org/projects/rocky-hacks/linecache
@@ -97,7 +97,7 @@ rdoc_options:
97
97
  - --main
98
98
  - README
99
99
  - --title
100
- - LineCache 0.45 Documentation
100
+ - LineCache 1.0 Documentation
101
101
  require_paths:
102
102
  - lib
103
103
  required_ruby_version: !ruby/object:Gem::Requirement