When patching profiles in, copy the user's indentation (#4555)

This will attempt to match the style of the user's JSON.

Caveats:
1. If the user has no profiles, it'll explode. This isn't new.
2. If the user's indentation style if `{profile}, {profile}, {profile}` (that is: no indentation), you'll get this:

```
{profile}, {profile}, {profile},
 {
     new profile content
 }
```

There may be something better we can do by copying their newline (or lack thereof) and using it in our generator or detecting the indentation of their members as well.
That's an exercise for later.

Ref #2805
This commit is contained in:
Dustin L. Howett (MSFT) 2020-02-12 16:09:49 -08:00 committed by GitHub
parent 04955a4395
commit 19ee4277c9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -39,7 +39,6 @@ static constexpr std::string_view SchemesKey{ "schemes" };
static constexpr std::string_view DisabledProfileSourcesKey{ "disabledProfileSources" };
static constexpr std::string_view Utf8Bom{ u8"\uFEFF" };
static constexpr std::string_view DefaultProfilesIndentation{ " " };
static constexpr std::string_view SettingsSchemaFragment{ "\n"
R"( "$schema": "https://aka.ms/terminal-profiles-schema")" };
@ -414,6 +413,11 @@ bool CascadiaSettings::_AppendDynamicProfilesToUserSettings()
const auto numProfiles = userProfilesObj.size();
const auto lastProfile = userProfilesObj[numProfiles - 1];
size_t currentInsertIndex = lastProfile.getOffsetLimit();
// Find the position of the first non-tab/space character before the last profile...
const auto lastProfileIndentStartsAt{ _userSettingsString.find_last_not_of(" \t", lastProfile.getOffsetStart() - 1) };
// ... and impute the user's preferred indentation.
// (we're taking a copy because a string_view into a string we mutate is a no-no.)
const std::string indentation{ _userSettingsString, lastProfileIndentStartsAt + 1, lastProfile.getOffsetStart() - lastProfileIndentStartsAt - 1 };
bool changedFile = false;
@ -444,17 +448,17 @@ bool CascadiaSettings::_AppendDynamicProfilesToUserSettings()
const auto diff = profile.GenerateStub();
auto profileSerialization = Json::writeString(wbuilder, diff);
// Add 8 spaces to the start of each line
profileSerialization.insert(0, DefaultProfilesIndentation);
// Add the user's indent to the start of each line
profileSerialization.insert(0, indentation);
// Get the first newline
size_t pos = profileSerialization.find("\n");
// for each newline...
while (pos != std::string::npos)
{
// Insert 8 spaces immediately following the current newline
profileSerialization.insert(pos + 1, DefaultProfilesIndentation);
profileSerialization.insert(pos + 1, indentation);
// Get the next newline
pos = profileSerialization.find("\n", pos + 9);
pos = profileSerialization.find("\n", pos + indentation.size() + 1);
}
// Write a comma, newline to the file