<commit_before>using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Media;

using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.Text;

using NQuery.Authoring.Completion;
using NQuery.Authoring.Wpf;
using NQuery.Text;

namespace NQuery.Authoring.VSEditorWpf.Completion
{
    internal sealed class NQueryCompletionSet : CompletionSet
    {
        private readonly ICompletionSession _session;
        private readonly ICompletionModelManager _completionModelManager;

        public NQueryCompletionSet(ICompletionSession session, ICompletionModelManager completionModelManager)
        {
            _session = session;
            _completionModelManager = completionModelManager;
            _completionModelManager.ModelChanged += CompletionModelManagerOnModelChanged;
            _session.Dismissed += SessionOnDismissed;
            Refresh();
        }

        private void SessionOnDismissed(object sender, EventArgs e)
        {
            _session.Dismissed -= SessionOnDismissed;
            _completionModelManager.ModelChanged -= CompletionModelManagerOnModelChanged;
        }

        private void CompletionModelManagerOnModelChanged(object sender, EventArgs e)
        {
            Refresh();
        }

        private void Refresh()
        {
            Recalculate();
            Filter();
            SelectBestMatch();

            if (CompletionBuilders.Count + Completions.Count == 0)
                _session.Dismiss();
        }

        public override void Recalculate()
        {
            UpdateModel(_completionModelManager.Model);
        }

        private void UpdateModel(CompletionModel model)
        {
            ApplicableTo = ToTrackingSpan(model.ApplicableSpan);

            WritableCompletions.BeginBulkOperation();
            try
            {
                WritableCompletions.Clear();
                WritableCompletions.AddRange(ToCompletions(model.Items));
            }
            finally
            {
                WritableCompletions.EndBulkOperation();
            }
        }

        private ITrackingSpan ToTrackingSpan(TextSpan span)
        {
            var snapshot = _session.TextView.TextBuffer.CurrentSnapshot;
            return snapshot.CreateTrackingSpan(span.Start, span.Length, SpanTrackingMode.EdgeInclusive);
        }

        private IEnumerable<Microsoft.VisualStudio.Language.Intellisense.Completion> ToCompletions(IEnumerable<CompletionItem> completionItems)
        {
            return completionItems.Select(ToCompletion);
        }

        private Microsoft.VisualStudio.Language.Intellisense.Completion ToCompletion(CompletionItem completionItem)
        {
            var displayText = completionItem.DisplayText;
            var insertionText = completionItem.InsertionText;
            var description = completionItem.Description;
            var image = ToImage(completionItem.Glyph);
            return new Microsoft.VisualStudio.Language.Intellisense.Completion(displayText, insertionText, description, image, null);
        }

        private ImageSource ToImage(NQueryGlyph? glyp)
        {
            return glyp == null ? null : NQueryGlyphImageSource.Get(glyp.Value);
        }<commit_msg>Make methods static<commit_after>using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Media;

using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.Text;

using NQuery.Authoring.Completion;
using NQuery.Authoring.Wpf;
using NQuery.Text;

namespace NQuery.Authoring.VSEditorWpf.Completion
{
    internal sealed class NQueryCompletionSet : CompletionSet
    {
        private readonly ICompletionSession _session;
        private readonly ICompletionModelManager _completionModelManager;

        public NQueryCompletionSet(ICompletionSession session, ICompletionModelManager completionModelManager)
        {
            _session = session;
            _completionModelManager = completionModelManager;
            _completionModelManager.ModelChanged += CompletionModelManagerOnModelChanged;
            _session.Dismissed += SessionOnDismissed;
            Refresh();
        }

        private void SessionOnDismissed(object sender, EventArgs e)
        {
            _session.Dismissed -= SessionOnDismissed;
            _completionModelManager.ModelChanged -= CompletionModelManagerOnModelChanged;
        }

        private void CompletionModelManagerOnModelChanged(object sender, EventArgs e)
        {
            Refresh();
        }

        private void Refresh()
        {
            Recalculate();
            Filter();
            SelectBestMatch();

            if (CompletionBuilders.Count + Completions.Count == 0)
                _session.Dismiss();
        }

        public override void Recalculate()
        {
            UpdateModel(_completionModelManager.Model);
        }

        private void UpdateModel(CompletionModel model)
        {
            ApplicableTo = ToTrackingSpan(model.ApplicableSpan);

            WritableCompletions.BeginBulkOperation();
            try
            {
                WritableCompletions.Clear();
                WritableCompletions.AddRange(ToCompletions(model.Items));
            }
            finally
            {
                WritableCompletions.EndBulkOperation();
            }
        }

        private ITrackingSpan ToTrackingSpan(TextSpan span)
        {
            var snapshot = _session.TextView.TextBuffer.CurrentSnapshot;
            return snapshot.CreateTrackingSpan(span.Start, span.Length, SpanTrackingMode.EdgeInclusive);
        }

        private static IEnumerable<Microsoft.VisualStudio.Language.Intellisense.Completion> ToCompletions(IEnumerable<CompletionItem> completionItems)
        {
            return completionItems.Select(ToCompletion);
        }

        private static Microsoft.VisualStudio.Language.Intellisense.Completion ToCompletion(CompletionItem completionItem)
        {
            var displayText = completionItem.DisplayText;
            var insertionText = completionItem.InsertionText;
            var description = completionItem.Description;
            var image = ToImage(completionItem.Glyph);

            return new Microsoft.VisualStudio.Language.Intellisense.Completion(displayText, insertionText, description, image, null);
        }

        private static ImageSource ToImage(NQueryGlyph? glyp)
        {
            return glyp == null ? null : NQueryGlyphImageSource.Get(glyp.Value);
        }
{'fraction_non_alphanumeric': 0.0675221509318668, 'fraction_numerical': 0.00030553009471432935, 'mean_word_length': 2.443976854287217, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6816411', 'n_tokens_mistral': 1621, 'n_tokens_neox': 1558, 'n_words': 287}