1. Introduction

C-xrefactory is a code browser and refactoring tool for C and Yacc, integrated with Emacs. It lets you navigate symbols, find usages, complete code, and safely refactor—all while understanding your code semantically.

All functions are available from the c-xref menu in Emacs.

2. Getting Started

2.1. Installation

Clone and load in Emacs:

git clone -b stable https://github.com/thoni56/c-xrefactory
make -j -C c-xrefactory
emacs -l c-xrefactory/load.el

Or via el-get: M-x el-get-install RET c-xrefactory RET

See the README for platform-specific details.

2.2. Projects

C-xrefactory is "project-based", meaning that it handles files within one project. C-xrefactory auto-detects projects based on the file you’re editing when you do you initial C-xrefactory operation. The path of the file is investigated upwards until a .c-xrefrc (C-xrefactory project config) file is found.

If no config file could be found, you’ll be prompted to create a project. The active project is shown in the modeline after each action.

3. Browsing

Browsing uses a list of references (occurrences of a symbol), including definition, declarations and usages, which allows you to navigate that list. c-xrefactory handles not only normal C variables, types etc. but also labels and include file references. In addition Yacc non-terminals can be browsed.

3.1. Basic Navigation

The core workflow uses four actions:

  • Push Symbol and Goto Definition — resolve the symbol at cursor, create the list of references and jump to its definition

  • Pop Symbol — return to where you were before pushing discarding the current list and picking up the previous list of references

  • Next Reference — step to the next occurence of the current symbol

  • Previous Reference — step to the previous occurance

Place cursor on a symbol, push it, then step through references. When done, pop to return.

3.2. The Browser Stack

You can browse multiple symbols simultaneously. Each push adds to a stack level. Each stack level holds the references for that symbol or referenceable item.

  1. While browsing variable, you see it passed to function

  2. Place cursor on function and Push to see its definition

  3. Use Next/Previous to navigate all occurrences of function

  4. Pop to return and continue browsing variable

You can Re-Push the symbol you just popped.

3.3. Push by Name

Push Name and Goto Definition finds symbols by name only, ignoring scope. Useful when you know a symbol’s name but aren’t looking at an occurrence of it.

3.4. Browser Dialog

Opens a visual representation of the browser stack with two panes:

  • Symbol Pane — shows matched symbols and where they’re defined

  • References Pane — lists all occurences with source context

Click a reference to jump to it. Multi-select symbols to combine their references into a navigable list of references.

4. Searching

The Symbol Retriever finds symbols by pattern matching across your entire project.

Use it when you:

  • Can’t remember a symbol’s exact name

  • Want to find symbols from libraries

  • Need to search by signature pattern

4.1. Patterns

Patterns use shell-style wildcards:

  • * — any string (including empty)

  • ? — any single character

  • [abc] — one of the enclosed characters

  • [a-z] — character range

  • [^0-9] — negation (any non-digit)

Searching is case-insensitive except within [].

4.2. Examples

  • get or get — symbols containing "get"

  • init* — symbols starting with "init"

  • (*int) — functions taking an int parameter

5. Completion

Press the completion key (default kbd:[F8]) to complete the identifier at cursor.

C-xrefactory understands context - it offers appropriate completions for function parameters, variable definitions, struct members, etc.

5.1. Completion Dialog

When multiple completions exist, a dialog appears showing each candidate with its full declaration.

  • kbd:[Return] — insert the selected completion

  • kbd:[Space] — inspect the symbol’s definition

  • kbd:[Escape] — cancel and return to editing

  • Arrow keys — navigate candidates

6. Refactoring

All refactorings are invoked from the Refactor menu with cursor on the relevant symbol. C-xrefactory checks that changes won’t alter program behavior.

6.1. Renaming

Rename Symbol — changes all occurrences of a variable, function, type, or macro throughout the project.

Rename Include File — renames a header file and updates all #include directives that reference it.

6.2. Function Signatures

These work on functions and macros:

Add Parameter — adds a new parameter at a specified position, inserting a default value at all call sites.

Delete Parameter — removes a parameter from the signature and all calls.

Move Parameter — reorders parameters, updating all calls accordingly.

6.3. Extracting Code

Extract Function / Extract Macro — select a region of code, then extract it into a new function or macro. C-xrefactory analyzes the code to determine parameters and return values.

6.4. Finding Unused Code

Browse File Local Unused — finds unused local variables, parameters, and labels in the current file.

Browse Global Unused — finds unused symbols across the project.

7. Quick Reference

7.1. Default Key Bindings

Key Action

kbd:[F6]

Push Symbol and Goto Definition

kbd:[F5]

Pop Symbol

kbd:[F3]

Previous Reference

kbd:[F4]

Next Reference

kbd:[F8]

Complete

kbd:[F11]

Refactor Menu

7.2. Common Workflows

Find where a function is called: Push the function name → step through references with Next/Previous

Rename a variable safely: Cursor on variable → Refactor → Rename Symbol → enter new name

Extract repeated code: Select the code → Refactor → Extract Function → name the new function

Find all globals starting with "config": Symbol Retriever → enter config* → browse results

8. Feedback

Issues and contributions welcome at GitHub.