VTSupport.h (7494B)
1 // Copyright (c) Microsoft Corporation. 2 // Licensed under the MIT License. 3 #pragma once 4 #include <AppInstallerLanguageUtilities.h> 5 6 #include <cstdint> 7 #include <iostream> 8 #include <optional> 9 #include <string> 10 #include <string_view> 11 12 13 // The escape character that begins all VT sequences 14 #define AICLI_VT_ESCAPE "\x1b" 15 16 namespace AppInstaller::CLI::VirtualTerminal 17 { 18 // RAII class to enable VT support and restore the console mode. 19 struct ConsoleModeRestoreBase 20 { 21 ConsoleModeRestoreBase(DWORD handle); 22 ~ConsoleModeRestoreBase(); 23 24 ConsoleModeRestoreBase(const ConsoleModeRestoreBase&) = delete; 25 ConsoleModeRestoreBase& operator=(const ConsoleModeRestoreBase&) = delete; 26 27 ConsoleModeRestoreBase(ConsoleModeRestoreBase&&) = default; 28 ConsoleModeRestoreBase& operator=(ConsoleModeRestoreBase&&) = default; 29 30 // Returns true if VT support has been enabled for the console. 31 bool IsVTEnabled() const { return m_token; } 32 33 protected: 34 DestructionToken m_token = false; 35 DWORD m_handle = 0; 36 DWORD m_previousMode = 0; 37 }; 38 39 // RAII class to enable VT output support and restore the console mode. 40 struct ConsoleModeRestore : public ConsoleModeRestoreBase 41 { 42 ConsoleModeRestore(const ConsoleModeRestore&) = delete; 43 ConsoleModeRestore& operator=(const ConsoleModeRestore&) = delete; 44 45 ConsoleModeRestore(ConsoleModeRestore&&) = default; 46 ConsoleModeRestore& operator=(ConsoleModeRestore&&) = default; 47 48 // Gets the singleton. 49 static const ConsoleModeRestore& Instance(); 50 51 private: 52 ConsoleModeRestore(); 53 }; 54 55 // RAII class to enable VT input support and restore the console mode. 56 struct ConsoleInputModeRestore : public ConsoleModeRestoreBase 57 { 58 ConsoleInputModeRestore(); 59 60 ConsoleInputModeRestore(const ConsoleInputModeRestore&) = delete; 61 ConsoleInputModeRestore& operator=(const ConsoleInputModeRestore&) = delete; 62 63 ConsoleInputModeRestore(ConsoleInputModeRestore&&) = default; 64 ConsoleInputModeRestore& operator=(ConsoleInputModeRestore&&) = default; 65 }; 66 67 // The base for all VT sequences. 68 struct Sequence 69 { 70 constexpr Sequence() = default; 71 explicit constexpr Sequence(std::string_view c) : m_chars(c) {} 72 73 std::string_view Get() const { return m_chars; } 74 75 protected: 76 void Set(const std::string& s) { m_chars = s; } 77 78 private: 79 std::string_view m_chars; 80 }; 81 82 // A VT sequence that is constructed at runtime. 83 struct ConstructedSequence : public Sequence 84 { 85 ConstructedSequence() { Set(m_str); } 86 explicit ConstructedSequence(std::string s) : m_str(std::move(s)) { Set(m_str); } 87 88 ConstructedSequence(const ConstructedSequence& other) : m_str(other.m_str) { Set(m_str); } 89 ConstructedSequence& operator=(const ConstructedSequence& other) { m_str = other.m_str; Set(m_str); return *this; } 90 91 ConstructedSequence(ConstructedSequence&& other) noexcept : m_str(std::move(other.m_str)) { Set(m_str); } 92 ConstructedSequence& operator=(ConstructedSequence&& other) noexcept { m_str = std::move(other.m_str); Set(m_str); return *this; } 93 94 void Append(const Sequence& sequence); 95 96 void Clear(); 97 98 private: 99 std::string m_str; 100 }; 101 102 // Below are mapped to the sequences described here: 103 // https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences 104 105 // Contains the response to a DA1 (Primary Device Attributes) request. 106 struct PrimaryDeviceAttributes 107 { 108 // Queries the device attributes on creation. 109 PrimaryDeviceAttributes(std::ostream& outStream, std::istream& inStream); 110 111 // The extensions that a device may support. 112 enum class Extension 113 { 114 Columns132 = 1, 115 PrinterPort = 2, 116 Sixel = 4, 117 SelectiveErase = 6, 118 SoftCharacterSet = 7, 119 UserDefinedKeys = 8, 120 NationalReplacementCharacterSets = 9, 121 SoftCharacterSet2 = 12, 122 EightBitInterface = 14, 123 TechnicalCharacterSet = 15, 124 WindowingCapability = 18, 125 HorizontalScrolling = 21, 126 ColorText = 22, 127 Greek = 23, 128 Turkish = 24, 129 RectangularAreaOperations = 28, 130 TextMacros = 32, 131 ISO_Latin2CharacterSet = 42, 132 PC_Term = 44, 133 SoftKeyMap = 45, 134 ASCII_Emulation = 46, 135 }; 136 137 // Determines if the given extension is supported. 138 bool Supports(Extension extension) const; 139 140 private: 141 uint32_t m_conformanceLevel = 0; 142 uint64_t m_extensions = 0; 143 }; 144 145 namespace Cursor 146 { 147 namespace Position 148 { 149 ConstructedSequence Up(int16_t cells); 150 ConstructedSequence Down(int16_t cells); 151 ConstructedSequence Forward(int16_t cells); 152 ConstructedSequence Backward(int16_t cells); 153 } 154 155 namespace Visibility 156 { 157 extern const Sequence EnableBlink; 158 extern const Sequence DisableBlink; 159 extern const Sequence EnableShow; 160 extern const Sequence DisableShow; 161 } 162 } 163 164 namespace TextFormat 165 { 166 // Returns all attributes to the default state prior to modification 167 extern const Sequence Default; 168 169 // Swaps foreground and background colors 170 extern const Sequence Negative; 171 172 // A color, used in constructed sequences. 173 struct Color 174 { 175 uint8_t R; 176 uint8_t G; 177 uint8_t B; 178 179 static Color GetAccentColor(); 180 }; 181 182 namespace Foreground 183 { 184 // Applies brightness/intensity flag to foreground color 185 extern const Sequence Bright; 186 // Removes brightness/intensity flag from foreground color 187 extern const Sequence NoBright; 188 189 extern const Sequence BrightRed; 190 extern const Sequence BrightGreen; 191 extern const Sequence BrightYellow; 192 extern const Sequence BrightBlue; 193 extern const Sequence BrightMagenta; 194 extern const Sequence BrightCyan; 195 extern const Sequence BrightWhite; 196 197 ConstructedSequence Extended(const Color& color); 198 } 199 200 namespace Background 201 { 202 ConstructedSequence Extended(const Color& color); 203 } 204 205 ConstructedSequence Hyperlink(const std::string& text, const std::string& ref); 206 } 207 208 namespace TextModification 209 { 210 extern const Sequence EraseLineForward; 211 extern const Sequence EraseLineBackward; 212 extern const Sequence EraseLineEntirely; 213 } 214 215 namespace Progress 216 { 217 enum class State 218 { 219 None, 220 Indeterminate, 221 Normal, 222 Paused, 223 Error 224 }; 225 226 ConstructedSequence Construct(State state, std::optional<uint32_t> percentage = std::nullopt); 227 } 228 } 229 230 inline std::ostream& operator<<(std::ostream& o, const AppInstaller::CLI::VirtualTerminal::Sequence& s) 231 { 232 return (o << s.Get()); 233 }