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.
-
While browsing
variable, you see it passed tofunction -
Place cursor on
functionand Push to see its definition -
Use Next/Previous to navigate all occurrences of
function -
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
-
getorget— 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.