pub struct FileIndex {
pub headings: Vec<HeadingIndex>,
pub reference_links: Vec<ReferenceLinkIndex>,
pub cross_file_links: Vec<CrossFileLinkIndex>,
pub root_relative_links: Vec<CrossFileLinkIndex>,
pub md057_link_targets: Vec<Md057LinkTarget>,
pub defined_references: HashSet<String>,
pub content_hash: String,
pub file_disabled_rules: HashSet<String>,
pub persistent_transitions: Vec<(usize, HashSet<String>, HashSet<String>)>,
pub line_disabled_rules: HashMap<usize, HashSet<String>>,
/* private fields */
}Expand description
Index data extracted from a single file
Fields§
§headings: Vec<HeadingIndex>Headings in this file with their anchors
reference_links: Vec<ReferenceLinkIndex>Reference links in this file (for cross-file analysis)
cross_file_links: Vec<CrossFileLinkIndex>Cross-file links in this file (for MD051 cross-file validation)
root_relative_links: Vec<CrossFileLinkIndex>Root-relative links (leading /) in this file. Resolved against the
configured content roots by the LSP for go-to-definition, hover, and
find-references. target_path has the leading / stripped. Linting does
not use these, so they never affect diagnostics.
md057_link_targets: Vec<Md057LinkTarget>Filesystem destinations MD057 may validate for this file.
These inputs stay unresolved so the rule can apply the current search paths, absolute-link policy, and per-file flavor during cache lookup.
defined_references: HashSet<String>Defined reference IDs (e.g., from [ref]: url definitions)
Used to filter out reference links that have explicit definitions
content_hash: StringContent hash for change detection
file_disabled_rules: HashSet<String>Rules disabled for the entire file (from inline comments) Used by cross-file rules to respect inline disable directives
persistent_transitions: Vec<(usize, HashSet<String>, HashSet<String>)>Persistent disable/enable state transitions, sorted by line number. Each entry: (line, disabled_rules, enabled_rules). Use binary search to query.
line_disabled_rules: HashMap<usize, HashSet<String>>Rules disabled at specific lines via disable-line / disable-next-line
Implementations§
Source§impl FileIndex
impl FileIndex
Sourcepub fn extracted_data_differs(&self, other: &Self) -> bool
pub fn extracted_data_differs(&self, other: &Self) -> bool
Whether the data extracted from the file differs, ignoring the hash of the text it came from.
This answers whether re-indexing a file can have changed a cross-file result, its own or that of a file linking to it. Every cross-file check reads the entry rather than the document, so two entries that agree on everything compared here produce the same answers however much the text between them changed. The hash is excluded precisely because it is a fingerprint of that text: it moves on every keystroke while the links and anchors a check reads stay put.
Entries carry the positions their headings and links were written at, so an edit that adds or removes a line does differ even when it changes no anchor. That is the conservative direction: it costs a re-lint of the open files linking here, and never withholds one.
Sourcepub fn add_heading(&mut self, heading: HeadingIndex)
pub fn add_heading(&mut self, heading: HeadingIndex)
Add a heading to the index
Also updates the anchor lookup maps for O(1) anchor queries. Both
lowercased (for ignore_case = true) and case-preserving (for
ignore_case = false) maps are populated.
Sourcepub fn add_anchor_alias(&mut self, anchor: &str, heading_index: usize)
pub fn add_anchor_alias(&mut self, anchor: &str, heading_index: usize)
Add an alternative anchor that resolves to an existing heading.
Used for platform-specific anchor conventions (e.g., Python-Markdown _N dedup).
Sourcepub fn has_anchor(&self, anchor: &str) -> bool
pub fn has_anchor(&self, anchor: &str) -> bool
Check if an anchor exists in this file (O(1) lookup)
Returns true if the anchor matches any of:
- Auto-generated heading anchors
- Custom heading anchors (from {#id} syntax on headings)
- HTML anchors (from
<a id="...">or<element id="...">) - Attribute anchors (from { #id } syntax on non-heading elements)
Matching is case-insensitive. URL-encoded anchors (e.g., CJK characters
like %E6%97%A5%E6%9C%AC%E8%AA%9E for 日本語) are decoded before matching.
Sourcepub fn has_anchor_with_case(&self, anchor: &str, ignore_case: bool) -> bool
pub fn has_anchor_with_case(&self, anchor: &str, ignore_case: bool) -> bool
Check if an anchor exists in this file, with explicit case sensitivity.
When ignore_case is true, behaves identically to [has_anchor] —
inputs are lowercased and matched against the lowercase storage.
When false, the input is compared as-is against parallel
case-preserving storage, matching markdownlint’s strict behavior for
generated heading slugs, custom heading IDs, HTML anchors, and
attribute anchors.
Sourcepub fn add_html_anchor(&mut self, anchor: &str)
pub fn add_html_anchor(&mut self, anchor: &str)
Add an HTML anchor (from <a id="..."> or <element id="..."> tags).
Populates both lowercase (case-insensitive) and case-preserving sets.
Sourcepub fn add_attribute_anchor(&mut self, anchor: &str)
pub fn add_attribute_anchor(&mut self, anchor: &str)
Add an attribute anchor (from { #id } syntax on non-heading elements). Populates both lowercase (case-insensitive) and case-preserving sets.
Sourcepub fn get_heading_by_anchor(&self, anchor: &str) -> Option<&HeadingIndex>
pub fn get_heading_by_anchor(&self, anchor: &str) -> Option<&HeadingIndex>
Get the heading index for an anchor (O(1) lookup)
Returns the index into self.headings if found.
Sourcepub fn add_reference_link(&mut self, link: ReferenceLinkIndex)
pub fn add_reference_link(&mut self, link: ReferenceLinkIndex)
Add a reference link to the index
Sourcepub fn is_rule_disabled_at_line(&self, rule_name: &str, line: usize) -> bool
pub fn is_rule_disabled_at_line(&self, rule_name: &str, line: usize) -> bool
Check if a rule is disabled at a specific line
Used by cross-file rules to respect inline disable directives. Checks both file-wide disables and line-specific disables.
Sourcepub fn add_cross_file_link(&mut self, link: CrossFileLinkIndex)
pub fn add_cross_file_link(&mut self, link: CrossFileLinkIndex)
Add a cross-file link to the index, keyed on the file it names, the fragment it asks for, and the line it sits on.
Several rules contribute the same link and spell it differently: MD051
records the destination as written and starts at the link, MD057 records
the file that destination names and starts at the URL. Neither the string
nor the column can identify a link, so the file it names does - comparing
the raw strings let page.md?raw=true in as a second entry alongside
page.md, and MD051, which reports every entry, then reported the same
broken fragment twice.
One key per line is what the index has always recorded, so two links on one line asking the same file for the same fragment are one entry however each of them spells the destination.
Sourcepub fn add_root_relative_link(&mut self, link: CrossFileLinkIndex)
pub fn add_root_relative_link(&mut self, link: CrossFileLinkIndex)
Add a root-relative link to the index (deduplicates by target_path, fragment, line)
Sourcepub fn add_md057_link_target(&mut self, target: Md057LinkTarget)
pub fn add_md057_link_target(&mut self, target: Md057LinkTarget)
Add one filesystem destination used by MD057.
Sourcepub fn add_defined_reference(&mut self, ref_id: String)
pub fn add_defined_reference(&mut self, ref_id: String)
Add a defined reference ID (e.g., from [ref]: url)
Sourcepub fn has_defined_reference(&self, ref_id: &str) -> bool
pub fn has_defined_reference(&self, ref_id: &str) -> bool
Check if a reference ID has an explicit definition
Sourcepub fn hash_matches(&self, hash: &str) -> bool
pub fn hash_matches(&self, hash: &str) -> bool
Check if the content hash matches
Sourcepub fn heading_count(&self) -> usize
pub fn heading_count(&self) -> usize
Get the number of headings
Sourcepub fn reference_link_count(&self) -> usize
pub fn reference_link_count(&self) -> usize
Get the number of reference links