static async Task <ScreenBufferLinesRange> GetScreenBufferLines( IMessagesSource src, long startFrom, int maxCount, EnumMessagesFlag flags, MessageTextGetter displayTextGetter, Diagnostics diag, CancellationToken cancellation, bool doNotCountFirstMessage = false // todo: needed? ) { var backward = (flags & EnumMessagesFlag.Backward) != 0; var lines = new List <DisplayLine>(); var loadedMessages = 0; var linesToIgnore = 0; await src.EnumMessages(startFrom, msg => { var messagesLinesCount = displayTextGetter(msg).GetLinesCount(); if (backward) { for (int i = messagesLinesCount - 1; i >= 0; --i) { lines.Add(new DisplayLine(msg, i, messagesLinesCount, displayTextGetter, src)); } } else { for (int i = 0; i < messagesLinesCount; ++i) { lines.Add(new DisplayLine(msg, i, messagesLinesCount, displayTextGetter, src)); } } if (diag.IsEnabled) { diag.VerifyLines(backward ? Enumerable.Reverse(lines) : lines, src.HasConsecutiveMessages); } ++loadedMessages; if (doNotCountFirstMessage && loadedMessages == 1) { linesToIgnore = lines.Count; } return((lines.Count - linesToIgnore) < maxCount); }, flags | EnumMessagesFlag.IsActiveLogPositionHint, LogProviderCommandPriority.RealtimeUserAction, cancellation); cancellation.ThrowIfCancellationRequested(); var firstRead = lines.FirstOrDefault(); if (backward) { lines.Reverse(); } var badPosition = backward ? src.PositionsRange.Begin : src.PositionsRange.End; ScreenBufferLinesRange ret; ret.Lines = lines; ret.BeginPosition = lines.Count > 0 ? lines[0].Message.Position : badPosition; ret.EndPosition = lines.Count > 0 ? lines[lines.Count - 1].Message.EndPosition : badPosition; diag.VerifyLines(ret.Lines, src.HasConsecutiveMessages); return(ret); }
Task IScreenBuffer.SetDisplayTextGetter(MessageTextGetter displayTextGetter, CancellationToken cancellation) { if (this.displayTextGetter == displayTextGetter) { return(Task.FromResult(0)); } this.displayTextGetter = displayTextGetter; changeNotification.Post(); var currentTop = EnumScreenBufferLines().FirstOrDefault(); return(PerformBuffersTransaction( string.Format("SetDisplayTextGetter({0})", displayTextGetter), cancellation, 
 modifyBuffers: tmp => Task.WhenAll(tmp.Select(b => b.LoadAround(GetMaxBufferSize(viewSize), cancellation))), 
 getPivotLine: (lines, bufs) => 
 { 
 var candidate = new DisplayLine(); if (!currentTop.IsEmpty) { candidate = lines.FirstOrDefault(l => MessagesComparer.Compare(l.Message, currentTop.Message) == 0 && l.LineIndex == currentTop.LineIndex); 
 if (candidate.IsEmpty) { candidate = lines.FirstOrDefault(l => MessagesComparer.Compare(l.Message, currentTop.Message) == 0); } } if (candidate.IsEmpty) { candidate = lines.FirstOrDefault(); } if (candidate.IsEmpty) { return null; } 
 return Tuple.Create(candidate, -scrolledLines); 
 } 
)); 
 }
public DisplayLine(IMessage msg, int lineIndex, int linesCount, MessageTextGetter displayTextGetter, IMessagesSource source, int index = -1) { Message = msg; LineIndex = lineIndex; TotalLinesInMessage = linesCount; DisplayTextGetter = displayTextGetter; var msgLen = msg.EndPosition - msg.Position; if (linesCount > 1) { var lineLen = msgLen / (double)linesCount; LineOffsetBegin = lineLen * lineIndex; LineOffsetEnd = (lineIndex + 1) * lineLen; if (lineIndex == linesCount - 1) { // this it to ensure the offset is strictly equal to the beginning of next message. // generic formula with floating point arithmetics leads to inequality. LineOffsetEnd = msgLen; } } else { LineOffsetBegin = 0; LineOffsetEnd = msgLen; } Index = index; Source = source; }
private static IHighlightingHandler MakeSelectionInplaceHighlightingHander( SelectionInfo selection, MessageTextGetter displayTextGetter, IWordSelection wordSelection, int cacheSize) { IHighlightingHandler newHandler = null; if (selection?.IsSingleLine == true) { var normSelection = selection.Normalize(); var text = displayTextGetter(normSelection.First.Message); var line = text.GetNthTextLine(normSelection.First.TextLineIndex); int beginIdx = normSelection.First.LineCharIndex; int endIdx = normSelection.Last.LineCharIndex; var selectedPart = line.SubString(beginIdx, endIdx - beginIdx); if (selectedPart.Any(c => !char.IsWhiteSpace(c))) { var options = new Search.Options() { Template = selectedPart, MessageTextGetter = displayTextGetter, }; var optionsPreprocessed = options.BeginSearch(); newHandler = new CachingHighlightingHandler(msg => GetSelectionHighlightingRanges(msg, optionsPreprocessed, wordSelection, (normSelection.First.Message, beginIdx + line.StartIndex - text.Text.StartIndex)), cacheSize); } } return(newHandler); }
static async Task <ScreenBufferLinesRange> GetScreenBufferLines( IMessagesSource src, DateTime dt, int maxCount, MessageTextGetter displayTextGetter, Diagnostics diag, CancellationToken cancellation) { var startFrom = await src.GetDateBoundPosition(dt, ValueBound.Lower, LogProviderCommandPriority.RealtimeUserAction, cancellation); cancellation.ThrowIfCancellationRequested(); var lines = new List <DisplayLine>(); var additionalMessagesCount = 0; await src.EnumMessages( startFrom.Position, msg => { var messagesLinesCount = displayTextGetter(msg).GetLinesCount(); for (int i = 0; i < messagesLinesCount; ++i) { lines.Add(new DisplayLine(msg, i, messagesLinesCount, displayTextGetter, src)); } var pastRequestedTime = msg.Time.ToLocalDateTime() > dt; if (!pastRequestedTime) { return(true); } ++additionalMessagesCount; return(additionalMessagesCount < maxCount); }, EnumMessagesFlag.Forward | EnumMessagesFlag.IsActiveLogPositionHint, LogProviderCommandPriority.RealtimeUserAction, cancellation ); cancellation.ThrowIfCancellationRequested(); var srcPositionsRange = src.PositionsRange; ScreenBufferLinesRange ret; ret.Lines = lines; ret.BeginPosition = lines.Count > 0 ? lines[0].Message.Position : srcPositionsRange.End; if (lines.Count > 0) { ret.EndPosition = lines[lines.Count - 1].Message.EndPosition; } else { ret.EndPosition = srcPositionsRange.End; } diag.VerifyLines(ret.Lines, src.HasConsecutiveMessages); return(ret); }
private static IEnumerable <(int, int, Color)> GetHlHighlightingRanges( IMessage msg, ImmutableList <IFilter> hlFilters, MessageTextGetter displayTextGetter, ImmutableArray <Color> hlColors) { var filtersState = hlFilters .Where(f => f.Enabled) .Select(filter => (filter.StartBulkProcessing(displayTextGetter, false), filter)) .ToArray(); try { var ret = new List <(int, int, Color)>(); for (int i = 0; i < filtersState.Length; ++i) { var filterState = filtersState[i]; for (int?startPos = null; ;) { var rslt = filterState.Item1.Match(msg, startPos); if (rslt == null) { break; } var r = rslt.Value; if (r.MatchBegin == r.MatchEnd) { break; } if (filterState.filter.Action == FilterAction.Exclude) { return(Enumerable.Empty <(int, int, Color)>()); } ret.Add((r.MatchBegin, r.MatchEnd, filterState.filter.Action.ToColor(hlColors).GetValueOrDefault())); if (r.WholeTextMatched) { break; } startPos = r.MatchEnd; } } return(ret); } finally { foreach (var f in filtersState) { f.Item1.Dispose(); } } }
IFilterBulkProcessing IFilter.StartBulkProcessing( MessageTextGetter messageTextGetter, bool reverseMatchDirection, bool timeboxedMatching) { CheckDisposed(); var tmp = options; tmp.MessageTextGetter = messageTextGetter; tmp.ReverseSearch = reverseMatchDirection; return(new BulkProcessing() { searchState = tmp.BeginSearch(regexFactory, timeboxedMatching) }); }
public BulkProcessing( MessageTextGetter messageTextGetter, bool reverseMatchDirection, IEnumerable <IFilter> filters, FilterAction defaultAction, bool timeboxedMatching ) { this.filters = filters .Where(f => f.Enabled) .Select(f => new KeyValuePair <IFilterBulkProcessing, IFilter>( f.StartBulkProcessing(messageTextGetter, reverseMatchDirection, timeboxedMatching), f )) .ToArray(); this.defaultAction = defaultAction; }
public SourceBuffer(SourceBuffer other, MessageTextGetter displayTextGetter) { this.source = other.source; this.displayTextGetter = displayTextGetter; if (other.displayTextGetter == this.displayTextGetter) { this.beginPosition = other.beginPosition; this.endPosition = other.endPosition; this.lines.AddRange(other.lines); } else { this.beginPosition = other.beginPosition; this.endPosition = other.beginPosition; } this.loggableId = source.LogSourceHint?.ConnectionId ?? this.GetHashCode().ToString("x8"); this.diagnostics = other.diagnostics; }
IFiltersListBulkProcessing IFiltersList.StartBulkProcessing( MessageTextGetter messageTextGetter, bool reverseMatchDirection, bool timeboxedMatching) { if (!filteringEnabled) { return(new DummyBulkProcessing(actionWhenEmptyOrDisabled)); } var defAction = ((IFiltersList)this).GetDefaultAction(); if (list.Count == 0) { return(new DummyBulkProcessing(defAction)); } return(new BulkProcessing(messageTextGetter, reverseMatchDirection, list, defAction, timeboxedMatching)); }
private static IEnumerable <(int b, int e, Color a)> FindSearchMatches( IMessage msg, MessageTextGetter textGetter, IFiltersList filters, bool skipWholeLines) { IFiltersListBulkProcessing processing; try { processing = filters.StartBulkProcessing(textGetter, reverseMatchDirection: false); } catch (Search.TemplateException) { yield break; } using (processing) { for (int?startPos = null; ;) { var rslt = processing.ProcessMessage(msg, startPos); if (rslt.Action == FilterAction.Exclude || rslt.MatchedRange == null) { yield break; } var r = rslt.MatchedRange.Value; if (skipWholeLines && r.WholeTextMatched) { yield break; } if (r.MatchBegin == r.MatchEnd) { yield break; } yield return(r.MatchBegin, r.MatchEnd, new Color()); startPos = r.MatchEnd; } } }
public SourceBuffer(IMessagesSource src, Diagnostics diagnostics, MessageTextGetter displayTextGetter) { this.source = src; this.diagnostics = diagnostics; this.displayTextGetter = displayTextGetter; }
public SelectionInfo(CursorPosition first, CursorPosition last, MessageTextGetter messageTextGetter) { this.first = first ?? throw new ArgumentNullException(nameof(first)); this.last = last; this.messageTextGetter = messageTextGetter; }
MessageDisplayTextInfo IHighlightingManager.GetSearchResultMessageText(IMessage msg, MessageTextGetter originalTextGetter, IFiltersList filters) { var originalText = originalTextGetter(msg); var retLines = new List <StringSlice>(); var retLinesMap = new List <int>(); int originalTextLineIdx = 0; foreach (var m in FindSearchMatches(msg, originalTextGetter, filters, skipWholeLines: false)) { for (int stage = 0; originalTextLineIdx < originalText.GetLinesCount() && stage != 2; ++originalTextLineIdx) { var line = originalText.GetNthTextLine(originalTextLineIdx); var lineBeginIndex = line.StartIndex - originalText.Text.StartIndex; var lineEndIndex = line.EndIndex - originalText.Text.StartIndex; if (lineBeginIndex >= m.e) { break; } if (stage == 0 && lineEndIndex >= m.b) { stage = 1; } if (stage == 1 && lineEndIndex >= m.e) { stage = 2; } if (stage != 0) { retLines.Add(line); retLinesMap.Add(originalTextLineIdx); } } } if (originalTextLineIdx == 0) { retLines.Add(originalText.GetNthTextLine(0)); retLinesMap.Add(originalTextLineIdx); } return(new MessageDisplayTextInfo() { DisplayText = new MultilineText(new StringSlice(string.Join("\n", retLines))), LinesMapper = i => retLinesMap.ElementAtOrDefault(i), ReverseLinesMapper = i => { int result = 0; while (result < retLinesMap.Count && retLinesMap[result] < i) { ++result; } return result; } }); }
private static IEnumerable <(int, int, Color)> GetSearchResultsHighlightingRanges( IMessage msg, IFiltersList filters, MessageTextGetter displayTextGetter) { return(FindSearchMatches(msg, displayTextGetter, filters, skipWholeLines: true)); }