Skip to content

Commit

Permalink
Add an experimental setting for making suggestions RGB (#17416)
Browse files Browse the repository at this point in the history
Adds `$profile:experimental.rainbowSuggestions`, which makes the
suggestion text all RGB. This sparks joy.
  • Loading branch information
zadjii-msft authored Jun 25, 2024
1 parent 9f7032a commit 174dcb9
Show file tree
Hide file tree
Showing 13 changed files with 67 additions and 27 deletions.
2 changes: 2 additions & 0 deletions src/cascadia/TerminalControl/IControlAppearance.idl
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,7 @@ namespace Microsoft.Terminal.Control
Boolean RetroTerminalEffect { get; };
String PixelShaderPath { get; };
String PixelShaderImagePath { get; };

// NOTE! When adding something here, make sure to update ControlProperties.h too!
};
}
2 changes: 2 additions & 0 deletions src/cascadia/TerminalControl/IControlSettings.idl
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,7 @@ namespace Microsoft.Terminal.Control
Boolean UseBackgroundImageForWindow { get; };
Boolean RightClickContextMenu { get; };
Boolean RepositionCursorWithMouse { get; };

// NOTE! When adding something here, make sure to update ControlProperties.h too!
};
}
2 changes: 2 additions & 0 deletions src/cascadia/TerminalCore/ICoreAppearance.idl
Original file line number Diff line number Diff line change
Expand Up @@ -122,5 +122,7 @@ namespace Microsoft.Terminal.Core
Boolean IntenseIsBold;
Boolean IntenseIsBright;
AdjustTextMode AdjustIndistinguishableColors;

// NOTE! When adding something here, make sure to update ControlProperties.h too!
};
}
2 changes: 2 additions & 0 deletions src/cascadia/TerminalCore/ICoreSettings.idl
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ namespace Microsoft.Terminal.Core
Windows.Foundation.IReference<Microsoft.Terminal.Core.Color> StartingTabColor;

Boolean AutoMarkPrompts;
Boolean RainbowSuggestions;

// NOTE! When adding something here, make sure to update ControlProperties.h too!
};

}
39 changes: 36 additions & 3 deletions src/cascadia/TerminalCore/Terminal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ void Terminal::UpdateSettings(ICoreSettings settings)
_startingTitle = settings.StartingTitle();
_trimBlockSelection = settings.TrimBlockSelection();
_autoMarkPrompts = settings.AutoMarkPrompts();
_rainbowSuggestions = settings.RainbowSuggestions();

_getTerminalInput().ForceDisableWin32InputMode(settings.ForceVTInput());

Expand Down Expand Up @@ -1586,7 +1587,7 @@ til::point Terminal::GetViewportRelativeCursorPosition() const noexcept

void Terminal::PreviewText(std::wstring_view input)
{
// Our suggestion text is default-on-default, in italics.
// Our default suggestion text is default-on-default, in italics.
static constexpr TextAttribute previewAttrs{ CharacterAttributes::Italics, TextColor{}, TextColor{}, 0u, TextColor{} };

auto lock = LockForWriting();
Expand Down Expand Up @@ -1626,11 +1627,43 @@ void Terminal::PreviewText(std::wstring_view input)
// pad it out
preview.insert(originalSize, expectedLenTillEnd - originalSize, L' ');
}
snippetPreview.text = til::visualize_nonspace_control_codes(preview);

// Build our composition data
// The text is just the trimmed command, with the spaces at the end.
snippetPreview.text = til::visualize_nonspace_control_codes(preview);

// The attributes depend on the $profile:experimental.rainbowSuggestions setting:.
const auto len = snippetPreview.text.size();
snippetPreview.attributes.clear();
snippetPreview.attributes.emplace_back(len, previewAttrs);

if (_rainbowSuggestions)
{
// Let's do something fun.

// Use the actual text length for the number of steps, not including the
// trailing spaces.
const float increment = 1.0f / originalSize;
for (auto i = 0u; i < originalSize; i++)
{
const auto color = til::color::from_hue(increment * i);
TextAttribute curr = previewAttrs;
curr.SetForeground(color);
snippetPreview.attributes.emplace_back(1, curr);
}

if (originalSize < len)
{
TextAttribute curr;
snippetPreview.attributes.emplace_back(len - originalSize, curr);
}
}
else
{
// Default:
// Use the default attribute we defined above.
snippetPreview.attributes.emplace_back(len, previewAttrs);
}

snippetPreview.cursorPos = len;
_activeBuffer().NotifyPaintFrame();
}
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalCore/Terminal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ class Microsoft::Terminal::Core::Terminal final :
bool _suppressApplicationTitle = false;
bool _trimBlockSelection = false;
bool _autoMarkPrompts = false;
bool _rainbowSuggestions = false;

