Skip to content

Add hierarchy-aware mode to include hierarchical parent context in search results #3395

@layzerar

Description

@layzerar

I’d like to propose a new --hierarchy option for ripgrep that prints hierarchical parent lines for each match, giving search results more useful context without substantially increasing output size.

For example, given test.md:

list content:
  1. list item (level 1)
  2. list item (level 1)
    - inner list item: foobar (level 2)

Running:

rg --hierarchy foobar test.md

could produce:

test.md
1: list content:
3:   2. list item (level 1)
4:     - inner list item: foobar (level 2)

The idea is that when a matching line is found, ripgrep would also print the relevant ancestor lines that establish its hierarchy. In this example, the match is inside a nested Markdown list, so the output includes the top-level context line and the parent list item.

This would be useful for more than Markdown. Many common file formats and programming languages encode useful structure through indentation or simple block hierarchy, including Python, C, C++, Java, YAML, TOML, configuration files, logs with grouped sections, and documentation formats. Current context options like -A, -B, and -C are line-distance based, which can be noisy or miss the actual structural context. A hierarchy-aware mode could provide more precise context with fewer extra lines.

The implementation would not need to perform full syntax parsing. A simple indentation/block-based heuristic would already be valuable:

  • Track previous lines that appear to be structural ancestors.
  • When a match is found, emit the nearest relevant parent lines before the matching line.
  • Deduplicate ancestor lines when multiple matches share the same hierarchy.
  • Preserve normal ripgrep behavior unless --hierarchy is explicitly enabled.

This should keep the feature relatively non-invasive and avoid significant performance impact compared with language-specific parsing. It would provide a middle ground between minimal search output and verbose surrounding-context output, making ripgrep results easier to understand when matches occur inside nested structures.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions