コード例 #1
0
        public IReadOnlyList <Segment> GetUnderliningInfo( )
        {
            if (LastMatches == null)
            {
                return(Enumerable.Empty <Segment>( ).ToList( ));
            }

            TextData td = null;

            if (!CheckAccess( ))
            {
                ChangeEventHelper.Invoke(CancellationToken.None, () =>
                {
                    td = rtb.GetTextData(LastEol);
                });
            }
            else
            {
                td = rtb.GetTextData(LastEol);
            }

            return(GetUnderliningInfo(NonCancellable.Instance, td, LastMatches, LastShowCaptures));
        }
コード例 #2
0
        void ShowMatchesThreadProc(ICancellable cnc)
        {
            lock ( MatchInfos )
            {
                MatchInfos.Clear( );
                ExternalUnderliningLoop.SendWaitAndExecute( );
            }

            string       text;
            RegexMatches matches;
            bool         show_captures;
            bool         show_succeeded_groups_only;
            bool         show_first_only;

            lock (this)
            {
                text          = LastText;
                matches       = LastMatches;
                show_captures = LastShowCaptures;
                show_succeeded_groups_only = LastShowSucceededGroupsOnly;
                show_first_only            = LastShowFirstOnly;
            }


            if (matches.Count == 0)
            {
                Dispatcher.BeginInvoke(new Action(() =>
                {
                    CancelInfo( );
                    ShowOne(rtbNoMatches);
                }));

                return;
            }


            ChangeEventHelper.Invoke(CancellationToken.None, () =>
            {
                pbProgress.Maximum = matches.Count;
                pbProgress.Value   = 0;

                if (secMatches.Blocks.Count > matches.Count)
                {
                    // remove unneeded paragraphs
                    var r  = new TextRange(secMatches.Blocks.ElementAt(matches.Count).ElementStart, secMatches.ContentEnd);
                    r.Text = "";
                }

                CancelInfo( );
                ShowOne(rtbMatches);
            });

            if (cnc.IsCancellationRequested)
            {
                return;
            }

            int show_pb_time = unchecked (Environment.TickCount + 333);            // (ignore overflow)

            Paragraph previous_para        = null;
            int       match_number         = -1;
            bool      document_has_changed = false;

            int left_width = EvaluateLeftWidth(matches, show_succeeded_groups_only);

            foreach (IMatch match in matches.Matches)
            {
                Debug.Assert(match.Success);

                ++match_number;

                if (cnc.IsCancellationRequested)
                {
                    break;
                }

                var ordered_groups =
                    match.Groups
                    .Skip(1)                                                               // skip match
                    .Where(g => g.Success || !show_succeeded_groups_only)
                    //OrderBy( g => g.Success ? g.Index : match.Index )
                    .ToList( );

                if (cnc.IsCancellationRequested)
                {
                    break;
                }


                int min_index = ordered_groups.Select(g => g.Success ? g.TextIndex : match.TextIndex).Concat(new[] { match.TextIndex }).Min( );
                if (show_captures)
                {
                    min_index = ordered_groups.SelectMany(g => g.Captures).Select(c => c.TextIndex).Concat(new[] { min_index }).Min( );
                }

                if (cnc.IsCancellationRequested)
                {
                    break;
                }

                int left_width_for_match = left_width + (match.TextIndex - min_index);

                Paragraph  para              = null;
                Run        run               = null;
                MatchInfo  match_info        = null;
                RunBuilder match_run_builder = new RunBuilder(MatchValueSpecialStyleInfo);

                var highlight_style       = HighlightStyleInfos[match_number % HighlightStyleInfos.Length];
                var highlight_light_style = HighlightLightStyleInfos[match_number % HighlightStyleInfos.Length];

                // show match

                string match_name_text = show_first_only ? "Fɪʀꜱᴛ Mᴀᴛᴄʜ" : $"Mᴀᴛᴄʜ {match_number + 1}";

                ChangeEventHelper.Invoke(CancellationToken.None, () =>
                {
                    pbProgress.Value = match_number;
                    if (Environment.TickCount >= show_pb_time)
                    {
                        pbProgress.Visibility = Visibility.Visible;
                    }

                    var span = new Span( );

                    para = new Paragraph(span);

                    var start_run = new Run(match_name_text.PadRight(left_width_for_match, ' '), span.ContentEnd);
                    start_run.Style(MatchNormalStyleInfo);

                    Inline value_inline;

                    if (match.Length == 0)
                    {
                        value_inline = new Run("(empty)", span.ContentEnd);                           //
                        value_inline.Style(MatchNormalStyleInfo, LocationStyleInfo);
                    }
                    else
                    {
                        value_inline = match_run_builder.Build(match.Value, span.ContentEnd);
                        value_inline.Style(MatchValueStyleInfo, highlight_style);
                    }

                    run = new Run($"\x200E  ({match.Index}, {match.Length})", span.ContentEnd);
                    run.Style(MatchNormalStyleInfo, LocationStyleInfo);

                    _ = new LineBreak(span.ElementEnd);                       // (after span)

                    match_info = new MatchInfo
                    {
                        MatchSegment = new Segment(match.TextIndex, match.TextLength),
                        Span         = span,
                        ValueInline  = value_inline,
                    };

                    span.Tag = match_info;

                    lock ( MatchInfos )
                    {
                        MatchInfos.Add(match_info);

                        //...ExternalUnderliningEvents.SendRestart( );
                    }

                    // captures for match
                    //if( showCaptures) AppendCaptures( ct, para, LEFT_WIDTH, match, match );
                });

                if (cnc.IsCancellationRequested)
                {
                    break;
                }

                // show groups

                RunBuilder sibling_run_builder = new RunBuilder(null);

                foreach (var group in ordered_groups)
                {
                    if (cnc.IsCancellationRequested)
                    {
                        break;
                    }

                    string group_name_text      = $" • Gʀᴏᴜᴘ ‹{group.Name}›";
                    int    left_width_for_group = left_width_for_match - Math.Max(0, match.TextIndex - (group.Success ? group.TextIndex : match.TextIndex));

                    ChangeEventHelper.Invoke(CancellationToken.None, () =>
                    {
                        var span = new Span( );

                        var start_run = new Run(group_name_text.PadRight(left_width_for_group, ' '), span.ContentEnd);
                        start_run.Style(GroupNameStyleInfo);

                        // (NOTE. Overlaps are possible in this example: (?=(..))

                        Inline value_inline;
                        Inline inl;

                        if (!group.Success)
                        {
                            value_inline = new Run("(fail)", span.ContentEnd);
                            value_inline.Style(GroupFailedStyleInfo);
                        }
                        else if (group.Length == 0)
                        {
                            value_inline = new Run("(empty)", span.ContentEnd);
                            value_inline.Style(LocationStyleInfo);
                        }
                        else
                        {
                            string left   = Utilities.SubstringFromTo(text, match.TextIndex, group.TextIndex);
                            string middle = group.Value;
                            string right  = Utilities.SubstringFromTo(text, group.TextIndex + group.TextLength, Math.Max(match.TextIndex + match.TextLength, group.TextIndex + group.TextLength));

                            inl = sibling_run_builder.Build(left, span.ContentEnd);
                            inl.Style(GroupSiblingValueStyleInfo);

                            value_inline = match_run_builder.Build(middle, span.ContentEnd);
                            value_inline.Style(GroupValueStyleInfo, highlight_light_style);

                            inl = sibling_run_builder.Build(right, span.ContentEnd);
                            inl.Style(GroupSiblingValueStyleInfo);
                        }

                        if (cnc.IsCancellationRequested)
                        {
                            return;
                        }

                        run = new Run($"\x200E  ({group.Index}, {group.Length})", span.ContentEnd);
                        run.Style(MatchNormalStyleInfo, LocationStyleInfo);

                        para.Inlines.Add(span);
                        _ = new LineBreak(span.ElementEnd);                           // (after span)

                        var group_info = new GroupInfo
                        {
                            Parent       = match_info,
                            IsSuccess    = group.Success,
                            GroupSegment = new Segment(group.TextIndex, group.TextLength),
                            Span         = span,
                            ValueInline  = value_inline,
                        };

                        span.Tag = group_info;

                        match_info.GroupInfos.Add(group_info);


                        // captures for group
                        if (show_captures)
                        {
                            AppendCaptures(cnc, group_info, para, left_width_for_match, text, match, group, highlight_light_style, match_run_builder, sibling_run_builder);
                        }
                    });
                }

                if (cnc.IsCancellationRequested)
                {
                    break;
                }

                ChangeEventHelper.Invoke(CancellationToken.None, () =>
                {
                    if (previous_para == null)
                    {
                        var first_block = secMatches.Blocks.FirstBlock;
                        if (first_block == null)
                        {
                            secMatches.Blocks.Add(para);
                        }
                        else
                        {
                            secMatches.Blocks.InsertBefore(first_block, para);
                            secMatches.Blocks.Remove(first_block);
                        }
                    }
                    else
                    {
                        if (!previous_para.ContentStart.IsInSameDocument(rtbMatches.Document.ContentStart))
                        {
                            document_has_changed = true;
                        }
                        else
                        {
                            var next = previous_para.NextBlock;
                            if (next != null)
                            {
                                secMatches.Blocks.Remove(next);
                            }

                            secMatches.Blocks.InsertAfter(previous_para, para);
                        }
                    }
                });

                if (document_has_changed)
                {
                    break;
                }

                previous_para = para;
            }

            if (document_has_changed)
            {
                return;
            }

            if (cnc.IsCancellationRequested)
            {
                return;
            }

            ChangeEventHelper.Invoke(CancellationToken.None, () =>
            {
                pbProgress.Visibility = Visibility.Hidden;
            });


            ExternalUnderliningLoop.SendWaitAndExecute( );
        }
