예제 #1
0
        void TestFoldings(string text)
        {
            var editor    = TextEditorFactory.CreateNewEditor();
            var sb        = new StringBuilder();
            var foldStack = new Stack <int> ();
            var expected  = new List <ISegment> ();

            foreach (var ch in text)
            {
                if (ch == '+')
                {
                    foldStack.Push(sb.Length);
                    continue;
                }
                if (ch == '-')
                {
                    expected.Add(TextSegment.FromBounds(foldStack.Pop(), sb.Length));
                    continue;
                }
                sb.Append(ch);
            }
            editor.Text = sb.ToString();
            var ext      = new TextMateFoldingTextEditorExtension();
            var foldings = ext.GetFoldingsAsync(editor, default(CancellationToken)).Result.ToList();

            Assert.AreEqual(expected.Count, foldings.Count);

            for (int i = 0; i < foldings.Count; i++)
            {
                Assert.AreEqual(expected [i].Offset, foldings [i].Offset);
                Assert.AreEqual(expected [i].Length, foldings [i].Length);
            }
        }
예제 #2
0
        void SelectLine()
        {
            editor.Caret.Column = 1;
            var lineEnd = editor.Document.GetLine(editor.Caret.Line).EndOffset;

            editor.Selection = TextSegment.FromBounds(editor.Caret.Offset, lineEnd);
        }
예제 #3
0
        MonoTextEditor CreateEditorWithLinks(string input, out List <TextLink> links)
        {
            links = new List <TextLink> ();
            var segments = new List <List <ISegment> > ();
            int caretOffset = 0;
            var text = new StringBuilder();
            int curLink = -1, linkStart = 0;

            for (int i = 0; i < input.Length; i++)
            {
                char ch = input [i];
                switch (ch)
                {
                case '[':
                    i++;                              // skip number
                    curLink = (int)(input[i] - '0');
                    if (segments.Count - 1 < curLink) // links need to be defined in order
                    {
                        segments.Add(new List <ISegment> ());
                    }
                    linkStart = text.Length;
                    break;

                case ']':
                    if (curLink < 0)
                    {
                        goto default;
                    }
                    segments [curLink].Add(TextSegment.FromBounds(linkStart, text.Length));
                    curLink = -1;
                    break;

                case '$':
                    caretOffset = text.Length;
                    break;

                default:
                    text.Append(ch);
                    break;
                }
            }

            for (int i = 0; i < segments.Count; i++)
            {
                links.Add(new TextLink(i.ToString())
                {
                    Links = segments [i]
                });
            }

            var result = new MonoTextEditor();

            result.Text         = text.ToString();
            result.Caret.Offset = caretOffset;
            return(result);
        }
예제 #4
0
 public static void ExpandSelectionToLine(TextEditor textEditor)
 {
     // from MonoDevelop.Ide.Editor.SelectionActions.ExpandSelectionToLine
     using (var undoGroup = textEditor.OpenUndoGroup()) {
         var curLineSegment = textEditor.GetLine(textEditor.CaretLine).SegmentIncludingDelimiter;
         var range          = textEditor.SelectionRange;
         var selection      = TextSegment.FromBounds(
             System.Math.Min(range.Offset, curLineSegment.Offset),
             System.Math.Max(range.EndOffset, curLineSegment.EndOffset));
         textEditor.CaretOffset    = selection.EndOffset;
         textEditor.SelectionRange = selection;
     }
 }
예제 #5
0
            ISegment CalcTypeBounds(BaseTypeDeclarationSyntax type)
            {
                int start = type.Span.Start;
                int end   = type.Span.End;

                foreach (var trivia in type.GetLeadingTrivia())
                {
                    if (trivia.Kind() == SyntaxKind.SingleLineDocumentationCommentTrivia)
                    {
                        start = trivia.FullSpan.Start;
                    }
                }

                return(TextSegment.FromBounds(start, end));
            }
