Move keyword completion stuff to frontend-independent module
This commit is contained in:
committed by
TeamCityServer
parent
d7a91cb05e
commit
62fe3930ff
+9
-1
@@ -13,12 +13,14 @@ import com.intellij.codeInsight.lookup.LookupElementBuilder
|
|||||||
import com.intellij.codeInsight.lookup.LookupElementDecorator
|
import com.intellij.codeInsight.lookup.LookupElementDecorator
|
||||||
import com.intellij.codeInsight.lookup.LookupElementPresentation
|
import com.intellij.codeInsight.lookup.LookupElementPresentation
|
||||||
import com.intellij.codeInsight.template.TemplateManager
|
import com.intellij.codeInsight.template.TemplateManager
|
||||||
|
import com.intellij.openapi.module.Module
|
||||||
import com.intellij.patterns.PatternCondition
|
import com.intellij.patterns.PatternCondition
|
||||||
import com.intellij.patterns.StandardPatterns
|
import com.intellij.patterns.StandardPatterns
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import com.intellij.util.ProcessingContext
|
import com.intellij.util.ProcessingContext
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.idea.analysis.analyzeInContext
|
import org.jetbrains.kotlin.idea.analysis.analyzeInContext
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.util.resolveToDescriptor
|
import org.jetbrains.kotlin.idea.caches.resolve.util.resolveToDescriptor
|
||||||
@@ -33,6 +35,7 @@ import org.jetbrains.kotlin.idea.core.NotPropertiesService
|
|||||||
import org.jetbrains.kotlin.idea.core.completion.DeclarationLookupObject
|
import org.jetbrains.kotlin.idea.core.completion.DeclarationLookupObject
|
||||||
import org.jetbrains.kotlin.idea.imports.importableFqName
|
import org.jetbrains.kotlin.idea.imports.importableFqName
|
||||||
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||||
|
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference.ShorteningMode.FORCED_SHORTENING
|
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference.ShorteningMode.FORCED_SHORTENING
|
||||||
import org.jetbrains.kotlin.idea.references.mainReference
|
import org.jetbrains.kotlin.idea.references.mainReference
|
||||||
import org.jetbrains.kotlin.idea.stubindex.PackageIndexUtil
|
import org.jetbrains.kotlin.idea.stubindex.PackageIndexUtil
|
||||||
@@ -539,6 +542,11 @@ class BasicCompletionSession(
|
|||||||
override val descriptorKindFilter: DescriptorKindFilter?
|
override val descriptorKindFilter: DescriptorKindFilter?
|
||||||
get() = null
|
get() = null
|
||||||
|
|
||||||
|
private val keywordCompletion = KeywordCompletion(object : KeywordCompletion.LanguageVersionSettingProvider {
|
||||||
|
override fun getLanguageVersionSetting(element: PsiElement) = element.languageVersionSettings
|
||||||
|
override fun getLanguageVersionSetting(module: Module) = module.languageVersionSettings
|
||||||
|
})
|
||||||
|
|
||||||
override fun doComplete() {
|
override fun doComplete() {
|
||||||
val keywordsToSkip = HashSet<String>()
|
val keywordsToSkip = HashSet<String>()
|
||||||
|
|
||||||
@@ -574,7 +582,7 @@ class BasicCompletionSession(
|
|||||||
|
|
||||||
val keywordsPrefix = prefix.substringBefore('@') // if there is '@' in the prefix - use shorter prefix to not loose 'this' etc
|
val keywordsPrefix = prefix.substringBefore('@') // if there is '@' in the prefix - use shorter prefix to not loose 'this' etc
|
||||||
val isUseSiteAnnotationTarget = position.prevLeaf()?.node?.elementType == KtTokens.AT
|
val isUseSiteAnnotationTarget = position.prevLeaf()?.node?.elementType == KtTokens.AT
|
||||||
KeywordCompletion.complete(expression ?: parameters.position, resultSet.prefixMatcher, isJvmModule) { lookupElement ->
|
keywordCompletion.complete(expression ?: parameters.position, resultSet.prefixMatcher, isJvmModule) { lookupElement ->
|
||||||
val keyword = lookupElement.lookupString
|
val keyword = lookupElement.lookupString
|
||||||
if (keyword in keywordsToSkip) return@complete
|
if (keyword in keywordsToSkip) return@complete
|
||||||
|
|
||||||
|
|||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.completion.handlers
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.completion.InsertionContext
|
||||||
|
import com.intellij.codeInsight.lookup.Lookup
|
||||||
|
import com.intellij.codeInsight.lookup.LookupElement
|
||||||
|
import org.jetbrains.kotlin.idea.completion.KEEP_OLD_ARGUMENT_LIST_ON_TAB_KEY
|
||||||
|
import org.jetbrains.kotlin.idea.completion.smart.SmartCompletion
|
||||||
|
import org.jetbrains.kotlin.idea.completion.tryGetOffset
|
||||||
|
|
||||||
|
class SmartCompletionTailOffsetProviderFE10Impl: SmartCompletionTailOffsetProvider() {
|
||||||
|
override fun getTailOffset(context: InsertionContext, item: LookupElement): Int {
|
||||||
|
val completionChar = context.completionChar
|
||||||
|
var tailOffset = context.tailOffset
|
||||||
|
if (completionChar == Lookup.REPLACE_SELECT_CHAR && item.getUserData(KEEP_OLD_ARGUMENT_LIST_ON_TAB_KEY) != null) {
|
||||||
|
context.offsetMap.tryGetOffset(SmartCompletion.OLD_ARGUMENTS_REPLACEMENT_OFFSET)
|
||||||
|
?.let { tailOffset = it }
|
||||||
|
}
|
||||||
|
return tailOffset
|
||||||
|
}
|
||||||
|
}
|
||||||
+68
-72
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
*
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.idea.completion
|
package org.jetbrains.kotlin.idea.completion
|
||||||
@@ -21,6 +10,7 @@ import com.intellij.codeInsight.completion.InsertionContext
|
|||||||
import com.intellij.codeInsight.completion.PrefixMatcher
|
import com.intellij.codeInsight.completion.PrefixMatcher
|
||||||
import com.intellij.codeInsight.lookup.LookupElement
|
import com.intellij.codeInsight.lookup.LookupElement
|
||||||
import com.intellij.codeInsight.lookup.LookupElementBuilder
|
import com.intellij.codeInsight.lookup.LookupElementBuilder
|
||||||
|
import com.intellij.openapi.module.Module
|
||||||
import com.intellij.openapi.module.ModuleUtilCore
|
import com.intellij.openapi.module.ModuleUtilCore
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
@@ -37,7 +27,6 @@ import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
|||||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget.*
|
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget.*
|
||||||
import org.jetbrains.kotlin.idea.completion.handlers.WithTailInsertHandler
|
import org.jetbrains.kotlin.idea.completion.handlers.WithTailInsertHandler
|
||||||
import org.jetbrains.kotlin.idea.completion.handlers.createKeywordConstructLookupElement
|
import org.jetbrains.kotlin.idea.completion.handlers.createKeywordConstructLookupElement
|
||||||
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
|
||||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens.*
|
import org.jetbrains.kotlin.lexer.KtTokens.*
|
||||||
@@ -59,70 +48,77 @@ open class KeywordLookupObject {
|
|||||||
override fun hashCode(): Int = javaClass.hashCode()
|
override fun hashCode(): Int = javaClass.hashCode()
|
||||||
}
|
}
|
||||||
|
|
||||||
object KeywordCompletion {
|
class KeywordCompletion(private val languageVersionSettingProvider: LanguageVersionSettingProvider) {
|
||||||
private val ALL_KEYWORDS = (KEYWORDS.types + SOFT_KEYWORDS.types)
|
interface LanguageVersionSettingProvider {
|
||||||
.map { it as KtKeywordToken }
|
fun getLanguageVersionSetting(element: PsiElement): LanguageVersionSettings
|
||||||
|
fun getLanguageVersionSetting(module: Module): LanguageVersionSettings
|
||||||
|
}
|
||||||
|
|
||||||
private val KEYWORDS_TO_IGNORE_PREFIX =
|
companion object {
|
||||||
TokenSet.create(OVERRIDE_KEYWORD /* it's needed to complete overrides that should be work by member name too */)
|
private val ALL_KEYWORDS = (KEYWORDS.types + SOFT_KEYWORDS.types)
|
||||||
|
.map { it as KtKeywordToken }
|
||||||
|
|
||||||
private val INCOMPATIBLE_KEYWORDS_AROUND_SEALED = setOf(
|
private val KEYWORDS_TO_IGNORE_PREFIX =
|
||||||
SEALED_KEYWORD,
|
TokenSet.create(OVERRIDE_KEYWORD /* it's needed to complete overrides that should be work by member name too */)
|
||||||
ANNOTATION_KEYWORD,
|
|
||||||
DATA_KEYWORD,
|
|
||||||
ENUM_KEYWORD,
|
|
||||||
OPEN_KEYWORD,
|
|
||||||
INNER_KEYWORD,
|
|
||||||
ABSTRACT_KEYWORD
|
|
||||||
).mapTo(HashSet()) { it.value }
|
|
||||||
|
|
||||||
private val COMPOUND_KEYWORDS = mapOf<KtKeywordToken, Set<KtKeywordToken>>(
|
private val INCOMPATIBLE_KEYWORDS_AROUND_SEALED = setOf(
|
||||||
COMPANION_KEYWORD to setOf(OBJECT_KEYWORD),
|
SEALED_KEYWORD,
|
||||||
DATA_KEYWORD to setOf(CLASS_KEYWORD),
|
ANNOTATION_KEYWORD,
|
||||||
ENUM_KEYWORD to setOf(CLASS_KEYWORD),
|
DATA_KEYWORD,
|
||||||
ANNOTATION_KEYWORD to setOf(CLASS_KEYWORD),
|
ENUM_KEYWORD,
|
||||||
SEALED_KEYWORD to setOf(CLASS_KEYWORD, INTERFACE_KEYWORD, FUN_KEYWORD),
|
OPEN_KEYWORD,
|
||||||
LATEINIT_KEYWORD to setOf(VAR_KEYWORD),
|
INNER_KEYWORD,
|
||||||
CONST_KEYWORD to setOf(VAL_KEYWORD),
|
ABSTRACT_KEYWORD
|
||||||
SUSPEND_KEYWORD to setOf(FUN_KEYWORD)
|
).mapTo(HashSet()) { it.value }
|
||||||
)
|
|
||||||
|
|
||||||
private val COMPOUND_KEYWORDS_NOT_SUGGEST_TOGETHER = mapOf<KtKeywordToken, Set<KtKeywordToken>>(
|
private val COMPOUND_KEYWORDS = mapOf<KtKeywordToken, Set<KtKeywordToken>>(
|
||||||
// 'fun' can follow 'sealed', e.g. "sealed fun interface". But "sealed fun" looks irrelevant differ to "sealed interface/class".
|
COMPANION_KEYWORD to setOf(OBJECT_KEYWORD),
|
||||||
SEALED_KEYWORD to setOf(FUN_KEYWORD),
|
DATA_KEYWORD to setOf(CLASS_KEYWORD),
|
||||||
)
|
ENUM_KEYWORD to setOf(CLASS_KEYWORD),
|
||||||
|
ANNOTATION_KEYWORD to setOf(CLASS_KEYWORD),
|
||||||
|
SEALED_KEYWORD to setOf(CLASS_KEYWORD, INTERFACE_KEYWORD, FUN_KEYWORD),
|
||||||
|
LATEINIT_KEYWORD to setOf(VAR_KEYWORD),
|
||||||
|
CONST_KEYWORD to setOf(VAL_KEYWORD),
|
||||||
|
SUSPEND_KEYWORD to setOf(FUN_KEYWORD)
|
||||||
|
)
|
||||||
|
|
||||||
private val KEYWORD_CONSTRUCTS = mapOf<KtKeywordToken, String>(
|
private val COMPOUND_KEYWORDS_NOT_SUGGEST_TOGETHER = mapOf<KtKeywordToken, Set<KtKeywordToken>>(
|
||||||
IF_KEYWORD to "fun foo() { if (caret)",
|
// 'fun' can follow 'sealed', e.g. "sealed fun interface". But "sealed fun" looks irrelevant differ to "sealed interface/class".
|
||||||
WHILE_KEYWORD to "fun foo() { while(caret)",
|
SEALED_KEYWORD to setOf(FUN_KEYWORD),
|
||||||
FOR_KEYWORD to "fun foo() { for(caret)",
|
)
|
||||||
TRY_KEYWORD to "fun foo() { try {\ncaret\n}",
|
|
||||||
CATCH_KEYWORD to "fun foo() { try {} catch (caret)",
|
|
||||||
FINALLY_KEYWORD to "fun foo() { try {\n}\nfinally{\ncaret\n}",
|
|
||||||
DO_KEYWORD to "fun foo() { do {\ncaret\n}",
|
|
||||||
INIT_KEYWORD to "class C { init {\ncaret\n}",
|
|
||||||
CONSTRUCTOR_KEYWORD to "class C { constructor(caret)"
|
|
||||||
)
|
|
||||||
|
|
||||||
private val NO_SPACE_AFTER = listOf(
|
private val KEYWORD_CONSTRUCTS = mapOf<KtKeywordToken, String>(
|
||||||
THIS_KEYWORD,
|
IF_KEYWORD to "fun foo() { if (caret)",
|
||||||
SUPER_KEYWORD,
|
WHILE_KEYWORD to "fun foo() { while(caret)",
|
||||||
NULL_KEYWORD,
|
FOR_KEYWORD to "fun foo() { for(caret)",
|
||||||
TRUE_KEYWORD,
|
TRY_KEYWORD to "fun foo() { try {\ncaret\n}",
|
||||||
FALSE_KEYWORD,
|
CATCH_KEYWORD to "fun foo() { try {} catch (caret)",
|
||||||
BREAK_KEYWORD,
|
FINALLY_KEYWORD to "fun foo() { try {\n}\nfinally{\ncaret\n}",
|
||||||
CONTINUE_KEYWORD,
|
DO_KEYWORD to "fun foo() { do {\ncaret\n}",
|
||||||
ELSE_KEYWORD,
|
INIT_KEYWORD to "class C { init {\ncaret\n}",
|
||||||
WHEN_KEYWORD,
|
CONSTRUCTOR_KEYWORD to "class C { constructor(caret)"
|
||||||
FILE_KEYWORD,
|
)
|
||||||
DYNAMIC_KEYWORD,
|
|
||||||
GET_KEYWORD,
|
private val NO_SPACE_AFTER = listOf(
|
||||||
SET_KEYWORD
|
THIS_KEYWORD,
|
||||||
).map { it.value } + "companion object"
|
SUPER_KEYWORD,
|
||||||
|
NULL_KEYWORD,
|
||||||
|
TRUE_KEYWORD,
|
||||||
|
FALSE_KEYWORD,
|
||||||
|
BREAK_KEYWORD,
|
||||||
|
CONTINUE_KEYWORD,
|
||||||
|
ELSE_KEYWORD,
|
||||||
|
WHEN_KEYWORD,
|
||||||
|
FILE_KEYWORD,
|
||||||
|
DYNAMIC_KEYWORD,
|
||||||
|
GET_KEYWORD,
|
||||||
|
SET_KEYWORD
|
||||||
|
).map { it.value } + "companion object"
|
||||||
|
}
|
||||||
|
|
||||||
fun complete(position: PsiElement, prefixMatcher: PrefixMatcher, isJvmModule: Boolean, consumer: (LookupElement) -> Unit) {
|
fun complete(position: PsiElement, prefixMatcher: PrefixMatcher, isJvmModule: Boolean, consumer: (LookupElement) -> Unit) {
|
||||||
if (!GENERAL_FILTER.isAcceptable(position, position)) return
|
if (!GENERAL_FILTER.isAcceptable(position, position)) return
|
||||||
val sealedInterfacesEnabled = position.languageVersionSettings.supportsFeature(LanguageFeature.SealedInterfaces)
|
val sealedInterfacesEnabled = languageVersionSettingProvider.getLanguageVersionSetting(position).supportsFeature(LanguageFeature.SealedInterfaces)
|
||||||
|
|
||||||
val parserFilter = buildFilter(position)
|
val parserFilter = buildFilter(position)
|
||||||
for (keywordToken in ALL_KEYWORDS) {
|
for (keywordToken in ALL_KEYWORDS) {
|
||||||
@@ -422,9 +418,9 @@ object KeywordCompletion {
|
|||||||
fun isKeywordCorrectlyApplied(keywordTokenType: KtKeywordToken, file: KtFile): Boolean {
|
fun isKeywordCorrectlyApplied(keywordTokenType: KtKeywordToken, file: KtFile): Boolean {
|
||||||
val elementAt = file.findElementAt(prefixText.length)!!
|
val elementAt = file.findElementAt(prefixText.length)!!
|
||||||
|
|
||||||
val languageVersionSettings = ModuleUtilCore.findModuleForPsiElement(position)?.languageVersionSettings
|
val languageVersionSettings =
|
||||||
?: LanguageVersionSettingsImpl.DEFAULT
|
ModuleUtilCore.findModuleForPsiElement(position)?.let(languageVersionSettingProvider::getLanguageVersionSetting)
|
||||||
|
?: LanguageVersionSettingsImpl.DEFAULT
|
||||||
when {
|
when {
|
||||||
!elementAt.node!!.elementType.matchesKeyword(keywordTokenType) -> return false
|
!elementAt.node!!.elementType.matchesKeyword(keywordTokenType) -> return false
|
||||||
|
|
||||||
+10
-22
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
*
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.idea.completion.handlers
|
package org.jetbrains.kotlin.idea.completion.handlers
|
||||||
@@ -19,13 +8,15 @@ package org.jetbrains.kotlin.idea.completion.handlers
|
|||||||
import com.intellij.codeInsight.AutoPopupController
|
import com.intellij.codeInsight.AutoPopupController
|
||||||
import com.intellij.codeInsight.completion.InsertHandler
|
import com.intellij.codeInsight.completion.InsertHandler
|
||||||
import com.intellij.codeInsight.completion.InsertionContext
|
import com.intellij.codeInsight.completion.InsertionContext
|
||||||
import com.intellij.codeInsight.lookup.Lookup
|
|
||||||
import com.intellij.codeInsight.lookup.LookupElement
|
import com.intellij.codeInsight.lookup.LookupElement
|
||||||
|
import com.intellij.openapi.components.serviceOrNull
|
||||||
import com.intellij.openapi.editor.Document
|
import com.intellij.openapi.editor.Document
|
||||||
import com.intellij.psi.PsiDocumentManager
|
import com.intellij.psi.PsiDocumentManager
|
||||||
import org.jetbrains.kotlin.idea.completion.KEEP_OLD_ARGUMENT_LIST_ON_TAB_KEY
|
|
||||||
import org.jetbrains.kotlin.idea.completion.smart.SmartCompletion
|
|
||||||
import org.jetbrains.kotlin.idea.completion.tryGetOffset
|
abstract class SmartCompletionTailOffsetProvider {
|
||||||
|
abstract fun getTailOffset(context: InsertionContext, item: LookupElement): Int
|
||||||
|
}
|
||||||
|
|
||||||
class WithTailInsertHandler(
|
class WithTailInsertHandler(
|
||||||
val tailText: String,
|
val tailText: String,
|
||||||
@@ -48,11 +39,8 @@ class WithTailInsertHandler(
|
|||||||
val document = context.document
|
val document = context.document
|
||||||
PsiDocumentManager.getInstance(context.project).doPostponedOperationsAndUnblockDocument(document)
|
PsiDocumentManager.getInstance(context.project).doPostponedOperationsAndUnblockDocument(document)
|
||||||
|
|
||||||
var tailOffset = context.tailOffset
|
var tailOffset = serviceOrNull<SmartCompletionTailOffsetProvider>()?.getTailOffset(context, item)
|
||||||
if (completionChar == Lookup.REPLACE_SELECT_CHAR && item.getUserData(KEEP_OLD_ARGUMENT_LIST_ON_TAB_KEY) != null) {
|
?:context.tailOffset
|
||||||
context.offsetMap.tryGetOffset(SmartCompletion.OLD_ARGUMENTS_REPLACEMENT_OFFSET)
|
|
||||||
?.let { tailOffset = it }
|
|
||||||
}
|
|
||||||
|
|
||||||
val moveCaret = context.editor.caretModel.offset == tailOffset
|
val moveCaret = context.editor.caretModel.offset == tailOffset
|
||||||
|
|
||||||
@@ -150,11 +150,6 @@ fun Editor.unblockDocument() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Editor.moveCaret(offset: Int, scrollType: ScrollType = ScrollType.RELATIVE) {
|
|
||||||
caretModel.moveToOffset(offset)
|
|
||||||
scrollingModel.scrollToCaret(scrollType)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun findInsertAfterAnchor(editor: Editor?, body: KtClassBody): PsiElement? {
|
private fun findInsertAfterAnchor(editor: Editor?, body: KtClassBody): PsiElement? {
|
||||||
val afterAnchor = body.lBrace ?: return null
|
val afterAnchor = body.lBrace ?: return null
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.core
|
||||||
|
|
||||||
|
import com.intellij.openapi.editor.Editor
|
||||||
|
import com.intellij.openapi.editor.ScrollType
|
||||||
|
|
||||||
|
|
||||||
|
fun Editor.moveCaret(offset: Int, scrollType: ScrollType = ScrollType.RELATIVE) {
|
||||||
|
caretModel.moveToOffset(offset)
|
||||||
|
scrollingModel.scrollToCaret(scrollType)
|
||||||
|
}
|
||||||
@@ -148,7 +148,8 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
|
|||||||
<extensions defaultExtensionNs="com.intellij">
|
<extensions defaultExtensionNs="com.intellij">
|
||||||
<pathMacroContributor implementation="org.jetbrains.kotlin.idea.KotlinPluginMacros"/>
|
<pathMacroContributor implementation="org.jetbrains.kotlin.idea.KotlinPluginMacros"/>
|
||||||
<applicationService serviceImplementation="org.jetbrains.kotlin.idea.PluginStartupApplicationService" />
|
<applicationService serviceImplementation="org.jetbrains.kotlin.idea.PluginStartupApplicationService" />
|
||||||
|
<applicationService serviceInterface="org.jetbrains.kotlin.idea.completion.handlers.SmartCompletionTailOffsetProvider"
|
||||||
|
serviceImplementation="org.jetbrains.kotlin.idea.completion.handlers.SmartCompletionTailOffsetProviderFE10Impl"/>
|
||||||
<postStartupActivity implementation="org.jetbrains.kotlin.idea.PluginStartupActivity"/>
|
<postStartupActivity implementation="org.jetbrains.kotlin.idea.PluginStartupActivity"/>
|
||||||
<projectService serviceImplementation="org.jetbrains.kotlin.idea.PluginStartupService"/>
|
<projectService serviceImplementation="org.jetbrains.kotlin.idea.PluginStartupService"/>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user