Norn

Code navigation for large C codebases,
without a build

Source Insight-style navigation in VS Code. No compile_commands.json. Calls through macros and function pointers, and only the code your build compiles.

or code --install-extension humphrey0925.norn-c · Windows, Linux, macOS · x64 & Arm64

Norn in VS Code: Project Symbols, File Symbols, Relation and Context around the editor

Why Norn

Language servers built on a compiler, such as clangd, need to know exactly how every file is compiled. A great deal of real C cannot tell them: firmware built with a proprietary toolchain, SDKs with a header per chip, vendor trees that only build on one machine. Text indexers such as ctags and cscope work anywhere, but they find names, not calls. Norn reads the sources the way a person would, and the build's own description where there is one.

No setup

Open a folder. Norn reads Arm DS-5, Keil, IAR, Visual Studio, CMake, Makefile, PlatformIO, Kconfig or compile_commands.json and works out which #if branches are compiled.

Calls, not just names

It follows calls through macros and through function pointers stored in structs, and says how each call comes about.

Fast enough to forget about

The whole Linux kernel indexes in about a minute on a desktop PC; saving a file updates the index in milliseconds.

Checked against the compiler

Measured call by call against clang's own view of real builds of public projects.

Private

Everything runs on your machine. No network, no telemetry.

Nornclangdctags / cscope / GNU Global
Works without a compilation database✅⚠️ less accurate✅
Knows which #if branches the build compiles✅✅ with a database❌
Call graph (callers and callees)✅✅⚠️ cscope, by name
Calls through function pointers✅❌❌
Calls generated by macros✅✅ with a database❌
Index updated as you save✅✅❌ re-run
Source Insight-style views (Relation, Context)✅❌❌

Benchmarks

Measured on public projects against clang's own view of a real build of each. Every call a tool reports is checked against the call clang compiles. clangd is measured twice: with each build's own compilation database, and with none. Norn is given nothing.

Calls found, per project and tool
Time to index, per project and tool
ProjectFilesNornclangd + build databaseclangdcscope
Redis801100.0%0.32 s100.0%1.67 s95.8%11 s96.9%0.26 s
git91999.9%0.25 s99.9%2.40 s64.2%32 s87.9%0.27 s
binutils1,62299.6%2.72 s92.7%9.72 s32.2%16 s70.6%1.34 s
STM32F4 HAL25396.5%0.64 s95.0%3.14 s0.0%1.14 s75.7%0.44 s
nrfx53598.0%0.84 s100.0%1.15 s14.1%1.22 s12.0%0.28 s

Each cell: the share of calls found (checked against clang), and below it the time to index. Methods, every figure and tool versions: docs/benchmarks. Every number is produced by bench/compare.py; none is typed in.

Features

Norn is a complete language server: Go to Definition, Find References, Call Hierarchy, signature help, rename, folding, formatting and quick fixes too. Alongside Microsoft's C/C++ extension it becomes IntelliSense's configuration provider instead of competing with it.

Project Symbols

Fuzzy search over every symbol: fragments in any order, initials, letters in order.

Project Symbols

Relation

Callers, callees, references and function-pointer assignments, as a tree or a graph.

Relation as a graph

Hover with documentation

A declaration and its doc comment; a macro's value worked out through other macros.

Hover

Context

The definition of whatever the cursor is on, beside your code, without leaving your place.

Relation and Context

Completion

Members after . and ->, locals, keywords, #include paths, every indexed name.

Member completion

Highlighting and hints

Names coloured by what they are; parameter names at call sites.

Semantic highlighting and inlay hints

File Symbols with locals

A function's parameters and local variables, and every line that uses one.

File Symbols with locals

Compile conditions

Configurations read from the build; switch between Debug, Release or one per board.

Switching configuration

Get started

  1. Install Norn — Code Navigation & Symbol Index from the Visual Studio Marketplace, from Open VSX for VSCodium, Cursor and Windsurf, or a .vsix from the releases.
  2. Open a folder with C sources. That is all.

The user guide covers every view and setting. Without VS Code, the same indexer is a command of its own, norn, for the terminal, scripts, CI and other editors: see the command line.

How it works

sources ─► tree-sitter parse ─► facts per file ─► link ─► call graph (CSR) ─► language server
              ▲                                     ▲
   #if worked out from the build's              calls through macros and
   own configuration and the sources            function pointers resolved

Norn is written in Rust. Each file is parsed once after its preprocessor conditions are worked out. The facts of each file are cached by content hash; linking them into a call graph takes milliseconds, and the graph answers a callers query in well under a microsecond.