Clean up function bracket insertion algorithm

- Rename methods
- Correct variables names
- Fix algo for searching open bracket
This commit is contained in:
Nikolay Krasko
2012-10-14 01:28:05 +04:00
parent 440f781a93
commit a1f23597d2
@@ -57,6 +57,10 @@ public class JetFunctionInsertHandler implements InsertHandler<LookupElement> {
private final BracketType bracketType; private final BracketType bracketType;
public JetFunctionInsertHandler(CaretPosition caretPosition, BracketType bracketType) { public JetFunctionInsertHandler(CaretPosition caretPosition, BracketType bracketType) {
if (caretPosition == CaretPosition.AFTER_BRACKETS && bracketType == BracketType.BRACES) {
throw new IllegalArgumentException("CaretPosition.AFTER_BRACKETS with bracketType == BracketType.BRACES combination is not supported");
}
this.caretPosition = caretPosition; this.caretPosition = caretPosition;
this.bracketType = bracketType; this.bracketType = bracketType;
} }
@@ -73,68 +77,82 @@ public class JetFunctionInsertHandler implements InsertHandler<LookupElement> {
return; return;
} }
if (shouldAddParenthesis(element)) { if (shouldAddBrackets(element)) {
addParenthesis(context, item, element); addBrackets(context, element);
} }
addImport(context, item); addImport(context, item);
} }
private static boolean shouldAddParenthesis(PsiElement element) { private static boolean shouldAddBrackets(PsiElement element) {
return PsiTreeUtil.getParentOfType(element, JetImportDirective.class) == null; return PsiTreeUtil.getParentOfType(element, JetImportDirective.class) == null;
} }
private void addParenthesis(InsertionContext context, LookupElement item, PsiElement offsetElement) { private void addBrackets(InsertionContext context, PsiElement offsetElement) {
int startOffset = context.getStartOffset(); int offset = context.getSelectionEndOffset();
int lookupStringLength = item.getLookupString().length();
int endOffset = startOffset + lookupStringLength;
Document document = context.getDocument(); Document document = context.getDocument();
boolean bothParentheses = false;
String documentText = document.getText(); String documentText = document.getText();
boolean braces = bracketType == BracketType.BRACES && context.getCompletionChar() != '('; boolean braces = bracketType == BracketType.BRACES && context.getCompletionChar() != '(';
char openingBracket = braces ? '{' : '('; char openingBracket = braces ? '{' : '(';
char closingBracket = braces ? '}' : ')'; char closingBracket = braces ? '}' : ')';
int openingBracketIndex = documentText.indexOf(openingBracket, endOffset);
if (openingBracketIndex != -1 && documentText.substring(endOffset, openingBracketIndex).trim().length() != 0) { int openingBracketIndex = indexOfSkippingSpace(documentText, openingBracket, offset);
openingBracketIndex = -1; // opening bracket is too far int inBracketsShift = 0;
}
if (openingBracketIndex == -1) { if (openingBracketIndex == -1) {
// Insert ()/{} if it's not already exist // Insert ()/{} if it's not already exist
if (braces) { if (braces) {
if (isInsertSpacesInOneLineFunctionEnabled(offsetElement.getProject())) { if (isInsertSpacesInOneLineFunctionEnabled(offsetElement.getProject())) {
document.insertString(endOffset, " { }"); document.insertString(offset, " { }");
openingBracketIndex = endOffset + 2; inBracketsShift = 1;
} }
else { else {
document.insertString(endOffset, " {}"); document.insertString(offset, " {}");
openingBracketIndex = endOffset + 1;
} }
} }
else { else {
document.insertString(endOffset, "()"); document.insertString(offset, "()");
openingBracketIndex = endOffset;
} }
bothParentheses = true;
} PsiDocumentManager.getInstance(context.getProject()).commitDocument(document);
else if (openingBracketIndex + 1 < documentText.length() && documentText.charAt(openingBracketIndex + 1) == closingBracket) { documentText = document.getText();
bothParentheses = true;
} }
openingBracketIndex = indexOfSkippingSpace(documentText, openingBracket, offset);
assert openingBracketIndex != -1 : "If there wasn't open bracket it should already have been inserted";
// CaretPosition.AFTER_BRACKETS mode cannot work when there are some non-empty chars between open and close bracket
int closeBracketIndex = indexOfSkippingSpace(documentText, closingBracket, openingBracketIndex + 1);
Editor editor = context.getEditor(); Editor editor = context.getEditor();
if (caretPosition == CaretPosition.IN_BRACKETS || !bothParentheses) { if (caretPosition == CaretPosition.IN_BRACKETS || closeBracketIndex == -1) {
editor.getCaretModel().moveToOffset(openingBracketIndex + 1); editor.getCaretModel().moveToOffset(openingBracketIndex + 1 + inBracketsShift);
AutoPopupController.getInstance(context.getProject()).autoPopupParameterInfo(editor, offsetElement); AutoPopupController.getInstance(context.getProject()).autoPopupParameterInfo(editor, offsetElement);
} }
else { else {
editor.getCaretModel().moveToOffset(openingBracketIndex + 2); editor.getCaretModel().moveToOffset(closeBracketIndex + 1);
} }
PsiDocumentManager.getInstance(context.getProject()).commitDocument(context.getDocument()); PsiDocumentManager.getInstance(context.getProject()).commitDocument(context.getDocument());
} }
private static int indexOfSkippingSpace(String str, char ch, int startIndex) {
for (int i = startIndex; i < str.length(); i++) {
char currentChar = str.charAt(i);
if (ch == currentChar) {
return i;
}
if (!Character.isWhitespace(currentChar)) {
return -1;
}
}
return -1;
}
private static boolean isInsertSpacesInOneLineFunctionEnabled(Project project) { private static boolean isInsertSpacesInOneLineFunctionEnabled(Project project) {
CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(project); CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(project);
JetCodeStyleSettings jetSettings = settings.getCustomSettings(JetCodeStyleSettings.class); JetCodeStyleSettings jetSettings = settings.getCustomSettings(JetCodeStyleSettings.class);