예제 #6
0
        protected internal override void MousePressed(MarginMouseEventArgs args)
        {
            base.MousePressed(args);

            if (args.Button == Xwt.PointerButton.Left)
            {
                var basePoint = editor.Caret.Location = XYToLocation(args.X, args.Y);

                editor.Selection = new TextSegment();

                int clickMode = args.MultipleClicks % 3;
                if (clickMode == 2)
                {
                    // TODO: Select Word
                }
                else if (clickMode == 0)
                {
                    SelectLine();
                }

                editor.RegisterMouseMotionTracker(Xwt.PointerButton.Left, (x, y) =>
                {
                    var newPoint          = XYToLocation(x, y);
                    editor.Caret.Location = newPoint;
                    editor.ResetCaretState();

                    var newOffset = editor.Document.GetOffset(newPoint);
                    var oldOffset = editor.Document.GetOffset(basePoint);

                    var startOffset = Math.Min(oldOffset, newOffset);
                    var endOffset   = Math.Max(oldOffset, newOffset);

                    editor.Selection = TextSegment.FromBounds(startOffset, endOffset);

                    if (clickMode == 0)
                    {
                        SelectLines();
                    }

                    editor.QueueDraw();
                });

                editor.ResetCaretState();
            }
        }
예제 #7
0
        public int Insert(TextEditor editor, DocumentContext ctx, string text)
        {
            int offset = editor.LocationToOffset(Location);

            using (var undo = editor.OpenUndoGroup()) {
                var line            = editor.GetLineByOffset(offset);
                int insertionOffset = line.Offset + Location.Column - 1;
                offset = insertionOffset;
                InsertNewLine(editor, LineBefore, ref offset);
                int result = offset - insertionOffset;

                editor.InsertText(offset, text);
                offset += text.Length;
                InsertNewLine(editor, LineAfter, ref offset);
                CodeFormatterService.Format(editor, ctx, TextSegment.FromBounds(insertionOffset - 1, offset));
                return(result);
            }
        }
예제 #8
0
        TextSegment?GetSegmentForLine(TextSegment segment, DocumentLine line)
        {
            var start = Math.Max(segment.Offset, line.Offset);

            if (!segment.Contains(start))
            {
                return(null);
            }

            var end = Math.Min(segment.EndOffset, line.EndOffset);

            if (!segment.Contains(end - 1))
            {
                return(null);
            }

            return(TextSegment.FromBounds(start, end));
        }
예제 #9
0
        void SelectLines()
        {
            // We have a selection which covers normal individual characters
            // We want to extend the selection to cover entire lines

            editor.Caret.Column = 1;

            var  firstLine             = editor.Document.GetLineByOffset(editor.Selection.Offset);
            int  lastLineNumberInRange = editor.Document.GetLineByOffset(editor.Selection.EndOffset).LineNumber;
            bool inEndOfDocument       = lastLineNumberInRange == editor.Document.LineCount;
            var  lastLine = editor.Document.GetLine(inEndOfDocument ? lastLineNumberInRange : lastLineNumberInRange + 1);

            if (editor.Caret.Offset != firstLine.Offset)
            {
                editor.Caret.Line++;
            }

            editor.Selection = TextSegment.FromBounds(firstLine.Offset, inEndOfDocument ? lastLine.EndOffset : lastLine.Offset);
        }
        void ShowReferences(IEnumerable <MemberReference> references)
        {
            RemoveMarkers();
            var lineNumbers = new HashSet <int> ();

            usages = ImmutableArray <Usage> .Empty;
            var editor = Editor;

            if (editor != null /*&& editor.TextViewMargin != null*/)
            {
                if (references != null)
                {
                    var builder = ImmutableArray <Usage> .Empty.ToBuilder();

                    foreach (var r in references)
                    {
                        if (r == null)
                        {
                            continue;
                        }
                        var start = r.Offset;
                        var end   = r.Offset + r.Length;
                        if (end > editor.Length)
                        {
                            continue;
                        }
                        var usage = new Usage(TextSegment.FromBounds(start, end), r.ReferenceUsageType);
                        builder.Add(usage);
                        var marker = TextMarkerFactory.CreateUsageMarker(editor, usage);
                        markers.Add(marker);
                        lineNumbers.Add(editor.OffsetToLineNumber(start));
                        editor.AddMarker(marker);
                    }
                    usages = builder.ToImmutable();
                }
            }
            OnUsagesUpdated(EventArgs.Empty);
        }
