Make inline completion helper opt-in by default

This commit is contained in:
Bill
2026-02-16 18:14:24 -07:00
parent 90560be614
commit 0404703d3e
7 changed files with 61 additions and 8 deletions

View File

@@ -305,6 +305,7 @@ inline void EditorState::applySession(const SessionData& session) {
inline void EditorState::applySettingsToState() { inline void EditorState::applySettingsToState() {
ui.showMinimap = settings.getShowMinimap(); ui.showMinimap = settings.getShowMinimap();
ui.showCompletionHelper = settings.getShowCompletionHelper();
ui.showLineNumbers = settings.getShowLineNumbers(); ui.showLineNumbers = settings.getShowLineNumbers();
ui.layoutPreset = LayoutManager::presetFromName(settings.getLayoutPreset()); ui.layoutPreset = LayoutManager::presetFromName(settings.getLayoutPreset());
keys.setProfile(KeybindingManager::profileFromName(settings.getKeybindingProfile())); keys.setProfile(KeybindingManager::profileFromName(settings.getKeybindingProfile()));
@@ -320,6 +321,7 @@ inline void EditorState::loadSettingsFromDisk() {
inline void EditorState::saveSettingsToDisk() { inline void EditorState::saveSettingsToDisk() {
settings.setShowMinimap(ui.showMinimap); settings.setShowMinimap(ui.showMinimap);
settings.setShowCompletionHelper(ui.showCompletionHelper);
settings.setShowLineNumbers(ui.showLineNumbers); settings.setShowLineNumbers(ui.showLineNumbers);
settings.setLayoutPreset(LayoutManager::presetName(ui.layoutPreset)); settings.setLayoutPreset(LayoutManager::presetName(ui.layoutPreset));
settings.setKeybindingProfile(KeybindingManager::profileName(keys.getProfile())); settings.setKeybindingProfile(KeybindingManager::profileName(keys.getProfile()));

View File

@@ -54,6 +54,8 @@ public:
void setAutoSaveSeconds(int seconds) { autoSaveSeconds_ = seconds; } void setAutoSaveSeconds(int seconds) { autoSaveSeconds_ = seconds; }
bool getShowMinimap() const { return showMinimap_; } bool getShowMinimap() const { return showMinimap_; }
void setShowMinimap(bool value) { showMinimap_ = value; } void setShowMinimap(bool value) { showMinimap_ = value; }
bool getShowCompletionHelper() const { return showCompletionHelper_; }
void setShowCompletionHelper(bool value) { showCompletionHelper_ = value; }
bool getShowLineNumbers() const { return showLineNumbers_; } bool getShowLineNumbers() const { return showLineNumbers_; }
void setShowLineNumbers(bool value) { showLineNumbers_ = value; } void setShowLineNumbers(bool value) { showLineNumbers_ = value; }
bool getReduceMotion() const { return reduceMotion_; } bool getReduceMotion() const { return reduceMotion_; }
@@ -101,6 +103,7 @@ public:
updateUrl_ = j.value("updateUrl", updateUrl_); updateUrl_ = j.value("updateUrl", updateUrl_);
autoSaveSeconds_ = j.value("autoSaveSeconds", autoSaveSeconds_); autoSaveSeconds_ = j.value("autoSaveSeconds", autoSaveSeconds_);
showMinimap_ = j.value("showMinimap", showMinimap_); showMinimap_ = j.value("showMinimap", showMinimap_);
showCompletionHelper_ = j.value("showCompletionHelper", showCompletionHelper_);
showLineNumbers_ = j.value("showLineNumbers", showLineNumbers_); showLineNumbers_ = j.value("showLineNumbers", showLineNumbers_);
reduceMotion_ = j.value("reduceMotion", reduceMotion_); reduceMotion_ = j.value("reduceMotion", reduceMotion_);
useAnnotationShapes_ = j.value("useAnnotationShapes", useAnnotationShapes_); useAnnotationShapes_ = j.value("useAnnotationShapes", useAnnotationShapes_);
@@ -149,6 +152,7 @@ public:
j["updateUrl"] = updateUrl_; j["updateUrl"] = updateUrl_;
j["autoSaveSeconds"] = autoSaveSeconds_; j["autoSaveSeconds"] = autoSaveSeconds_;
j["showMinimap"] = showMinimap_; j["showMinimap"] = showMinimap_;
j["showCompletionHelper"] = showCompletionHelper_;
j["showLineNumbers"] = showLineNumbers_; j["showLineNumbers"] = showLineNumbers_;
j["reduceMotion"] = reduceMotion_; j["reduceMotion"] = reduceMotion_;
j["useAnnotationShapes"] = useAnnotationShapes_; j["useAnnotationShapes"] = useAnnotationShapes_;
@@ -234,6 +238,7 @@ private:
std::string updateUrl_ = "https://example.com/whetstone/releases.json"; std::string updateUrl_ = "https://example.com/whetstone/releases.json";
int autoSaveSeconds_ = 0; int autoSaveSeconds_ = 0;
bool showMinimap_ = false; bool showMinimap_ = false;
bool showCompletionHelper_ = false;
bool showLineNumbers_ = true; bool showLineNumbers_ = true;
bool reduceMotion_ = false; bool reduceMotion_ = false;
bool useAnnotationShapes_ = true; bool useAnnotationShapes_ = true;

View File

@@ -321,12 +321,19 @@ static void renderEditorPanel(EditorState& state) {
} }
if (res.changed) { if (res.changed) {
state.onTextChanged(); state.onTextChanged();
state.completionPending = true; if (state.ui.showCompletionHelper) {
state.completionLastChange = ImGui::GetTime(); state.completionPending = true;
state.completionVisible = false; state.completionLastChange = ImGui::GetTime();
state.completionDismissed = false; state.completionVisible = false;
state.completionSelected = 0; state.completionDismissed = false;
if (state.lsp) state.lsp->clearCompletionItems(); state.completionSelected = 0;
if (state.lsp) state.lsp->clearCompletionItems();
} else {
state.completionPending = false;
state.completionVisible = false;
state.completionDismissed = false;
if (state.lsp) state.lsp->clearCompletionItems();
}
if (state.lsp && state.active() && state.active()->path.rfind("(untitled", 0) != 0) { if (state.lsp && state.active() && state.active()->path.rfind("(untitled", 0) != 0) {
int cursor = state.active()->widget.getCursor(); int cursor = state.active()->widget.getCursor();
if (cursor > 0 && state.active()->editBuf[cursor - 1] == '(') { if (cursor > 0 && state.active()->editBuf[cursor - 1] == '(') {
@@ -356,7 +363,9 @@ static void renderEditorPanel(EditorState& state) {
} }
double now = ImGui::GetTime(); double now = ImGui::GetTime();
if (state.completionPending && (now - state.completionLastChange) > 0.2) { if (state.ui.showCompletionHelper &&
state.completionPending &&
(now - state.completionLastChange) > 0.2) {
if (state.lsp && state.active() && state.active()->path.rfind("(untitled", 0) != 0) { if (state.lsp && state.active() && state.active()->path.rfind("(untitled", 0) != 0) {
int lineZero = std::max(0, state.active()->cursorLine - 1); int lineZero = std::max(0, state.active()->cursorLine - 1);
int colZero = std::max(0, state.active()->cursorCol - 1); int colZero = std::max(0, state.active()->cursorCol - 1);
@@ -403,7 +412,7 @@ static void renderEditorPanel(EditorState& state) {
state.analysisPending = false; state.analysisPending = false;
} }
if (state.lsp && state.active()) { if (state.ui.showCompletionHelper && state.lsp && state.active()) {
auto items = state.lsp->getCompletionItems(); auto items = state.lsp->getCompletionItems();
int cursor = state.active()->widget.getCursor(); int cursor = state.active()->widget.getCursor();
std::string prefix = EditorState::wordPrefixAt(state.active()->editBuf, cursor); std::string prefix = EditorState::wordPrefixAt(state.active()->editBuf, cursor);
@@ -525,6 +534,11 @@ static void renderEditorPanel(EditorState& state) {
} }
} }
} }
if (!state.ui.showCompletionHelper) {
state.completionPending = false;
state.completionVisible = false;
state.completionDismissed = false;
}
if (state.showSuggestionPopup) { if (state.showSuggestionPopup) {
if (ImGui::BeginPopupModal("SuggestionPopup", &state.showSuggestionPopup, ImGuiWindowFlags_AlwaysAutoResize)) { if (ImGui::BeginPopupModal("SuggestionPopup", &state.showSuggestionPopup, ImGuiWindowFlags_AlwaysAutoResize)) {

View File

@@ -90,6 +90,7 @@ static void renderMenuBar(EditorState& state) {
if (ImGui::BeginMenu("View")) { if (ImGui::BeginMenu("View")) {
ImGui::MenuItem("Show Whitespace", nullptr, &state.ui.showWhitespace); ImGui::MenuItem("Show Whitespace", nullptr, &state.ui.showWhitespace);
ImGui::MenuItem("Show Minimap", nullptr, &state.ui.showMinimap); ImGui::MenuItem("Show Minimap", nullptr, &state.ui.showMinimap);
ImGui::MenuItem("Inline Completion Helper", nullptr, &state.ui.showCompletionHelper);
ImGui::MenuItem("Show Annotations", nullptr, &state.ui.showAnnotations); ImGui::MenuItem("Show Annotations", nullptr, &state.ui.showAnnotations);
ImGui::MenuItem("Show Outline", nullptr, &state.ui.showOutline); ImGui::MenuItem("Show Outline", nullptr, &state.ui.showOutline);
ImGui::MenuItem("Terminal", state.keys.getBinding("view.toggleTerminal").toString().c_str(), ImGui::MenuItem("Terminal", state.keys.getBinding("view.toggleTerminal").toString().c_str(),

View File

@@ -339,6 +339,17 @@ static void renderSettingsPanel(EditorState& state) {
state.ui.showMinimap = showMinimap; state.ui.showMinimap = showMinimap;
settingsChanged = true; settingsChanged = true;
} }
bool showCompletionHelper = state.ui.showCompletionHelper;
if (ImGui::Checkbox("Inline Completion Helper", &showCompletionHelper)) {
state.ui.showCompletionHelper = showCompletionHelper;
if (!showCompletionHelper) {
state.completionPending = false;
state.completionVisible = false;
state.completionDismissed = false;
if (state.lsp) state.lsp->clearCompletionItems();
}
settingsChanged = true;
}
bool showLineNumbers = state.ui.showLineNumbers; bool showLineNumbers = state.ui.showLineNumbers;
if (ImGui::Checkbox("Show Line Numbers", &showLineNumbers)) { if (ImGui::Checkbox("Show Line Numbers", &showLineNumbers)) {
state.ui.showLineNumbers = showLineNumbers; state.ui.showLineNumbers = showLineNumbers;

View File

@@ -12,6 +12,7 @@ enum class FocusRegion {
struct UIFlags { struct UIFlags {
bool showWhitespace = false; bool showWhitespace = false;
bool showMinimap = false; bool showMinimap = false;
bool showCompletionHelper = false;
bool showAnnotations = false; bool showAnnotations = false;
bool showOutline = true; bool showOutline = true;
bool showLineNumbers = true; bool showLineNumbers = true;

View File

@@ -5318,6 +5318,25 @@ confirming with Enter/Tab).
- `step54_test` — PASS (10/10) regression coverage - `step54_test` — PASS (10/10) regression coverage
- `step437_test` — PASS (8/8) regression coverage - `step437_test` — PASS (8/8) regression coverage
### Hotfix E: inline completion helper default-off + toggle
**Status:** PASS (helper now opt-in)
Changed inline completion helper to default OFF and only appear when explicitly
enabled by the user.
**Files modified:**
- `editor/src/state/UIFlags.h` — added `showCompletionHelper` UI flag (default `false`)
- `editor/src/SettingsManager.h` — added persisted `showCompletionHelper` setting
- `editor/src/BufferOps.h` — synced `showCompletionHelper` with settings load/save
- `editor/src/panels/MenuBarPanel.h` — View toggle: `Inline Completion Helper`
- `editor/src/panels/SettingsPanel.h` — Settings checkbox and cleanup on disable
- `editor/src/panels/EditorPanel.h` — gated completion requests/rendering behind toggle
**Verification run:**
- `cmake --build editor/build-native --target whetstone_editor` — PASS
- `step54_test` — PASS (10/10) regression coverage
- `step437_test` — PASS (8/8) regression coverage
# Roadmap Planning — Sprints 12-25+ # Roadmap Planning — Sprints 12-25+
## Status: Planning Complete (Sprints 12-19 detailed, 20-25 in roadmap.md) ## Status: Planning Complete (Sprints 12-19 detailed, 20-25 in roadmap.md)