size_t _taskbarState = 0;
size_t _taskbarProgress = 0;
Expand Down
3 changes: 2 additions & 1 deletion src/cascadia/TerminalSettingsModel/MTSMSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ Author(s):
X(bool, AutoMarkPrompts, "autoMarkPrompts", false) \
X(bool, ShowMarks, "showMarksOnScrollbar", false) \
X(bool, RepositionCursorWithMouse, "experimental.repositionCursorWithMouse", false) \
X(bool, ReloadEnvironmentVariables, "compatibility.reloadEnvironmentVariables", true)
X(bool, ReloadEnvironmentVariables, "compatibility.reloadEnvironmentVariables", true) \
X(bool, RainbowSuggestions, "experimental.rainbowSuggestions", false)

// Intentionally omitted Profile settings:
// * Name
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalSettingsModel/Profile.idl
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ namespace Microsoft.Terminal.Settings.Model
INHERITABLE_PROFILE_SETTING(Boolean, RepositionCursorWithMouse);

INHERITABLE_PROFILE_SETTING(Boolean, ReloadEnvironmentVariables);
INHERITABLE_PROFILE_SETTING(Boolean, RainbowSuggestions);

}
}
3 changes: 1 addition & 2 deletions src/cascadia/TerminalSettingsModel/TerminalSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,10 +343,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
_ShowMarks = Feature_ScrollbarMarks::IsEnabled() && profile.ShowMarks();

_RightClickContextMenu = profile.RightClickContextMenu();

_RepositionCursorWithMouse = profile.RepositionCursorWithMouse();

_ReloadEnvironmentVariables = profile.ReloadEnvironmentVariables();
_RainbowSuggestions = profile.RainbowSuggestions();
}

// Method Description:
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalSettingsModel/TerminalSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
INHERITABLE_SETTING(Model::TerminalSettings, bool, IntenseIsBright);

INHERITABLE_SETTING(Model::TerminalSettings, Microsoft::Terminal::Core::AdjustTextMode, AdjustIndistinguishableColors, Core::AdjustTextMode::Never);
INHERITABLE_SETTING(Model::TerminalSettings, bool, RainbowSuggestions, false);

// ------------------------ End of Core Settings -----------------------

Expand Down
21 changes: 1 addition & 20 deletions src/cascadia/WindowsTerminal/AppHost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1128,33 +1128,14 @@ void AppHost::_stopFrameTimer()
// is called as the `_frameTimer` Tick callback, roughly 60 times per second.
void AppHost::_updateFrameColor(const winrt::Windows::Foundation::IInspectable&, const winrt::Windows::Foundation::IInspectable&)
{
// First, a couple helper functions:
static const auto saturateAndToColor = [](const float a, const float b, const float c) -> til::color {
return til::color{
base::saturated_cast<uint8_t>(255.f * std::clamp(a, 0.f, 1.f)),
base::saturated_cast<uint8_t>(255.f * std::clamp(b, 0.f, 1.f)),
base::saturated_cast<uint8_t>(255.f * std::clamp(c, 0.f, 1.f))
};
};

// Helper for converting a hue [0, 1) to an RGB value.
// Credit to https://www.chilliant.com/rgb2hsv.html
static const auto hueToRGB = [&](const float H) -> til::color {
float R = abs(H * 6 - 3) - 1;
float G = 2 - abs(H * 6 - 2);
float B = 2 - abs(H * 6 - 4);
return saturateAndToColor(R, G, B);
};

// Now, the main body of work.
// - Convert the time delta between when we were started and now, to a hue. This will cycle us through all the colors.
// - Convert that hue to an RGB value.
// - Set the frame's color to that RGB color.
const auto now = std::chrono::high_resolution_clock::now();
const std::chrono::duration<float> delta{ now - _started };
const auto seconds = delta.count() / 4; // divide by four, to make the effect slower. Otherwise it flashes way to fast.
float ignored;
const auto color = hueToRGB(modf(seconds, &ignored));
const auto color = til::color::from_hue(modf(seconds, &ignored));

_frameColorHelper(_window->GetHandle(), color);
}
Expand Down
3 changes: 2 additions & 1 deletion src/cascadia/inc/ControlProperties.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@
X(winrt::hstring, StartingTitle) \
X(bool, DetectURLs, true) \
X(bool, AutoMarkPrompts) \
X(bool, RepositionCursorWithMouse, false)
X(bool, RepositionCursorWithMouse, false) \
X(bool, RainbowSuggestions)

// --------------------------- Control Settings ---------------------------
// All of these settings are defined in IControlSettings.
Expand Down
14 changes: 14 additions & 0 deletions src/inc/til/color.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,20 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
}
#endif

// Helper for converting a hue [0, 1) to an RGB value.
// Credit to https://www.chilliant.com/rgb2hsv.html
static til::color from_hue(float hue)
{
const float R = abs(hue * 6 - 3) - 1;
const float G = 2 - abs(hue * 6 - 2);
const float B = 2 - abs(hue * 6 - 4);
return color{
base::saturated_cast<uint8_t>(255.f * std::clamp(R, 0.f, 1.f)),
base::saturated_cast<uint8_t>(255.f * std::clamp(G, 0.f, 1.f)),
base::saturated_cast<uint8_t>(255.f * std::clamp(B, 0.f, 1.f))
};
}

constexpr bool operator==(const til::color& other) const
{
return abgr == other.abgr;
Expand Down

0 comments on commit 174dcb9

Please sign in to comment.