예제 #11
0
        protected override void ApplyDocumentTextChanged(DocumentId id, SourceText text)
        {
            var document = GetDocument(id);

            if (document == null)
            {
                return;
            }
            bool isOpen;
            var  filePath = document.FilePath;
            var  data     = TextFileProvider.Instance.GetTextEditorData(filePath, out isOpen);

            // Guard against already done changes in linked files.
            // This shouldn't happen but the roslyn merging seems not to be working correctly in all cases :/
            if (document.GetLinkedDocumentIds().Length > 0 && isOpen && !(text.GetType().FullName == "Microsoft.CodeAnalysis.Text.ChangedText"))
            {
                return;
            }
            SourceText formerText;

            if (changedFiles.TryGetValue(filePath, out formerText))
            {
                if (formerText.Length == text.Length && formerText.ToString() == text.ToString())
                {
                    return;
                }
            }
            changedFiles [filePath] = text;

            Projection projection = null;

            foreach (var entry in ProjectionList)
            {
                var p = entry.Projections.FirstOrDefault(proj => FilePath.PathComparer.Equals(proj.Document.FileName, filePath));
                if (p != null)
                {
                    filePath   = entry.File.FilePath;
                    projection = p;
                    break;
                }
            }
            SourceText oldFile;

            if (!isOpen || !document.TryGetText(out oldFile))
            {
                oldFile = new MonoDevelopSourceText(data);
            }
            var changes = text.GetTextChanges(oldFile).OrderByDescending(c => c.Span.Start).ToList();
            int delta   = 0;

            if (!isOpen)
            {
                delta = ApplyChanges(projection, data, changes);
                var    formatter   = CodeFormatterService.GetFormatter(data.MimeType);
                var    mp          = GetMonoProject(CurrentSolution.GetProject(id.ProjectId));
                string currentText = data.Text;

                foreach (var change in changes)
                {
                    delta -= change.Span.Length - change.NewText.Length;
                    var startOffset = change.Span.Start - delta;

                    if (projection != null)
                    {
                        int originalOffset;
                        if (projection.TryConvertFromProjectionToOriginal(startOffset, out originalOffset))
                        {
                            startOffset = originalOffset;
                        }
                    }

                    string str;
                    if (change.NewText.Length == 0)
                    {
                        str = formatter.FormatText(mp.Policies, currentText, TextSegment.FromBounds(Math.Max(0, startOffset - 1), Math.Min(data.Length, startOffset + 1)));
                    }
                    else
                    {
                        str = formatter.FormatText(mp.Policies, currentText, new TextSegment(startOffset, change.NewText.Length));
                    }
                    data.ReplaceText(startOffset, change.NewText.Length, str);
                }
                data.Save();
                OnDocumentTextChanged(id, new MonoDevelopSourceText(data), PreservationMode.PreserveValue);
                FileService.NotifyFileChanged(filePath);
            }
            else
            {
                var formatter       = CodeFormatterService.GetFormatter(data.MimeType);
                var documentContext = IdeApp.Workbench.Documents.FirstOrDefault(d => FilePath.PathComparer.Compare(d.FileName, filePath) == 0);
                if (documentContext != null)
                {
                    var editor = (TextEditor)data;
                    using (var undo = editor.OpenUndoGroup()) {
                        delta = ApplyChanges(projection, data, changes);

                        foreach (var change in changes)
                        {
                            delta -= change.Span.Length - change.NewText.Length;
                            var startOffset = change.Span.Start - delta;
                            if (projection != null)
                            {
                                int originalOffset;
                                if (projection.TryConvertFromProjectionToOriginal(startOffset, out originalOffset))
                                {
                                    startOffset = originalOffset;
                                }
                            }
                            if (change.NewText.Length == 0)
                            {
                                formatter.OnTheFlyFormat(editor, documentContext, TextSegment.FromBounds(Math.Max(0, startOffset - 1), Math.Min(data.Length, startOffset + 1)));
                            }
                            else
                            {
                                formatter.OnTheFlyFormat(editor, documentContext, new TextSegment(startOffset, change.NewText.Length));
                            }
                        }
                    }
                }
                OnDocumentTextChanged(id, new MonoDevelopSourceText(data.CreateDocumentSnapshot()), PreservationMode.PreserveValue);
                Runtime.RunInMainThread(() => {
                    if (IdeApp.Workbench != null)
                    {
                        foreach (var w in IdeApp.Workbench.Documents)
                        {
                            w.StartReparseThread();
                        }
                    }
                });
            }
        }
