Skip to content

feat(D1): implement tab handling per issue #37#46

Open
tig wants to merge 1 commit intodevelopfrom
experiment/claude/d1-tabs
Open

feat(D1): implement tab handling per issue #37#46
tig wants to merge 1 commit intodevelopfrom
experiment/claude/d1-tabs

Conversation

@tig
Copy link
Copy Markdown
Member

@tig tig commented May 9, 2026

Summary

  • Rename Editor.TabWidthIndentationSize — mirrors AvaloniaEdit's TextEditorOptions.IndentationSize (R3 compliant)
  • Add ConvertTabsToSpaces (bool, default false) — governs Tab key behavior, not document content
  • Add ShowTabs (bool, default false) — renders glyph at tab positions
  • Add Tab / Shift+Tab key handlers — insert, block indent/unindent with single undo step (R5)
  • Mouse snap to nearest edge — click inside tab span snaps to nearest logical edge (§7)
  • Updated ted demo — Indent Size control, Convert Tabs To Spaces menu toggle, ShowTabs status checkbox
  • 21 new tests across Editor.Tests and IntegrationTests; all 337 tests pass

B1 dependency — choice (c): stopgap, explicitly owned

The spec (§8 D1) says D1 depends on B1 (VisualLineBuilder pipeline) and without B1 "becomes another welded shortcut and is rejected." I chose to ship a working implementation and own the R1/R2 violation:

What violates R1/R2:

  • Tab rendering in DrawLineContent still operates char-by-char inside OnDrawingContent
  • No TabElement in a visual-line pipeline (B1 doesn't exist yet)

What's clean:

  • All interim helpers marked // TODO(VisualLineBuilder) for deletion when B1 lands
  • Tab key behavior is self-contained in Editor.Commands.cs
  • Properties mirror AvaloniaEdit names (R3)
  • Block operations use RunUpdate() for single undo step (R5)
  • Mouse nearest-edge snap is correct

Skipped

  • Backspace-at-indentation (§5) — marked as stretch goal in the spec
  • Full grapheme-aware rendering rewrite (§6 interim) — the right fix is B1, not a second interim hack
  • IIndentationStrategy plumbing — separate work item D7

Test plan

  • dotnet run --project tests/Terminal.Gui.Text.Tests — 212 passed
  • dotnet run --project tests/Terminal.Gui.Editor.Tests — 44 passed
  • dotnet run --project tests/Terminal.Gui.Editor.IntegrationTests — 81 passed
  • dotnet format --verify-no-changes — clean
  • dotnet jb cleanupcode — no changes

🤖 Generated with Claude Code

Rename Editor.TabWidth → IndentationSize (R3). Add ConvertTabsToSpaces,
ShowTabs properties. Add Tab/Shift+Tab key handlers: insert tab or
spaces, block indent/unindent with single-undo-step (R5), nearest-edge
mouse snap. Update ted demo with Indent Size control, Convert Tabs To
Spaces toggle, and ShowTabs status-bar checkbox.

Stopgap: ships without B1 (VisualLineBuilder pipeline). Tab rendering
still operates inside OnDrawingContent's char-by-char loop (R1/R2
violation acknowledged). Interim helpers marked TODO(VisualLineBuilder)
for deletion when B1 lands.

Closes #42. Addresses #37.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant