cruxlines

Crates.iocruxlines
lib.rscruxlines
version0.3.0
created_at2025-12-27 21:28:24.700475+00
updated_at2026-01-23 19:20:40.445419+00
descriptionRanks symbol definitions by cross-file references using tree-sitter.
homepage
repositoryhttps://github.com/kantord/cruxlines
max_upload_size
id2007861
size155,390
Dániel Kántor (kantord)

documentation

README

cruxlines

cruxlines analyzes a codebase and ranks symbol definitions by how often they are referenced, with a bias toward references coming from "hot" files. It outputs quickfix-friendly lines for jumping to definitions.

What it does

  • Parses source files with tree-sitter.
  • Finds definitions and references across files.
  • Builds a file-level reference graph and computes a file rank.
  • Weights references by file rank and git frecency.
  • Outputs one line per definition.

How it works

cruxlines works in two layers:

  1. File graph

    • A file-level graph is built from usage file -> definition file edges.
    • PageRank is computed on this small graph to get a per-file rank.
  2. Definition scoring

    • Each definition gets a local score based on how many references it has.
    • References are weighted by the rank of the file they come from.
    • If a name is defined multiple times, the score is divided by the number of definitions to reduce name-collision noise.
    • Final score = local_score * file_rank(definition_file).

The output includes all components so you can interpret the score.

Heuristics (and why)

The goal is to keep logic simple and avoid heavy per-language semantics:

  • Python: only top-level definitions/assignments (importable symbols).
  • JavaScript/TypeScript: only exported declarations (importable symbols).
  • Rust: only top-level items (importable symbols).
  • References are name-based, which is fast and language-agnostic.
  • Name collisions are smoothed by splitting score across same-name definitions.

These heuristics are not semantically perfect, but they keep complexity low while producing useful rankings.

CLI usage

Analyze the current repo (run from the repo root):

cruxlines

Filter by ecosystem (defaults to all):

cruxlines --ecosystem python

Shorthand aliases are supported (py, js, ts, tsx, rs):

cruxlines -e py

Java/Kotlin use the java ecosystem (alias jvm):

cruxlines -e java

Include score metadata in the output:

cruxlines --metadata

Library usage

Use the library API by passing a repo root and selected ecosystems:

use std::collections::HashSet;
use std::path::PathBuf;

use cruxlines::{cruxlines, Ecosystem};

let repo_root = PathBuf::from(".");
let ecosystems = HashSet::from([Ecosystem::Python, Ecosystem::JavaScript]);
let rows = cruxlines(&repo_root, &ecosystems)?;

Output format

Each line matches the Vim quickfix format and includes the definition line:

path:line:col: <line>

With --metadata, the message includes the scoring fields:

path:line:col: rank=... local=... file=... name=... | <line>

Reference detection is heuristic and may include false positives.

Supported languages

  • Java (.java)
  • Python (.py)
  • JavaScript (.js, .jsx)
  • TypeScript (.ts, .tsx)
  • Kotlin (.kt, .kts)
  • Rust (.rs)

Git ignore behavior

  • Directory scans respect gitignore and common ignore files.

Repo root

cruxlines expects to run from the repository root (a directory with .git) and always scans the whole repo.

Notes

cruxlines uses git history to compute frecency for files via the frecenfile crate. If no git repository is found, frecency defaults to neutral weighting.

Commit count: 89

cargo fmt