예제 #12
0
        protected override void ApplyDocumentTextChanged(DocumentId id, SourceText text)
        {
            var document = GetDocument(id);

            if (document == null)
            {
                return;
            }
            bool isOpen;
            var  filePath = document.FilePath;

            Projection projection = null;

            foreach (var entry in ProjectionList)
            {
                var p = entry.Projections.FirstOrDefault(proj => FilePath.PathComparer.Equals(proj.Document.FileName, filePath));
                if (p != null)
                {
                    filePath   = entry.File.FilePath;
                    projection = p;
                    break;
                }
            }

            var data    = TextFileProvider.Instance.GetTextEditorData(filePath, out isOpen);
            var oldFile = isOpen ? document.GetTextAsync().Result : new MonoDevelopSourceText(data);
            var changes = text.GetTextChanges(oldFile).OrderByDescending(c => c.Span.Start).ToList();
            int delta   = 0;

            if (!isOpen)
            {
                delta = ApplyChanges(projection, data, changes);
                var    formatter   = CodeFormatterService.GetFormatter(data.MimeType);
                var    mp          = GetMonoProject(CurrentSolution.GetProject(id.ProjectId));
                string currentText = data.Text;

                foreach (var change in changes)
                {
                    delta -= change.Span.Length - change.NewText.Length;
                    var startOffset = change.Span.Start - delta;

                    if (projection != null)
                    {
                        int originalOffset;
                        if (projection.TryConvertFromProjectionToOriginal(startOffset, out originalOffset))
                        {
                            startOffset = originalOffset;
                        }
                    }


                    string str;
                    if (change.NewText.Length == 0)
                    {
                        str = formatter.FormatText(mp.Policies, currentText, TextSegment.FromBounds(Math.Max(0, startOffset - 1), Math.Min(data.Length, startOffset + 1)));
                    }
                    else
                    {
                        str = formatter.FormatText(mp.Policies, currentText, new TextSegment(startOffset, change.NewText.Length));
                    }
                    data.ReplaceText(startOffset, change.NewText.Length, str);
                }
                data.Save();
                OnDocumentTextChanged(id, new MonoDevelopSourceText(data), PreservationMode.PreserveValue);
                FileService.NotifyFileChanged(filePath);
            }
            else
            {
                var formatter       = CodeFormatterService.GetFormatter(data.MimeType);
                var documentContext = IdeApp.Workbench.Documents.FirstOrDefault(d => FilePath.PathComparer.Compare(d.FileName, filePath) == 0);
                if (documentContext != null)
                {
                    var editor = (TextEditor)data;
                    using (var undo = editor.OpenUndoGroup()) {
                        delta = ApplyChanges(projection, data, changes);

                        foreach (var change in changes)
                        {
                            delta -= change.Span.Length - change.NewText.Length;
                            var startOffset = change.Span.Start - delta;

                            if (projection != null)
                            {
                                int originalOffset;
                                if (projection.TryConvertFromProjectionToOriginal(startOffset, out originalOffset))
                                {
                                    startOffset = originalOffset;
                                }
                            }
                            if (change.NewText.Length == 0)
                            {
                                formatter.OnTheFlyFormat(editor, documentContext, TextSegment.FromBounds(Math.Max(0, startOffset - 1), Math.Min(data.Length, startOffset + 1)));
                            }
                            else
                            {
                                formatter.OnTheFlyFormat(editor, documentContext, new TextSegment(startOffset, change.NewText.Length));
                            }
                        }
                    }
                }
                OnDocumentTextChanged(id, new MonoDevelopSourceText(data.CreateDocumentSnapshot()), PreservationMode.PreserveValue);
                Runtime.RunInMainThread(() => {
                    if (IdeApp.Workbench != null)
                    {
                        foreach (var w in IdeApp.Workbench.Documents)
                        {
                            w.StartReparseThread();
                        }
                    }
                });
            }
        }
