Skip to content

Modernized fork of ImGuiColorTextEdit — an ImGui code/text editor with syntax highlighting. ImGuiKey-based shortcuts (SDL2 optional), ImGui 1.92+ compatibility, optional SPIR-V tools, C++17.

License

Notifications You must be signed in to change notification settings

NewYaroslav/ImGuiColorTextEdit

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ImGuiColorTextEdit

Syntax highlighting text editor for ImGui This project is a fork of dfranx/ImGuiColorTextEdit.

Compatible with Dear ImGui 1.92 and later. Deprecated ImGui APIs such as GetKeyIndex have been removed.

Screenshot

Demo project: https://github.com/BalazsJako/ColorTextEditorDemo

Public API

TextEditor

  • void Render(const char* title, const ImVec2& size = ImVec2(), bool border = false); – draw the editor.
  • void SetText(const std::string& text); / std::string GetText() const;
  • void SetLanguageDefinition(const LanguageDefinition& lang); – enable syntax highlighting.
  • void SetPalette(const TextEditor::Palette& colors); / const TextEditor::Palette& GetPalette() const;
  • void SetReadOnly(bool value); / bool IsReadOnly();
  • Coordinates GetCursorPosition() const; / void SetCursorPosition(const Coordinates& pos);
  • void InsertText(const std::string& text, bool indent = false);
  • void Undo(); void Redo(); void Copy(); void Cut(); void Paste(); void Delete();

Helpers

  • Language definitions: CPlusPlus(), HLSL(), GLSL(), SPIRV(), C(), SQL(), AngelScript(), Lua(), JSON(), JSONC(), JSONWithHash()
  • Palettes: GetDarkPalette(), GetLightPalette(), GetRetroBluePalette()
  • Shortcuts: GetDefaultShortcuts()

Build Flags

  • IMGUICTE_USE_SDL2: enable when using SDL2 backend to handle keyboard input.
  • IMGUICTE_ENABLE_SPIRV: enable to support SPIR-V highlighting, requiring spirv_cross and disabling certain non-SPIR-V features.

The project originated as Balazs Jako's ImGuiColorTextEdit, a simple text editor widget with syntax highlighting. It has since grown through contributions from many developers.

The editor builds on Omar Cornut's Dear ImGui but departs from the strictly immediate "one widget – one function" paradigm. To manage its substantial internal state, the widget stores data in a persistent object reused across frames.

The codebase remains a work in progress; please report any issues.

Supported Languages

Language Function
CPlusPlus const LanguageDefinition& CPlusPlus();
HLSL const LanguageDefinition& HLSL();
GLSL const LanguageDefinition& GLSL();
SPIRV const LanguageDefinition& SPIRV();
C const LanguageDefinition& C();
SQL const LanguageDefinition& SQL();
AngelScript const LanguageDefinition& AngelScript();
Lua const LanguageDefinition& Lua();
JSON const LanguageDefinition& JSON();
JSONC const LanguageDefinition& JSONC();
JSON5 const LanguageDefinition& JSON5();
JSONWithHash const LanguageDefinition& JSONWithHash();
Markdown const LanguageDefinition& Markdown();
DotEnv const LanguageDefinition& DotEnv();
XML const LanguageDefinition& XML();
CSV const LanguageDefinition& CSV();
HTML const LanguageDefinition& HTML();
CSS const LanguageDefinition& CSS();
CMake const LanguageDefinition& CMake();
YAML const LanguageDefinition& YAML();
TOML const LanguageDefinition& TOML();
INI const LanguageDefinition& INI();
Dockerfile const LanguageDefinition& Dockerfile();
Diff const LanguageDefinition& Diff();
Bash const LanguageDefinition& Bash();

JSON editor example

The snippet below demonstrates how to embed ImGuiColorTextEdit in a JSON tool and how to tweak the color palette. The code is condensed for clarity but shows a typical integration pattern.

#include "ImGuiColorTextEdit.h"

// Create the editor and enable JSON syntax
ImTextEdit::TextEditor editor;
auto lang = ImTextEdit::JSON();
editor.SetLanguageDefinition(lang);

// Optional: create a custom color palette based on the dark theme
ImTextEdit::TextEditor::Palette customPalette = ImTextEdit::GetDarkPalette();
customPalette[(int)ImTextEdit::PaletteIndex::Keyword] = ImVec4(0.86f, 0.40f, 0.24f, 1.0f); // keywords
customPalette[(int)ImTextEdit::PaletteIndex::String]  = ImVec4(0.90f, 0.76f, 0.18f, 1.0f); // strings
editor.SetPalette(customPalette);

// --- main render loop ---
const float window_width  = window.getSize().x;
const float window_height = window.getSize().y;
auto cpos = editor.GetCursorPosition();

ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always);
ImGui::SetNextWindowSize(ImVec2(window_width, window_height - indent_basement), ImGuiCond_Always);
ImGui::Begin("CryptoJsonMainMenu", nullptr,
    ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize |
    ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar |
    ImGuiWindowFlags_MenuBar);

