Skip to content

Commit

Permalink
Adding:
Browse files Browse the repository at this point in the history
Intellisense - I've only added TextBlock but we can easily add any of the XAML elements
Error highlighting works - Only issue is that the XAML parser doesn't seem to be that accurate with where the errors actually are, so perhaps a bit of refinement to be done but at least the user sees the marking in the right spot
  • Loading branch information
nickrandolph committed Jul 8, 2020
1 parent a651565 commit debc30c
Showing 1 changed file with 114 additions and 15 deletions.
129 changes: 114 additions & 15 deletions src/Uno.Playground.Shared/Samples/Playground.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
using Uno.Logging;
using Uno.UI.Demo.Behaviors;
using Uno.UI.Toolkit;
using Monaco.Languages;
using Monaco.Editor;
using Monaco;
using System.Threading;

namespace Uno.UI.Demo.Samples
{
Expand Down Expand Up @@ -63,6 +67,7 @@ public Playground()

xamlText.PropertyChanged += OnPropertyChanged;
xamlText.Loaded += OnEditorLoaded;
xamlText.Loading += OnEditorLoading;

jsonDataContext.TextChanged += OnDataContextTextChanged;

Expand All @@ -84,6 +89,7 @@ public Playground()


}

private void OnInputPaneShowing(InputPane sender, InputPaneVisibilityEventArgs args)
{
VisibleBoundsPadding.SetPaddingMask(TabsPane, VisibleBoundsPadding.PaddingMask.Top);
Expand Down Expand Up @@ -263,6 +269,11 @@ private void OnExpandoChanged(object sender, PropertyChangedEventArgs e)
jsonDataContext.Text = data;
}

private async void OnEditorLoading(object sender, RoutedEventArgs e)
{
await xamlText.Languages.RegisterCompletionItemProviderAsync("xml", new XamlLanguageProvider());
}

private async void OnEditorLoaded(object sender, RoutedEventArgs e)
{
xamlText.CodeLanguage = "xml";
Expand Down Expand Up @@ -390,17 +401,19 @@ private async Task Update()
}
}

/// When parsing XAML we need to prepend a Grid element (see GetXamlInput) which adds lines to the start
/// of the XAML, causing any errors to be off by that many lines
private int GetXamlPrefixLineCount => 4;
private string GetXamlInput()
{
Console.WriteLine("Current text: " + xamlText.Text);
return string.Concat(
@"<Grid
xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:x= ""http://schemas.microsoft.com/winfx/2006/xaml""
xmlns:behaviors=""using:Uno.UI.Demo.Behaviors"">",
xamlText.Text,
"\n</Grid>"
);
return
$@"<Grid
xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:x= ""http://schemas.microsoft.com/winfx/2006/xaml""
xmlns:behaviors=""using:Uno.UI.Demo.Behaviors"">
{xamlText.Text}
</Grid>";
}

private static readonly string _appName =
Expand Down Expand Up @@ -442,7 +455,7 @@ private async void ShowHint()