예제 #13
0
            //this runs as a glib idle handler so it can add/remove text editor markers
            //in order to to block the GUI thread, we batch them in UPDATE_COUNT
            bool IdleHandler()
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return(false);
                }
                var editor = ext.Editor;

                if (editor == null)
                {
                    return(false);
                }

                if (id == null)
                {
                    foreach (var markerQueue in ext.markers)
                    {
                        while (markerQueue.Value.Count != 0)
                        {
                            editor.RemoveMarker(markerQueue.Value.Dequeue());
                        }
                    }
                    ext.markers.Clear();
                    return(false);
                }

                //clear the old results out at the same rate we add in the new ones
                for (int i = 0; oldMarkers > 0 && i < UPDATE_COUNT; i++)
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return(false);
                    }
                    editor.RemoveMarker(ext.markers [id].Dequeue());
                    oldMarkers--;
                }

                //add in the new markers
                for (int i = 0; i < UPDATE_COUNT; i++)
                {
                    if (!enumerator.MoveNext())
                    {
                        ext.tasks [id] = builder.ToImmutable();
                        ext.OnTasksUpdated(EventArgs.Empty);
                        return(false);
                    }
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return(false);
                    }
                    var currentResult = (Result)enumerator.Current;
                    if (currentResult.InspectionMark != IssueMarker.None)
                    {
                        int start = currentResult.Region.Start;
                        int end   = currentResult.Region.End;
                        if (start >= end)
                        {
                            continue;
                        }
                        var marker = TextMarkerFactory.CreateGenericTextSegmentMarker(editor, GetSegmentMarkerEffect(currentResult.InspectionMark), TextSegment.FromBounds(start, end));
                        marker.Tag       = currentResult;
                        marker.IsVisible = currentResult.Underline;

                        if (currentResult.InspectionMark != IssueMarker.GrayOut)
                        {
                            marker.Color      = GetColor(editor, currentResult);
                            marker.IsVisible &= currentResult.Level != DiagnosticSeverity.Hidden;
                        }
                        editor.AddMarker(marker);
                        ext.markers [id].Enqueue(marker);
                    }
                    builder.Add(new QuickTask(currentResult.Message, currentResult.Region.Start, currentResult.Level));
                }

                return(true);
            }
예제 #14
0
 public void Select(int startPosition, int endPosition)
 {
     data.SelectionRange = TextSegment.FromBounds(startPosition, endPosition);
 }
예제 #15
0
        protected override void DocumentParsed()
        {
            var parsedDocument = documentContext.ParsedDocument;

            if (parsedDocument == null)
            {
                return;
            }
            var resolver = parsedDocument.GetAst <SemanticModel> ();

            if (resolver == null)
            {
                return;
            }
            CancelHighlightingTask();
            var token = src.Token;
            var theme = editor.Options.GetEditorTheme();

            Task.Run(async delegate {
                try {
                    var root    = await resolver.SyntaxTree.GetRootAsync(token);
                    var newTree = new HighlightingSegmentTree();

                    var visitor = new HighlightingVisitior(theme, resolver, newTree.Add, token, TextSegment.FromBounds(0, root.FullSpan.Length));
                    visitor.Visit(root);
                    var doNotify = !AreEqual(highlightTree, newTree, token);

                    if (!token.IsCancellationRequested)
                    {
                        Gtk.Application.Invoke(delegate {
                            if (token.IsCancellationRequested)
                            {
                                return;
                            }
                            if (highlightTree != null)
                            {
                                highlightTree.RemoveListener();
                            }
                            highlightTree = newTree;
                            highlightTree.InstallListener(editor);
                            if (doNotify)
                            {
                                NotifySemanticHighlightingUpdate();
                            }
                        });
                    }
                } catch (OperationCanceledException) {
                } catch (AggregateException ae) {
                    ae.Flatten().Handle(x => x is OperationCanceledException);
                }
            }, token);
        }