if (ImGui::BeginMenuBar()) {
    if (ImGui::BeginMenu("File")) {
        if (ImGui::MenuItem("Open"))
            file_dialog_open = true;
        if (ImGui::MenuItem("Save", nullptr, false, cj_config.is_init)) {
            auto text = editor.GetText();
            // save text to file
        }
        if (ImGui::MenuItem("Save as..."))
            file_dialog_save = true;
        if (ImGui::MenuItem("Quit", "Alt-F4"))
            break;
        ImGui::EndMenu();
    }
    if (ImGui::BeginMenu("Edit")) {
        bool readOnly = editor.IsReadOnly();
        if (ImGui::MenuItem("Read-only mode", nullptr, &readOnly))
            editor.SetReadOnly(readOnly);
        ImGui::Separator();

        if (ImGui::MenuItem("Undo", "ALT-Backspace", nullptr, !readOnly && editor.CanUndo()))
            editor.Undo();
        if (ImGui::MenuItem("Redo", "Ctrl-Y", nullptr, !readOnly && editor.CanRedo()))
            editor.Redo();

        ImGui::Separator();

        if (ImGui::MenuItem("Copy", "Ctrl-C", nullptr, editor.HasSelection()))
            editor.Copy();
        if (ImGui::MenuItem("Cut", "Ctrl-X", nullptr, !readOnly && editor.HasSelection()))
            editor.Cut();
        if (ImGui::MenuItem("Delete", "Del", nullptr, !readOnly && editor.HasSelection()))
            editor.Delete();
        if (ImGui::MenuItem("Paste", "Ctrl-V", nullptr, !readOnly && ImGui::GetClipboardText() != nullptr))
            editor.Paste();

        ImGui::Separator();

        if (ImGui::MenuItem("Select all"))
editor.SetSelection(ImTextEdit::Coordinates(), ImTextEdit::Coordinates(editor.GetTotalLines(), 0));

        ImGui::EndMenu();
    }

    if (ImGui::BeginMenu("View")) {
        if (ImGui::MenuItem("Dark palette"))
            editor.SetPalette(ImTextEdit::GetDarkPalette());
        if (ImGui::MenuItem("Light palette"))
            editor.SetPalette(ImTextEdit::GetLightPalette());
        if (ImGui::MenuItem("Retro blue palette"))
            editor.SetPalette(ImTextEdit::GetRetroBluePalette());
        if (ImGui::MenuItem("Custom palette"))
            editor.SetPalette(customPalette);
        ImGui::EndMenu();
    }
    ImGui::EndMenuBar();
}

ImGui::Text("%6d/%-6d %6d lines  | %s | %s | %s | %s", cpos.mLine + 1, cpos.mColumn + 1, editor.GetTotalLines(),
            editor.IsOverwrite() ? "Ovr" : "Ins",
            editor.CanUndo() ? "*" : " ",
            editor.GetLanguageDefinition().mName.c_str(), cj_config.path.c_str());

editor.Render("TextEditor");
ImGui::End();

ImGui::Begin("##basement", NULL,
    ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize |
    ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar);
{
    if (ImGui::Button("Validate")) {
        JsonSax json_sax;
        const std::string text = editor.GetText();
        json::sax_parse(text, &json_sax);

        ImTextEdit::TextEditor::ErrorMarkers markers;
        for (const auto& err : json_sax.errors) {
            int line = std::count(text.begin(), text.begin() + err.first, '\n');
            markers.insert({line, err.second});
        }
        editor.SetErrorMarkers(markers);
    }

    ImGui::SameLine();

    if (ImGui::Button("Copy")) {
        const std::string text = editor.GetText();
        ImGui::SetClipboardText(text.c_str());
    }
}
ImGui::End();

Main features

  • approximates typical code editor look and feel (essential mouse/keyboard commands work - I mean, the commands I normally use :))
  • undo/redo
  • UTF-8 support
  • works with both fixed and variable-width fonts
  • extensible syntax highlighting for multiple languages
  • identifier declarations: a small piece of description can be associated with an identifier. The editor displays it in a tooltip when the mouse cursor is hovered over the identifier
  • error markers: the user can specify a list of error messages together the line of occurence, the editor will highligh the lines with red backround and display error message in a tooltip when the mouse cursor is hovered over the line
  • large files: there is no explicit limit set on file size or number of lines (below 2GB, performance is not affected when large files are loaded (except syntax coloring, see below)
  • color palette support: you can switch between different color palettes, or even define your own
  • whitespace indicators (TAB, space)

Known issues

  • syntax highligthing of most languages - except C/C++ - is based on std::regex, which is diasppointingly slow. Because of that, the highlighting process is amortized between multiple frames. C/C++ has a hand-written tokenizer which is much faster.

Please post your screenshots if you find this little piece of software useful. :)

Contribute

If you want to contribute, please refer to CONTRIBUTE file.

About

Modernized fork of ImGuiColorTextEdit — an ImGui code/text editor with syntax highlighting. ImGuiKey-based shortcuts (SDL2 optional), ImGui 1.92+ compatibility, optional SPIR-V tools, C++17.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published

Languages

  • C++ 100.0%