Repository: colbymchenry/codegraph (2026-07-16T20:30:15Z)

Issue:
problem with showing node content in c++
hello

I've got this problem when trying to read content of a function. please help to check 
I want to read a content of a function which many files has that function name
when using only function it can show content  

codegraph node setState                                                      
**132 definitions named "setState"**
Returning 8 in full; 124 more listed below — pick the one you need (no Read required).

--other content of other file--

**setState** (method)

**Location:** external/icu/icu4c/source/i18n/formattedvalue.cpp:56

```cpp
56	void ConstrainedFieldPosition::setState(
57	        int32_t category,
58	        int32_t field,
59	        int32_t start,
60	        int32_t limit) {
61	    fCategory = category;
62	    fField = field;
63	    fStart = start;
64	    fLimit = limit;
65	}
```
**Trail — codegraph_node any of these to follow it (no Read needed)**
**Called by ←** nextPosition (external/icu/icu4c/source/i18n/formattedval_iterimpl.cpp:45), nextFieldPosition (external/icu/icu4c/source/i18n/formattedval_sbimpl.cpp:52), nextPositionImpl (external/icu/icu4c/source/i18n/formattedval_sbimpl.cpp:108), ucfpos_setState (external/icu/icu4c/source/i18n/formattedvalue.cpp:173), play (external/skia/modules/audioplayer/SkAudioPlayer.h:40), pause (external/skia/modules/audioplayer/SkAudioPlayer.h:41), stop (external/skia/modules/audioplayer/SkAudioPlayer.h:42)

---

then I want to exactly see content in external/icu/icu4c/source/i18n/formattedvalue.cpp
so I use command with -f but it doesn't show content of the function. is there problem or any other way to show?

codegraph node setState -f external/icu/icu4c/source/i18n/formattedvalue.cpp                                                   
**setState** (method)

**Location:** external/icu/icu4c/source/i18n/formattedvalue.cpp:56
**Trail — codegraph_node any of these to follow it (no Read needed)**
**Called by ←** nextPosition (external/icu/icu4c/source/i18n/formattedval_iterimpl.cpp:45), nextFieldPosition (external/icu/icu4c/source/i18n/formattedval_sbimpl.cpp:52), nextPositionImpl (external/icu/icu4c/source/i18n/formattedval_sbimpl.cpp:108), ucfpos_setState (external/icu/icu4c/source/i18n/formattedvalue.cpp:173), play (external/skia/modules/audioplayer/SkAudioPlayer.h:40), pause (external/skia/modules/audioplayer/SkAudioPlayer.h:41), stop (external/skia/modules/audioplayer/SkAudioPlayer.h:42)




Discussion:
codegraph verion 1.4.1
Fixed in #1314 (merged to main, ships in the next release) — you found a real bug, and your command was exactly right.

`codegraph node setState -f external/icu/icu4c/source/i18n/formattedvalue.cpp` was correctly narrowing to that file's definition, but the CLI forgot to ask the underlying engine for the source body on that specific path (the bare `codegraph node setState` path did ask, which is why that one showed code). So the more precise you were, the less you got — now the pinned definition prints its full line-numbered body just like the unpinned listing does.

Pinned by a regression test with two same-named definitions. After the next release, your exact command will show the ConstrainedFieldPosition::setState body.



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1da973b10..cecc9ba0f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,6 +18,7 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
 ### Fixes
 