예제 #16
0
            //this runs as a glib idle handler so it can add/remove text editor markers
            //in order to to block the GUI thread, we batch them in UPDATE_COUNT
            bool IdleHandler()
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return(false);
                }
                var editor = ext.Editor;

                if (editor == null || editor.Document == null)
                {
                    return(false);
                }
                //clear the old results out at the same rate we add in the new ones
                for (int i = 0; oldMarkers > 0 && i < UPDATE_COUNT; i++)
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return(false);
                    }
                    editor.Document.RemoveMarker(ext.markers.Dequeue());
                    oldMarkers--;
                }
                //add in the new markers
                for (int i = 0; i < UPDATE_COUNT; i++)
                {
                    if (!enumerator.MoveNext())
                    {
                        ext.OnTasksUpdated(EventArgs.Empty);
                        return(false);
                    }
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return(false);
                    }
                    var currentResult = (Result)enumerator.Current;

                    if (currentResult.InspectionMark != IssueMarker.None)
                    {
                        int start = editor.LocationToOffset(currentResult.Region.Begin);
                        int end   = editor.LocationToOffset(currentResult.Region.End);
                        if (start >= end)
                        {
                            continue;
                        }
                        if (currentResult.InspectionMark == IssueMarker.GrayOut)
                        {
                            var marker = new GrayOutMarker(currentResult, TextSegment.FromBounds(start, end));
                            marker.IsVisible = currentResult.Underline;
                            editor.Document.AddMarker(marker);
                            ext.markers.Enqueue(marker);
                            editor.Parent.TextViewMargin.RemoveCachedLine(editor.GetLineByOffset(start));
                            editor.Parent.QueueDraw();
                        }
                        else
                        {
                            var marker = new ResultMarker(currentResult, TextSegment.FromBounds(start, end));
                            marker.IsVisible = currentResult.Underline;
                            editor.Document.AddMarker(marker);
                            ext.markers.Enqueue(marker);
                        }
                    }

                    ext.tasks.Add(new QuickTask(currentResult.Message, currentResult.Region.Begin, currentResult.Level));
                }

                return(true);
            }
예제 #17
0
            //this runs as a glib idle handler so it can add/remove text editor markers
            //in order to to block the GUI thread, we batch them in UPDATE_COUNT
            bool IdleHandler()
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return(false);
                }
                var editor = ext.Editor;

                if (editor == null)
                {
                    return(false);
                }
                //clear the old results out at the same rate we add in the new ones
                for (int i = 0; oldMarkers > 0 && i < UPDATE_COUNT; i++)
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return(false);
                    }
                    editor.RemoveMarker(ext.markers.Dequeue());
                    oldMarkers--;
                }
                //add in the new markers
                for (int i = 0; i < UPDATE_COUNT; i++)
                {
                    if (!enumerator.MoveNext())
                    {
                        ext.tasks = builder.ToImmutable();
                        ext.OnTasksUpdated(EventArgs.Empty);
                        return(false);
                    }
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return(false);
                    }
                    var currentResult = (Result)enumerator.Current;
                    if (currentResult.InspectionMark != IssueMarker.None)
                    {
                        int start = currentResult.Region.Start;
                        int end   = currentResult.Region.End;
                        if (start >= end)
                        {
                            continue;
                        }
                        if (currentResult.InspectionMark == IssueMarker.GrayOut)
                        {
                            var marker = TextMarkerFactory.CreateGenericTextSegmentMarker(editor, TextSegmentMarkerEffect.GrayOut, TextSegment.FromBounds(start, end));
                            marker.IsVisible = currentResult.Underline;
                            marker.Tag       = currentResult;
                            editor.AddMarker(marker);
                            ext.markers.Enqueue(marker);
//							editor.Parent.TextViewMargin.RemoveCachedLine (editor.GetLineByOffset (start));
//							editor.Parent.QueueDraw ();
                        }
                        else
                        {
                            var effect = currentResult.InspectionMark == IssueMarker.DottedLine ? TextSegmentMarkerEffect.DottedLine : TextSegmentMarkerEffect.WavedLine;
                            var marker = TextMarkerFactory.CreateGenericTextSegmentMarker(editor, effect, TextSegment.FromBounds(start, end));
                            marker.Color     = GetColor(editor, currentResult);
                            marker.IsVisible = currentResult.Underline;
                            marker.Tag       = currentResult;
                            editor.AddMarker(marker);
                            ext.markers.Enqueue(marker);
                        }
                    }
                    builder.Add(new QuickTask(currentResult.Message, currentResult.Region.Start, currentResult.Level));
                }

                return(true);
            }
