Skip to content

"Dim the gutter" setting appears to do nothing #317

Description

@flyingrobots

Reported from live use.

The gutter dimming entry in the settings screen does not appear to change anything.

gutterDimmed exists in the workspace model (initialSettingsState() in src/app/workspace/init.ts) and is threaded into the source viewer render options as gutterDimmed (src/app/workspace/viewer-content.ts). So the wiring is at least partly present — determine whether the toggle mutates the model, whether the renderer honours it, or whether the visual difference is simply too small to perceive.

Note this is hard to evaluate while #318 stands, since the settings drawer covers the gutter being configured.

Acceptance

  • Toggling the setting produces a visible, intentional change to the gutter
  • If the effect is real but imperceptible, the design is corrected rather than the observation dismissed
  • A spec asserts the rendered gutter differs between states

Activity

  1. flyingrobots commented on Sep 7, 2026

    @flyingrobots
    OwnerAuthor

    Investigated. The setting is not broken in code, and I backed out an attempted fix because it violated two existing invariants. Recording the diagnosis so the next attempt starts from the real constraint.

    What is actually happening

    Dimming is expressed only as the ANSI SGR 2 "faint" attribute. applyGutterVariant in src/ui/jedit-themes.ts sets identical foreground colours for both variants and distinguishes them purely by modifier:

    for (const token of Object.values(tokens)) {
      token.backgroundColor = variables.surface;
      if (variant === GUTTER_VARIANT.Dimmed) {
        token.modifiers = [JEDIT_TEXT_MODIFIER.Dim];
      }
    }

    Measured across all 8 built-in themes and all 9 gutter tokens, the rendered foreground RGB is identical between gutter.normal and gutter.dimmed — channel distance 0 in every case, contrast ratio unchanged to two decimals.

    So the toggle does mutate the model, the model does reach the renderer, and the renderer does select a different token set. Whether anything appears on screen depends entirely on whether the terminal implements SGR 2. Many do not, and render faint identically to normal.

    Why this is not a one-line fix

    spec/theme-switch.spec.mjs already constrains both variants:

    • token.foregroundVariables.length > 0 — foregrounds must be named palette variables, not literal RGB
    • contrastRatio(fgRGB, bgRGB) >= 3 — applied to dimmed as well as normal

    I tried blending the dimmed foreground toward the surface. It produced a visible difference in every theme, but it fails both rules: an RgbColor has no variable name, and a genuinely dimmer colour cannot also hold contrast ≥ 3 against the same surface. Reverted.

    Read together, those two rules plus the identical colours suggest the current design is deliberate: keep the gutter legible and traceable to named palette variables, and delegate the visual dimming to the terminal.

    Options, all requiring a decision rather than a patch

    1. Introduce a named dimmed palette variable per theme (e.g. mutedDim) and relax the contrast floor for the dimmed variant only. Keeps naming discipline; needs a considered floor, and pairs naturally with Audit every jedit theme for legibility #309.
    2. Keep SGR 2 and set expectations — document that gutter dimming requires a terminal implementing faint, and note it in the setting label.
    3. Remove the setting, per the suggestion in Settings drawer covers the surface it configures #318 that it may not earn its place.

    My recommendation is 1, folded into the #309 theme audit, since that work has to establish per-surface contrast floors anyway. 3 is defensible if the setting is not worth the palette work.

    No code change on this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions