2 * Copyright 2000-2010 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.
16 package com
.intellij
.codeInsight
.template
;
18 import com
.intellij
.codeInsight
.template
.impl
.TemplateImpl
;
19 import com
.intellij
.codeInsight
.template
.impl
.TemplateManagerImpl
;
20 import com
.intellij
.codeInsight
.template
.impl
.TemplateSettings
;
21 import com
.intellij
.openapi
.editor
.Editor
;
22 import com
.intellij
.openapi
.project
.Project
;
23 import com
.intellij
.psi
.PsiFile
;
24 import com
.intellij
.psi
.codeStyle
.CodeStyleManager
;
25 import com
.intellij
.util
.containers
.HashMap
;
26 import com
.intellij
.util
.containers
.HashSet
;
27 import org
.jetbrains
.annotations
.NotNull
;
28 import org
.jetbrains
.annotations
.Nullable
;
30 import java
.util
.List
;
35 * @author Eugene.Kudelevsky
37 public class CustomTemplateCallback
{
38 private final TemplateManager myTemplateManager
;
39 private final Editor myEditor
;
40 private final PsiFile myFile
;
41 private int myStartOffset
;
42 private int myStartLength
;
43 private Project myProject
;
45 private final Map
<Object
, MyCheckpoint
> myCheckpoints
= new HashMap
<Object
, MyCheckpoint
>();
47 private static class MyCheckpoint
{
48 int myFixedLength
= -1;
52 public CustomTemplateCallback(Editor editor
, PsiFile file
) {
55 myProject
= file
.getProject();
56 myTemplateManager
= TemplateManagerImpl
.getInstance(myProject
);
59 public void fixInitialEditorState() {
60 myStartOffset
= myEditor
.getCaretModel().getOffset();
61 myStartLength
= myEditor
.getDocument().getCharsSequence().length();
64 public boolean isLiveTemplateApplicable(@NotNull String key
) {
65 List
<TemplateImpl
> templates
= getMatchingTemplates(key
);
66 templates
= TemplateManagerImpl
.filterApplicableCandidates(myFile
, myStartOffset
, templates
);
67 return templates
.size() > 0;
70 public boolean isTemplateContainsVars(@NotNull String key
, String
... varNames
) {
71 List
<TemplateImpl
> templates
= getMatchingTemplates(key
);
72 templates
= TemplateManagerImpl
.filterApplicableCandidates(myFile
, myStartOffset
, templates
);
73 if (templates
.size() == 0) {
76 TemplateImpl template
= templates
.get(0);
77 Set
<String
> varSet
= new HashSet
<String
>();
78 for (int i
= 0; i
< template
.getVariableCount(); i
++) {
79 varSet
.add(template
.getVariableNameAt(i
));
81 for (String varName
: varNames
) {
82 if (!varSet
.contains(varName
)) {
91 * @param predefinedVarValues
92 * @param listener @return returns if template invokation is finished
94 public boolean startTemplate(@NotNull String key
,
95 Map
<String
, String
> predefinedVarValues
,
96 @Nullable TemplateInvokationListener listener
) {
97 int caretOffset
= myEditor
.getCaretModel().getOffset();
98 List
<TemplateImpl
> templates
= getMatchingTemplates(key
);
99 templates
= TemplateManagerImpl
.filterApplicableCandidates(myFile
, caretOffset
, templates
);
100 if (templates
.size() > 0) {
101 TemplateImpl template
= templates
.get(0);
102 return startTemplate(template
, predefinedVarValues
, listener
);
104 else if (listener
!= null) {
105 listener
.finished(false);
112 * @param predefinedVarValues
114 * @return returns if template invokation is finished
116 public boolean startTemplate(@NotNull Template template
,
117 Map
<String
, String
> predefinedVarValues
,
118 @Nullable final TemplateInvokationListener listener
) {
119 final boolean[] templateEnded
= new boolean[]{false};
120 final boolean[] templateFinished
= new boolean[]{false};
121 myTemplateManager
.startTemplate(myEditor
, template
, false, predefinedVarValues
, new TemplateEditingAdapter() {
123 public void templateFinished(Template template
, boolean brokenOff
) {
124 int lengthAfter
= myEditor
.getDocument().getCharsSequence().length();
125 CodeStyleManager style
= CodeStyleManager
.getInstance(myProject
);
126 style
.reformatText(myFile
, myStartOffset
, myStartOffset
+ lengthAfter
- myStartLength
);
127 if (brokenOff
) return;
128 templateFinished
[0] = true;
129 if (templateEnded
[0] && listener
!= null) {
130 listener
.finished(true);
134 templateEnded
[0] = true;
135 if (templateFinished
[0] && listener
!= null) {
136 listener
.finished(false);
138 return templateFinished
[0];
141 public void fixStartOfTemplate(@NotNull Object key
) {
142 MyCheckpoint checkpoint
= new MyCheckpoint();
143 checkpoint
.myFixedOffset
= myEditor
.getCaretModel().getOffset();
144 checkpoint
.myFixedLength
= myEditor
.getDocument().getTextLength();
145 myCheckpoints
.put(key
, checkpoint
);
148 public void gotoEndOfTemplate(@NotNull Object key
) {
149 MyCheckpoint checkpoint
= myCheckpoints
.get(key
);
150 if (checkpoint
== null) {
151 throw new IllegalArgumentException();
153 int length
= myEditor
.getDocument().getTextLength();
154 myEditor
.getCaretModel().moveToOffset(checkpoint
.myFixedOffset
+ length
- checkpoint
.myFixedLength
);
157 private static List
<TemplateImpl
> getMatchingTemplates(@NotNull String templateKey
) {
158 TemplateSettings settings
= TemplateSettings
.getInstance();
159 return settings
.collectMatchingCandidates(templateKey
, settings
.getDefaultShortcutChar(), false);
163 public Editor
getEditor() {
167 public PsiFile
getFile() {