예제 #18
0
            //this runs as a glib idle handler so it can add/remove text editor markers
            //in order to to block the GUI thread, we batch them in UPDATE_COUNT
            bool IdleHandler()
            {
                var editor = ext.Editor;

                if (editor == null)
                {
                    return(false);
                }
                if (id == null)
                {
                    foreach (var markerQueue in ext.markers)
                    {
                        foreach (var marker in markerQueue.Value)
                        {
                            editor.RemoveMarker(marker);
                        }
                        PutBackCachedList(markerQueue.Value);
                    }
                    ext.markers.Clear();
                    lock (ext.tasks)
                        ext.tasks.Clear();
                    ext.OnTasksUpdated(EventArgs.Empty);
                    return(false);
                }

                if (cancellationToken.IsCancellationRequested)
                {
                    FinishUpdateRun();
                    return(false);
                }

                //clear the old results out at the same rate we add in the new ones
                for (int i = 0; oldMarkerIndex < oldMarkers.Count && i < UPDATE_COUNT; i++)
                {
                    var oldMarker = oldMarkers [oldMarkerIndex++];

                    var oldResult = (Result)oldMarker.Tag;
                    if (curResult < results.Count)
                    {
                        Result currentResult = results [curResult];
                        if (currentResult.Equals(oldResult, oldMarker.Offset))
                        {
                            oldMarker.Tag = currentResult;
                            newMarkers.Add(oldMarker);
                            if (oldResult.QuickTask != null)
                            {
                                currentResult.QuickTask = oldResult.QuickTask;
                                builder.Add(currentResult.QuickTask);
                            }
                            curResult++;
                            continue;
                        }
                    }
                    editor.RemoveMarker(oldMarker);
                }

                //add in the new markers
                for (int i = 0; i < UPDATE_COUNT; i++)
                {
                    if (curResult >= results.Count)
                    {
                        FinishUpdateRun();
                        return(false);
                    }
                    var currentResult = results [curResult++];
                    if (currentResult.InspectionMark != IssueMarker.None)
                    {
                        int start = currentResult.Region.Start;
                        int end   = currentResult.Region.End;
                        if (start > end)
                        {
                            continue;
                        }

                        // In case a diagnostic has a 0 length span, force it to 1.
                        if (start == end)
                        {
                            end = end + 1;
                        }

                        var marker = TextMarkerFactory.CreateGenericTextSegmentMarker(editor, GetSegmentMarkerEffect(currentResult.InspectionMark), TextSegment.FromBounds(start, end));
                        marker.Tag       = currentResult;
                        marker.IsVisible = currentResult.Underline;

                        if (currentResult.InspectionMark != IssueMarker.GrayOut)
                        {
                            marker.Color      = GetColor(editor, currentResult);
                            marker.IsVisible &= currentResult.Level != DiagnosticSeverity.Hidden;
                        }
                        editor.AddMarker(marker);
                        newMarkers.Add(marker);
                    }
                    builder.Add(currentResult.QuickTask = new QuickTask(currentResult.Message, currentResult.Region.Start, currentResult.Level));
                }
                return(true);
            }
예제 #19
0
        /// <summary>
        /// Don't use this unless you're implementing ICodeTemplateWidget. Use Insert instead.
        /// </summary>
        public TemplateResult InsertTemplateContents(TextEditor editor, DocumentContext context)
        {
            var data = editor;

            int offset = data.CaretOffset;
//			string leadingWhiteSpace = GetLeadingWhiteSpace (editor, editor.CursorLine);

            var templateCtx = new TemplateContext {
                Template        = this,
                DocumentContext = context,
                Editor          = editor,
                //ParsedDocument = context.ParsedDocument != null ? context.ParsedDocument.ParsedFile : null,
                InsertPosition = data.CaretLocation,
                LineIndent     = data.GetLineIndent(data.CaretLocation.Line),
                TemplateCode   = Code
            };

            if (data.IsSomethingSelected)
            {
                int start = data.SelectionRange.Offset;
                while (Char.IsWhiteSpace(data.GetCharAt(start)))
                {
                    start++;
                }
                int end = data.SelectionRange.EndOffset;
                while (Char.IsWhiteSpace(data.GetCharAt(end - 1)))
                {
                    end--;
                }
                templateCtx.LineIndent   = data.GetLineIndent(data.OffsetToLineNumber(start));
                templateCtx.SelectedText = RemoveIndent(data.GetTextBetween(start, end), templateCtx.LineIndent);
                data.RemoveText(start, end - start);
                offset = start;
            }
            else
            {
                string word = GetTemplateShortcutBeforeCaret(data).Trim();
                if (word.Length > 0)
                {
                    offset = DeleteTemplateShortcutBeforeCaret(data);
                }
            }

            TemplateResult template = FillVariables(templateCtx);

            template.InsertPosition = offset;
            editor.InsertText(offset, template.Code);

            int newoffset;

            if (template.CaretEndOffset >= 0)
            {
                newoffset = offset + template.CaretEndOffset;
            }
            else
            {
                newoffset = offset + template.Code.Length;
            }

            editor.CaretLocation = editor.OffsetToLocation(newoffset);

            var prettyPrinter = CodeFormatterService.GetFormatter(data.MimeType);

            if (prettyPrinter != null && prettyPrinter.SupportsOnTheFlyFormatting)
            {
                int endOffset  = template.InsertPosition + template.Code.Length;
                var oldVersion = data.Version;
                prettyPrinter.OnTheFlyFormat(editor, context, TextSegment.FromBounds(template.InsertPosition, editor.CaretOffset));
                if (editor.CaretOffset < endOffset)
                {
                    prettyPrinter.OnTheFlyFormat(editor, context, TextSegment.FromBounds(editor.CaretOffset, endOffset));
                }

                foreach (var textLink in template.TextLinks)
                {
                    for (int i = 0; i < textLink.Links.Count; i++)
                    {
                        var segment          = textLink.Links [i];
                        var translatedOffset = oldVersion.MoveOffsetTo(data.Version, template.InsertPosition + segment.Offset) - template.InsertPosition;
                        textLink.Links [i] = new TextSegment(translatedOffset, segment.Length);
                    }
                }
            }
            return(template);
        }
