Removed IDE templates from completion, replaced them with keywords.

This commit is contained in:
Evgeny Gerashchenko
2013-09-13 20:20:30 +04:00
parent dcfeea4029
commit 1ed168fd14
13 changed files with 73 additions and 228 deletions
@@ -41,7 +41,6 @@ import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lexer.JetToken;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.plugin.completion.handlers.JetKeywordInsertHandler;
import org.jetbrains.jet.plugin.completion.handlers.JetTemplateInsertHandler;
import org.jetbrains.jet.plugin.completion.weigher.WeigherPackage;
import java.util.ArrayList;
@@ -71,28 +70,6 @@ public class JetKeywordCompletionContributor extends CompletionContributor {
private final static List<String> FUNCTION_KEYWORDS = Lists.newArrayList(GET_KEYWORD.toString(), SET_KEYWORD.toString());
private static final String IF_TEMPLATE = "if (<#<condition>#>) {\n<#<block>#>\n}";
private static final String IF_ELSE_TEMPLATE = "if (<#<condition>#>) {\n<#<block>#>\n} else {\n<#<block>#>\n}";
private static final String IF_ELSE_ONE_LINE_TEMPLATE = "if (<#<condition>#>) <#<value>#> else <#<value>#>";
private static final String FUN_TEMPLATE = "fun <#<name>#>(<#<params>#>) : <#<returnType>#> {\n<#<body>#>\n}";
private static final String VAL_SIMPLE_TEMPLATE = "val <#<name>#> = <#<value>#>";
private static final String VAL_WITH_TYPE_TEMPLATE = "val <#<name>#> : <#<valType>#> = <#<value>#>";
private static final String VAL_WITH_GETTER_TEMPLATE = "val <#<name>#> : <#<valType>#>\nget() {\n<#<body>#>\n}";
private static final String VAR_SIMPLE_TEMPLATE = "var <#<name>#> = <#<value>#>";
private static final String VAR_WITH_TYPE_TEMPLATE = "var <#<name>#> : <#<varType>#> = <#<initial>#>";
private static final String VAR_WITH_GETTER_AND_SETTER_TEMPLATE = "var <#<name>#> : <#<varType>#>\nget() {\n<#<body>#>\n}\nset(value) {\n<#<body>#>\n}";
private static final String TRAIT_TEMPLATE = "trait <#<name>#> {\n<#<body>#>\n}";
private static final String CLASS_TEMPLATE = "class <#<name>#> {\n<#<body>#>\n}";
private static final String CLASS_OBJECT_TEMPLATE = "class object {\n<#<body>#>\n}";
private static final String CLASS_OBJECT_WITHOUT_CLASS_TEMPLATE = "object {\n<#<body>#>\n}";
private static final String FOR_TEMPLATE = "for (<#<i>#> in <#<elements>#>) {\n<#<body>#>\n}";
private static final String WHEN_TEMPLATE = "when (<#<expression>#>) {\n<#<condition>#> -> <#<value>#>\n" +
"else -> <#<elseValue>#>\n}";
private static final String WHEN_ENTRY_TEMPLATE = "<#<condition>#> -> <#<value>#>";
private static final String WHILE_TEMPLATE = "while (<#<condition>#>) {\n<#<body>#>\n}";
private static final String DO_WHILE_TEMPLATE = "do {\n<#<body>#>\n} while (<#<condition>#>)";
private static final String ENUM_CLASS_TEMPLATE = "enum class <#<name>#> {\n<#<body>#>\n}";
private static class CommentFilter implements ElementFilter {
@Override
public boolean isAcceptable(Object element, PsiElement context) {
@@ -202,13 +179,6 @@ public class JetKeywordCompletionContributor extends CompletionContributor {
}
}
private static class InWhenFilter extends PositionElementFilter {
@Override
public boolean isAcceptable(Object element, PsiElement context) {
return PsiTreeUtil.getParentOfType(context, JetWhenExpression.class, false) != null;
}
}
private static class SimplePrefixMatcher extends PrefixMatcher {
protected SimplePrefixMatcher(String prefix) {
super(prefix);
@@ -240,10 +210,6 @@ public class JetKeywordCompletionContributor extends CompletionContributor {
public LookupElement apply(String keyword) {
LookupElementBuilder lookupElementBuilder = LookupElementBuilder.create(keyword).bold();
if (keyword.contains("<#<")) {
return JetTemplateInsertHandler.lookup(keyword);
}
if (!FUNCTION_KEYWORDS.contains(keyword)) {
return lookupElementBuilder.withInsertHandler(KEYWORDS_INSERT_HANDLER);
}
@@ -270,12 +236,12 @@ public class JetKeywordCompletionContributor extends CompletionContributor {
public JetKeywordCompletionContributor() {
registerScopeKeywordsCompletion(InTopFilter.class.getName(), new InTopFilter(),
ABSTRACT_KEYWORD,
FINAL_KEYWORD, GET_KEYWORD,
ABSTRACT_KEYWORD, CLASS_KEYWORD, ENUM_KEYWORD,
FINAL_KEYWORD, FUN_KEYWORD, GET_KEYWORD,
IMPORT_KEYWORD, INLINE_KEYWORD, INTERNAL_KEYWORD,
OPEN_KEYWORD, PACKAGE_KEYWORD, PRIVATE_KEYWORD,
PROTECTED_KEYWORD, PUBLIC_KEYWORD, SET_KEYWORD,
TYPE_KEYWORD);
PROTECTED_KEYWORD, PUBLIC_KEYWORD, SET_KEYWORD, TRAIT_KEYWORD,
TYPE_KEYWORD, VAL_KEYWORD, VAR_KEYWORD);
registerScopeKeywordsCompletion(
"In modifier list but not in parameters",
@@ -286,73 +252,49 @@ public class JetKeywordCompletionContributor extends CompletionContributor {
OPEN_KEYWORD, PRIVATE_KEYWORD, PROTECTED_KEYWORD, PUBLIC_KEYWORD);
registerScopeKeywordsCompletion(InClassBodyFilter.class.getName(), new InClassBodyFilter(),
ABSTRACT_KEYWORD,
FINAL_KEYWORD, GET_KEYWORD,
ABSTRACT_KEYWORD, CLASS_KEYWORD, ENUM_KEYWORD,
FINAL_KEYWORD, FUN_KEYWORD, GET_KEYWORD,
INLINE_KEYWORD, INTERNAL_KEYWORD,
OPEN_KEYWORD, OVERRIDE_KEYWORD, PRIVATE_KEYWORD,
PROTECTED_KEYWORD, PUBLIC_KEYWORD, SET_KEYWORD,
TYPE_KEYWORD);
PROTECTED_KEYWORD, PUBLIC_KEYWORD, SET_KEYWORD, TRAIT_KEYWORD,
TYPE_KEYWORD, VAL_KEYWORD, VAR_KEYWORD);
registerScopeKeywordsCompletion(InNonClassBlockFilter.class.getName(), new InNonClassBlockFilter(),
AS_KEYWORD, BREAK_KEYWORD, BY_KEYWORD,
CATCH_KEYWORD, CONTINUE_KEYWORD,
ELSE_KEYWORD,
FALSE_KEYWORD, FINALLY_KEYWORD,
GET_KEYWORD,
CATCH_KEYWORD, CLASS_KEYWORD, CONTINUE_KEYWORD,
DO_KEYWORD, ELSE_KEYWORD, ENUM_KEYWORD,
FALSE_KEYWORD, FINALLY_KEYWORD, FOR_KEYWORD, FUN_KEYWORD,
GET_KEYWORD, IF_KEYWORD,
IN_KEYWORD, INLINE_KEYWORD, INTERNAL_KEYWORD,
IS_KEYWORD, NULL_KEYWORD, OBJECT_KEYWORD,
PRIVATE_KEYWORD, PROTECTED_KEYWORD, PUBLIC_KEYWORD,
RETURN_KEYWORD, SET_KEYWORD, SUPER_KEYWORD,
CAPITALIZED_THIS_KEYWORD, THIS_KEYWORD, THROW_KEYWORD,
TRUE_KEYWORD, TRY_KEYWORD,
TYPE_KEYWORD,
VARARG_KEYWORD, WHERE_KEYWORD);
TRAIT_KEYWORD, TRUE_KEYWORD, TRY_KEYWORD,
TYPE_KEYWORD, VAL_KEYWORD, VAR_KEYWORD,
VARARG_KEYWORD, WHEN_KEYWORD, WHERE_KEYWORD, WHILE_KEYWORD);
registerScopeKeywordsCompletion(InPropertyBodyFilter.class.getName(), new InPropertyBodyFilter(),
ELSE_KEYWORD, FALSE_KEYWORD,
NULL_KEYWORD, THIS_KEYWORD, TRUE_KEYWORD);
ELSE_KEYWORD, FALSE_KEYWORD, IF_KEYWORD,
NULL_KEYWORD, THIS_KEYWORD, TRUE_KEYWORD, WHEN_KEYWORD);
registerScopeKeywordsCompletion(InTypeParameterFirstChildFilter.class.getName(), new InTypeParameterFirstChildFilter(), false,
IN_KEYWORD, OUT_KEYWORD);
// templates
registerScopeKeywordsCompletion(InWhenFilter.class.getName(), new InWhenFilter(),
WHEN_ENTRY_TEMPLATE);
registerScopeKeywordsCompletion(InTopFilter.class.getName(), new InTopFilter(),
FUN_TEMPLATE, VAL_WITH_TYPE_TEMPLATE, VAL_WITH_GETTER_TEMPLATE,
VAR_WITH_TYPE_TEMPLATE, VAR_WITH_GETTER_AND_SETTER_TEMPLATE,
TRAIT_TEMPLATE, CLASS_TEMPLATE, ENUM_CLASS_TEMPLATE);
registerScopeKeywordsCompletion(InClassBodyFilter.class.getName(), new InClassBodyFilter(),
FUN_TEMPLATE, VAL_WITH_TYPE_TEMPLATE, VAL_WITH_GETTER_TEMPLATE,
VAR_WITH_TYPE_TEMPLATE, VAR_WITH_GETTER_AND_SETTER_TEMPLATE,
TRAIT_TEMPLATE, CLASS_TEMPLATE, CLASS_OBJECT_TEMPLATE,
ENUM_CLASS_TEMPLATE);
registerScopeKeywordsCompletion(InNonClassBlockFilter.class.getName(), new InNonClassBlockFilter(),
IF_TEMPLATE, IF_ELSE_TEMPLATE, IF_ELSE_ONE_LINE_TEMPLATE,
FUN_TEMPLATE, VAL_SIMPLE_TEMPLATE, VAR_SIMPLE_TEMPLATE,
TRAIT_TEMPLATE, CLASS_TEMPLATE, FOR_TEMPLATE,
WHEN_TEMPLATE, WHILE_TEMPLATE, DO_WHILE_TEMPLATE, ENUM_CLASS_TEMPLATE);
registerScopeKeywordsCompletion(InPropertyBodyFilter.class.getName(), new InPropertyBodyFilter(),
IF_ELSE_ONE_LINE_TEMPLATE, WHEN_TEMPLATE);
registerScopeKeywordsCompletion(AfterClassInClassBodyFilter.class.getName(), new AfterClassInClassBodyFilter(), false,
CLASS_OBJECT_WITHOUT_CLASS_TEMPLATE);
OBJECT_KEYWORD);
}
private void registerScopeKeywordsCompletion(String debugName, ElementFilter placeFilter, boolean notIdentifier, String... keywords) {
extend(CompletionType.BASIC, getPlacePattern(placeFilter, notIdentifier),
new KeywordsCompletionProvider(debugName, keywords));
extend(CompletionType.BASIC, getPlacePattern(placeFilter, notIdentifier), new KeywordsCompletionProvider(debugName, keywords));
}
private void registerScopeKeywordsCompletion(String debugName, ElementFilter placeFilter, boolean notIdentifier, JetToken... keywords) {
registerScopeKeywordsCompletion(debugName, placeFilter, notIdentifier, convertTokensToStrings(keywords));
}
private void registerScopeKeywordsCompletion(String debugName, ElementFilter placeFilter, String... keywords) {
registerScopeKeywordsCompletion(debugName, placeFilter, true, keywords);
}
private void registerScopeKeywordsCompletion(String debugName, ElementFilter placeFilter, JetToken... keywords) {
registerScopeKeywordsCompletion(debugName, placeFilter, convertTokensToStrings(keywords));
registerScopeKeywordsCompletion(debugName, placeFilter, true, convertTokensToStrings(keywords));
}
private static String[] convertTokensToStrings(JetToken... keywords) {
@@ -1,91 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* 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.jet.plugin.completion.handlers;
import com.intellij.codeInsight.completion.InsertHandler;
import com.intellij.codeInsight.completion.InsertionContext;
import com.intellij.codeInsight.folding.CodeFoldingManager;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.SelectionModel;
import com.intellij.psi.codeStyle.CodeStyleManager;
public class JetTemplateInsertHandler implements InsertHandler<LookupElement> {
private String myInsertion;
public JetTemplateInsertHandler(String insertion) {
myInsertion = insertion;
}
@Override
public void handleInsert(InsertionContext context, LookupElement item) {
Document document = context.getDocument();
Editor editor = context.getEditor();
String insertion = myInsertion;
char currentChar = context.getTailOffset() < document.getTextLength() ? document.getCharsSequence().charAt(context.getTailOffset()) : 0;
if (insertion.endsWith(" ") && context.getCompletionChar() != ' ' && (currentChar == ')' || currentChar == ' ' || currentChar == '\t')) {
insertion = insertion.trim();
}
int tailOffset = context.getStartOffset() + insertion.length();
int caretOffset = insertion.indexOf('|');
if (caretOffset != -1) {
insertion = insertion.replace("|", "");
tailOffset = context.getStartOffset() + caretOffset;
}
document.replaceString(context.getStartOffset(), context.getTailOffset(), insertion);
context.setTailOffset(tailOffset);
CodeFoldingManager foldManager = CodeFoldingManager.getInstance(context.getProject());
foldManager.updateFoldRegions(editor);
String text = document.getText();
int firstParamStart = text.indexOf("<#<", context.getStartOffset());
int firstParamEnd = text.indexOf(">#>", firstParamStart);
SelectionModel selectionModel = editor.getSelectionModel();
if (firstParamStart >= 0 && firstParamEnd >= 0 && firstParamStart < context.getTailOffset()) {
selectionModel.setSelection(firstParamStart, firstParamEnd + 2);
}
if (!insertion.endsWith(" ")) {
CodeStyleManager.getInstance(context.getProject()).reformatText(context.getFile(), context.getStartOffset(), context.getTailOffset());
}
if (firstParamStart >= 0 && firstParamEnd >= 0 && selectionModel.hasSelection()) {
editor.getCaretModel().moveToOffset(selectionModel.getSelectionStart());
}
else {
editor.getCaretModel().moveToOffset(context.getTailOffset());
}
if (context.getCompletionChar() == ' ') {
context.setAddCompletionChar(false);
}
}
public static LookupElementBuilder lookup(String template) {
String presentation = template.replaceAll("<#<(\\w+)>#>", "...").replace("\n", "");
LookupElementBuilder builder = LookupElementBuilder.create(presentation).setBold();
return builder.setInsertHandler(new JetTemplateInsertHandler(template));
}
}
@@ -15,17 +15,17 @@ public class Test {
// ABSENT: break
// ABSENT: by
// ABSENT: catch
// EXIST: class ... {...}
// EXIST: class
// ABSENT: continue
// ABSENT: default
// ABSENT: do
// ABSENT: else
// EXIST: enum class ... {...}
// EXIST: enum
// ABSENT: false
// EXIST: final
// ABSENT: finally
// ABSENT: for
// EXIST: fun ...(...) : ... {...}
// EXIST: fun
// EXIST: get
// ABSENT: if
// ABSENT: import
@@ -49,14 +49,12 @@ public class Test {
// ABSENT: This
// ABSENT: this
// ABSENT: throw
// EXIST: trait ... {...}
// EXIST: trait
// ABSENT: true
// ABSENT: try
// EXIST: type
// EXIST: val ... : ... = ...
// EXIST: val ... : ...get() {...}
// EXIST: var ... : ... = ...
// EXIST: var ... : ...get() {...}set(value) {...}
// EXIST: val
// EXIST: var
// ABSENT: vararg
// ABSENT: when
// ABSENT: where
@@ -10,17 +10,17 @@ class TestClass {
// ABSENT: break
// ABSENT: by
// ABSENT: catch
// EXIST: class ... {...}
// EXIST: class
// ABSENT: continue
// ABSENT: default
// ABSENT: do
// ABSENT: else
// EXIST: enum class ... {...}
// EXIST: enum
// ABSENT: false
// EXIST: final
// ABSENT: finally
// ABSENT: for
// EXIST: fun ...(...) : ... {...}
// EXIST: fun
// EXIST: get
// ABSENT: if
// ABSENT: import
@@ -44,14 +44,12 @@ class TestClass {
// ABSENT: This
// ABSENT: this
// ABSENT: throw
// EXIST: trait ... {...}
// EXIST: trait
// ABSENT: true
// ABSENT: try
// EXIST: type
// EXIST: val ... : ... = ...
// EXIST: val ... : ...get() {...}
// EXIST: var ... : ... = ...
// EXIST: var ... : ...get() {...}set(value) {...}
// EXIST: val
// EXIST: var
// ABSENT: vararg
// ABSENT: when
// ABSENT: where
@@ -8,18 +8,18 @@ fun foo() {
// EXIST: break
// EXIST: by
// EXIST: catch
// EXIST: class ... {...}
// EXIST: class
// EXIST: continue
// EXIST: do {...} while (...)
// EXIST: do
// EXIST: else
// EXIST: enum class ... {...}
// EXIST: enum
// EXIST: false
// ABSENT: final
// EXIST: finally
// EXIST: for (... in ...) {...}
// EXIST: fun ...(...) : ... {...}
// EXIST: for
// EXIST: fun
// EXIST: get
// EXIST: if (...) {...}
// EXIST: if
// ABSENT: import
// EXIST: in
// EXIST: inline
@@ -40,13 +40,13 @@ fun foo() {
// EXIST: This
// EXIST: this
// EXIST: throw
// EXIST: trait ... {...}
// EXIST: trait
// EXIST: true
// EXIST: try
// EXIST: type
// EXIST: val ... = ...
// EXIST: var ... = ...
// EXIST: val
// EXIST: var
// EXIST: vararg
// EXIST: when (...) {... -> ...else -> ...}
// EXIST: when
// EXIST: where
// EXIST: while (...) {...}
// EXIST: while
@@ -2,7 +2,7 @@ var a : Int = <caret>
// EXIST: else
// EXIST: false
// EXIST: if (...) ... else ...
// EXIST: if
// EXIST: null
// EXIST: this
// EXIST: true
@@ -2,8 +2,8 @@ package Test
<caret>
// EXIST: enum class ... {...}
// EXIST: trait ... {...}
// EXIST: class ... {...}
// EXIST: fun ...(...) : ... {...}
// EXIST: enum
// EXIST: trait
// EXIST: class
// EXIST: fun
@@ -8,18 +8,18 @@ fun foo() {
// EXIST: break
// EXIST: by
// EXIST: catch
// EXIST: class ... {...}
// EXIST: class
// EXIST: continue
// EXIST: do {...} while (...)
// EXIST: do
// EXIST: else
// EXIST: enum class ... {...}
// EXIST: enum
// EXIST: false
// ABSENT: final
// EXIST: finally
// EXIST: for (... in ...) {...}
// EXIST: fun ...(...) : ... {...}
// EXIST: for
// EXIST: fun
// EXIST: get
// EXIST: if (...) {...}
// EXIST: if
// ABSENT: import
// EXIST: in
// EXIST: inline
@@ -40,13 +40,13 @@ fun foo() {
// EXIST: This
// EXIST: this
// EXIST: throw
// EXIST: trait ... {...}
// EXIST: trait
// EXIST: true
// EXIST: try
// EXIST: type
// EXIST: val ... = ...
// EXIST: var ... = ...
// EXIST: val
// EXIST: var
// EXIST: vararg
// EXIST: when (...) {... -> ...else -> ...}
// EXIST: when
// EXIST: where
// EXIST: while (...) {...}
// EXIST: while
@@ -6,17 +6,17 @@
// ABSENT: break
// ABSENT: by
// ABSENT: catch
// EXIST: class ... {...}
// EXIST: class
// ABSENT: continue
// ABSENT: default
// ABSENT: do
// ABSENT: else
// EXIST: enum class ... {...}
// EXIST: enum
// ABSENT: false
// EXIST: final
// ABSENT: finally
// ABSENT: for
// EXIST: fun ...(...) : ... {...}
// EXIST: fun
// EXIST: get
// ABSENT: if
// EXIST: import
@@ -39,14 +39,12 @@
// ABSENT: This
// ABSENT: this
// ABSENT: throw
// EXIST: trait ... {...}
// EXIST: trait
// ABSENT: true
// ABSENT: try
// EXIST: type
// EXIST: val ... : ... = ...
// EXIST: val ... : ...get() {...}
// EXIST: var ... : ... = ...
// EXIST: var ... : ...get() {...}set(value) {...}
// EXIST: val
// EXIST: var
// ABSENT: vararg
// ABSENT: when
// ABSENT: where
@@ -2,4 +2,4 @@ class Test {
class <caret>
}
// EXIST: object {...}
// EXIST: object
@@ -3,4 +3,4 @@ fun main(variables: Array<String>) {
va<caret>
}
// ORDER: values, variables, val ... = ..., var ... = ..., vararg
// ORDER: values, val, variables, var, vararg
@@ -2,4 +2,4 @@ fun bar(fop: Int) {
fo<caret>
}
// ORDER: fop, for (... in ...) {...}
// ORDER: fop, for
@@ -41,6 +41,11 @@ public class CompletionWeigherTestGenerated extends AbstractCompletionWeigherTes
doTest("idea/testData/completion/weighers/DeprecatedFun.kt");
}
@TestMetadata("KeywordsLast.kt")
public void testKeywordsLast() throws Exception {
doTest("idea/testData/completion/weighers/KeywordsLast.kt");
}
@TestMetadata("LocalFileBeforeImported.kt")
public void testLocalFileBeforeImported() throws Exception {
doTest("idea/testData/completion/weighers/LocalFileBeforeImported.kt");
@@ -71,9 +76,4 @@ public class CompletionWeigherTestGenerated extends AbstractCompletionWeigherTes
doTest("idea/testData/completion/weighers/PropertiesBeforeKeywords.kt");
}
@TestMetadata("TemplatesAndKeywordsLast.kt")
public void testTemplatesAndKeywordsLast() throws Exception {
doTest("idea/testData/completion/weighers/TemplatesAndKeywordsLast.kt");
}
}