| /* |
| * 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 == '$'; |
| } |
| } |