예제 #20
0
            //this runs as a glib idle handler so it can add/remove text editor markers
            //in order to to block the GUI thread, we batch them in UPDATE_COUNT
            bool IdleHandler()
            {
                try {
                    var editor = ext.Editor;
                    if (editor == null)
                    {
                        return(false);
                    }
                    if (id == null)
                    {
                        ext.RemoveMarkersAndTasks();
                        return(false);
                    }

                    //clear the old results out at the same rate we add in the new ones
                    if (oldMarkers != null)
                    {
                        for (int i = 0; oldMarkerIndex < oldMarkers.Count && i < UPDATE_COUNT; i++)
                        {
                            var oldMarker = oldMarkers [oldMarkerIndex++];

                            var oldResult = (Result)oldMarker.Tag;
                            if (oldResult != null && curResult < results.Count)
                            {
                                Result currentResult = results [curResult];
                                if (currentResult.Equals(oldResult, oldMarker.Offset))
                                {
                                    oldMarker.Tag = currentResult;
                                    newMarkers.Add(oldMarker);
                                    if (oldResult.QuickTask != null)
                                    {
                                        currentResult.QuickTask = oldResult.QuickTask;
                                        builder.Add(currentResult.QuickTask);
                                    }
                                    curResult++;
                                    continue;
                                }
                            }
                            editor.RemoveMarker(oldMarker);
                        }
                    }

                    //add in the new markers
                    for (int i = 0; i < UPDATE_COUNT; i++)
                    {
                        if (curResult >= results.Count)
                        {
                            FinishUpdateRun();
                            return(false);
                        }
                        var currentResult = results [curResult++];
                        if (currentResult.InspectionMark != IssueMarker.None)
                        {
                            int start = currentResult.Region.Start;
                            int end   = currentResult.Region.End;
                            if (start > end)
                            {
                                continue;
                            }

                            // In case a diagnostic has a 0 length span, force it to 1.
                            if (start == end)
                            {
                                end = end + 1;
                            }

                            var marker = TextMarkerFactory.CreateGenericTextSegmentMarker(editor, GetSegmentMarkerEffect(currentResult.InspectionMark), TextSegment.FromBounds(start, end));
                            marker.Tag       = currentResult;
                            marker.IsVisible = currentResult.Underline;

                            if (currentResult.InspectionMark != IssueMarker.GrayOut)
                            {
                                marker.Color      = GetColor(editor, currentResult);
                                marker.IsVisible &= currentResult.Level != DiagnosticSeverity.Hidden;
                            }
                            editor.AddMarker(marker);
                            newMarkers.Add(marker);
                        }
                        builder.Add(currentResult.QuickTask = new QuickTask(currentResult.Message, currentResult.Region.Start, currentResult.Level));
                    }
                    return(true);
                } catch (Exception ex) {
                    LoggingService.LogInternalError("Error while ResutsUpdater.IdleHandler", ex);
                    return(false);
                }
            }