Skip to main content

Overview

Zep supports custom editor modes that define how the editor responds to keyboard input and user interactions. A mode controls the editing behavior, key mappings, and visual feedback for the editor.

Creating a Custom Mode

To create a custom mode, inherit from the ZepMode base class and implement the required virtual methods.

Basic Structure

#include "zep/mode.h"

namespace Zep
{

class ZepMode_Custom : public ZepMode
{
public:
    ZepMode_Custom(ZepEditor& editor);
    virtual ~ZepMode_Custom();

    virtual void Init() override;
    virtual void Begin(ZepWindow* pWindow) override;
    virtual const char* Name() const override { return "Custom"; }
    virtual EditorMode DefaultMode() const override;
};

} // namespace Zep
The Name() method returns the identifier for your mode, and DefaultMode() specifies the initial editing mode (Normal, Insert, Visual, or Ex).

Essential Virtual Methods

1
Initialize the Mode
2
Implement Init() to set up key mappings and mode flags:
3
void ZepMode_Custom::Init()
{
    // Set cursor type for visual mode
    m_visualCursorType = CursorType::Insert;

    // Configure mode behavior flags
    m_modeFlags |= ModeFlags::InsertModeGroupUndo | ModeFlags::StayInInsertMode;

    // Initialize registers
    for (int i = 0; i <= 9; i++)
    {
        GetEditor().SetRegister('0' + (const char)i, "");
    }
    GetEditor().SetRegister('"', "");
}
4
Set Up Key Mappings
5
Add keyboard mappings using the keymap_add function:
6
void ZepMode_Custom::Init()
{
    // Map backspace in insert mode
    keymap_add({ &m_insertMap }, { "<Backspace>" }, id_Backspace);
    
    // Map Ctrl+Z for undo
    keymap_add({ &m_insertMap, &m_visualMap }, { "<C-z>" }, id_Undo);
    
    // Map arrow keys
    keymap_add({ &m_insertMap }, { "<Left>" }, id_MotionStandardLeft);
    keymap_add({ &m_insertMap }, { "<Right>" }, id_MotionStandardRight);
    keymap_add({ &m_insertMap }, { "<Up>" }, id_MotionStandardUp);
    keymap_add({ &m_insertMap }, { "<Down>" }, id_MotionStandardDown);
}
7
Begin Mode Execution
8
Implement Begin() to activate the mode:
9
void ZepMode_Custom::Begin(ZepWindow* pWindow)
{
    ZepMode::Begin(pWindow);
    
    // Switch to the default editing mode
    SwitchMode(EditorMode::Insert);
}

Key Mapping Reference

Modifier Keys

ModifierNotationExample
Control<C-><C-z>
Shift<S-><S-Left>
Alt<A-><A-f>
CombinedMultiple<C-S-z>

Special Keys

"<Return>"      // Enter key
"<Backspace>"   // Backspace
"<Tab>"         // Tab
"<Del>"         // Delete
"<Escape>"      // Escape
"<Left>"        // Left arrow
"<Right>"       // Right arrow
"<Up>"          // Up arrow
"<Down>"        // Down arrow
"<Home>"        // Home
"<End>"         // End
"<PageDown>"    // Page Down
"<PageUp>"      // Page Up
"<F1>" to "<F12>" // Function keys

Advanced Features

Handle Custom Input

Override AddKeyPress() to process raw keyboard input:
void ZepMode_Custom::AddKeyPress(uint32_t key, uint32_t modifierKeys)
{
    // Custom key handling logic
    if (key == 'q' && (modifierKeys & ModifierKey::Ctrl))
    {
        // Handle Ctrl+Q
        return;
    }
    
    // Delegate to base class
    ZepMode::AddKeyPress(key, modifierKeys);
}

Custom Command Handling

Implement GetCommand() to handle custom command sequences:
bool ZepMode_Custom::GetCommand(CommandContext& context)
{
    // Parse and execute custom commands
    if (context.fullCommand == "mycommand")
    {
        // Execute custom command
        return true;
    }
    
    return ZepMode::GetCommand(context);
}

Modify Window Flags

Override ModifyWindowFlags() to customize window appearance:
uint32_t ZepMode_Custom::ModifyWindowFlags(uint32_t windowFlags)
{
    // Hide line numbers in this mode
    windowFlags &= ~WindowFlags::ShowLineNumbers;
    
    return windowFlags;
}

Mode Flags

// Groups multiple insert operations into a single undo action
m_modeFlags |= ModeFlags::InsertModeGroupUndo;

Editor Modes

Your custom mode can switch between these editing modes:
  • EditorMode::Normal - Navigation and command mode (like Vim normal mode)
  • EditorMode::Insert - Text insertion mode
  • EditorMode::Visual - Visual selection mode
  • EditorMode::Ex - Command-line mode
// Switch to insert mode
SwitchMode(EditorMode::Insert);

// Switch to normal mode
SwitchMode(EditorMode::Normal);

Complete Example

Here’s a complete custom mode implementation based on the Standard mode:
class ZepMode_Minimal : public ZepMode
{
public:
    ZepMode_Minimal(ZepEditor& editor) : ZepMode(editor) {}
    
    virtual void Init() override
    {
        // Configure mode for insert-only behavior
        m_visualCursorType = CursorType::Insert;
        m_modeFlags |= ModeFlags::InsertModeGroupUndo | ModeFlags::StayInInsertMode;
        
        // Basic text editing
        keymap_add({ &m_insertMap }, { "<Backspace>" }, id_Backspace);
        keymap_add({ &m_insertMap }, { "<Return>" }, id_InsertCarriageReturn);
        keymap_add({ &m_insertMap }, { "<Tab>" }, id_InsertTab);
        keymap_add({ &m_insertMap }, { "<Del>" }, id_Delete);
        
        // Navigation
        keymap_add({ &m_insertMap }, { "<Left>" }, id_MotionStandardLeft);
        keymap_add({ &m_insertMap }, { "<Right>" }, id_MotionStandardRight);
        keymap_add({ &m_insertMap }, { "<Up>" }, id_MotionStandardUp);
        keymap_add({ &m_insertMap }, { "<Down>" }, id_MotionStandardDown);
        
        // Undo/Redo
        keymap_add({ &m_insertMap }, { "<C-z>" }, id_Undo);
        keymap_add({ &m_insertMap }, { "<C-y>" }, id_Redo);
    }
    
    virtual void Begin(ZepWindow* pWindow) override
    {
        ZepMode::Begin(pWindow);
        SwitchMode(EditorMode::Insert);
    }
    
    virtual const char* Name() const override { return "Minimal"; }
    virtual EditorMode DefaultMode() const override { return EditorMode::Insert; }
};
Be sure to call the base class implementation when overriding Begin() to ensure proper initialization.

Next Steps

Build docs developers (and LLMs) love