diff --git a/src/modules/Hosts/Hosts.Tests/HostsServiceTest.cs b/src/modules/Hosts/Hosts.Tests/HostsServiceTest.cs index 8eaa37a34811..81052fd101c5 100644 --- a/src/modules/Hosts/Hosts.Tests/HostsServiceTest.cs +++ b/src/modules/Hosts/Hosts.Tests/HostsServiceTest.cs @@ -298,5 +298,34 @@ public async Task Save_Hidden_Hosts() var hidden = fileSystem.FileInfo.New(service.HostsFilePath).Attributes.HasFlag(FileAttributes.Hidden); Assert.IsTrue(hidden); } + + [TestMethod] + public async Task NoLeadingSpaces_Disabled_RemovesIndent() + { + var content = + @"10.1.1.1 host host.local # comment +10.1.1.2 host2 host2.local # another comment +"; + + var expected = + @"10.1.1.1 host host.local # comment +10.1.1.2 host2 host2.local # another comment +# 10.1.1.30 host30 host30.local # new entry +"; + + var fs = new CustomMockFileSystem(); + var settings = new Mock(); + settings.Setup(s => s.NoLeadingSpaces).Returns(true); + var svc = new HostsService(fs, settings.Object, _elevationHelper.Object); + fs.AddFile(svc.HostsFilePath, new MockFileData(content)); + + var data = await svc.ReadAsync(); + var entries = data.Entries.ToList(); + entries.Add(new Entry(0, "10.1.1.30", "host30 host30.local", "new entry", false)); + await svc.WriteAsync(data.AdditionalLines, entries); + + var result = fs.GetFile(svc.HostsFilePath); + Assert.AreEqual(expected, result.TextContents); + } } } diff --git a/src/modules/Hosts/Hosts/Settings/UserSettings.cs b/src/modules/Hosts/Hosts/Settings/UserSettings.cs index 3530a3f74b7b..75da5d214de9 100644 --- a/src/modules/Hosts/Hosts/Settings/UserSettings.cs +++ b/src/modules/Hosts/Hosts/Settings/UserSettings.cs @@ -26,6 +26,8 @@ public class UserSettings : IUserSettings private bool _loopbackDuplicates; + public bool NoLeadingSpaces { get; private set; } + public bool LoopbackDuplicates { get => _loopbackDuplicates; @@ -88,6 +90,7 @@ private void LoadSettingsFromJson() AdditionalLinesPosition = (HostsAdditionalLinesPosition)settings.Properties.AdditionalLinesPosition; Encoding = (HostsEncoding)settings.Properties.Encoding; LoopbackDuplicates = settings.Properties.LoopbackDuplicates; + NoLeadingSpaces = settings.Properties.NoLeadingSpaces; } retry = false; diff --git a/src/modules/Hosts/HostsUILib/Helpers/HostsService.cs b/src/modules/Hosts/HostsUILib/Helpers/HostsService.cs index b07eb8f93ccc..83aa3544b1e4 100644 --- a/src/modules/Hosts/HostsUILib/Helpers/HostsService.cs +++ b/src/modules/Hosts/HostsUILib/Helpers/HostsService.cs @@ -157,7 +157,7 @@ public async Task WriteAsync(string additionalLines, IEnumerable entries) { lineBuilder.Append('#').Append(' '); } - else if (anyDisabled) + else if (anyDisabled && !_userSettings.NoLeadingSpaces) { lineBuilder.Append(' ').Append(' '); } diff --git a/src/modules/Hosts/HostsUILib/Settings/IUserSettings.cs b/src/modules/Hosts/HostsUILib/Settings/IUserSettings.cs index 21a8e6fa36d3..46c7a7dab560 100644 --- a/src/modules/Hosts/HostsUILib/Settings/IUserSettings.cs +++ b/src/modules/Hosts/HostsUILib/Settings/IUserSettings.cs @@ -19,5 +19,7 @@ public interface IUserSettings event EventHandler LoopbackDuplicatesChanged; public delegate void OpenSettingsFunction(); + + public bool NoLeadingSpaces { get; } } } diff --git a/src/settings-ui/Settings.UI.Library/HostsProperties.cs b/src/settings-ui/Settings.UI.Library/HostsProperties.cs index 90a576601dd6..6ec992404929 100644 --- a/src/settings-ui/Settings.UI.Library/HostsProperties.cs +++ b/src/settings-ui/Settings.UI.Library/HostsProperties.cs @@ -24,6 +24,9 @@ public class HostsProperties public HostsEncoding Encoding { get; set; } + [JsonConverter(typeof(BoolPropertyJsonConverter))] + public bool NoLeadingSpaces { get; set; } + public HostsProperties() { ShowStartupWarning = true; @@ -31,6 +34,7 @@ public HostsProperties() LoopbackDuplicates = false; AdditionalLinesPosition = HostsAdditionalLinesPosition.Top; Encoding = HostsEncoding.Utf8; + NoLeadingSpaces = false; } } } diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/HostsPage.xaml b/src/settings-ui/Settings.UI/SettingsXAML/Views/HostsPage.xaml index 2d0a6d0c2d0c..6ceffa96d460 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Views/HostsPage.xaml +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/HostsPage.xaml @@ -56,6 +56,9 @@ + + + diff --git a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw index 76f15a390c82..c31076bb8303 100644 --- a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw +++ b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw @@ -5127,4 +5127,10 @@ To record a specific window, enter the hotkey with the Alt key in the opposite m Back key + + No leading spaces + + + Do not prepend spaces to active lines when saving the hosts file + \ No newline at end of file diff --git a/src/settings-ui/Settings.UI/ViewModels/HostsViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/HostsViewModel.cs index d2bfb989e77e..34b6157d63a0 100644 --- a/src/settings-ui/Settings.UI/ViewModels/HostsViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/HostsViewModel.cs @@ -105,6 +105,19 @@ public bool LaunchAdministrator } } + public bool NoLeadingSpaces + { + get => Settings.Properties.NoLeadingSpaces; + set + { + if (value != Settings.Properties.NoLeadingSpaces) + { + Settings.Properties.NoLeadingSpaces = value; + NotifyPropertyChanged(); + } + } + } + public int AdditionalLinesPosition { get => (int)Settings.Properties.AdditionalLinesPosition;