terminal/src/cascadia/TerminalSettingsModel/FileUtils.h

42 lines
1.4 KiB
C
Raw Normal View History

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
Persist window layout cont. save multiple windows (#11083) <!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request Continuation of https://github.com/microsoft/terminal/pull/10972 to handle multiple windows, requires that to be merged first. <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Also closes #766 * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [ ] Tests added/passed * [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx * [x] Schema updated. * [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx <!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments Rough changelog: Normally saving is triggered to occur every 30s, or sooner if a window is created/closed. The existing behavior of saving on last close is maintained to bypass that throttling. The automatic saving allows for crash recovery. Additionally all window layouts will be saved upon taking the `quit` action. For loading we will check if we are the first window, that there are any saved layouts, and if the setting is enabled, and then depending on if we were given command line args or startup actions. - create a new window for each saved layout, or - take the first layout for our self and then a new window for each other layout. This also saves the layout when the quit action is taken. Misc changes - A -s,--saved argument was added to the command line to facilitate opening all of the windows with the right settings. This also means that while a terminal session is running you can do wt -s idx to open a copy of window idx. There isn't a stable ordering of which idx each window gets saved as (it is whatever the iteration order of _peasants is), so it is just a cute hack for now. - All position calculation has been moved up to AppHost this does mean we need to awkwardly pass around positions in a couple of unexpected places, but no solution was perfect. - Renamed "Open tabs from a previous session" to "Open windows from a previous session". (not reflected in video below) - Now save runtime tab color and window names - Only enabled for non-elevated windows - Add some change tracking to ApplicationState <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed ![output](https://user-images.githubusercontent.com/6185249/131163473-d649d204-a589-41ad-b9d9-c4c0528cb684.gif)
2021-09-27 23:18:39 +02:00
#pragma once
Reduce usage of Json::Value throughout Terminal.Settings.Model (#11184) This commit reduces the code surface that interacts with raw JSON data, reducing code complexity and improving maintainability. Files that needed to be changed drastically were additionally cleaned up to remove any code cruft that has accrued over time. In order to facility this the following changes were made: * Move JSON handling from `CascadiaSettings` into `SettingsLoader` This allows us to use STL containers for data model instances. For instance profiles are now added to a hashmap for O(1) lookup. * JSON parsing within `SettingsLoader` doesn't differentiate between user, inbox and fragment JSON data, reducing code complexity and size. It also centralizes common concerns, like profile deduplication and ensuring that all profiles are assigned a GUID. * Direct JSON modification, like the insertion of dynamic profiles into settings.json were removed. This vastly reduces code complexity, but unfortunately removes support for comments in JSON on first start. * `ColorScheme`s cannot be layered. As such its `LayerJson` API was replaced with `FromJson`, allowing us to remove JSON-based color scheme validation. * `Profile`s used to test their wish to layer using `ShouldBeLayered`, which was replaced with a GUID-based hashmap lookup on previously parsed profiles. Further changes were made as improvements upon the previous changes: * Compact the JSON files embedded binary, saving 28kB * Prevent double-initialization of the color table in `ColorScheme` * Making `til::color` getters `constexpr`, allow better optimizations The result is a reduction of: * 48kB binary size for the Settings.Model.dll * 5-10% startup duration * 26% code for the `CascadiaSettings` class * 1% overall code in this project Furthermore this results in the following breaking changes: * The long deprecated "globals" settings object will not be detected and no warning will be created during load. * The initial creation of a new settings.json will not produce helpful comments. Both cases are caused by the removal of manual JSON handling and the move to representing the settings file with model objects instead ## PR Checklist * [x] Closes #5276 * [x] Closes #7421 * [x] I work here * [x] Tests added/passed ## Validation Steps Performed * Out-of-box-experience is identical to before ✔️ (Except for the settings.json file lacking comments.) * Existing user settings load correctly ✔️ * New WSL instances are added to user settings ✔️ * New fragments are added to user settings ✔️ * All profiles are assigned GUIDs ✔️
2021-09-22 18:27:31 +02:00
namespace winrt::Microsoft::Terminal::Settings::Model
{
Persist window layout cont. save multiple windows (#11083) <!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request Continuation of https://github.com/microsoft/terminal/pull/10972 to handle multiple windows, requires that to be merged first. <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Also closes #766 * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [ ] Tests added/passed * [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx * [x] Schema updated. * [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx <!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments Rough changelog: Normally saving is triggered to occur every 30s, or sooner if a window is created/closed. The existing behavior of saving on last close is maintained to bypass that throttling. The automatic saving allows for crash recovery. Additionally all window layouts will be saved upon taking the `quit` action. For loading we will check if we are the first window, that there are any saved layouts, and if the setting is enabled, and then depending on if we were given command line args or startup actions. - create a new window for each saved layout, or - take the first layout for our self and then a new window for each other layout. This also saves the layout when the quit action is taken. Misc changes - A -s,--saved argument was added to the command line to facilitate opening all of the windows with the right settings. This also means that while a terminal session is running you can do wt -s idx to open a copy of window idx. There isn't a stable ordering of which idx each window gets saved as (it is whatever the iteration order of _peasants is), so it is just a cute hack for now. - All position calculation has been moved up to AppHost this does mean we need to awkwardly pass around positions in a couple of unexpected places, but no solution was perfect. - Renamed "Open tabs from a previous session" to "Open windows from a previous session". (not reflected in video below) - Now save runtime tab color and window names - Only enabled for non-elevated windows - Add some change tracking to ApplicationState <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed ![output](https://user-images.githubusercontent.com/6185249/131163473-d649d204-a589-41ad-b9d9-c4c0528cb684.gif)
2021-09-27 23:18:39 +02:00
// I couldn't find a wil helper for this so I made it myself
class locked_hfile
{
public:
wil::unique_hfile file;
OVERLAPPED lockedRegion;
~locked_hfile()
{
if (file)
{
// Need to unlock the file before it is closed
UnlockFileEx(file.get(), 0, INT_MAX, 0, &lockedRegion);
}
}
HANDLE get() const noexcept
{
return file.get();
}
};
std::filesystem::path GetBaseSettingsPath();
Persist window layout cont. save multiple windows (#11083) <!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request Continuation of https://github.com/microsoft/terminal/pull/10972 to handle multiple windows, requires that to be merged first. <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Also closes #766 * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [ ] Tests added/passed * [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx * [x] Schema updated. * [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx <!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments Rough changelog: Normally saving is triggered to occur every 30s, or sooner if a window is created/closed. The existing behavior of saving on last close is maintained to bypass that throttling. The automatic saving allows for crash recovery. Additionally all window layouts will be saved upon taking the `quit` action. For loading we will check if we are the first window, that there are any saved layouts, and if the setting is enabled, and then depending on if we were given command line args or startup actions. - create a new window for each saved layout, or - take the first layout for our self and then a new window for each other layout. This also saves the layout when the quit action is taken. Misc changes - A -s,--saved argument was added to the command line to facilitate opening all of the windows with the right settings. This also means that while a terminal session is running you can do wt -s idx to open a copy of window idx. There isn't a stable ordering of which idx each window gets saved as (it is whatever the iteration order of _peasants is), so it is just a cute hack for now. - All position calculation has been moved up to AppHost this does mean we need to awkwardly pass around positions in a couple of unexpected places, but no solution was perfect. - Renamed "Open tabs from a previous session" to "Open windows from a previous session". (not reflected in video below) - Now save runtime tab color and window names - Only enabled for non-elevated windows - Add some change tracking to ApplicationState <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed ![output](https://user-images.githubusercontent.com/6185249/131163473-d649d204-a589-41ad-b9d9-c4c0528cb684.gif)
2021-09-27 23:18:39 +02:00
locked_hfile OpenFileReadSharedLocked(const std::filesystem::path& path);
locked_hfile OpenFileRWExclusiveLocked(const std::filesystem::path& path);
std::string ReadUTF8FileLocked(const locked_hfile& file);
void WriteUTF8FileLocked(const locked_hfile& file, const std::string_view& content);
std::string ReadUTF8File(const std::filesystem::path& path);
std::optional<std::string> ReadUTF8FileIfExists(const std::filesystem::path& path);
Reduce usage of Json::Value throughout Terminal.Settings.Model (#11184) This commit reduces the code surface that interacts with raw JSON data, reducing code complexity and improving maintainability. Files that needed to be changed drastically were additionally cleaned up to remove any code cruft that has accrued over time. In order to facility this the following changes were made: * Move JSON handling from `CascadiaSettings` into `SettingsLoader` This allows us to use STL containers for data model instances. For instance profiles are now added to a hashmap for O(1) lookup. * JSON parsing within `SettingsLoader` doesn't differentiate between user, inbox and fragment JSON data, reducing code complexity and size. It also centralizes common concerns, like profile deduplication and ensuring that all profiles are assigned a GUID. * Direct JSON modification, like the insertion of dynamic profiles into settings.json were removed. This vastly reduces code complexity, but unfortunately removes support for comments in JSON on first start. * `ColorScheme`s cannot be layered. As such its `LayerJson` API was replaced with `FromJson`, allowing us to remove JSON-based color scheme validation. * `Profile`s used to test their wish to layer using `ShouldBeLayered`, which was replaced with a GUID-based hashmap lookup on previously parsed profiles. Further changes were made as improvements upon the previous changes: * Compact the JSON files embedded binary, saving 28kB * Prevent double-initialization of the color table in `ColorScheme` * Making `til::color` getters `constexpr`, allow better optimizations The result is a reduction of: * 48kB binary size for the Settings.Model.dll * 5-10% startup duration * 26% code for the `CascadiaSettings` class * 1% overall code in this project Furthermore this results in the following breaking changes: * The long deprecated "globals" settings object will not be detected and no warning will be created during load. * The initial creation of a new settings.json will not produce helpful comments. Both cases are caused by the removal of manual JSON handling and the move to representing the settings file with model objects instead ## PR Checklist * [x] Closes #5276 * [x] Closes #7421 * [x] I work here * [x] Tests added/passed ## Validation Steps Performed * Out-of-box-experience is identical to before ✔️ (Except for the settings.json file lacking comments.) * Existing user settings load correctly ✔️ * New WSL instances are added to user settings ✔️ * New fragments are added to user settings ✔️ * All profiles are assigned GUIDs ✔️
2021-09-22 18:27:31 +02:00
void WriteUTF8File(const std::filesystem::path& path, const std::string_view& content);
void WriteUTF8FileAtomic(const std::filesystem::path& path, const std::string_view& content);
}