An embeddable code editor built with Dear ImGui. Runs standalone (GLFW + OpenGL/Vulkan) or embedded as a static library inside other ImGui applications.
Features: Tree-Sitter syntax highlighting, LSP integration, AI agent with MCP tools, terminal emulator, multi-cursor editing, git integration.
NedContext owns all top-level services. Leaf components receive dependencies through constructors and cannot access NedContext at runtime.
NedContext (composition root)
├── Settings — themes, fonts, configuration
├── LSPServices — LSP client, goto-def, goto-ref, symbol info, dashboard
├── FileServices — file explorer, tree, finder, content search
├── AppServices — font, keybinds, welcome, terminal, debug console
├── AIAgent — chat agent, MCP tools, tab completion, editor diff
├── Editor — text editing (14 sub-components, 6 state structs)
├── EditorEvents — typed signal bus for cross-service communication
└── NedCallbacks — host engine callback interface
Components declare exactly what they need.
// Each sub-component takes only the services it uses
EditorKeyboard(AIAgent& ai, FileServices& files, Settings& settings, LSPServices& lsp, AppServices& app);
EditorCursor(Settings& settings, FileServices& files);
EditorScroll(AIAgent& ai);Services communicate across boundaries using typed signals. Emitters don't know who listens.
// FileExplorer emits after opening a file
events.fileOpened.emit(path, document);
// Editor subscribes in its constructor
connFileOpened = events.fileOpened.connect([this](const std::string& path, DocumentState& doc) {
highlight.highlightContent(doc, false, true);
lineNumbers.setCurrentFilePath(path);
tabs.onFileOpened(path, cursor_state, scroll);
});
// Editor disconnects in its destructor
events.fileOpened.disconnect(connFileOpened);Signals: fileOpened, fileContentChanged, fileReloaded, folderOpened, navigateToLocation, themeChanged, consoleToggleRequested, closePopupsRequested, projectChanged
Six private state structs owned by Editor, passed as function parameters:
| Struct | Contents |
|---|---|
DocumentState |
File content, syntax colors, line positions |
CursorState |
Cursor position, multi-cursor list |
SelectionState |
Selection ranges, multi-selection |
ScrollState |
Scroll position, visibility flags |
LayoutState |
Dimensions, margins, line height |
EditorSignals |
Frame flags (input blocked, text changed) |
Only host-layer entry points (NedApp, NedEmbed, NedEditorLayer) access state structs directly via friend access.
Standalone: main.cpp -> NedApp -> GLFW window + render loop.
Embedded: Host creates NedEmbed with options and calls render() each frame:
NedCallbacks provides the bridge between the AI agent's MCP tools and the host engine (entity manipulation, asset queries, script building, viewport capture).
GetNedContext() / SetNedContext() in globals.h exists for a few cases:
- Async threads (git, highlighting, LSP goto) set the thread-local so they can access services
- Bootstrap during initialization
Regular code uses constructor-injected references.
ned— standalone executable (GLFW + OpenGL/Vulkan)ned_embed— static library (no window deps)
Build flags: NED_BUILD_WITH_GLFW, NED_BUILD_WITH_VULKAN, NED_BUILD_WITH_OPENGL, NED_BUILD_WITH_CURL, NED_BUILD_WITH_GIT, NED_BUILD_WITH_FREETYPE