package com.jantvrdik.intellij.latte.completion.handlers; import com.intellij.codeInsight.completion.InsertHandler; import com.intellij.codeInsight.completion.InsertionContext; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.openapi.editor.CaretModel; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.EditorModificationUtil; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.TokenType; import com.jantvrdik.intellij.latte.LatteLanguage; import com.jantvrdik.intellij.latte.config.LatteConfiguration; import com.jantvrdik.intellij.latte.psi.LatteMacroCloseTag; import com.jantvrdik.intellij.latte.psi.LatteMacroTag; import com.jantvrdik.intellij.latte.psi.LatteTypes; import com.jantvrdik.intellij.latte.settings.LatteTagSettings; import com.jantvrdik.intellij.latte.utils.LatteUtil; import org.jetbrains.annotations.NotNull; public class MacroInsertHandler implements InsertHandler<LookupElement> { private static final MacroInsertHandler instance = new MacroInsertHandler(); public MacroInsertHandler() { super(); } public void handleInsert(@NotNull InsertionContext context, @NotNull LookupElement lookupElement) { PsiElement element = context.getFile().findElementAt(context.getStartOffset()); if (element != null && element.getLanguage() == LatteLanguage.INSTANCE) { PsiElement parent = element.getParent(); String spacesBefore = ""; boolean resolvePairMacro = false; boolean lastError = parent.getLastChild().getNode().getElementType() == TokenType.ERROR_ELEMENT; String macroName = null; LatteTagSettings macro = null; if (lastError && element.getNode().getElementType() == LatteTypes.T_MACRO_NAME) { macroName = element.getText(); macro = LatteConfiguration.getInstance(element.getProject()).getTag(macroName); } else if (parent instanceof LatteMacroTag) { macroName = ((LatteMacroTag) parent).getMacroName(); macro = LatteConfiguration.getInstance(element.getProject()).getTag(macroName); } boolean isCloseTag = parent instanceof LatteMacroCloseTag; if (!isCloseTag && macro != null && macro.getType() == LatteTagSettings.Type.PAIR) { resolvePairMacro = true; } if (macroName != null) { if (resolvePairMacro && macro.isMultiLine()) { spacesBefore += LatteUtil.getSpacesBeforeCaret(context.getEditor()); } Editor editor = context.getEditor(); CaretModel caretModel = editor.getCaretModel(); String text = editor.getDocument().getText(); int spaceInserted = 0; int offset = caretModel.getOffset(); if (macro != null && !isCloseTag && macro.hasParameters() && !LatteUtil.isStringAtCaret(editor, " ")) { EditorModificationUtil.insertStringAtCaret(editor, " "); spaceInserted = 1; } int lastBraceOffset = text.indexOf("}", offset); int endOfLineOffset = text.indexOf("\n", offset); if (endOfLineOffset == -1) { endOfLineOffset = text.length(); } if (lastBraceOffset == -1 || lastBraceOffset > endOfLineOffset) { caretModel.moveToOffset(endOfLineOffset + spaceInserted); EditorModificationUtil.insertStringAtCaret(editor, "}"); lastBraceOffset = endOfLineOffset; endOfLineOffset++; } if (resolvePairMacro) { String endTag = ""; if (macro.isMultiLine()) { endTag += "\n\n" + spacesBefore; } endTag += "{/" + macroName + "}"; int endTagOffset = text.indexOf(endTag, offset); if (endTagOffset == -1 || endTagOffset > endOfLineOffset) { caretModel.moveToOffset(lastBraceOffset + spaceInserted + 1); EditorModificationUtil.insertStringAtCaret(editor, endTag); } } caretModel.moveToOffset(offset + 1); PsiDocumentManager.getInstance(context.getProject()).commitDocument(editor.getDocument()); } } } public static MacroInsertHandler getInstance() { return instance; } }