[PreviewPane][Monaco]Format json/xml before rendering (#19980)

This commit is contained in:
Davide Giacometti 2022-08-24 13:08:10 +02:00 коммит произвёл GitHub
Родитель e7d3aadec3
Коммит 16c7a22410
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
10 изменённых файлов: 198 добавлений и 11 удалений

1
.github/actions/spell-check/expect.txt поставляемый
Просмотреть файл

@ -836,6 +836,7 @@ IFilter
ifndef
IFolder
IFormat
IFormatter
ifstream
IGraph
iid

Просмотреть файл

@ -0,0 +1,21 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.PowerToys.PreviewHandler.Monaco.Formatters
{
public interface IFormatter
{
/// <summary>
/// Gets the language to which the formatter is applied
/// </summary>
string LangSet { get; }
/// <summary>
/// Format the value
/// </summary>
/// <param name="value">The value to format</param>
/// <returns>The value formatted</returns>
string Format(string value);
}
}

Просмотреть файл

@ -0,0 +1,28 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.PowerToys.PreviewHandler.Monaco.Formatters
{
using System.Text.Json;
public class JsonFormatter : IFormatter
{
/// <inheritdoc/>
public string LangSet => "json";
/// <inheritdoc/>
public string Format(string value)
{
if (string.IsNullOrWhiteSpace(value))
{
return string.Empty;
}
using (var jDocument = JsonDocument.Parse(value, new JsonDocumentOptions { CommentHandling = JsonCommentHandling.Skip }))
{
return JsonSerializer.Serialize(jDocument, new JsonSerializerOptions { WriteIndented = true });
}
}
}
}

Просмотреть файл

@ -0,0 +1,41 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.PowerToys.PreviewHandler.Monaco.Formatters
{
using System.Text;
using System.Xml;
public class XmlFormatter : IFormatter
{
/// <inheritdoc/>
public string LangSet => "xml";
/// <inheritdoc/>
public string Format(string value)
{
if (string.IsNullOrWhiteSpace(value))
{
return string.Empty;
}
var xmlDocument = new XmlDocument();
xmlDocument.LoadXml(value);
var stringBuilder = new StringBuilder();
var xmlWriterSettings = new XmlWriterSettings()
{
OmitXmlDeclaration = xmlDocument.FirstChild.NodeType != XmlNodeType.XmlDeclaration,
Indent = true,
};
using (var xmlWriter = XmlWriter.Create(stringBuilder, xmlWriterSettings))
{
xmlDocument.Save(xmlWriter);
}
return stringBuilder.ToString();
}
}
}

Просмотреть файл

@ -3,14 +3,16 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Windows.Forms;
using Common;
using Microsoft.PowerToys.PreviewHandler.Monaco.Formatters;
using Microsoft.PowerToys.PreviewHandler.Monaco.Helpers;
using Microsoft.PowerToys.PreviewHandler.Monaco.Properties;
using Microsoft.Web.WebView2.Core;
@ -26,6 +28,15 @@ namespace Microsoft.PowerToys.PreviewHandler.Monaco
/// </summary>
private readonly Settings _settings = new Settings();
/// <summary>
/// Formatters applied before rendering the preview
/// </summary>
private readonly IReadOnlyCollection<IFormatter> _formatters = new List<IFormatter>
{
new JsonFormatter(),
new XmlFormatter(),
}.AsReadOnly();
/// <summary>
/// Saves if the user already navigated to the index page
/// </summary>
@ -367,6 +378,23 @@ namespace Microsoft.PowerToys.PreviewHandler.Monaco
{
Logger.LogInfo("Starting reading requested file");
var fileContent = fileReader.ReadToEnd();
if (_settings.TryFormat)
{
var formatter = _formatters.SingleOrDefault(f => f.LangSet == _vsCodeLangSet);
if (formatter != null)
{
try
{
fileContent = formatter.Format(fileContent);
}
catch (Exception ex)
{
Logger.LogError($"Failed to apply formatting to {filePath}", ex);
}
}
}
fileReader.Close();
_base64FileCode = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(fileContent));
Logger.LogInfo("Reading requested file ended");
@ -379,7 +407,7 @@ namespace Microsoft.PowerToys.PreviewHandler.Monaco
_html = htmlFileReader.ReadToEnd();
htmlFileReader.Close();
Logger.LogInfo("Reading HTML source file ended");
}
}
_html = _html.Replace("[[PT_LANG]]", _vsCodeLangSet, StringComparison.InvariantCulture);
_html = _html.Replace("[[PT_WRAP]]", _settings.Wrap ? "1" : "0", StringComparison.InvariantCulture);

Просмотреть файл

@ -37,6 +37,26 @@ namespace Microsoft.PowerToys.PreviewHandler.Monaco
}
}
/// <summary>
/// Gets a value indicating whether to try formatting the file. Set by PT settings.
/// </summary>
public bool TryFormat
{
get
{
try
{
return moduleSettings.GetSettings<PowerPreviewSettings>(PowerPreviewSettings.ModuleName).Properties.MonacoPreviewTryFormat;
}
catch (FileNotFoundException)
{
// Couldn't read the settings.
// Assume default of false.
return false;
}
}
}
/// <summary>
/// Max file size for displaying (in bytes).
/// </summary>

Просмотреть файл

