Class: OllamaChat::Utils::TagResolver

Inherits:
Object
  • Object
show all
Defined in:
lib/ollama_chat/utils/tag_resolver.rb

Overview

YARD documentation for the TagResolver utility.

The OllamaChat::Utils::TagResolver class provides a lightweight interface to query ctags-generated tag files. It can resolve symbols by name, optional kind and directory constraints, returning an array of TagResult objects that include helpful metadata such as the line number where the symbol is defined.

Defined Under Namespace

Classes: TagResult

Constant Summary collapse

HEADERS =

Header fields used in a ctags tag entry. These are kept private to avoid leaking implementation details outside the class.

%i[ symbol filename regexp kind rest ]

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(tags_file) ⇒ TagResolver

Initialize a new resolver with the path or IO object pointing at a tags file.

Parameters:

  • tags_file (IO, String)

    Path to the tags file or an already opened IO.



71
72
73
74
# File 'lib/ollama_chat/utils/tag_resolver.rb', line 71

def initialize(tags_file)
  tags_file.is_a?(IO) or tags_file = File.new(tags_file)
  @tags_file = tags_file
end

Class Method Details

.kind_of(kind) ⇒ String

Return a human‑readable description of a ctags tag kind. For example, f (function) becomes “methods”.

Parameters:

  • kind (String)

    The single character kind identifier from the tags file.

Returns:

  • (String)


31
32
33
# File 'lib/ollama_chat/utils/tag_resolver.rb', line 31

def self.kind_of(kind)
  kinds.fetch(kind, 'unknown')
end

.kindsHash

The kinds method returns a mapping of single character kind identifiers to human‑readable descriptions for Ruby ctags kinds.

Returns:

  • (Hash)

    a hash mapping kind identifiers to their descriptions.



17
18
19
20
21
22
23
24
# File 'lib/ollama_chat/utils/tag_resolver.rb', line 17

def self.kinds
  ctags = ::OC::OLLAMA::CHAT::TOOLS::CTAGS_TOOL? or
    raise OllamaChat::ConfigMissingError,
    'need ctags tool path defined in %s' % (
      ::OC::OLLAMA::CHAT::TOOLS::CTAGS_TOOL!.env_var_name
    )
  @kinds ||= `#{ctags} --list-kinds=Ruby`.lines.map { _1.chomp.split(/\s+/, 2) }.to_h
end

Instance Method Details

#resolve(symbol:, kind: nil, directory: nil) ⇒ Array<TagResult>

Resolve a symbol in the tag file and return all matching results.

The method scans each line of the tags file, filters by symbol, optional kind and an optional directory prefix. For each match it calculates the exact line number where the definition occurs using a regular expression.

Parameters:

  • symbol (String)

    Name of the symbol to look up (required).

  • kind (String, nil) (defaults to: nil)

    Optional tag kind filter (f, v …). If omitted all kinds are considered.

  • directory (String, nil) (defaults to: nil)

    Only consider tags whose file path starts with this string.

Returns:

  • (Array<TagResult>)

    All matching results sorted by the order they appear in the tags file.



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/ollama_chat/utils/tag_resolver.rb', line 89

def resolve(symbol:, kind: nil, directory: nil)
  directory and directory = Pathname.new(directory).expand_path.to_path
  @tags_file.rewind
  results       = []
  @tags_file.each_line do |line|
    line.chomp!
    line =~ /\A([^\t]+)\t([^\t]+)\t\/\^([^\t]+)\$\/\;"\t([^\t])(.*)/ or next
    obj = TagResult.new(*$~.captures)
    next unless obj.symbol == symbol
    if kind
      obj.kind == kind or next
    end
    filename = Pathname.new(obj.filename).expand_path
    filename.exist? or next
    if directory
      filename.to_path.start_with?(directory) or next
    end
    regexp = Regexp.new(?^ + Regexp.quote(obj.regexp) + ?$)
    linenumber =
      begin
        File.open(filename) do |f|
          f.each_with_index.find { _1 =~ regexp and break 1 + _2 }
        end
      rescue
        1
      end
    obj.regexp     = regexp
    obj.filename   = filename.to_path
    obj.linenumber = linenumber
    results << obj
  rescue => e
    log(:error, e, warn: true)
  end
  results
end