From orbit, nuke the Telnet connection and all supporting infra. (#7840)

This is not going to be our plan of record for Universal going forward.

This updates the Universal configuration to 1) match non-universal and 2) switch to local applications
This commit is contained in:
Dustin L. Howett 2020-10-09 11:59:58 -07:00 committed by GitHub
parent f0b8875770
commit d33ca7e8eb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 117 additions and 536 deletions

View file

@ -48,36 +48,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
## telnetpp
**Source**: https://github.com/KazDragon/telnetpp
### License
```
The MIT License (MIT)
Copyright (c) 2015-2017 Matthew Chaplain a.k.a KazDragon
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
## chromium/base/numerics
**Source**: https://github.com/chromium/chromium/tree/master/base/numerics

View file

@ -45,9 +45,6 @@
<ClInclude Include="Commandline.h" />
<ClInclude Include="DebugTapConnection.h" />
<ClInclude Include="ColorHelper.h" />
<ClInclude Include="TelnetGenerator.h">
<Filter>profileGeneration</Filter>
</ClInclude>
<ClInclude Include="TerminalSettings.h">
<Filter>settings</Filter>
</ClInclude>

View file

@ -761,12 +761,6 @@ namespace winrt::TerminalApp::implementation
winrt::guid());
}
else if (hasConnectionType &&
connectionType == TerminalConnection::TelnetConnection::ConnectionType())
{
connection = TerminalConnection::TelnetConnection(settings.Commandline());
}
else
{
std::wstring guidWString = Utils::GuidToString(profileGuid);

View file

@ -3,10 +3,6 @@
#include "pch.h"
// We have to define GSL here, not PCH
// because TelnetConnection has a conflicting GSL implementation.
#include <gsl/gsl>
#include "AzureConnection.h"
#include "AzureClientID.h"
#include <sstream>

View file

@ -3,10 +3,6 @@
#include "pch.h"
// We have to define GSL here, not PCH
// because TelnetConnection has a conflicting GSL implementation.
#include <gsl/gsl>
#include "ConptyConnection.h"
#include <windows.h>

View file

@ -5,10 +5,6 @@
#include "EchoConnection.h"
#include <sstream>
// We have to define GSL here, not PCH
// because TelnetConnection has a conflicting GSL implementation.
#include <gsl/gsl>
#include "EchoConnection.g.cpp"
namespace winrt::Microsoft::Terminal::TerminalConnection::implementation

View file

@ -212,7 +212,4 @@
<comment>The first argument {0...} is the hexadecimal error code. The second argument {1} is the user-specified path to a program.
If this string is broken to multiple lines, it will not be displayed properly.</comment>
</data>
<data name="TelnetInternetOrServerIssue" xml:space="preserve">
<value>Could not connect to telnet server.</value>
</data>
</root>

View file

@ -1,341 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "TelnetConnection.h"
#include <LibraryResources.h>
#include "TelnetConnection.g.cpp"
#include "../../types/inc/Utils.hpp"
using namespace ::Microsoft::Console;
constexpr std::wstring_view telnetScheme = L"telnet";
constexpr std::wstring_view msTelnetLoopbackScheme = L"ms-telnet-loop";
// {311153fb-d3f0-4ac6-b920-038de7cf5289}
static constexpr winrt::guid TelnetConnectionType = { 0x311153fb, 0xd3f0, 0x4ac6, { 0xb9, 0x20, 0x03, 0x8d, 0xe7, 0xcf, 0x52, 0x89 } };
namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
{
winrt::guid TelnetConnection::ConnectionType() noexcept
{
return TelnetConnectionType;
}
TelnetConnection::TelnetConnection(const hstring& uri) :
_reader{ nullptr },
_writer{ nullptr },
_uri{ uri },
_receiveBuffer{}
{
_session.install(_nawsServer);
_nawsServer.activate([](auto&&) {});
}
// Method description:
// - ascribes to the ITerminalConnection interface
// - creates the output thread
void TelnetConnection::Start()
try
{
// Create our own output handling thread
// Each connection needs to make sure to drain the output from its backing host.
_hOutputThread.reset(CreateThread(
nullptr,
0,
[](LPVOID lpParameter) {
auto pInstance = static_cast<TelnetConnection*>(lpParameter);
if (pInstance)
{
return pInstance->_outputThread();
}
return gsl::narrow_cast<DWORD>(ERROR_BAD_ARGUMENTS);
},
this,
0,
nullptr));
THROW_LAST_ERROR_IF_NULL(_hOutputThread);
_transitionToState(ConnectionState::Connecting);
// Set initial window title.
_TerminalOutputHandlers(L"\x1b]0;Telnet\x7");
}
catch (...)
{
LOG_CAUGHT_EXCEPTION();
_transitionToState(ConnectionState::Failed);
}
// Method description:
// - ascribes to the ITerminalConnection interface
// - handles the different possible inputs in the different states
// Arguments:
// the user's input
void TelnetConnection::WriteInput(hstring const& data)
{
if (!_isStateOneOf(ConnectionState::Connected, ConnectionState::Connecting))
{
return;
}
auto str = winrt::to_string(data);
if (str.size() == 1 && str.at(0) == L'\r')
{
str = "\r\n";
}
#pragma warning(suppress : 26490) // Using something that isn't reinterpret_cast to forward stream bytes is more clumsy than just using it.
telnetpp::bytes bytes(reinterpret_cast<const uint8_t*>(str.data()), str.size());
_session.send(bytes, [=](telnetpp::bytes data) {
_socketSend(data);
});
}
// Method description:
// - ascribes to the ITerminalConnection interface
// - resizes the terminal
// Arguments:
// - the new rows/cols values
void TelnetConnection::Resize(uint32_t rows, uint32_t columns)
{
if (_prevResize.has_value() && _prevResize.value().first == rows && _prevResize.value().second == columns)
{
return;
}
_prevResize.emplace(std::pair{ rows, columns });
_nawsServer.set_window_size(gsl::narrow<uint16_t>(columns),
gsl::narrow<uint16_t>(rows),
[=](telnetpp::subnegotiation sub) {
_session.send(sub,
[=](telnetpp::bytes data) {
_socketBufferedSend(data);
});
_socketFlushBuffer();
});
}
// Method description:
// - ascribes to the ITerminalConnection interface
// - closes the socket connection and the output thread
void TelnetConnection::Close()
try
{
if (_transitionToState(ConnectionState::Closing))
{
_socket.Close();
if (_hOutputThread)
{
// Tear down our output thread
WaitForSingleObject(_hOutputThread.get(), INFINITE);
_hOutputThread.reset();
}
_transitionToState(ConnectionState::Closed);
}
}
catch (...)
{
LOG_CAUGHT_EXCEPTION();
_transitionToState(ConnectionState::Failed);
}
// Method description:
// - this is the output thread, where we initiate the connection to the remote host
// and establish a socket connection
// Return value:
// - return status
DWORD TelnetConnection::_outputThread()
try
{
while (true)
{
if (_isStateOneOf(ConnectionState::Failed))
{
_TerminalOutputHandlers(RS_(L"TelnetInternetOrServerIssue") + L"\r\n");
return E_FAIL;
}
else if (_isStateAtOrBeyond(ConnectionState::Closing))
{
return S_FALSE;
}
else if (_isStateOneOf(ConnectionState::Connecting))
{
try
{
const auto uri = Windows::Foundation::Uri(_uri);
const auto host = Windows::Networking::HostName(uri.Host());
bool autoLogin = false;
// If we specified the special ms loopback scheme, then set autologin and proceed below.
if (msTelnetLoopbackScheme == uri.SchemeName())
{
autoLogin = true;
}
// Otherwise, make sure we said telnet://, anything else is not supported here.
else if (telnetScheme != uri.SchemeName())
{
THROW_HR(E_INVALIDARG);
}
_socket.ConnectAsync(host, winrt::to_hstring(uri.Port())).get();
_writer = Windows::Storage::Streams::DataWriter(_socket.OutputStream());
_reader = Windows::Storage::Streams::DataReader(_socket.InputStream());
_reader.InputStreamOptions(Windows::Storage::Streams::InputStreamOptions::Partial); // returns when 1 or more bytes ready.
_transitionToState(ConnectionState::Connected);
if (autoLogin)
{
// Send newline to bypass User Name prompt.
const auto newline = winrt::to_hstring("\r\n");
WriteInput(newline);
// Wait for login.
Sleep(1000);
// Send "cls" enter to clear the thing and just look like a prompt.
const auto clearScreen = winrt::to_hstring("cls\r\n");
WriteInput(clearScreen);
}
}
catch (...)
{
LOG_CAUGHT_EXCEPTION();
_transitionToState(ConnectionState::Failed);
}
}
else if (_isStateOneOf(ConnectionState::Connected))
{
// Read from socket
const auto amountReceived = _socketReceive(_receiveBuffer);
_session.receive(
telnetpp::bytes{ _receiveBuffer.data(), amountReceived },
[=](telnetpp::bytes data,
std::function<void(telnetpp::bytes)> const& send) {
_applicationReceive(data, send);
},
[=](telnetpp::bytes data) {
_socketSend(data);
});
}
}
}
catch (...)
{
// If the exception was thrown while we were already supposed to be closing, fine. We're closed.
// This is because the socket got mad things were being torn down.
if (_isStateAtOrBeyond(ConnectionState::Closing))
{
_transitionToState(ConnectionState::Closed);
return S_OK;
}
else
{
LOG_CAUGHT_EXCEPTION();
_transitionToState(ConnectionState::Failed);
return E_FAIL;
}
}
// Routine Description:
// - Call to buffer up bytes to send to the remote device.
// - You must flush before they'll go out.
// Arguments:
// - data - View of bytes to be sent
// Return Value:
// - <none>
void TelnetConnection::_socketBufferedSend(telnetpp::bytes data)
{
// winrt::array_view should take data/size but it doesn't.
// We contacted the WinRT owners and they said, more or less, that it's not worth fixing
// with std::span on the horizon instead of this. So we're suppressing the warning
// and hoping for a std::span future that will eliminate winrt::array_view<T>
#pragma warning(push)
#pragma warning(disable : 26481)
const uint8_t* first = data.data();
const uint8_t* last = data.data() + data.size();
#pragma warning(pop)
const winrt::array_view<const uint8_t> arrayView(first, last);
_writer.WriteBytes(arrayView);
}
// Routine Description:
// - Flushes any buffered bytes to the underlying socket
// Arguments:
// - <none>
// Return Value:
// - <none>
fire_and_forget TelnetConnection::_socketFlushBuffer()
{
co_await _writer.StoreAsync();
}
// Routine Description:
// - Used to send bytes into the socket to the remote device
// Arguments:
// - data - View of bytes to be sent
// Return Value:
// - <none>
void TelnetConnection::_socketSend(telnetpp::bytes data)
{
_socketBufferedSend(data);
_socketFlushBuffer();
}
// Routine Description:
// - Reads bytes from the socket into the given array.
// Arguments:
// - buffer - The array of bytes to use for storage
// Return Value:
// - The number of bytes actually read (less than or equal to input array size)
size_t TelnetConnection::_socketReceive(gsl::span<telnetpp::byte> buffer)
{
const auto bytesLoaded = _reader.LoadAsync(gsl::narrow<uint32_t>(buffer.size())).get();
// winrt::array_view, despite having a pointer and size constructor
// hides it as protected.
// So we have to get first/last (even though cppcorechecks will be
// mad at us for it) to use a public array_view constructor.
// The WinRT team isn't fixing this because std::span is coming
// soon and that will do it.
#pragma warning(push)
#pragma warning(disable : 26481)
const auto first = buffer.data();
const auto last = first + bytesLoaded;
#pragma warning(pop)
const winrt::array_view<uint8_t> arrayView(first, last);
_reader.ReadBytes(arrayView);
return bytesLoaded;
}
// Routine Description:
// - Called by telnetpp framework when application data is received on the channel
// In contrast, telnet metadata payload is consumed by telnetpp and not forwarded to us.
// Arguments:
// - data - The relevant application-level payload received
// - send - A function where we can send a reply to given data immediately
// in reaction to the received message.
// Return Value:
// - <none>
void TelnetConnection::_applicationReceive(telnetpp::bytes data,
std::function<void(telnetpp::bytes)> const& /*send*/)
{
// Convert telnetpp bytes to standard string_view
#pragma warning(suppress : 26490) // Using something that isn't reinterpret_cast to forward stream bytes is more clumsy than just using it.
const auto stringView = std::string_view{ reinterpret_cast<const char*>(data.data()), gsl::narrow<size_t>(data.size()) };
// Convert to hstring
const auto hstr = winrt::to_hstring(stringView);
// Pass the output to our registered event handlers
_TerminalOutputHandlers(hstr);
}
}

View file

@ -1,74 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "TelnetConnection.g.h"
#include <mutex>
#include <condition_variable>
#pragma warning(push)
#pragma warning(disable : 4100)
#pragma warning(disable : 4251)
#include <telnetpp/core.hpp>
#include <telnetpp/session.hpp>
#include <telnetpp/options/naws/server.hpp>
#pragma warning(pop)
#include "winrt/Windows.Networking.Sockets.h"
#include "winrt/Windows.Storage.Streams.h"
#include "../cascadia/inc/cppwinrt_utils.h"
#include "ConnectionStateHolder.h"
namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
{
struct TelnetConnection : TelnetConnectionT<TelnetConnection>, ConnectionStateHolder<TelnetConnection>
{
static winrt::guid ConnectionType() noexcept;
TelnetConnection(const hstring& uri);
void Start();
void WriteInput(hstring const& data);
void Resize(uint32_t rows, uint32_t columns);
void Close();
WINRT_CALLBACK(TerminalOutput, TerminalOutputHandler);
private:
hstring _uri;
void _applicationReceive(telnetpp::bytes data,
std::function<void(telnetpp::bytes)> const& send);
void _socketBufferedSend(telnetpp::bytes data);
fire_and_forget _socketFlushBuffer();
void _socketSend(telnetpp::bytes data);
size_t _socketReceive(gsl::span<telnetpp::byte> buffer);
telnetpp::session _session;
// NAWS = Negotiation About Window Size
telnetpp::options::naws::server _nawsServer;
Windows::Networking::Sockets::StreamSocket _socket;
Windows::Storage::Streams::DataWriter _writer;
Windows::Storage::Streams::DataReader _reader;
std::optional<std::pair<uint32_t, uint32_t>> _prevResize;
static constexpr size_t _receiveBufferSize = 1024;
std::array<telnetpp::byte, _receiveBufferSize> _receiveBuffer;
wil::unique_handle _hOutputThread;
DWORD _outputThread();
};
}
namespace winrt::Microsoft::Terminal::TerminalConnection::factory_implementation
{
struct TelnetConnection : TelnetConnectionT<TelnetConnection, implementation::TelnetConnection>
{
};
}

View file

@ -1,15 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import "ITerminalConnection.idl";
namespace Microsoft.Terminal.TerminalConnection
{
[default_interface]
runtimeclass TelnetConnection : ITerminalConnection
{
static Guid ConnectionType { get; };
TelnetConnection(String uri);
};
}

View file

@ -28,9 +28,6 @@
<ClInclude Include="EchoConnection.h">
<DependentUpon>EchoConnection.idl</DependentUpon>
</ClInclude>
<ClInclude Include="TelnetConnection.h">
<DependentUpon>TelnetConnection.idl</DependentUpon>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="init.cpp" />
@ -47,16 +44,12 @@
<DependentUpon>ConptyConnection.idl</DependentUpon>
</ClCompile>
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
<ClCompile Include="TelnetConnection.cpp">
<DependentUpon>TelnetConnection.idl</DependentUpon>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Midl Include="ITerminalConnection.idl" />
<Midl Include="ConptyConnection.idl" />
<Midl Include="EchoConnection.idl" />
<Midl Include="AzureConnection.idl" />
<Midl Include="TelnetConnection.idl" />
</ItemGroup>
<ItemGroup>
<PRIResource Include="Resources\en-US\Resources.resw" />
@ -88,14 +81,12 @@
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\packages\vcpkg-cpprestsdk.2.10.14\build\native\vcpkg-cpprestsdk.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\vcpkg-cpprestsdk.2.10.14\build\native\vcpkg-cpprestsdk.targets'))" />
<Error Condition="!Exists('..\..\..\packages\vcpkg-telnetpp.1.0.1\build\native\vcpkg-telnetpp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\vcpkg-telnetpp.1.0.1\build\native\vcpkg-telnetpp.targets'))" />
</Target>
<ItemDefinitionGroup>
<Link>
<AdditionalDependencies>$(OpenConsoleCommonOutDir)\conptylib.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Import Project="..\..\..\packages\vcpkg-telnetpp.1.0.1\build\native\vcpkg-telnetpp.targets" Condition="Exists('..\..\..\packages\vcpkg-telnetpp.1.0.1\build\native\vcpkg-telnetpp.targets')" />
<Import Project="$(SolutionDir)build\rules\CollectWildcardResources.targets" />
</Project>

View file

@ -18,21 +18,18 @@
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
<ClCompile Include="AzureConnection.cpp" />
<ClCompile Include="init.cpp" />
<ClCompile Include="TelnetConnection.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="EchoConnection.h" />
<ClInclude Include="AzureConnection.h" />
<ClInclude Include="AzureClientID.h" />
<ClInclude Include="TelnetConnection.h" />
</ItemGroup>
<ItemGroup>
<Midl Include="ITerminalConnection.idl" />
<Midl Include="EchoConnection.idl" />
<Midl Include="AzureConnection.idl" />
<Midl Include="ConptyConnection.idl" />
<Midl Include="TelnetConnection.idl" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />

View file

@ -2,5 +2,4 @@
<packages>
<package id="Microsoft.Windows.CppWinRT" version="2.0.200316.3" targetFramework="native" />
<package id="vcpkg-cpprestsdk" version="2.10.14" targetFramework="native" />
<package id="vcpkg-telnetpp" version="1.0.1" targetFramework="native" />
</packages>
</packages>

View file

@ -10,8 +10,6 @@
// Needs to be defined or we get redeclaration errors
#define WIN32_LEAN_AND_MEAN
#define BLOCK_GSL
// Manually include til after we include Windows.Foundation to give it winrt superpowers
#define BLOCK_TIL
#include <LibraryIncludes.h>

View file

@ -18,5 +18,4 @@ Author(s):
static constexpr std::wstring_view WslGeneratorNamespace{ L"Windows.Terminal.Wsl" };
static constexpr std::wstring_view AzureGeneratorNamespace{ L"Windows.Terminal.Azure" };
static constexpr std::wstring_view TelnetGeneratorNamespace{ L"Windows.Terminal.Telnet" };
static constexpr std::wstring_view PowershellCoreGeneratorNamespace{ L"Windows.Terminal.PowershellCore" };

View file

@ -1,15 +1,16 @@
// THIS IS AN AUTO-GENERATED FILE! Changes to this file will be ignored.
{
"defaultProfile": "{550ce7b8-d500-50ad-8a1a-c400c3262db3}",
"defaultProfile": "{70bfecf4-bcbb-443b-a8fa-d7ac4f7ad201}",
// Launch Settings
"initialCols": 120,
"initialRows": 30,
"launchMode": "default",
"alwaysOnTop": false,
// Selection
"copyOnSelect": false,
"copyFormatting": false,
"copyFormatting": true,
"wordDelimiters": " /\\()\"'-.,:;<>~!@#$%^&*|+=[]{}~?\u2502",
// Tab UI
@ -17,30 +18,56 @@
"showTabsInTitlebar": true,
"showTerminalTitleInTitlebar": true,
"tabWidthMode": "equal",
"useTabSwitcher": true,
// Miscellaneous
"confirmCloseAllTabs": true,
"startOnUserLogin": false,
"theme": "system",
"snapToGridOnResize": true,
"profiles":
[
{
"guid": "{550ce7b8-d500-50ad-8a1a-c400c3262db3}",
"name": "Telnet Loopback",
"commandline": "ms-telnet-loop://127.0.0.1:23",
"connectionType" : "{311153fb-d3f0-4ac6-b920-038de7cf5289}",
"hidden": false,
"startingDirectory": "%USERPROFILE%",
"guid": "{70bfecf4-bcbb-443b-a8fa-d7ac4f7ad201}",
"name": "PowerShell",
"commandline": "pwsh.exe",
"icon": "ms-appx:///ProfileIcons/pwsh.png",
"colorScheme": "Campbell",
"antialiasingMode": "grayscale",
"closeOnExit": "graceful",
"colorScheme": "Vintage",
"cursorColor": "#FFFFFF",
"cursorShape": "bar",
"fontFace": "Cascadia Mono",
"icon": "ms-appx:///ProfileIcons/{550ce7b8-d500-50ad-8a1a-c400c3262db3}.png",
"fontSize": 12,
"hidden": false,
"historySize": 9001,
"padding": "8, 8, 8, 8",
"snapOnInput": true,
"altGrAliasing": true,
"startingDirectory": "%SystemRoot%",
"useAcrylic": false,
"backgroundImage": "ms-appx:///internal-background.png",
"backgroundImageAlignment": "bottomRight",
"backgroundImageOpacity": 0.4,
"backgroundImageStretchMode": "none"
},
{
"guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
"name": "Command Prompt",
"commandline": "%SystemRoot%\\System32\\cmd.exe",
"icon": "ms-appx:///ProfileIcons/{0caa0dad-35be-5f56-a8ff-afceeeaa6101}.png",
"colorScheme": "Campbell",
"antialiasingMode": "grayscale",
"closeOnExit": "graceful",
"cursorShape": "bar",
"fontFace": "Cascadia Mono",
"fontSize": 12,
"hidden": false,
"historySize": 9001,
"padding": "8, 8, 8, 8",
"snapOnInput": true,
"altGrAliasing": true,
"startingDirectory": "%SystemRoot%",
"useAcrylic": false,
"backgroundImage": "ms-appx:///internal-background.png",
"backgroundImageAlignment": "bottomRight",
@ -51,25 +78,26 @@
"schemes":
[
{
"name": "Vintage",
"foreground": "#C0C0C0",
"background": "#000000",
"black": "#000000",
"red": "#800000",
"green": "#008000",
"yellow": "#808000",
"blue": "#000080",
"purple": "#800080",
"cyan": "#008080",
"white": "#C0C0C0",
"brightBlack": "#808080",
"brightRed": "#FF0000",
"brightGreen": "#00FF00",
"brightYellow": "#FFFF00",
"brightBlue": "#0000FF",
"brightPurple": "#FF00FF",
"brightCyan": "#00FFFF",
"brightWhite": "#FFFFFF"
"name": "Campbell",
"foreground": "#CCCCCC",
"background": "#0C0C0C",
"cursorColor": "#FFFFFF",
"black": "#0C0C0C",
"red": "#C50F1F",
"green": "#13A10E",
"yellow": "#C19C00",
"blue": "#0037DA",
"purple": "#881798",
"cyan": "#3A96DD",
"white": "#CCCCCC",
"brightBlack": "#767676",
"brightRed": "#E74856",
"brightGreen": "#16C60C",
"brightYellow": "#F9F1A5",
"brightBlue": "#3B78FF",
"brightPurple": "#B4009E",
"brightCyan": "#61D6D6",
"brightWhite": "#F2F2F2"
}
],
"actions":
@ -78,14 +106,21 @@
{ "command": "closeWindow", "keys": "alt+f4" },
{ "command": "toggleFullscreen", "keys": "alt+enter" },
{ "command": "toggleFullscreen", "keys": "f11" },
{ "command": "toggleFocusMode" },
{ "command": "toggleAlwaysOnTop" },
{ "command": "openNewTabDropdown", "keys": "ctrl+shift+space" },
{ "command": "openSettings", "keys": "ctrl+," },
{ "command": { "action": "openSettings", "target": "defaultsFile" }, "keys": "ctrl+alt+," },
{ "command": "find", "keys": "ctrl+shift+f" },
{ "command": "toggleRetroEffect" },
{ "command": "openTabColorPicker" },
{ "command": "commandPalette", "keys":"ctrl+shift+p" },
// Tab Management
// "command": "closeTab" is unbound by default.
// The closeTab command closes a tab without confirmation, even if it has multiple panes.
{ "command": "closeOtherTabs" },
{ "command": "closeTabsAfter" },
{ "command": "newTab", "keys": "ctrl+shift+t" },
{ "command": { "action": "newTab", "index": 0 }, "keys": "ctrl+shift+1" },
{ "command": { "action": "newTab", "index": 1 }, "keys": "ctrl+shift+2" },
@ -121,6 +156,7 @@
{ "command": { "action": "moveFocus", "direction": "left" }, "keys": "alt+left" },
{ "command": { "action": "moveFocus", "direction": "right" }, "keys": "alt+right" },
{ "command": { "action": "moveFocus", "direction": "up" }, "keys": "alt+up" },
{ "command": "togglePaneZoom" },
// Clipboard Integration
{ "command": { "action": "copy", "singleLine": false }, "keys": "ctrl+shift+c" },
@ -137,6 +173,53 @@
// Visual Adjustments
{ "command": { "action": "adjustFontSize", "delta": 1 }, "keys": "ctrl+=" },
{ "command": { "action": "adjustFontSize", "delta": -1 }, "keys": "ctrl+-" },
{ "command": "resetFontSize", "keys": "ctrl+0" }
{ "command": "resetFontSize", "keys": "ctrl+0" },
// Other commands
{
// Select color scheme...
"name": { "key": "SetColorSchemeParentCommandName" },
"commands": [
{
"iterateOn": "schemes",
"name": "${scheme.name}",
"command": { "action": "setColorScheme", "colorScheme": "${scheme.name}" }
}
]
},
{
// New tab...
"name": { "key": "NewTabParentCommandName" },
"commands": [
{
"iterateOn": "profiles",
"icon": "${profile.icon}",
"name": "${profile.name}",
"command": { "action": "newTab", "profile": "${profile.name}" }
}
]
},
{
// Split pane...
"name": { "key": "SplitPaneParentCommandName" },
"commands": [
{
"iterateOn": "profiles",
"icon": "${profile.icon}",
"name": "${profile.name}...",
"commands": [
{
"command": { "action": "splitPane", "profile": "${profile.name}", "split": "auto" }
},
{
"command": { "action": "splitPane", "profile": "${profile.name}", "split": "vertical" }
},
{
"command": { "action": "splitPane", "profile": "${profile.name}", "split": "horizontal" }
}
]
}
]
}
]
}

View file

@ -61,11 +61,9 @@
// GSL
// Block GSL Multi Span include because it both has C++17 deprecated iterators
// and uses the C-namespaced "max" which conflicts with Windows definitions.
#ifndef BLOCK_GSL
#define GSL_MULTI_SPAN_H
#include <gsl/gsl>
#include <gsl/span_ext>
#endif
// CppCoreCheck
#include <CppCoreCheck/Warnings.h>

View file

@ -405,7 +405,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
const auto bitShift = delta_y * _sz.width();
#pragma warning(push)
// we can't depend on GSL here (some libraries use BLOCK_GSL), so we use static_cast for explicit narrowing
// we can't depend on GSL here, so we use static_cast for explicit narrowing
#pragma warning(disable : 26472)
const auto newBits = static_cast<size_t>(std::abs(bitShift));
#pragma warning(pop)

View file

@ -8,7 +8,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
// color is a universal integral 8bpp RGBA (0-255) color type implicitly convertible to/from
// a number of other color types.
#pragma warning(push)
// we can't depend on GSL here (some libraries use BLOCK_GSL), so we use static_cast for explicit narrowing
// we can't depend on GSL here, so we use static_cast for explicit narrowing
#pragma warning(disable : 26472)
struct color
{