diff options
4 files changed, 68 insertions, 13 deletions
diff --git a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs index f750fcd8b1..ca15510bb5 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs @@ -332,7 +332,6 @@ namespace Mono.TextEditor { for (int i = 0; i < e.TextChanges.Count; ++i) { var change = e.TextChanges[i]; - RemoveCachedLine (Document.OffsetToLineNumber (change.NewOffset)); if (mouseSelectionMode == MouseSelectionMode.Word && change.Offset < mouseWordStart) { int delta = change.ChangeDelta; mouseWordStart += delta; @@ -1322,12 +1321,27 @@ namespace Mono.TextEditor cacheSrc = new CancellationTokenSource (); cachedLines.Clear (); } - public void PurgeLayoutCache () { DisposeLayoutDict (); } + void PurgeLayoutCacheAfter (int lineNumber) + { + foreach (var descr in layoutDict.ToArray()) { + if (descr.Key >= lineNumber) { + descr.Value.Dispose (); + layoutDict.Remove (descr.Key); + } + } + + foreach (var descr in cachedLines.ToArray()) { + if (descr.Key >= lineNumber) { + cachedLines.Remove (descr.Key); + } + } + } + class ChunkDescriptor : LineDescriptor { public List<MonoDevelop.Ide.Editor.Highlighting.ColoredSegment> Chunk { @@ -1353,16 +1367,44 @@ namespace Mono.TextEditor var token = cacheSrc.Token; var task = doc.SyntaxMode.GetHighlightedLineAsync (line, token); if (task.IsCompleted) { - cachedLines [lineNumber] = task.Result; - return Tuple.Create (TrimChunks (task.Result.Segments, offset - line.Offset, length), true); + if (task.Result != null) { + UpdateLineHighlight (lineNumber, result, task.Result); + return Tuple.Create (TrimChunks (task.Result.Segments, offset - line.Offset, length), true); + } } task.ContinueWith (t => { - cachedLines [lineNumber] = t.Result; - Document.CommitLineUpdate (lineNumber); // Required for highlighting updates + if (t.Result == null) + return; + if (UpdateLineHighlight (lineNumber, result, t.Result)) { + RemoveCachedLine (lineNumber); + Document.CommitLineUpdate (line); + } }, token, TaskContinuationOptions.OnlyOnRanToCompletion, Runtime.MainTaskScheduler); return Tuple.Create (new List<ColoredSegment> (new [] { new ColoredSegment (0, line.Length, ScopeStack.Empty) }), false); } + bool UpdateLineHighlight (int lineNumber, HighlightedLine oldLine, HighlightedLine newLine) + { + if (oldLine != null && ShouldUpdateSpan (oldLine, newLine)) { + PurgeLayoutCacheAfter (lineNumber); + cachedLines [lineNumber] = newLine; + textEditor.QueueDraw (); + return false; + } + cachedLines [lineNumber] = newLine; + return true; + } + + static bool ShouldUpdateSpan (HighlightedLine line1, HighlightedLine line2) + { + if (line1.IsContinuedBeyondLineEnd != line2.IsContinuedBeyondLineEnd) + return true; + if (line1.IsContinuedBeyondLineEnd == true) { + return line1.Segments.Last ().ScopeStack.Peek () != line2.Segments.Last ().ScopeStack.Peek (); + } + return false; + } + internal static List<ColoredSegment> TrimChunks (IReadOnlyList<ColoredSegment> segments, int offset, int length) { var result = new List<ColoredSegment> (); diff --git a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/DocumentUpdateRequest.cs b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/DocumentUpdateRequest.cs index 2cd7c20c7c..dded9bdb91 100644 --- a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/DocumentUpdateRequest.cs +++ b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/DocumentUpdateRequest.cs @@ -84,12 +84,8 @@ namespace Mono.TextEditor public override void Update (MonoTextEditor editor) { if (start == end) { - editor.TextViewMargin.RemoveCachedLine (start); editor.RedrawLine (start); } else { - for (int i = start; i <= end; i++) { - editor.TextViewMargin.RemoveCachedLine (i); - } editor.RedrawLines (start, end); } } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/ISyntaxHighlighting.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/ISyntaxHighlighting.cs index 34b6f7d4f3..215e49ba47 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/ISyntaxHighlighting.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/ISyntaxHighlighting.cs @@ -31,6 +31,7 @@ using MonoDevelop.Core.Text; using System.Collections.Immutable; using System.Threading.Tasks; using System.Threading; +using System.Linq; namespace MonoDevelop.Ide.Editor.Highlighting { @@ -41,6 +42,20 @@ namespace MonoDevelop.Ide.Editor.Highlighting /// The segment offsets are 0 at line start regardless of where the line is inside the document. /// </summary> public IReadOnlyList<ColoredSegment> Segments { get; private set; } + + bool? isContinuedBeyondLineEnd; + public bool? IsContinuedBeyondLineEnd { + get { + if (isContinuedBeyondLineEnd.HasValue) + return isContinuedBeyondLineEnd.Value; + var result = Segments.Count > 0 ? TextSegment.Length < Segments.Last ().EndOffset : false; + return isContinuedBeyondLineEnd = result; + } + set { + isContinuedBeyondLineEnd = value; + } + } + public HighlightedLine (ISegment textSegment, IReadOnlyList<ColoredSegment> segments) { TextSegment = textSegment; @@ -89,4 +104,4 @@ namespace MonoDevelop.Ide.Editor.Highlighting {
} } -}
\ No newline at end of file +} diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/SyntaxHighlighting.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/SyntaxHighlighting.cs index c8340e77e8..153a651a5a 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/SyntaxHighlighting.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/SyntaxHighlighting.cs @@ -188,7 +188,7 @@ namespace MonoDevelop.Ide.Editor.Highlighting int lastMatch = -1; var highlightedSegment = new TextSegment (startOffset, length); string lineText = text.GetTextAt (startOffset, length); - + var initialState = state.Clone (); int timeoutOccursAt; unchecked { timeoutOccursAt = Environment.TickCount + (int)matchTimeout.TotalMilliseconds; @@ -330,7 +330,9 @@ namespace MonoDevelop.Ide.Editor.Highlighting segments.Add (new ColoredSegment (curSegmentOffset, endOffset - curSegmentOffset, ScopeStack)); } - return Task.FromResult (new HighlightedLine (highlightedSegment, segments)); + return Task.FromResult (new HighlightedLine (highlightedSegment, segments) { + IsContinuedBeyondLineEnd = !initialState.Equals (state) + }); } void PushStack (SyntaxMatch curMatch, IEnumerable<SyntaxContext> nextContexts) |