linecache-tf 0.45 → 1.0

Sign up to get free protection for your applications and to get access to all the features.
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