blob: 63b96e8a962577e1943fd13e42d7db679f20863a [file] [log] [blame]
/*
* Copyright 2005 Sascha Weinreuter
*
* 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.intellij.lang.xpath.completion;
import com.intellij.codeInsight.completion.*;
import com.intellij.codeInsight.lookup.*;
import com.intellij.openapi.editor.CaretModel;
import com.intellij.openapi.editor.EditorModificationUtil;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.diagnostic.Logger;
class XPathInsertHandler implements InsertHandler {
private static final Logger LOG = Logger.getInstance(XPathInsertHandler.class.getName());
public void handleInsert(InsertionContext context, LookupElement lookupItem) {
final Object object = lookupItem.getObject();
LOG.debug("object = " + object);
handleInsertImpl(context, lookupItem, context.getCompletionChar());
final Editor editor = context.getEditor();
final CharSequence charsSequence = editor.getDocument().getCharsSequence();
final CaretModel caretModel = editor.getCaretModel();
int offset = caretModel.getOffset();
if (object instanceof Lookup) {
final Lookup item = (Lookup)object;
if (item.isFunction()) {
if (charAt(charsSequence, offset) != '(') {
EditorModificationUtil.insertStringAtCaret(editor, "()");
if (item.hasParameters()) {
caretModel.moveCaretRelatively(-1, 0, false, false, true);
}
} else {
caretModel.moveCaretRelatively(1, 0, false, false, true);
}
} else if (item instanceof NamespaceLookup) {
if (charAt(charsSequence, offset) != ':') {
EditorModificationUtil.insertStringAtCaret(editor, ":");
return;
}
}
}
if (context.getCompletionChar() == '\t') {
if (charAt(charsSequence, offset) == ',') {
offset++;
caretModel.moveCaretRelatively(1, 0, false, false, true);
while (charAt(charsSequence, offset++) == ' ') {
caretModel.moveCaretRelatively(1, 0, false, false, true);
}
} else if (isIdentifier(charAt(charsSequence, offset)) && isIdentifier(charAt(charsSequence, offset - 1))) {
EditorModificationUtil.insertStringAtCaret(editor, " ");
} else if (charAt(charsSequence, offset) == ':') {
caretModel.moveCaretRelatively(1, 0, false, false, true);
}
}
}
private static char charAt(CharSequence charsSequence, int offset) {
return charsSequence.length() > offset ? charsSequence.charAt(offset) : 0;
}
public static void handleInsertImpl(InsertionContext context, LookupElement item, char c) {
// final int selectionLength = (context.getSelectionEndOffset() - context.getStartOffset());
// context.shiftOffsets(item.getLookupString().length() - data.prefix.length() - selectionLength);
adjustIdentifierEnd(context, item);
final int idEndOffset = context.getOffsetMap().getOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET);
final boolean isOverwrite = c == com.intellij.codeInsight.lookup.Lookup.REPLACE_SELECT_CHAR;
if (idEndOffset != context.getSelectionEndOffset() && isOverwrite) {
context.getEditor().getDocument().deleteString(context.getSelectionEndOffset(), idEndOffset);
}
}
private static void adjustIdentifierEnd(InsertionContext context, LookupElement item) {
final boolean isNamespace = (item.getObject() instanceof NamespaceLookup);
final CharSequence charsSequence = context.getEditor().getDocument().getCharsSequence();
final int textLength = context.getEditor().getDocument().getTextLength();
int x = context.getSelectionEndOffset();
while (x < textLength) {
final char c = charAt(charsSequence, x);
if (isIdentifier(c) || c == '*' || (c == ':' && !isNamespace)) {
x++;
} else {
break;
}
}
context.getOffsetMap().addOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET, x);
}
private static boolean isIdentifier(char c) {
return Character.isLetter(c) || Character.isDigit(c) || c == '-' || c == '.' || c == '_' || c == '$';
}
}