コード例 #3
0
ファイル: UCPattern.xaml.cs プロジェクト: Viorel/RegExpress
        void HighlightingThreadProc(ICancellable cnc)
        {
            IRegexEngine regex_engine;
            string       eol;

            lock (this)
            {
                regex_engine = mRegexEngine;
                eol          = mEol;
            }

            if (regex_engine == null)
            {
                return;
            }

            TextData td           = null;
            Rect     clip_rect    = Rect.Empty;
            int      top_index    = 0;
            int      bottom_index = 0;
            bool     is_focused   = false;

            UITaskHelper.Invoke(rtb, () =>
            {
                td = null;

                var start_doc = rtb.Document.ContentStart;
                var end_doc   = rtb.Document.ContentStart;

                if (!start_doc.HasValidLayout || !end_doc.HasValidLayout)
                {
                    return;
                }

                var td0 = rtb.GetTextData(eol);

                if (cnc.IsCancellationRequested)
                {
                    return;
                }

                td        = td0;
                clip_rect = new Rect(new Size(rtb.ViewportWidth, rtb.ViewportHeight));

                TextPointer top_pointer = rtb.GetPositionFromPoint(new Point(0, 0), snapToText: true).GetLineStartPosition(-1, out int _);
                if (cnc.IsCancellationRequested)
                {
                    return;
                }

                top_index = td.TextPointers.GetIndex(top_pointer, LogicalDirection.Backward);
                if (top_index < 0)
                {
                    top_index = 0;
                }

                TextPointer bottom_pointer = rtb.GetPositionFromPoint(new Point(0, rtb.ViewportHeight), snapToText: true).GetLineStartPosition(+1, out int lines_skipped);
                if (cnc.IsCancellationRequested)
                {
                    return;
                }

                if (bottom_pointer == null || lines_skipped == 0)
                {
                    bottom_index = td.Text.Length;
                }
                else
                {
                    bottom_index = td.TextPointers.GetIndex(bottom_pointer, LogicalDirection.Forward);
                    if (cnc.IsCancellationRequested)
                    {
                        return;
                    }
                }
                if (bottom_index > td.Text.Length)
                {
                    bottom_index = td.Text.Length;
                }
                if (bottom_index < top_index)
                {
                    bottom_index = top_index;                                            // (including 'if bottom_index == 0')
                }
                is_focused = rtb.IsFocused;
            });

            if (cnc.IsCancellationRequested)
            {
                return;
            }

            if (td == null)
            {
                return;
            }
            if (td.Text.Length == 0)
            {
                return;
            }

            Debug.Assert(top_index >= 0);
            Debug.Assert(bottom_index >= top_index);
            Debug.Assert(bottom_index <= td.Text.Length);

            Highlights highlights = null;

            if (is_focused)
            {
                var visible_segment = new Segment(top_index, bottom_index - top_index + 1);

                highlights = new Highlights( );

                regex_engine.HighlightPattern(cnc, highlights, td.Text, td.SelectionStart, td.SelectionEnd, visible_segment);
            }

            if (cnc.IsCancellationRequested)
            {
                return;
            }

            lock ( Locker )
            {
                ChangeEventHelper.Invoke(CancellationToken.None, () =>
                {
                    TryHighlight(ref LeftHighlightedParenthesis, highlights?.LeftPar ?? Segment.Empty, td, PatternParaHighlightStyleInfo);
                    if (cnc.IsCancellationRequested)
                    {
                        return;
                    }

                    TryHighlight(ref RightHighlightedParenthesis, highlights?.RightPar ?? Segment.Empty, td, PatternParaHighlightStyleInfo);
                    if (cnc.IsCancellationRequested)
                    {
                        return;
                    }

                    TryHighlight(ref LeftHighlightedBracket, highlights?.LeftBracket ?? Segment.Empty, td, PatternCharGroupBracketHighlightStyleInfo);
                    if (cnc.IsCancellationRequested)
                    {
                        return;
                    }

                    TryHighlight(ref RightHighlightedBracket, highlights?.RightBracket ?? Segment.Empty, td, PatternCharGroupBracketHighlightStyleInfo);
                    if (cnc.IsCancellationRequested)
                    {
                        return;
                    }

                    TryHighlight(ref LeftHighlightedCurlyBrace, highlights?.LeftCurlyBrace ?? Segment.Empty, td, PatternRangeCurlyBraceHighlightStyleInfo);
                    if (cnc.IsCancellationRequested)
                    {
                        return;
                    }

                    TryHighlight(ref RightHighlightedCurlyBrace, highlights?.RightCurlyBrace ?? Segment.Empty, td, PatternRangeCurlyBraceHighlightStyleInfo);
                    if (cnc.IsCancellationRequested)
                    {
                        return;
                    }
                });
            }
        }