refactoring, cancel custom template by Escape
[fedora-idea.git] / platform / lang-impl / src / com / intellij / codeInsight / completion / TemplateInsertHandler.java
blob977adac61580c7b7204150738a7a0e673c138a69
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.intellij.codeInsight.completion;
19 import com.intellij.codeInsight.lookup.LookupElement;
20 import com.intellij.codeInsight.lookup.LookupItem;
21 import com.intellij.codeInsight.template.Template;
22 import com.intellij.codeInsight.template.TemplateEditingAdapter;
23 import com.intellij.codeInsight.template.TemplateManager;
24 import com.intellij.openapi.command.CommandProcessor;
25 import com.intellij.openapi.diagnostic.Logger;
26 import com.intellij.openapi.editor.Document;
27 import com.intellij.openapi.editor.Editor;
28 import com.intellij.openapi.editor.RangeMarker;
29 import com.intellij.openapi.util.Key;
30 import com.intellij.psi.PsiDocumentManager;
31 import com.intellij.psi.PsiFile;
32 import org.jetbrains.annotations.NotNull;
34 /**
35 * @author spleaner
37 public abstract class TemplateInsertHandler implements InsertHandler {
38 private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.TemplateInsertHandler");
40 protected static final Object EXPANDED_TEMPLATE_ATTR = Key.create("EXPANDED_TEMPLATE_ATTR");
42 public void handleInsert(final InsertionContext context, final LookupElement item) {
43 context.setAddCompletionChar(false);
44 if (isTemplateToBeCompleted(item)) {
45 handleTemplate((LookupItem) item, context);
49 protected static boolean isTemplateToBeCompleted(final LookupElement lookupItem) {
50 return lookupItem instanceof LookupItem && lookupItem.getObject() instanceof Template
51 && ((LookupItem)lookupItem).getAttribute(EXPANDED_TEMPLATE_ATTR) == null;
54 protected void handleTemplate(@NotNull final LookupItem lookupItem,
55 @NotNull final InsertionContext context) {
56 LOG.assertTrue(CommandProcessor.getInstance().getCurrentCommand() != null);
57 PsiDocumentManager.getInstance(context.getProject()).commitDocument(context.getEditor().getDocument());
59 Template template = (Template)lookupItem.getObject();
61 final Editor editor = context.getEditor();
62 final Document document = editor.getDocument();
64 final int templateStartOffset = context.getStartOffset();
65 document.replaceString(templateStartOffset, templateStartOffset + lookupItem.getLookupString().length(), "");
67 final RangeMarker offsetRangeMarker = document.createRangeMarker(templateStartOffset, templateStartOffset);
69 TemplateManager.getInstance(editor.getProject()).startTemplate(editor, template, new TemplateEditingAdapter() {
70 public void templateFinished(Template template, boolean brokenOff) {
71 lookupItem.setAttribute(EXPANDED_TEMPLATE_ATTR, Boolean.TRUE);
73 if (!offsetRangeMarker.isValid()) return;
75 final Editor editor = context.getEditor();
76 final int startOffset = offsetRangeMarker.getStartOffset();
77 final int endOffset = editor.getCaretModel().getOffset();
78 String lookupString = editor.getDocument().getCharsSequence().subSequence(startOffset, endOffset).toString();
79 lookupItem.setLookupString(lookupString);
81 final OffsetMap offsetMap = context.getOffsetMap();
82 offsetMap.addOffset(CompletionInitializationContext.SELECTION_END_OFFSET, endOffset);
83 offsetMap.addOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET, endOffset);
85 final PsiFile psiFile = context.getFile();
87 InsertionContext newContext =
88 new InsertionContext(offsetMap, context.getCompletionChar(), LookupElement.EMPTY_ARRAY, psiFile, editor);
90 populateInsertMap(psiFile, offsetMap);
92 handleInsert(newContext, lookupItem);
94 });
97 protected void populateInsertMap(@NotNull final PsiFile file, @NotNull final OffsetMap offsetMap) {