Ejemplo n.º 1
0
        public bool Highlight(Range range, bool highlight)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            if (!highlight)
            {
                _highlightAdornmentLayer.RemoveAllAdornments();
                return(false);
            }

            CreateLineInfos(_textView, _textView.TextViewLines);

            try {
                var brush = CreateBrush();

                range = range.Normalize();
                var lineStart = range.Start.Line;
                var lineEnd   = range.End.Line;

                for (var i = range.Start.Line; i <= range.End.Line; i++)
                {
                    var isInnerOrLastLine = i > range.Start.Line && i <= range.End.Line;
                    if (!_lineInfos.TryGetValue(i, out ITextViewLine lineInfo))
                    {
                        if (Log.IsVerboseEnabled())
                        {
                            try {
                                var visible = _textView.TextViewLines.AsQueryable().Select(_ =>
                                                                                           _textView.TextSnapshot.GetLineNumberFromPosition(_.Extent.Start.Position)
                                                                                           ).ToList();
                                if (visible.Count() >= 1)
                                {
                                    Log.Verbose($"Could not find lineInfo for line={i}, only lines {visible.First()}-{visible.Last()} are visible");
                                }
                            }
                            catch (Exception ex) {
                                Log.Verbose(ex, $"Problem with logging message for line={i}");
                            }
                        }
                        continue;
                    }

                    Placement placement;
                    if (lineStart == lineEnd)
                    {
                        //single line
                        var length = range.End.Character == int.MaxValue
                                                        ? lineInfo.Extent.End.Position - lineInfo.Extent.Start.Position
                                                        : range.End.Character - range.Start.Character;
                        if (length == 0)
                        {
                            //highlight whole line
                            placement = new Placement(_textView.ViewportLeft, _textView.ViewportWidth);
                        }
                        else
                        {
                            placement = _textView
                                        .GetGeometryPlacement(new SnapshotSpan(lineInfo.Extent.Snapshot,
                                                                               new Span(lineInfo.Extent.Start + range.Start.Character, length)));
                        }
                    }
                    else
                    {
                        if (i == lineStart)
                        {
                            var startPosition = range.Start.Character + lineInfo.Extent.Start;
                            var endLength     = startPosition >= lineInfo.Extent.End.Position
                                                                ? 1
                                                                : lineInfo.Extent.End.Position - Math.Max(startPosition, 0);
                            placement = _textView
                                        .GetGeometryPlacement(new SnapshotSpan(lineInfo.Extent.Snapshot,
                                                                               new Span(startPosition, endLength)));
                        }
                        else if (i == lineEnd)
                        {
                            var endLength = range.End.Character == int.MaxValue
                                                                ? lineInfo.Extent.End.Position - lineInfo.Extent.Start.Position
                                                                : range.End.Character;
                            placement = _textView
                                        .GetGeometryPlacement(new SnapshotSpan(lineInfo.Extent.Snapshot,
                                                                               new Span(lineInfo.Extent.Start, endLength)));
                        }
                        else
                        {
                            // some middle line
                            placement = _textView.GetGeometryPlacement(lineInfo.Extent);
                        }
                    }

                    var rectangleHeight = lineInfo.TextHeight + 1.35;                     //buffer ;)
                    if (lineInfo.Height > rectangleHeight)
                    {
                        // height _might_ be taller than line height because of codelenses
                        if (isInnerOrLastLine)
                        {
                            rectangleHeight = lineInfo.Height + 0.5;                             //buffer :)
                        }
                    }

                    var element = new Rectangle {
                        Height = rectangleHeight,
                        Width  = placement.Width,
                        Fill   = brush
                    };

                    Canvas.SetLeft(element, range.Start.Character == 0 ? (int)_textView.ViewportLeft : placement.Left);
                    Canvas.SetTop(element, isInnerOrLastLine ? lineInfo.Top : lineInfo.TextTop);

                    _highlightAdornmentLayer.AddAdornment(lineInfo.Extent, null, element);
                }

                return(true);
            }
            catch (ArgumentException ex) {
                Log.Debug(ex, $"{range?.ToJson()}");
            }
            catch (Exception ex) {
                Log.Warning(ex, $"{range?.ToJson()}");
            }
            return(false);
        }