Step 107a: add text mode toggle
This commit is contained in:
@@ -207,8 +207,9 @@ All 38 steps implemented and passing. Each step has a corresponding test (`step1
|
||||
- [x] Step 104: **IMPLEMENTED** — Cross-language projection button with read-only projected tabs and annotation summary (2/2 tests pass)
|
||||
- [x] Step 105: **IMPLEMENTED** — Optimization controls panel with constraint-aware buttons and summaries (2/2 tests pass)
|
||||
- [x] Step 106: **IMPLEMENTED** — Transform history panel with undo controls and provenance coloring (1/1 tests pass)
|
||||
- [ ] Step 107a–107c: **PLANNED** — Text-Editor Mode toggle, UI behavior by mode, and per-buffer persistence (not started)
|
||||
- [x] Step 107: **IMPLEMENTED** — Before/after diff view with preview and accept/reject (1/1 tests pass)
|
||||
- [x] Step 107a: **IMPLEMENTED** — Text-Editor Mode toggle and per-buffer mode tracking (2/2 tests pass)
|
||||
- [ ] Step 107b–107c: **PLANNED** — Mode-specific UI behavior and per-buffer persistence (not started)
|
||||
|
||||
---
|
||||
|
||||
@@ -296,6 +297,7 @@ vcpkg's imgui 1.91.9 removed the `sdl2-binding` feature (only `sdl3-binding` exi
|
||||
**Step 105:** Compile and pass (2/2)
|
||||
**Step 106:** Compile and pass (1/1)
|
||||
**Step 107:** Compile and pass (1/1)
|
||||
**Step 107a:** Compile and pass (2/2)
|
||||
|
||||
---
|
||||
|
||||
@@ -413,3 +415,4 @@ Sprint 4 in progress. Step 76 (LayoutManager) done. Next: Step 77 (custom code e
|
||||
| 2026-02-09 | Codex | Step 106: Transform history panel with undo controls and provenance coloring. 1/1 tests pass. |
|
||||
| 2026-02-09 | Codex | Planned Step 107a–107c: add Text-Editor Mode toggle, mode-specific UI behavior, and per-buffer persistence. |
|
||||
| 2026-02-09 | Codex | Step 107: Before/after diff view with preview and accept/reject. 1/1 tests pass. |
|
||||
| 2026-02-09 | Codex | Step 107a: Text-Editor Mode toggle and per-buffer mode tracking. 2/2 tests pass. |
|
||||
|
||||
@@ -578,6 +578,10 @@ add_executable(step107_test tests/step107_test.cpp)
|
||||
target_include_directories(step107_test PRIVATE src)
|
||||
target_link_libraries(step107_test PRIVATE nlohmann_json::nlohmann_json)
|
||||
|
||||
add_executable(step107a_test tests/step107a_test.cpp)
|
||||
target_include_directories(step107a_test PRIVATE src)
|
||||
target_link_libraries(step107a_test PRIVATE nlohmann_json::nlohmann_json)
|
||||
|
||||
find_package(SDL2 CONFIG REQUIRED)
|
||||
find_package(OpenGL REQUIRED)
|
||||
find_package(glad CONFIG REQUIRED)
|
||||
|
||||
@@ -11,20 +11,27 @@
|
||||
|
||||
class BufferManager {
|
||||
public:
|
||||
enum class BufferMode {
|
||||
Structured,
|
||||
Text
|
||||
};
|
||||
|
||||
struct BufferInfo {
|
||||
std::string path;
|
||||
std::string content;
|
||||
std::string language;
|
||||
bool modified = false;
|
||||
BufferMode mode = BufferMode::Structured;
|
||||
};
|
||||
|
||||
BufferManager() = default;
|
||||
|
||||
// Open a file into a buffer (makes it active)
|
||||
bool openBuffer(const std::string& path, const std::string& content,
|
||||
const std::string& language) {
|
||||
const std::string& language,
|
||||
BufferMode mode = BufferMode::Structured) {
|
||||
if (hasBuffer(path)) return false; // already open
|
||||
BufferInfo info{path, content, language, false};
|
||||
BufferInfo info{path, content, language, false, mode};
|
||||
buffers_[path] = info;
|
||||
activeBuffer_ = path;
|
||||
return true;
|
||||
@@ -70,6 +77,19 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void setBufferMode(const std::string& path, BufferMode mode) {
|
||||
auto it = buffers_.find(path);
|
||||
if (it != buffers_.end()) {
|
||||
it->second.mode = mode;
|
||||
}
|
||||
}
|
||||
|
||||
BufferMode getBufferMode(const std::string& path) const {
|
||||
auto it = buffers_.find(path);
|
||||
if (it != buffers_.end()) return it->second.mode;
|
||||
return BufferMode::Structured;
|
||||
}
|
||||
|
||||
// Get list of all open buffer paths
|
||||
std::vector<std::string> getOpenBuffers() const {
|
||||
std::vector<std::string> result;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "TextASTSync.h"
|
||||
#include "SyntaxHighlighter.h"
|
||||
#include "KeybindingManager.h"
|
||||
#include "BufferManager.h"
|
||||
#include "CodeEditorWidget.h"
|
||||
#include "EditorMode.h"
|
||||
#include "FileDialog.h"
|
||||
@@ -70,6 +71,7 @@ struct BufferState {
|
||||
std::string generatedLanguage = "python";
|
||||
std::string path = "(untitled)";
|
||||
bool readOnly = false;
|
||||
BufferManager::BufferMode mode = BufferManager::BufferMode::Structured;
|
||||
bool modified = false;
|
||||
int cursorLine = 1;
|
||||
int cursorCol = 1;
|
||||
@@ -251,7 +253,8 @@ struct EditorState {
|
||||
state->generatedHighlightsDirty = true;
|
||||
state->modified = false;
|
||||
state->lspVersion = 1;
|
||||
buffers.openBuffer(path, content, language);
|
||||
buffers.openBuffer(path, content, language, BufferManager::BufferMode::Structured);
|
||||
state->mode = BufferManager::BufferMode::Structured;
|
||||
activeBuffer = state.get();
|
||||
bufferStates[path] = std::move(state);
|
||||
if (path.rfind("(untitled", 0) != 0) watcher.watch(path);
|
||||
@@ -1328,6 +1331,15 @@ int main(int, char**) {
|
||||
ImGui::MenuItem("Show Minimap", nullptr, &state.showMinimap);
|
||||
ImGui::MenuItem("Show Annotations", nullptr, &state.showAnnotations);
|
||||
ImGui::MenuItem("LSP Servers...", nullptr, &state.showLspSettings);
|
||||
if (state.active()) {
|
||||
bool textMode = state.active()->mode == BufferManager::BufferMode::Text;
|
||||
if (ImGui::MenuItem("Text-Editor Mode", nullptr, textMode)) {
|
||||
state.active()->mode = textMode ?
|
||||
BufferManager::BufferMode::Structured :
|
||||
BufferManager::BufferMode::Text;
|
||||
state.buffers.setBufferMode(state.active()->path, state.active()->mode);
|
||||
}
|
||||
}
|
||||
if (ImGui::BeginMenu("Layout")) {
|
||||
if (ImGui::MenuItem("VSCode", nullptr, state.layoutPreset == LayoutPreset::VSCode))
|
||||
state.layoutPreset = LayoutPreset::VSCode;
|
||||
@@ -2575,6 +2587,16 @@ int main(int, char**) {
|
||||
ImGui::Text("-");
|
||||
ImGui::SameLine(0, 30);
|
||||
|
||||
// Mode
|
||||
if (state.active()) {
|
||||
const char* modeLabel =
|
||||
state.active()->mode == BufferManager::BufferMode::Text ? "Text" : "Structured";
|
||||
ImGui::Text("Mode: %s", modeLabel);
|
||||
} else {
|
||||
ImGui::Text("Mode: -");
|
||||
}
|
||||
ImGui::SameLine(0, 30);
|
||||
|
||||
// Keybinding profile
|
||||
ImGui::Text("Keys: %s", KeybindingManager::profileName(state.keys.getProfile()));
|
||||
ImGui::SameLine(0, 30);
|
||||
|
||||
28
editor/tests/step107a_test.cpp
Normal file
28
editor/tests/step107a_test.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
// Step 107a TDD Test: Text editor mode toggle persistence in BufferManager
|
||||
//
|
||||
// Tests:
|
||||
// 1. Default mode is Structured
|
||||
// 2. setBufferMode updates mode
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include "BufferManager.h"
|
||||
|
||||
int main() {
|
||||
int passed = 0;
|
||||
int failed = 0;
|
||||
|
||||
BufferManager bm;
|
||||
bm.openBuffer("file1", "", "python");
|
||||
assert(bm.getBufferMode("file1") == BufferManager::BufferMode::Structured);
|
||||
std::cout << "Test 1 PASS: default mode structured" << std::endl;
|
||||
++passed;
|
||||
|
||||
bm.setBufferMode("file1", BufferManager::BufferMode::Text);
|
||||
assert(bm.getBufferMode("file1") == BufferManager::BufferMode::Text);
|
||||
std::cout << "Test 2 PASS: mode updated" << std::endl;
|
||||
++passed;
|
||||
|
||||
std::cout << "\n=== Step 107a Results: " << passed << " passed, " << failed << " failed ===" << std::endl;
|
||||
return failed > 0 ? 1 : 0;
|
||||
}
|
||||
Reference in New Issue
Block a user