Skip to main content
Get a fully functional text editor up and running in just a few minutes. This guide shows you how to create a minimal ImGui-based editor.

What You’ll Build

A simple text editor window with:
  • Syntax highlighting
  • Vim or Standard editing mode
  • Line numbers
  • Full keyboard support

Prerequisites

  • Zep installed (see Installation)
  • ImGui set up in your project
  • SDL2 and OpenGL context (for this example)

Creating Your First Editor

1

Include Zep headers

Start by including the necessary Zep headers:
#include "zep/imgui/editor_imgui.h"
#include "zep/imgui/display_imgui.h"
#include "zep/mode_vim.h"
#include "zep/mode_standard.h"

using namespace Zep;
2

Create the editor instance

Initialize the Zep editor with ImGui display:
// Get pixel scale for high DPI displays
NVec2f pixelScale = NVec2f(1.0f, 1.0f);

// Create editor with ImGui display
auto editor = std::make_unique<ZepEditor_ImGui>(
    "/path/to/config",  // Config root path
    pixelScale,          // Pixel scale
    0,                   // Flags (0 = default)
    nullptr              // File system (nullptr = default)
);
The config path is where Zep looks for configuration files. Pass an empty string or your app’s config directory.
3

Load content into a buffer

Create a buffer and add some text:
// Initialize with text
const char* sampleCode = R"(
#include <iostream>

int main() {
std::cout << "Hello from Zep!" << std::endl;
return 0;
}
)";

editor->InitWithText("sample.cpp", sampleCode);
Or load from a file:
// Initialize with a file
editor->InitWithFile("/path/to/file.cpp");
4

Setup the display region

In your ImGui render loop, set the display region and render:
// In your ImGui render loop
ImGui::Begin("Zep Editor");

auto min = ImGui::GetCursorScreenPos();
auto max = ImGui::GetContentRegionAvail();

// Convert to Zep coordinates
max.x = std::max(1.0f, max.x);
max.y = std::max(1.0f, max.y);
max.x = min.x + max.x;
max.y = min.y + max.y;

// Set the display region
editor->SetDisplayRegion(
    NVec2f(min.x, min.y),
    NVec2f(max.x, max.y)
);

// Display the editor
editor->Display();

// Handle input
editor->HandleInput();

ImGui::End();

Complete Minimal Example

Here’s a complete minimal example based on the demo:
#include <imgui.h>
#include "zep/imgui/editor_imgui.h"
#include "zep/mode_standard.h"
#include "zep/mode_vim.h"

using namespace Zep;

class MyZepEditor {
public:
    MyZepEditor(const std::string& configPath) {
        // Create editor
        auto pixelScale = NVec2f(1.0f, 1.0f);
        editor = std::make_unique<ZepEditor_ImGui>(
            configPath,
            pixelScale
        );
        
        // Initialize with some content
        editor->InitWithText("welcome.txt", 
            "Welcome to Zep!\n\nPress Ctrl+1 for Standard mode\nPress Ctrl+2 for Vim mode\n");
    }
    
    void Display() {
        ImGui::Begin("Text Editor", nullptr, 
            ImGuiWindowFlags_NoScrollbar);
        
        // Get the region
        auto min = ImGui::GetCursorScreenPos();
        auto max = ImGui::GetContentRegionAvail();
        
        max.x = std::max(1.0f, max.x);
        max.y = std::max(1.0f, max.y);
        
        // Set display region
        editor->SetDisplayRegion(
            NVec2f(min.x, min.y),
            NVec2f(min.x + max.x, min.y + max.y)
        );
        
        // Render and handle input
        editor->Display();
        editor->HandleInput();
        
        ImGui::End();
    }
    
private:
    std::unique_ptr<ZepEditor_ImGui> editor;
};

Switching Editor Modes

Zep supports both Standard (notepad-style) and Vim modes:
// Switch to Standard mode
editor->SetGlobalMode(ZepMode_Standard::StaticName());

// Switch to Vim mode
editor->SetGlobalMode(ZepMode_Vim::StaticName());
Users can switch modes at runtime with:
  • Ctrl+1 - Standard mode
  • Ctrl+2 - Vim mode

Working with Buffers

Open a file

auto buffer = editor->GetFileBuffer("/path/to/file.txt");
if (buffer) {
    editor->EnsureWindow(*buffer);
}

Get the active buffer

auto buffer = editor->GetActiveBuffer();
if (buffer) {
    // Work with buffer
    auto mode = buffer->GetMode();
}

Create an empty buffer

auto buffer = editor->GetEmptyBuffer("untitled.txt");

Customizing Themes

Switch between light and dark themes:
// Dark theme
editor->GetTheme().SetThemeType(ThemeType::Dark);

// Light theme
editor->GetTheme().SetThemeType(ThemeType::Light);

Common Operations

Check if refresh needed

if (editor->RefreshRequired()) {
    // Redraw your window
}

Handle clipboard

Zep uses callbacks for clipboard operations. Implement IZepComponent interface:
class MyComponent : public IZepComponent {
    void Notify(std::shared_ptr<ZepMessage> message) override {
        if (message->messageId == Msg::GetClipBoard) {
            // Get clipboard text and set message->str
        }
        else if (message->messageId == Msg::SetClipBoard) {
            // Set clipboard from message->str
        }
    }
    
    ZepEditor& GetEditor() const override {
        return *editor;
    }
};

// Register callback
editor->RegisterCallback(myComponent);

Next Steps

API Reference

Explore the full API documentation

Examples

See more advanced usage examples
For a complete working example with SDL2 and OpenGL setup, check out the demo_imgui in the Zep repository.

Build docs developers (and LLMs) love