2 * Copyright 2000-2017 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.intellij.stats.completion
19 import com.intellij.codeInsight.lookup.LookupAdapter
20 import com.intellij.codeInsight.lookup.LookupElement
21 import com.intellij.codeInsight.lookup.LookupEvent
22 import com.intellij.codeInsight.lookup.impl.LookupImpl
23 import com.intellij.completion.FeatureManagerImpl
24 import com.intellij.stats.personalization.UserFactorDescriptions
25 import com.intellij.stats.personalization.UserFactorStorage
26 import com.jetbrains.completion.ranker.features.impl.FeatureUtils
29 * @author Vitaliy.Bibaev
31 class LookupCompletedTracker : LookupAdapter() {
32 override fun lookupCanceled(event: LookupEvent?) {
33 val lookup = event?.lookup as? LookupImpl ?: return
34 val element = lookup.currentItem ?: return
35 if (isSelectedByTyping(lookup, element)) {
36 processTypedSelect(lookup, element)
40 override fun itemSelected(event: LookupEvent?) {
41 val lookup = event?.lookup as? LookupImpl ?: return
42 val element = event.item ?: return
43 processExplicitSelect(lookup, element)
46 private fun isSelectedByTyping(lookup: LookupImpl, element: LookupElement): Boolean =
47 element.lookupString == lookup.itemPattern(element)
49 private fun processElementSelected(lookup: LookupImpl, element: LookupElement) {
50 val relevanceObjects =
51 lookup.getRelevanceObjects(listOf(element), false)
52 val relevanceMap = relevanceObjects[element]?.associate { it.first to it.second } ?: return
53 val featuresValues = FeatureUtils.preparedMap(relevanceMap)
54 val project = lookup.project
55 val featureManager = FeatureManagerImpl.getInstance()
56 featureManager.binaryFactors.filter { !featureManager.isUserFeature(it.name) }.forEach { feature ->
57 UserFactorStorage.applyOnBoth(project, UserFactorDescriptions.binaryFeatureDescriptor(feature))
59 updater.update(featuresValues[feature.name])
63 featureManager.doubleFactors.filter { !featureManager.isUserFeature(it.name) }.forEach { feature ->
64 UserFactorStorage.applyOnBoth(project, UserFactorDescriptions.doubleFeatureDescriptor(feature))
66 updater.update(featuresValues[feature.name])
70 featureManager.categorialFactors.filter { !featureManager.isUserFeature(it.name) }.forEach { feature ->
71 UserFactorStorage.applyOnBoth(project, UserFactorDescriptions.categoriealFeatureDescriptor(feature))
73 updater.update(featuresValues[feature.name])
78 private fun processExplicitSelect(lookup: LookupImpl, element: LookupElement) {
79 processElementSelected(lookup, element)
81 UserFactorStorage.applyOnBoth(lookup.project, UserFactorDescriptions.COMPLETION_FINISH_TYPE) { updater ->
82 updater.fireExplicitCompletionPerformed()
85 val prefixLength = lookup.getPrefixLength(element)
86 UserFactorStorage.applyOnBoth(lookup.project, UserFactorDescriptions.PREFIX_LENGTH_ON_COMPLETION) { updater ->
87 updater.fireCompletionPerformed(prefixLength)
90 val itemPosition = lookup.selectedIndex
91 if (itemPosition != -1) {
92 UserFactorStorage.applyOnBoth(lookup.project, UserFactorDescriptions.SELECTED_ITEM_POSITION) { updater ->
93 updater.fireCompletionPerformed(itemPosition)
97 if (prefixLength > 1) {
98 val pattern = lookup.itemPattern(element)
99 val isMmemonicsUsed = !element.lookupString.startsWith(pattern)
100 UserFactorStorage.applyOnBoth(lookup.project, UserFactorDescriptions.MNEMONICS_USAGE) { updater ->
101 updater.fireCompletionFinished(isMmemonicsUsed)
106 private fun processTypedSelect(lookup: LookupImpl, element: LookupElement) {
107 processElementSelected(lookup, element)
109 UserFactorStorage.applyOnBoth(lookup.project, UserFactorDescriptions.COMPLETION_FINISH_TYPE) { updater ->
110 updater.fireTypedSelectPerformed()