mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 10:46:33 +02:00
Hosts: add “No leading spaces” option and honor it when saving (#41206)
## Summary of the Pull Request Adds a new Hosts File Editor setting “No leading spaces” that prevents prepending spaces to active lines when saving the hosts file (when any entry is disabled). Default is Off to preserve current behavior. ## PR Checklist - [x] Closes: #36386 - [ ] Communication: N/A (small, scoped option) - [x] Tests: Added/updated and all pass - [x] Localization: New en-US strings added; other locales handled by loc pipeline - [ ] Dev docs: N/A - [x] New binaries: None - [x] Documentation updated: N/A ## Detailed Description of the Pull Request / Additional comments - Settings surface: - `src/settings-ui/Settings.UI.Library/HostsProperties.cs`: add `NoLeadingSpaces` - `src/modules/Hosts/HostsUILib/Settings/IUserSettings.cs`: add `NoLeadingSpaces` - `src/modules/Hosts/Hosts/Settings/UserSettings.cs`: load/save value from settings.json - `src/settings-ui/Settings.UI/ViewModels/HostsViewModel.cs`: expose `NoLeadingSpaces` - `src/settings-ui/Settings.UI/SettingsXAML/Views/HostsPage.xaml`: new SettingsCard toggle - `src/settings-ui/Settings.UI/Strings/en-us/Resources.resw`: add `Hosts_NoLeadingSpaces.Header/Description` - Writer change: - `src/modules/Hosts/HostsUILib/Helpers/HostsService.cs`: gate indent with `anyDisabled && !_userSettings.NoLeadingSpaces` - Tests: - `src/modules/Hosts/Hosts.Tests/HostsServiceTest.cs`: `NoLeadingSpaces_Disabled_RemovesIndent` Backward compatibility: default Off, current formatting unchanged unless the user enables the option. ## Validation Steps Performed - Automated: `HostsEditor.UnitTests` including `NoLeadingSpaces_Disabled_RemovesIndent` passing. - Manual: 1. Run PowerToys (runner) as Admin. 2. Settings → Hosts File Editor → enable “No leading spaces”. 3. In editor, add active `127.0.0.10 example1` and disabled `127.0.0.11 example2`; Save. 4. Open `C:\Windows\System32\drivers\etc\hosts` in Notepad. - ON: active line starts at column 0; disabled is `# 127...`. - OFF: active line begins with two spaces when a disabled entry exists.
This commit is contained in:
committed by
GitHub
parent
8737de29af
commit
6130d2ad39
@@ -298,5 +298,34 @@ namespace Hosts.Tests
|
|||||||
var hidden = fileSystem.FileInfo.New(service.HostsFilePath).Attributes.HasFlag(FileAttributes.Hidden);
|
var hidden = fileSystem.FileInfo.New(service.HostsFilePath).Attributes.HasFlag(FileAttributes.Hidden);
|
||||||
Assert.IsTrue(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<IUserSettings>();
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ namespace Hosts.Settings
|
|||||||
|
|
||||||
private bool _loopbackDuplicates;
|
private bool _loopbackDuplicates;
|
||||||
|
|
||||||
|
public bool NoLeadingSpaces { get; private set; }
|
||||||
|
|
||||||
public bool LoopbackDuplicates
|
public bool LoopbackDuplicates
|
||||||
{
|
{
|
||||||
get => _loopbackDuplicates;
|
get => _loopbackDuplicates;
|
||||||
@@ -88,6 +90,7 @@ namespace Hosts.Settings
|
|||||||
AdditionalLinesPosition = (HostsAdditionalLinesPosition)settings.Properties.AdditionalLinesPosition;
|
AdditionalLinesPosition = (HostsAdditionalLinesPosition)settings.Properties.AdditionalLinesPosition;
|
||||||
Encoding = (HostsEncoding)settings.Properties.Encoding;
|
Encoding = (HostsEncoding)settings.Properties.Encoding;
|
||||||
LoopbackDuplicates = settings.Properties.LoopbackDuplicates;
|
LoopbackDuplicates = settings.Properties.LoopbackDuplicates;
|
||||||
|
NoLeadingSpaces = settings.Properties.NoLeadingSpaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
retry = false;
|
retry = false;
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ namespace HostsUILib.Helpers
|
|||||||
{
|
{
|
||||||
lineBuilder.Append('#').Append(' ');
|
lineBuilder.Append('#').Append(' ');
|
||||||
}
|
}
|
||||||
else if (anyDisabled)
|
else if (anyDisabled && !_userSettings.NoLeadingSpaces)
|
||||||
{
|
{
|
||||||
lineBuilder.Append(' ').Append(' ');
|
lineBuilder.Append(' ').Append(' ');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,5 +19,7 @@ namespace HostsUILib.Settings
|
|||||||
event EventHandler LoopbackDuplicatesChanged;
|
event EventHandler LoopbackDuplicatesChanged;
|
||||||
|
|
||||||
public delegate void OpenSettingsFunction();
|
public delegate void OpenSettingsFunction();
|
||||||
|
|
||||||
|
public bool NoLeadingSpaces { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
|||||||
|
|
||||||
public HostsEncoding Encoding { get; set; }
|
public HostsEncoding Encoding { get; set; }
|
||||||
|
|
||||||
|
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||||
|
public bool NoLeadingSpaces { get; set; }
|
||||||
|
|
||||||
public HostsProperties()
|
public HostsProperties()
|
||||||
{
|
{
|
||||||
ShowStartupWarning = true;
|
ShowStartupWarning = true;
|
||||||
@@ -31,6 +34,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
|||||||
LoopbackDuplicates = false;
|
LoopbackDuplicates = false;
|
||||||
AdditionalLinesPosition = HostsAdditionalLinesPosition.Top;
|
AdditionalLinesPosition = HostsAdditionalLinesPosition.Top;
|
||||||
Encoding = HostsEncoding.Utf8;
|
Encoding = HostsEncoding.Utf8;
|
||||||
|
NoLeadingSpaces = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,9 @@
|
|||||||
<tkcontrols:SettingsCard x:Uid="Hosts_Toggle_LoopbackDuplicates" HeaderIcon="{ui:FontIcon Glyph=}">
|
<tkcontrols:SettingsCard x:Uid="Hosts_Toggle_LoopbackDuplicates" HeaderIcon="{ui:FontIcon Glyph=}">
|
||||||
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind ViewModel.LoopbackDuplicates, Mode=TwoWay}" />
|
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind ViewModel.LoopbackDuplicates, Mode=TwoWay}" />
|
||||||
</tkcontrols:SettingsCard>
|
</tkcontrols:SettingsCard>
|
||||||
|
<tkcontrols:SettingsCard x:Uid="Hosts_NoLeadingSpaces" HeaderIcon="{ui:FontIcon Glyph=}">
|
||||||
|
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind ViewModel.NoLeadingSpaces, Mode=TwoWay}" />
|
||||||
|
</tkcontrols:SettingsCard>
|
||||||
<tkcontrols:SettingsCard x:Uid="Hosts_Encoding">
|
<tkcontrols:SettingsCard x:Uid="Hosts_Encoding">
|
||||||
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind Path=ViewModel.Encoding, Mode=TwoWay}">
|
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind Path=ViewModel.Encoding, Mode=TwoWay}">
|
||||||
<ComboBoxItem x:Uid="Hosts_Encoding_Utf8" />
|
<ComboBoxItem x:Uid="Hosts_Encoding_Utf8" />
|
||||||
|
|||||||
@@ -5127,4 +5127,10 @@ To record a specific window, enter the hotkey with the Alt key in the opposite m
|
|||||||
<data name="KeyBack" xml:space="preserve">
|
<data name="KeyBack" xml:space="preserve">
|
||||||
<value>Back key</value>
|
<value>Back key</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Hosts_NoLeadingSpaces.Header" xml:space="preserve">
|
||||||
|
<value>No leading spaces</value>
|
||||||
|
</data>
|
||||||
|
<data name="Hosts_NoLeadingSpaces.Description" xml:space="preserve">
|
||||||
|
<value>Do not prepend spaces to active lines when saving the hosts file</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -105,6 +105,19 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool NoLeadingSpaces
|
||||||
|
{
|
||||||
|
get => Settings.Properties.NoLeadingSpaces;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != Settings.Properties.NoLeadingSpaces)
|
||||||
|
{
|
||||||
|
Settings.Properties.NoLeadingSpaces = value;
|
||||||
|
NotifyPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public int AdditionalLinesPosition
|
public int AdditionalLinesPosition
|
||||||
{
|
{
|
||||||
get => (int)Settings.Properties.AdditionalLinesPosition;
|
get => (int)Settings.Properties.AdditionalLinesPosition;
|
||||||
|
|||||||
Reference in New Issue
Block a user