+- `codegraph node <symbol> -f <file>` now prints the symbol's source body. Pinning an ambiguous name to a specific file (the whole point of `-f` when many files define the same function) returned only the location and caller trail with no code. (#1284)
 - Deleting a whole directory is now picked up by watch mode: the files inside it are removed from the index on the next auto-sync instead of lingering as stale records until an unrelated edit happened to trigger one. Operating systems often report a directory deletion as a single event on the directory itself (with no per-file events for its contents), which the watcher previously discarded. (#1285)
 - `codegraph sync` now gets the same slow-disk fix that made full indexing fast in 1.4.0: database checkpointing is deferred for the whole incremental run instead of firing every few megabytes of writes. On mechanical drives and other high-latency storage, a small sync on a large index no longer stalls for minutes at near-zero CPU — the cost of a sync scales with what changed, not with the size of the existing index. The same `CODEGRAPH_NO_WAL_DEFER=1` switch turns it off. (#1248)
 - C functions declared with a project-specific attribute macro in front of a typedef'd return type (`SEC_ATTR UINT32 MyFunc(VOID)` — common in embedded and kernel code) are now indexed under their real names. Previously the parser tripped over the unknown macro and stored the parameter list as the function name, leaving entries like `"(VOID)"` in the graph and making the real function unfindable. (#1211)
diff --git a/src/bin/codegraph.ts b/src/bin/codegraph.ts
index dd1fe8a7e..eefb5d907 100644
--- a/src/bin/codegraph.ts
+++ b/src/bin/codegraph.ts
@@ -1414,7 +1414,14 @@ program
       const args: Record<string, unknown> = {};
       if (options.file) {
         args.file = options.file;
-        if (name && name !== options.file) args.symbol = name;
+        if (name && name !== options.file) {
+          args.symbol = name;
+          // Symbol mode pinned to a file is still symbol mode — the CLI
+          // always wants the body, exactly like the bare-symbol branch
+          // below. Omitting this printed location + trail with no source
+          // (#1284).
+          args.includeCode = true;
+        }
       } else if (name && (name.includes('/') || name.includes('\\'))) {
         args.file = name.replace(/\\/g, '/');
       } else if (name) {


Test patch:
diff --git a/__tests__/cli-node-command.test.ts b/__tests__/cli-node-command.test.ts
index 4d3485031..dfd28acf8 100644
--- a/__tests__/cli-node-command.test.ts
+++ b/__tests__/cli-node-command.test.ts
@@ -78,3 +78,42 @@ describe('codegraph node — argument handling (#1044)', () => {
     expect(stderr).not.toMatch(/missing required argument/);
   });
 });
+
+describe('codegraph node — symbol pinned to a file includes the body (#1284)', () => {
+  let tempDir: string;
+
+  beforeEach(async () => {
+    tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'codegraph-node-pin-'));
+    fs.mkdirSync(path.join(tempDir, 'a'));
+    fs.mkdirSync(path.join(tempDir, 'b'));
+    // Two same-named definitions, so `-f` is genuinely disambiguating.
+    fs.writeFileSync(
+      path.join(tempDir, 'a', 'state.ts'),
+      'export function setState(x: number): void {\n  console.log("A", x);\n}\n'
+    );
+    fs.writeFileSync(
+      path.join(tempDir, 'b', 'state.ts'),
+      'export function setState(y: string): void {\n  console.log("B", y);\n}\n'
+    );
+    const cg = CodeGraph.initSync(tempDir);
+    await cg.indexAll();
+    cg.close();
+  });
+
+  afterEach(() => {
+    fs.rmSync(tempDir, { recursive: true, force: true });
+  });
+
+  it('`node <symbol> -f <file>` prints the pinned definition WITH its source body', () => {
+    // The exact #1284 shape: `-f` narrowed the overload correctly but printed
+    // only Location + trail — no code fence — so the user had nothing to read.
+    const { stdout, code } = runNode(tempDir, ['setState', '-f', 'a/state.ts']);
+    expect(code).toBe(0);
+    expect(stdout).toContain('a/state.ts');
+    // The body is present (line-numbered fence), and it's the pinned overload.
+    expect(stdout).toMatch(/1\s+export function setState\(x: number\)/);
+    expect(stdout).toContain('console.log("A", x)');
+    // The other file's overload is not what was pinned.
+    expect(stdout).not.toContain('console.log("B", y)');
+  });
+});