@ -99,6 +99,23 @@ namespace Microsoft.PowerToys.Settings.UI.Library
}
}
private bool monacoPreviewTryFormat;
[JsonPropertyName("monaco-previewer-toggle-try-format")]
[JsonConverter(typeof(BoolPropertyJsonConverter))]
public bool MonacoPreviewTryFormat
{
get => monacoPreviewTryFormat;
set
{
if (value != monacoPreviewTryFormat)
{
LogTelemetryEvent(value);
monacoPreviewTryFormat = value;
}
}
}
private bool enablePdfPreview;
[JsonPropertyName("pdf-previewer-toggle-setting")]

Просмотреть файл

@ -51,6 +51,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels
_mdRenderIsEnabled = Settings.Properties.EnableMdPreview;
_monacoRenderIsEnabled = Settings.Properties.EnableMonacoPreview;
_monacoWrapText = Settings.Properties.EnableMonacoPreviewWordWrap;
_monacoPreviewTryFormat = Settings.Properties.MonacoPreviewTryFormat;
_pdfRenderIsEnabled = Settings.Properties.EnablePdfPreview;
_gcodeRenderIsEnabled = Settings.Properties.EnableGcodePreview;
_pdfThumbnailIsEnabled = Settings.Properties.EnablePdfThumbnail;
@ -63,6 +64,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels
private bool _mdRenderIsEnabled;
private bool _monacoRenderIsEnabled;
private bool _monacoWrapText;
private bool _monacoPreviewTryFormat;
private bool _pdfRenderIsEnabled;
private bool _gcodeRenderIsEnabled;
private bool _svgThumbnailIsEnabled;
@ -161,6 +163,24 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels
}
}
public bool MonacoPreviewTryFormat
{
get
{
return _monacoPreviewTryFormat;
}
set
{
if (_monacoPreviewTryFormat != value)
{
_monacoPreviewTryFormat = value;
Settings.Properties.MonacoPreviewTryFormat = value;
RaisePropertyChanged();
}
}
}
public bool PDFRenderIsEnabled
{
get

Просмотреть файл

@ -422,21 +422,21 @@
<value>Wait for more input before searching. This reduces interface jumpiness and system load.</value>
</data>
<data name="PowerLauncher_FastSearchInputDelayMs.Header" xml:space="preserve">
<value>Immediate plugins</value>
<value>Immediate plugins</value>
</data>
<data name="PowerLauncher_FastSearchInputDelayMs.Description" xml:space="preserve">
<value>Affects the plugins that make the UI wait for their results by this amount. Recommended: 30-50 ms.</value>
<data name="PowerLauncher_FastSearchInputDelayMs.Description" xml:space="preserve">
<value>Affects the plugins that make the UI wait for their results by this amount. Recommended: 30-50 ms.</value>
</data>
<data name="PowerLauncher_SlowSearchInputDelayMs.Header" xml:space="preserve">
<value>Background execution plugins</value>
<data name="PowerLauncher_SlowSearchInputDelayMs.Header" xml:space="preserve">
<value>Background execution plugins</value>
</data>
<data name="PowerLauncher_SlowSearchInputDelayMs.Description" xml:space="preserve">
<value>Affects the plugins that execute in the background by this amount. Recommended: 100-150 ms.</value>
<data name="PowerLauncher_SlowSearchInputDelayMs.Description" xml:space="preserve">
<value>Affects the plugins that execute in the background by this amount. Recommended: 100-150 ms.</value>
</data>
<data name="PowerLauncher_SearchInputDelayMs.Header" xml:space="preserve">
<data name="PowerLauncher_SearchInputDelayMs.Header" xml:space="preserve">
<value>Fast plugin throttle (ms)</value>
<comment>ms = milliseconds</comment>
</data>
</data>
<data name="KeyboardManager_KeysMappingLayoutRightHeader.Text" xml:space="preserve">
<value>To:</value>
<comment>Keyboard Manager mapping keys view right header</comment>
@ -2164,6 +2164,12 @@ From there, simply click on one of the supported files in the File Explorer and
<data name="AlwaysOnTop_RoundCorners.Content" xml:space="preserve">
<value>Enable round corners</value>
</data>
<data name="FileExplorerPreview_ToggleSwitch_Monaco_Try_Format.Description" xml:space="preserve">
<value>Applies to json and xml. Files remain unchanged.</value>
</data>
<data name="FileExplorerPreview_ToggleSwitch_Monaco_Try_Format.Header" xml:space="preserve">
<value>Try to format the source for preview</value>
</data>
<data name="Run_ConflictingKeywordInfo.Title" xml:space="preserve">
<value>Some characters and phrases may conflict with global queries of other plugins if you use them as activation command.</value>
</data>

Просмотреть файл

@ -57,6 +57,11 @@
IsChecked="{x:Bind ViewModel.MonacoWrapText, Mode=TwoWay}"
Margin="{StaticResource ExpanderSettingMargin}"
IsEnabled="{x:Bind ViewModel.MonacoRenderIsEnabled, Mode=OneWay}" />
<Rectangle Style="{StaticResource ExpanderSeparatorStyle}" />
<controls:CheckBoxWithDescriptionControl x:Uid="FileExplorerPreview_ToggleSwitch_Monaco_Try_Format"
IsChecked="{x:Bind ViewModel.MonacoPreviewTryFormat, Mode=TwoWay}"
Margin="{StaticResource ExpanderSettingMargin}"
IsEnabled="{x:Bind ViewModel.MonacoRenderIsEnabled, Mode=OneWay}"/>
</StackPanel>
</controls:SettingExpander.Content>
</controls:SettingExpander>