private async void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs args)
        {
            _viewModel = (OpenDocumentViewModel)args.NewValue;
            _viewModel.NuGet.PackageInstalled += NuGetOnPackageInstalled;
            _roslynHost = _viewModel.MainViewModel.RoslynHost;

            _viewModel.MainViewModel.EditorFontSizeChanged += OnEditorFontSizeChanged;
            Editor.FontSize = _viewModel.MainViewModel.EditorFontSize;

            var avalonEditTextContainer = new AvalonEditTextContainer(Editor);

            await _viewModel.Initialize(
                avalonEditTextContainer,
                a => _syncContext.Post(o => ProcessDiagnostics(a), null),
                text => avalonEditTextContainer.UpdateText(text),
                this).ConfigureAwait(true);

            var documentText = await _viewModel.LoadText().ConfigureAwait(true);

            Editor.AppendText(documentText);
            Editor.Document.UndoStack.ClearAll();
            Editor.Document.TextChanged += (o, e) => _viewModel.SetDirty(Editor.Document.TextLength);

            Editor.TextArea.TextView.LineTransformers.Insert(0, new RoslynHighlightingColorizer(_viewModel.DocumentId, _roslynHost));

            _contextActionsRenderer = new ContextActionsRenderer(Editor, _textMarkerService);
            _contextActionsRenderer.Providers.Add(new RoslynContextActionProvider(_viewModel.DocumentId, _roslynHost));

            Editor.CompletionProvider = new RoslynCodeEditorCompletionProvider(_viewModel.DocumentId, _roslynHost);
        }
        protected override void Initialize()
        {
            base.Initialize();

            // Duplicate the text so it is more easily accessible from a different thread
            mirroredText = new Rope <char>(Asset.TextAccessor.Get());

            // Text document and container needs to be owned by the UI thread
            TextContainer = Dispatcher.Invoke(() =>
            {
                // Load initial text from asset and create a text document
                var textDocument = new TextDocument(Asset.TextAccessor.Get());
                textDocument.UndoStack.PropertyChanged += UndoStackOnPropertyChanged;

                // Replace the text accessor with one using custom save logic
                Asset.TextAccessor = new ScriptTextAccessor(this);

                textDocument.Changed += TextDocumentOnChanged;

                return(new AvalonEditTextContainer(textDocument));
            });

            // Track document
            TrackDocument();
        }
        public void RegisterEditor(ITextEditor editor)
        {
            _editor = editor;

            if (dataAssociations.TryGetValue(editor, out CSharpDataAssociation association))
            {
                throw new Exception("Source file already registered with language service.");
            }

            association = new CSharpDataAssociation
            {
                Solution = editor.SourceFile.Project.Solution
            };

            dataAssociations.Add(editor, association);

            if (!(editor.SourceFile is MetaDataFile))
            {
                var avaloniaEditTextContainer = new AvalonEditTextContainer(editor.Document)
                {
                    Editor = editor
                };

                RoslynWorkspace.GetWorkspace(association.Solution).OpenDocument(editor.SourceFile, avaloniaEditTextContainer, (diagnostics) =>
                {
                    var dataAssociation = GetAssociatedData(editor);

                    var results = new List <Diagnostic>();

                    var fadedCode = new SyntaxHighlightDataList();

                    foreach (var diagnostic in diagnostics.Diagnostics)
                    {
                        if (diagnostic.CustomTags.Contains("Unnecessary"))
                        {
                            fadedCode.Add(new OffsetSyntaxHighlightingData
                            {
                                Start  = diagnostic.TextSpan.Start,
                                Length = diagnostic.TextSpan.Length,
                                Type   = HighlightType.Unnecessary
                            });
                        }
                        else
                        {
                            results.Add(FromRoslynDiagnostic(diagnostic, editor.SourceFile.Location, editor.SourceFile.Project));
                        }
                    }

                    var errorList = IoC.Get <IErrorList>();
                    errorList.Remove((diagnostics.Id, editor.SourceFile));
                    errorList.Create((diagnostics.Id, editor.SourceFile), editor.SourceFile.FilePath, DiagnosticSourceKind.Analysis, results.ToImmutableArray(), fadedCode);
                });
示例#4
0
        private void CleanupCodeEditor()
        {
            workspace.CloseDocument(DocumentId);

            codeEditor.Unbind();

            sourceTextContainer.TextChanged -= SourceTextContainer_TextChanged;
            sourceTextContainer              = null;

            // Remove working document
            workspace.RemoveDocument(DocumentId);
            DocumentId = null;
        }
        public void OpenDocument(AvalonStudio.Projects.ISourceFile file, AvalonEditTextContainer textContainer, Action <DiagnosticsUpdatedArgs> onDiagnosticsUpdated, Action <SourceText> onTextUpdated = null)
        {
            var documentId = GetDocumentId(file);

            var document = GetDocument(file);

            OnDocumentOpened(documentId, textContainer);
            OnDocumentContextUpdated(documentId);

            _diagnosticsUpdatedNotifiers[documentId] = onDiagnosticsUpdated;
            _openDocumentTextLoaders.Add(documentId, textContainer);

            if (onTextUpdated != null)
            {
                ApplyingTextChange += (d, s) =>
                {
                    if (documentId == d)
                    {
                        onTextUpdated(s);
                    }
                };
            }
        }
        private async void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs args)
        {
            _viewModel = (OpenDocumentViewModel)args.NewValue;
            _viewModel.NuGet.PackageInstalled += NuGetOnPackageInstalled;
            _roslynHost = _viewModel.MainViewModel.RoslynHost;

            var avalonEditTextContainer = new AvalonEditTextContainer(Editor);

            await _viewModel.Initialize(
                avalonEditTextContainer,
                a => _syncContext.Post(o => ProcessDiagnostics(a), null),
                text => avalonEditTextContainer.UpdateText(text)
                ).ConfigureAwait(true);

            Editor.Document.UndoStack.ClearAll();

            Editor.TextArea.TextView.LineTransformers.Insert(0, new RoslynHighlightingColorizer(_viewModel.DocumentId, _roslynHost));

            _contextActionsRenderer = new ContextActionsRenderer(Editor, _textMarkerService);
            _contextActionsRenderer.Providers.Add(new RoslynContextActionProvider(_viewModel.DocumentId, _roslynHost));

            Editor.CompletionProvider = new RoslynCodeEditorCompletionProvider(_viewModel.DocumentId, _roslynHost);
        }
示例#7
0
        private void SetupCodeEditor()
        {
            // Already created?
            if (workspace != null)
            {
                // Anything changed?
                if (workspace == Workspace /* && projectId == ProjectId*/)
                {
                    return;
                }

                CleanupCodeEditor();
            }

            // Check we have everything we need
            if (Workspace == null || codeEditor == null || ProjectId == null)
            {
                return;
            }

            this.workspace = Workspace;

            // Start with initial text
            var textDocument = new TextDocument(Text);

            sourceTextContainer              = new AvalonEditTextContainer(textDocument);
            sourceTextContainer.TextChanged += SourceTextContainer_TextChanged;

            var documentId = workspace.AddDocument(ProjectId, $"script-{Guid.NewGuid()}.cs", SourceCodeKind.Script, TextLoader.From(sourceTextContainer, VersionStamp.Create()));

            DocumentId = documentId;
            workspace.OpenDocument(sourceTextContainer, documentId, a => Dispatcher.Invoke(() => codeEditor.ProcessDiagnostics(a)));

            // Bind SourceTextContainer to UI
            codeEditor.BindSourceTextContainer(workspace, sourceTextContainer, documentId);
        }
示例#8
0
        public MainWindow()
        {
            _viewModel = new MainViewModel();
            _viewModel.NuGet.PackageInstalled += NuGetOnPackageInstalled;
            DataContext = _viewModel;

            InitializeComponent();

            _textMarkerService = new TextMarkerService(Editor);
            Editor.TextArea.TextView.BackgroundRenderers.Add(_textMarkerService);
            Editor.TextArea.TextView.LineTransformers.Add(_textMarkerService);

            ConfigureEditor();

            _lock    = new object();
            _objects = new ObservableCollection <ResultObject>();
            BindingOperations.EnableCollectionSynchronization(_objects, _lock);
            Results.ItemsSource = _objects;

            ObjectExtensions.Dumped += OnDumped;

            var syncContext = SynchronizationContext.Current;

            _viewModel.RoslynHost.GetService <IDiagnosticService>().DiagnosticsUpdated += (sender, args) => syncContext.Post(o => ProcessDiagnostics(args), null);
            var avalonEditTextContainer = new AvalonEditTextContainer(Editor);

            _viewModel.RoslynHost.SetDocument(avalonEditTextContainer);
            _viewModel.RoslynHost.ApplyingTextChange += (id, text) => avalonEditTextContainer.UpdateText(text);

            Editor.TextArea.TextView.LineTransformers.Insert(0, new RoslynHighlightingColorizer(_viewModel.RoslynHost));

            _contextActionsRenderer = new ContextActionsRenderer(Editor, _textMarkerService);
            _contextActionsRenderer.Providers.Add(new RoslynContextActionProvider(_viewModel.RoslynHost));

            Editor.CompletionProvider = new RoslynCodeEditorCompletionProvider(_viewModel.RoslynHost);
        }
示例#9
0
 public CreatingDocumentEventArgs(AvalonEditTextContainer textContainer, Action <DiagnosticsUpdatedArgs> processDiagnostics)
 {
     TextContainer      = textContainer;
     ProcessDiagnostics = processDiagnostics;
     RoutedEvent        = RoslynCodeEditor.CreatingDocumentEvent;
 }
示例#10
0
 public ScriptEditorViewModel([NotNull] ScriptSourceFileAssetViewModel script, AvalonEditTextContainer sourceTextContainer)
     : base(script)
 {
     Code = StrideAssetsViewModel.Instance.Code;
     SourceTextContainer = sourceTextContainer;
 }
示例#11
0
        public void RegisterSourceFile(IEditor editor)
        {
            if (dataAssociations.TryGetValue(editor, out CSharpDataAssociation association))
            {
                throw new Exception("Source file already registered with language service.");
            }

            IndentationStrategy = new CSharpIndentationStrategy(new AvaloniaEdit.TextEditorOptions {
                ConvertTabsToSpaces = true
            });

            association = new CSharpDataAssociation
            {
                Solution = editor.SourceFile.Project.Solution
            };

            dataAssociations.Add(editor, association);

            if (!(editor.SourceFile is MetaDataFile))
            {
                var avaloniaEditTextContainer = new AvalonEditTextContainer(editor.Document)
                {
                    Editor = editor
                };

                RoslynWorkspace.GetWorkspace(association.Solution).OpenDocument(editor.SourceFile, avaloniaEditTextContainer, (diagnostics) =>
                {
                    var dataAssociation = GetAssociatedData(editor);

                    //var results = new TextSegmentCollection<Diagnostic>();

                    //foreach (var diagnostic in diagnostics.Diagnostics)
                    //{
                    //    results.Add(FromRoslynDiagnostic(diagnostic, editor.SourceFile.Location, editor.SourceFile.Project));
                    //}

                    //(Diagnostics as Subject<TextSegmentCollection<Diagnostic>>).OnNext(results);
                });

                association.TextInputHandler = (sender, e) =>
                {
                    switch (e.Text)
                    {
                    case "}":
                    case ";":
                        editor.IndentLine(editor.Line);
                        break;

                    case "{":
                        if (IndentationStrategy != null)
                        {
                            editor.IndentLine(editor.Line);
                        }
                        break;
                    }

                    OpenBracket(editor, editor.Document, e.Text);
                    CloseBracket(editor, editor.Document, e.Text);
                };

                association.BeforeTextInputHandler = (sender, e) =>
                {
                    switch (e.Text)
                    {
                    case "\n":
                    case "\r\n":
                        var nextChar = ' ';

                        if (editor.CaretOffset != editor.Document.TextLength)
                        {
                            nextChar = editor.Document.GetCharAt(editor.CaretOffset);
                        }

                        if (nextChar == '}')
                        {
                            var newline = "\r\n";     // TextUtilities.GetNewLineFromDocument(editor.Document, editor.TextArea.Caret.Line);
                            editor.Document.Insert(editor.CaretOffset, newline);

                            editor.Document.TrimTrailingWhiteSpace(editor.Line - 1);

                            editor.IndentLine(editor.Line);

                            editor.CaretOffset -= newline.Length;
                        }
                        break;
                    }
                };

                editor.TextEntered  += association.TextInputHandler;
                editor.TextEntering += association.BeforeTextInputHandler;
            }
        }
示例#12
0
        public void RegisterSourceFile(IEditor editor)
        {
            if (dataAssociations.TryGetValue(editor, out CSharpDataAssociation association))
            {
                throw new Exception("Source file already registered with language service.");
            }

            IndentationStrategy = new CSharpIndentationStrategy(new AvaloniaEdit.TextEditorOptions {
                ConvertTabsToSpaces = true
            });

            association = new CSharpDataAssociation
            {
                Solution = editor.SourceFile.Project.Solution
            };

            dataAssociations.Add(editor, association);

            if (!(editor.SourceFile is MetaDataFile))
            {
                var avaloniaEditTextContainer = new AvalonEditTextContainer(editor.Document)
                {
                    Editor = editor
                };

                RoslynWorkspace.GetWorkspace(association.Solution).OpenDocument(editor.SourceFile, avaloniaEditTextContainer, (diagnostics) =>
                {
                    var dataAssociation = GetAssociatedData(editor);

                    var results = new List <Diagnostic>();

                    var fadedCode = new SyntaxHighlightDataList();

                    foreach (var diagnostic in diagnostics.Diagnostics)
                    {
                        if (diagnostic.CustomTags.Contains("Unnecessary"))
                        {
                            fadedCode.Add(new OffsetSyntaxHighlightingData
                            {
                                Start  = diagnostic.TextSpan.Start,
                                Length = diagnostic.TextSpan.Length,
                                Type   = HighlightType.Unnecessary
                            });
                        }
                        else
                        {
                            results.Add(FromRoslynDiagnostic(diagnostic, editor.SourceFile.Location, editor.SourceFile.Project));
                        }
                    }

                    DiagnosticsUpdated?.Invoke(this, new DiagnosticsUpdatedEventArgs(diagnostics.Id, editor.SourceFile, (DiagnosticsUpdatedKind)diagnostics.Kind, results.ToImmutableArray(), fadedCode));
                });

                association.TextInputHandler = (sender, e) =>
                {
                    switch (e.Text)
                    {
                    case "}":
                    case ";":
                        editor.IndentLine(editor.Line);
                        break;

                    case "{":
                        if (IndentationStrategy != null)
                        {
                            editor.IndentLine(editor.Line);
                        }
                        break;
                    }

                    OpenBracket(editor, editor.Document, e.Text);
                    CloseBracket(editor, editor.Document, e.Text);
                };

                association.BeforeTextInputHandler = (sender, e) =>
                {
                    switch (e.Text)
                    {
                    case "\n":
                    case "\r\n":
                        var nextChar = ' ';

                        if (editor.CaretOffset != editor.Document.TextLength)
                        {
                            nextChar = editor.Document.GetCharAt(editor.CaretOffset);
                        }

                        if (nextChar == '}')
                        {
                            var newline = "\r\n";     // TextUtilities.GetNewLineFromDocument(editor.Document, editor.TextArea.Caret.Line);
                            editor.Document.Insert(editor.CaretOffset, newline);

                            editor.Document.TrimTrailingWhiteSpace(editor.Line - 1);

                            editor.IndentLine(editor.Line);

                            editor.CaretOffset -= newline.Length;
                        }
                        break;
                    }
                };

                editor.TextEntered  += association.TextInputHandler;
                editor.TextEntering += association.BeforeTextInputHandler;
            }
        }