# Find declarations, references and source locations

Use Outline, Peek and exact reference targets without losing unsaved source; inspect the same source graph from a complete agent client.

## Compatibility

2.9.0 release target; scoped Windows current-source editor/C API checks

Published guidance with release-applicability limits. Confirm package applicability before following this guide.

[Download Complete editor navigation, completion and static-inspection teaching files (ZIP)](/_functions/kbExample?name=josim-editor-workflow.zip)

Includes: cells.cir, editor.cir, inspect_editor.py, snippet.cir, README.txt.

## Choose a source-aware navigation action

Use Outline for declarations in the current source, Peek for a read-only definition/include preview, and Find All References for locations tied to a selected symbol identity. Follow a source link when you want to edit its declaration. These actions inspect source; they do not save it or run the numerical solver.

Use the complete four-file teaching download with the compatible JoSIM 2.9 editor. Open editor.cir and keep cells.cir beside it. The optional inspect_editor.py gives agents the source graph through the matching Windows C API. Keep snippet.cir for the paired completion/snippet exercise.

## Follow the included declaration and references

1. Open editor.cir and let current static analysis finish. Edit > Outline (Ctrl+Shift+U on Windows/Linux; Cmd+Shift+U on macOS) shows this file’s RB parameter and three devices. The included divider is not a local declaration in this view.
2. Place the caret on divider in Xleft. Choose Edit > Peek definition / include, or Alt+F12, to read the included .SUBCKT declaration without switching source. Use Open in editor or F12 in Peek to follow its exact location: cells.cir, physical line 2.
3. Use Edit > Go Back / Go Forward or Alt+Left/Right on Windows/Linux to return to the call site and revisit the declaration. On macOS the documented history bindings are Cmd+Alt+Left/Right; the native checks here exercise Windows.
4. Return to divider on Xleft and choose Find All References (Shift+F12). The example has one definition and two uses across two files. Select an actual location before Open in editor becomes available. Follow the exact location rather than replacing every matching word.

