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); }