private void SetLink(string id, bool clipboard = false)
{
var url = new Uri($"{PlaygroundUrl}#{Uri.EscapeUriString(id)}");
var url = new System.Uri($"{PlaygroundUrl}#{System.Uri.EscapeUriString(id)}");
if (clipboard)
{
var clipboardData = new DataPackage();
Expand Down Expand Up @@ -480,7 +493,7 @@ private async Task LoadSample(string id)
xamlText.Text = "<!-- loading... -->";
jsonDataContext.Text = "/* loading... */";

var response = await httpClient.GetAsync($"{BaseApiUrl}/{Uri.EscapeUriString(id)}");
var response = await httpClient.GetAsync($"{BaseApiUrl}/{System.Uri.EscapeUriString(id)}");
var responsePayload = await response.Content.ReadAsStringAsync();
var json = JObject.Parse(responsePayload);

Expand Down Expand Up @@ -561,21 +574,49 @@ private void Update_OnTapped(object sender, RoutedEventArgs e)
LaunchUpdate();
}

private void ClearError()
private async void ClearError()
{
_currentError = null;
errorBorder.Visibility = Visibility.Collapsed;
errorText.Text = "No error";
if (errorBorder.Visibility == Visibility.Visible)
{
errorBorder.Visibility = Visibility.Collapsed;
errorText.Text = "No error";
//xamlText.Markers.Clear();
await xamlText.SetModelMarkersAsync("CodeEditor", Array.Empty<IMarkerData>());
}
}

private void ShowError(Exception error)
private async void ShowError(Exception error)
{
_currentError = error;
if (error != null && !_isLoadingSample)
{
errorText.Text = error.Message;
if(errorBorder.Visibility == Visibility.Visible)
{
// Only clear the errors if the error bubble is already showing, in which
// case we need to update the errors
await xamlText.SetModelMarkersAsync("CodeEditor", Array.Empty<IMarkerData>());
}
errorBorder.Visibility = Visibility.Visible;

if (error is System.Xml.XmlException xamlError)
{
xamlText.Markers.Add(
new MarkerData()
{
Code = "0000",
Message = error.Message,
Severity = MarkerSeverity.Error,
Source = "Origin",
StartLineNumber = (uint)(xamlError.LineNumber- GetXamlPrefixLineCount),
StartColumn = (uint)xamlError.LinePosition,
EndLineNumber = (uint)(xamlError.LineNumber- GetXamlPrefixLineCount),
EndColumn = (uint)xamlError.LinePosition+5
});
}
}

}

private void CopyError(object sender, RoutedEventArgs e)
Expand Down Expand Up @@ -676,7 +717,7 @@ private void RestoreCodePaneSize(Size oldSize, Size newSize)

private async void LogoClicked(object sender, RoutedEventArgs e)
{
await Launcher.LaunchUriAsync(new Uri("http://platform.uno/"));
await Launcher.LaunchUriAsync(new System.Uri("http://platform.uno/"));
}

private void ShowXaml(object sender, RoutedEventArgs e) => SelectTab("XAML");
Expand Down Expand Up @@ -753,4 +794,62 @@ private void SelectTab(string pane)
}
}
}


public class XamlLanguageProvider : CompletionItemProvider
{
public string[] TriggerCharacters => new string[] { "<" };

public IAsyncOperation<CompletionList> ProvideCompletionItemsAsync(IModel document, Position position, CompletionContext context)
{
return AsyncInfo.Run(async delegate (CancellationToken cancelationToken)
{
var textUntilPosition = await document.GetValueInRangeAsync(new Range(1, 1, position.LineNumber, position.Column));

if (textUntilPosition.EndsWith("boo"))
{
return new CompletionList()
{
Suggestions = new[]
{
new CompletionItem("booyah", "booyah", CompletionItemKind.Folder),
new CompletionItem("booboo", "booboo", CompletionItemKind.File),
}
};
}
else if (context.TriggerKind == CompletionTriggerKind.TriggerCharacter)
{
return new CompletionList()
{
Suggestions = new[]
{
new CompletionItem("TextBlock", "TextBlock>\n\t$0\n</TextBlock", CompletionItemKind.Snippet)
{
InsertTextRules = CompletionItemInsertTextRule.InsertAsSnippet
},
}
};
}

return new CompletionList()
{
Suggestions = new[]
{
new CompletionItem("foreach", "foreach (var ${2:element} in ${1:array}) {\n\t$0\n}", CompletionItemKind.Snippet)
{
InsertTextRules = CompletionItemInsertTextRule.InsertAsSnippet
}
}
};
});
}

public IAsyncOperation<CompletionItem> ResolveCompletionItemAsync(IModel model, Position position, CompletionItem item)
{
return AsyncInfo.Run(delegate (CancellationToken cancelationToken)
{
return Task.FromResult(item); // throw new NotImplementedException();
});
}
}
}

0 comments on commit debc30c

Please sign in to comment.