Class: RipperTags::EmacsFormatter

Inherits:
DefaultFormatter show all
Defined in:
lib/ripper-tags/emacs_formatter.rb

Overview

Generates etags format as described in en.wikipedia.org/wiki/Ctags#Etags_2

The format is non-trivial since it requires section header for each source file to contain the size of tag data in bytes. This is accomplished by buffering tag definitions per-file and flushing them to target IO when a new source file is encountered or when ‘with_output` block finishes. This assumes that incoming tags are ordered by source file.

Instance Attribute Summary

Attributes inherited from DefaultFormatter

#options

Instance Method Summary collapse

Methods inherited from DefaultFormatter

#constant?, #display_inheritance, #display_kind, #extra_flag?, #relative_path, #stdout?, #tag_file_dir

Constructor Details

#initializeEmacsFormatter

Returns a new instance of EmacsFormatter.



14
15
16
17
18
# File 'lib/ripper-tags/emacs_formatter.rb', line 14

def initialize(*)
  super
  @current_file = nil
  @section_io = nil
end

Instance Method Details

#flush_file_section(out) ⇒ Object



56
57
58
59
60
61
62
# File 'lib/ripper-tags/emacs_formatter.rb', line 56

def flush_file_section(out)
  if @section_io
    data = @section_io.string
    out.write format_section_header(@current_file, data)
    out.write data
  end
end

#format(tag, name_field = :name) ⇒ Object



69
70
71
72
73
74
75
76
# File 'lib/ripper-tags/emacs_formatter.rb', line 69

def format(tag, name_field = :name)
  "%s\x7F%s\x01%d,%d" % [
    tag.fetch(:pattern),
    tag.fetch(name_field),
    tag.fetch(:line),
    0,
  ]
end

#format_section_header(filename, data) ⇒ Object



64
65
66
67
# File 'lib/ripper-tags/emacs_formatter.rb', line 64

def format_section_header(filename, data)
  data_size = data.respond_to?(:bytesize) ? data.bytesize : data.size
  "\x0C\n%s,%d\n" % [ filename, data_size ]
end

#include_qualified_names?Boolean

Returns:

  • (Boolean)


22
23
24
25
# File 'lib/ripper-tags/emacs_formatter.rb', line 22

def include_qualified_names?
  return @include_qualified_names if defined? @include_qualified_names
  @include_qualified_names = extra_flag?('q')
end

#start_file_section(filename, io) ⇒ Object



46
47
48
49
50
51
52
53
54
# File 'lib/ripper-tags/emacs_formatter.rb', line 46

def start_file_section(filename, io)
  if filename != @current_file
    flush_file_section(io)
    @current_file = filename
    @section_io = StringIO.new
  else
    @section_io
  end
end

#supported_flagsObject



20
# File 'lib/ripper-tags/emacs_formatter.rb', line 20

def supported_flags() ['q'] end

#with_outputObject



27
28
29
30
31
32
33
34
35
# File 'lib/ripper-tags/emacs_formatter.rb', line 27

def with_output
  super do |io|
    begin
      yield io
    ensure
      flush_file_section(io)
    end
  end
end

#write(tag, io) ⇒ Object



37
38
39
40
41
42
43
44
# File 'lib/ripper-tags/emacs_formatter.rb', line 37

def write(tag, io)
  filename = relative_path(tag)
  section_io = start_file_section(filename, io)
  section_io.puts format(tag)
  if include_qualified_names? && tag[:full_name] != tag[:name] && constant?(tag)
    section_io.puts format(tag, :full_name)
  end
end