![Current-file Outline beside editor.cir lists RB, Vdrive, Xleft and Xright; the included divider definition is followed through a source link.](https://static.wixstatic.com/media/31de30_781d7b7221c4440eaa1b5f8c11c94935~mv2.png)

Outline lists declarations in editor.cir. Peek follows the included divider definition; a text match and a declaration identity serve different purposes.

![Read-only native Peek excerpt with the included divider declaration selected and its RVAL default and resistor body visible.](https://static.wixstatic.com/media/31de30_a8dcb00b327d4fab9493a2d6bc6a98ba~mv2.png)

The native Peek excerpt selects the exact included divider declaration. This captured region excludes the header containing the full local path.

## Keep unsaved sources and stale results distinct

Changing cells.cir’s default from RVAL=1000 to RVAL=2000 without saving changes the root editor’s refreshed Peek. The saved file still contains 1000. The native check follows and returns through the source locations without saving either buffer; Undo restores the include.

Wait for current analysis after an edit. Changed or incomplete sources can disable or qualify navigation; Refresh/F5 rechecks Peek or References from the editor caret. Missing includes, ambiguous declarations and possible uses must retain their labels. An older target list is not evidence about the current buffer.

Find All References is scoped to the current root/include graph. Go to Workspace Symbol and literal workspace search address different scopes. Their complete picker/refactoring routes are outside this check. A source jump itself does not rename a symbol or replace source text.

## Inspect the saved source graph from PowerShell

For an agent or script, select a matching 64-bit Windows JoSIM 2.9 C API DLL with its required runtime dependencies. Use 64-bit Python; CPython 3.13.11 was checked. Run this command from the extracted teaching folder, with a new JSON filename. If an installed package has an older interface, select the intended compatible runtime before using this client.

The client reads the selected UTF-8 source and its include graph. It does not discover unsaved GUI buffers automatically. Use --overlay TARGET SNAPSHOT for an explicit saved UTF-8 snapshot of an existing included target. The checked overlay changes the inspected RVAL default to 2000 while the target remains unchanged on disk.

No product licence is configured by this inspection client and no simulation API is called. The separate optional numerical example run requires its normal product licence. Inspection JSON contains full local source paths, source hashes and declaration identities; review it before sharing.

The recorded actual browser download replays this complete command successfully with only the Python/C API selections changed. It reproduces the divider declaration, both uses and clear static diagnostics while preserving all four extracted input files.

```text
$ErrorActionPreference = 'Stop'
$python = 'python'
$capi = 'C:\Program Files\SUN Magnetics\JoSIM-Pro\bin\josim-pro_CAPI_AMD64.dll'
& $python .\inspect_editor.py --capi $capi --source .\editor.cir --output .\editor-inspection-001.json
if ($LASTEXITCODE -ne 0) { throw 'Inspection is incomplete, contains visible errors or failed. Review any current JSON and diagnostic before continuing.' }
Get-Content -LiteralPath .\editor-inspection-001.json
```

## Interpret the inspection contract

Read complete, diagnostics and source_revisions first. The graph’s definitions and references retain declaration_id/candidates relationships; equal text in two scopes does not make it the same symbol. This example has the divider definition at cells.cir line 2, two resolved uses and distinct /Xleft and /Xright instance paths.

C API line numbers are one-based and byte_column is a zero-based UTF-8 byte offset. GUI Quick Open location columns are one-based UTF-16 text positions. Convert between these coordinate systems; a byte offset after a non-ASCII node name cannot be copied directly into a GUI column field. Both a Unicode path and the differing byte/character positions pass the client check.

A subcircuit parameter default is not automatically an instance value. The inspected RVAL declaration retains expression 1000 and context-dependent evaluation because instance overrides can change it. Use the actual caller/model context when interpreting values; source inspection does not run the circuit.

The supplied client exits 0 only for complete analysis without visible error diagnostics, 3 for complete analysis with visible errors, 4 for incomplete analysis, and 2 for an input/API/I/O failure. Warnings can remain at exit 0 and still require review. A missing include retains diagnostic JSON and exits 4. A static success does not establish saved-circuit validity, numerical convergence or physical accuracy.

The client accepts a selected root/overlay text budget of 2 MiB and at most 63 distinct include overlays; the core supplies its own graph/result limits and incomplete labels. The reply buffer is bounded to the editor’s 8 MiB contract. Existing results, source/result collisions, duplicate/root overlays, invalid UTF-8 and oversized selected input are refused. Choose a new result generation after correcting a failure.

## Save editor.cir

The two instances share a divider definition and vary its named resistance parameter. Both resistors in each divider scale together, so the output ratio remains one half.

```text
* Public editor navigation and completion teaching circuit
.INCLUDE "cells.cir"
.PARAM RB=1000
Vdrive input 0 DC 1
Xleft input left divider RVAL=RB
Xright input right divider RVAL=2*RB
.PRINT V(left) V(right)
.TRAN 1p 10p
.END
```

## Save cells.cir

The formal port order is in then out. RVAL is declared and consumed by both resistor values. The main deck owns the final .END.

```text
* A public resistive divider with a local parameter
.SUBCKT divider in out RVAL=1000
Rseries in out RVAL
Rshunt out 0 RVAL
.ENDS divider
```

## Save snippet.cir

This complete scratch file is for the paired editor exercise. Inserting an unused cell does not by itself make a simulated circuit.

```text
* Public scratch file for snippet insertion; no numerical result is implied
.END
```

## Save inspect_editor.py

The complete standard-library client below is also in the ZIP. Its optional --dll-directory argument selects an existing dependency directory without changing system settings.

```text
"""Inspect a UTF-8 JoSIM source/include graph through the matching editor C API.

This reads source and reports static analysis. It never runs a simulation,
copies a licence, writes a source file or discovers unsaved GUI buffers.
Supply explicit saved UTF-8 snapshots as overlays when they are required.
"""
import argparse
import ctypes
import json
import os
from pathlib import Path
import sys

MAX_SOURCE = 2 * 1024 * 1024
MAX_REPLY = 8 * 1024 * 1024 + 1


def read_utf8(path):
    data = path.read_bytes()
    if len(data) > MAX_SOURCE:
        raise ValueError('The selected source exceeds the checked 2 MiB input bound.')
    return data.decode('utf-8-sig')


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('--capi', type=Path, required=True,
                        help='Matching 64-bit Windows josim-pro_CAPI_AMD64.dll beside its dependencies')
    parser.add_argument('--source', type=Path, required=True)
    parser.add_argument('--output', type=Path, required=True, help='New JSON result; never overwritten')
    parser.add_argument('--overlay', type=Path, nargs=2, action='append', default=[],
                        metavar=('TARGET', 'SNAPSHOT'), help='Use SNAPSHOT text for an included TARGET without changing it')
    parser.add_argument('--dll-directory', type=Path, action='append', default=[],
                        help='Optional existing dependency directory; repeat when needed')
    args = parser.parse_args()
    handles = []
    try:
        if os.name != 'nt' or ctypes.sizeof(ctypes.c_void_p) != 8:
            raise ValueError('This checked client requires 64-bit Windows Python and a matching Windows C API.')
        library = args.capi.resolve(strict=True)
        source = args.source.resolve(strict=True)
        output = args.output.absolute()
        if not library.is_file() or not source.is_file():
            raise ValueError('Select existing C API and source files.')
        if output.exists() or not output.parent.is_dir():
            raise ValueError('Select a new result filename in an existing writable directory.')
        request = {'path': str(source), 'text': read_utf8(source),
                   'document_id': 'kb-cli-root', 'revision': 1, 'buffers': []}
        if len(args.overlay) > 63:
            raise ValueError('This client accepts at most 63 included-source overlays.')
        targets = set()
        source_bytes = len(request['text'].encode('utf-8'))
        for target_arg, snapshot_arg in args.overlay:
            target = target_arg.resolve(strict=True)
            snapshot = snapshot_arg.resolve(strict=True)
            identity = os.path.normcase(str(target))
            if not target.is_file() or target == source or identity in targets:
                raise ValueError('Overlay targets must be existing distinct included source files.')
            targets.add(identity)
            text = read_utf8(snapshot)
            source_bytes += len(text.encode('utf-8'))
            if source_bytes > MAX_SOURCE:
                raise ValueError('Selected root and overlay text exceed this client’s 2 MiB bound.')
            request['buffers'].append({'path': str(target), 'text': text,
                                       'document_id': 'kb-overlay-' + str(len(targets)), 'revision': 1})
        for directory in [library.parent, *args.dll_directory]:
            directory = directory.resolve(strict=True)
            if not directory.is_dir():
                raise ValueError('A dependency directory is not an existing directory.')
            handles.append(os.add_dll_directory(str(directory)))
        api = ctypes.WinDLL(str(library))
        inspect = api.JPRO_Editor_InspectWorkspace
        inspect.argtypes = [ctypes.c_char_p, ctypes.POINTER(ctypes.c_int), ctypes.c_void_p, ctypes.c_int]
        inspect.restype = ctypes.c_int
        api.JPRO_GetLastError.argtypes = []
        api.JPRO_GetLastError.restype = ctypes.c_char_p
        # One bounded reply avoids repeating filesystem reads between size/value calls.
        buffer = ctypes.create_string_buffer(MAX_REPLY)
        needed = ctypes.c_int(0)
        code = inspect(json.dumps(request, ensure_ascii=False).encode('utf-8'),
                       ctypes.byref(needed), buffer, len(buffer))
        if code != 0:
            message = api.JPRO_GetLastError()
            raise RuntimeError('Editor inspection failed (' + str(code) + '): ' +
                               (message.decode('utf-8', errors='replace') if message else 'no detail'))
        if not 1 <= needed.value <= len(buffer):
            raise RuntimeError('The C API returned an invalid reply length.')
        result = json.loads(buffer.raw[:needed.value - 1].decode('utf-8'))
        complete = result.get('complete') is True
        visible_errors = [d for d in result.get('diagnostics', [])
                          if d.get('severity') == 'error' and not d.get('suppressed', False)]
        # Exclusive creation protects source/snapshot collisions and concurrent results.
        with output.open('x', encoding='utf-8', newline='\n') as stream:
            json.dump(result, stream, ensure_ascii=False, indent=2)
            stream.write('\n')
        print(json.dumps({'complete': complete, 'visible_errors': len(visible_errors),
                          'diagnostics': len(result.get('diagnostics', [])),
                          'limit': 'Static source analysis only; not saved-circuit or numerical acceptance.'}))
        return 4 if not complete else 3 if visible_errors else 0
    except (OSError, ValueError, RuntimeError, AttributeError) as error:
        print(str(error), file=sys.stderr)
        return 2
    finally:
        for handle in reversed(handles):
            handle.close()


if __name__ == '__main__':
    raise SystemExit(main())
```

## Check the teaching circuit separately

The licensed Windows 2.9 CLI completes editor.cir with 11 CSV samples from 0 to 10 ps and headers time, V(LEFT), V(RIGHT). The first sample is zero; the ten following samples agree with the 0.5 V resistive-divider reference within 1e-12 V in this example. A missing library fails without current CSV; restoring it reproduces the original parsed data.

That separate run checks the complete teaching inputs. It does not turn Outline, Peek or static JSON into a numerical solve, calibrate a physical device or qualify every parameter/refinement case. Use the existing first-run and hierarchy guides for the normal simulation route.

## Sources and verification details

Recorded inputs/builds only. Complete walkthrough and final-package acceptance remain separate.

- VAL-042: Frozen Windows JoSIM 2.9 CLI. Normal licensed frozen maintained Windows JoSIM 2.9 CLI on complete public editor teaching inputs; two resistive dividers and missing-include recovery. No editor UI, physical accuracy or final-package qualification Complete public teaching inputs only. Editor inspection is static and does not establish a numerical result. Native key/insertion handlers are checked; physical menu/picker, all language contexts, other platforms and final packages remain pending.
- VAL-044: Windows JoSIM 2.9 C API / CPython 3.13.11. Complete standard-library Python client through the matching Windows JoSIM 2.9 editor C API: source graph/spans/identity, explicit overlay, incomplete result, file preservation, Unicode path/UTF-8 columns and bounded input refusals. No numerical or GUI execution and no product licence configured by this client; the actual browser-downloaded four-file ZIP also passes nine checks using the exact full article/README PowerShell command with only Python/C API selections changed Complete public teaching inputs only. Editor inspection is static and does not establish a numerical result. Native key/insertion handlers are checked; physical menu/picker, all language contexts, other platforms and final packages remain pending.
- VAL-043: Frozen maintained Windows JoSIM GUI 2.9. Normal current-source Windows JoSIM 2.9 native editor with 11 maintained-source comparisons: actual Outline, Peek, explicit References selection, unsaved include, Alt+Left/Right, parameter/include completion, Escape/Undo and built-in snippet/Redo. Key events use production handlers; snippet insertion uses its production method with the actual built-in template. No native simulation, physical menu/picker or final-package acceptance Complete public teaching inputs only. Editor inspection is static and does not establish a numerical result. Native key/insertion handlers are checked; physical menu/picker, all language contexts, other platforms and final packages remain pending.

- josim-editor-outline: Windows current-source JoSIM 2.9 native editor scenario, reviewed 4 November 2026. Current native source-assistance controls and bounded interactions; no physical menu/picker, numerical result or final-package acceptance.
- josim-editor-peek-source: Windows current-source JoSIM 2.9 native editor scenario, reviewed 4 November 2026. Current native source-assistance controls and bounded interactions; no physical menu/picker, numerical result or final-package acceptance.

- josim-pro:docs/manual_source/sections/gui_navigation_search.tex: Source-aware Outline, Peek, References and navigation history
- josim-pro:docs/manual_source/sections/gui_editor.tex: Completion, quoted includes, snippets and live source assistance
- validation:josim-editor-windows-20261104: VAL-042 complete input/CLI, VAL-043 actual native editor route, VAL-044 complete C API client and explicit limits

- 62 scoped checks across complete numerical input, native editor and static agent routes. These do not qualify the full final GUI article, physical menu/pickers, all language contexts, every bound or final distributed 2.9 packages.

## Related guides

- [Use completion, linked snippets and live diagnostics](/knowledge-base/josim-editor-completion)
- [Reuse a parameterised subcircuit from an included library](/knowledge-base/josim-hierarchical-design)
- [A JoSIM®-Pro netlist cannot find an included file](/knowledge-base/josim-missing-include)
- [Review Git changes, stage selected lines and resolve a source conflict](/knowledge-base/josim-git-review)
- [Compare and restore a previous saved source version](/knowledge-base/josim-local-save-history)
- [Choose autosave and recover unsaved source](/knowledge-base/josim-autosave-recovery)
- [Search and replace across a workspace](/knowledge-base/josim-workspace-replace)
