support passing an argument to live template (WI-626)
[fedora-idea.git] / platform / lang-impl / src / com / intellij / codeInsight / template / impl / TemplateImpl.java
blobdac35a95ccd90dbb2a54484ce9078ff37827fc31
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.template.impl;
19 import com.intellij.codeInsight.template.Expression;
20 import com.intellij.codeInsight.template.Template;
21 import com.intellij.codeInsight.template.TemplateContextType;
22 import com.intellij.openapi.extensions.Extensions;
23 import com.intellij.openapi.options.SchemeElement;
24 import com.intellij.openapi.util.text.StringUtil;
25 import com.intellij.psi.tree.IElementType;
26 import org.jetbrains.annotations.NonNls;
27 import org.jetbrains.annotations.NotNull;
29 import java.util.*;
31 /**
34 public class TemplateImpl extends Template implements SchemeElement {
35 private String myKey;
36 private String myString = null;
37 private String myDescription;
38 private String myGroupName;
39 private char myShortcutChar = TemplateSettings.DEFAULT_CHAR;
40 private final ArrayList<Variable> myVariables = new ArrayList<Variable>();
41 private ArrayList<Segment> mySegments = null;
42 private String myTemplateText = null;
43 private String myId;
45 public boolean equals(Object o) {
46 if (this == o) return true;
47 if (!(o instanceof TemplateImpl)) return false;
49 final TemplateImpl template = (TemplateImpl) o;
50 if (myId != null && template.myId != null && myId.equals(template.myId)) return true;
52 if (isToReformat != template.isToReformat) return false;
53 if (isToShortenLongNames != template.isToShortenLongNames) return false;
54 if (myShortcutChar != template.myShortcutChar) return false;
55 if (myDescription != null ? !myDescription.equals(template.myDescription) : template.myDescription != null) return false;
56 if (myGroupName != null ? !myGroupName.equals(template.myGroupName) : template.myGroupName != null) return false;
57 if (myKey != null ? !myKey.equals(template.myKey) : template.myKey != null) return false;
58 if (myString != null ? !myString.equals(template.myString) : template.myString != null) return false;
59 if (myTemplateText != null ? !myTemplateText.equals(template.myTemplateText) : template.myTemplateText != null) return false;
61 if (myVariables == null && template.myVariables == null) return true;
62 if (myVariables == null || template.myVariables == null) return false;
63 if (myVariables.size() != template.myVariables.size()) return false;
64 for (Variable variable : myVariables) {
65 if (template.myVariables.indexOf(variable) < 0) return false;
68 return true;
71 public int hashCode() {
72 if (myId != null) {
73 return myId.hashCode();
75 int result;
76 result = myKey.hashCode();
77 result = 29 * result + (myString == null ? 0 : myString.hashCode());
78 result = 29 * result + myGroupName.hashCode();
79 return result;
82 private boolean isToReformat = false;
83 private boolean isToShortenLongNames = true;
84 private boolean toParseSegments = true;
85 private TemplateContext myTemplateContext = new TemplateContext();
87 @NonNls public static final String END = "END";
88 @NonNls public static final String SELECTION = "SELECTION";
89 @NonNls public static final String SELECTION_START = "SELECTION_START";
90 @NonNls public static final String SELECTION_END = "SELECTION_END";
91 @NonNls public static final String ARG = "ARG";
93 public static final Set<String> INTERNAL_VARS_SET = new HashSet<String>(Arrays.asList(
94 END, SELECTION, SELECTION_START, SELECTION_END));
96 private boolean isDeactivated = false;
98 public boolean isInline() {
99 return myIsInline;
102 private boolean isToIndent = true;
105 public void setInline(boolean isInline) {
106 myIsInline = isInline;
109 private boolean myIsInline = false;
113 public TemplateImpl(@NotNull String key, String group) {
114 this(key, null, group);
115 toParseSegments = false;
116 myTemplateText = "";
117 mySegments = new ArrayList<Segment>();
120 public TemplateImpl(@NotNull String key, String string, String group) {
121 myKey = key;
122 myString = string;
123 myGroupName = group;
127 public void addTextSegment(@NotNull String text) {
128 text = StringUtil.convertLineSeparators(text);
129 myTemplateText += text;
132 public void addVariableSegment (String name) {
133 mySegments.add(new Segment(name, myTemplateText.length()));
136 public Variable addVariable(String name, Expression expression, Expression defaultValueExpression, boolean isAlwaysStopAt) {
137 if (mySegments != null) {
138 Segment segment = new Segment(name, myTemplateText.length());
139 mySegments.add(segment);
141 Variable variable = new Variable(name, expression, defaultValueExpression, isAlwaysStopAt);
142 myVariables.add(variable);
143 return variable;
146 public void addEndVariable() {
147 Segment segment = new Segment(END, myTemplateText.length());
148 mySegments.add(segment);
151 public void addSelectionStartVariable() {
152 Segment segment = new Segment(SELECTION_START, myTemplateText.length());
153 mySegments.add(segment);
156 public void addSelectionEndVariable() {
157 Segment segment = new Segment(SELECTION_END, myTemplateText.length());
158 mySegments.add(segment);
161 public String getId() {
162 return myId;
165 public TemplateImpl copy() {
166 TemplateImpl template = new TemplateImpl(myKey, myString, myGroupName);
167 template.myId = myId;
168 template.myDescription = myDescription;
169 template.myShortcutChar = myShortcutChar;
170 template.isToReformat = isToReformat;
171 template.isToShortenLongNames = isToShortenLongNames;
172 template.myIsInline = myIsInline;
173 template.myTemplateContext = myTemplateContext.createCopy();
174 template.isDeactivated = isDeactivated;
175 for (Variable variable : myVariables) {
176 template.addVariable(variable.getName(), variable.getExpressionString(), variable.getDefaultValueString(), variable.isAlwaysStopAt());
178 return template;
181 public boolean isToReformat() {
182 return isToReformat;
185 public void setToReformat(boolean toReformat) {
186 isToReformat = toReformat;
189 public void setToIndent(boolean toIndent) {
190 isToIndent = toIndent;
193 public boolean isToIndent() {
194 return isToIndent;
197 public boolean isToShortenLongNames() {
198 return isToShortenLongNames;
201 public void setToShortenLongNames(boolean toShortenLongNames) {
202 isToShortenLongNames = toShortenLongNames;
205 public void setDeactivated(boolean isDeactivated) {
206 this.isDeactivated = isDeactivated;
209 public boolean isDeactivated() {
210 return isDeactivated;
213 public TemplateContext getTemplateContext() {
214 return myTemplateContext;
217 public int getEndSegmentNumber() {
218 return getVariableSegmentNumber(END);
221 public int getSelectionStartSegmentNumber() {
222 return getVariableSegmentNumber(SELECTION_START);
225 public int getSelectionEndSegmentNumber() {
226 return getVariableSegmentNumber(SELECTION_END);
229 public int getVariableSegmentNumber(String variableName) {
230 parseSegments();
231 for (int i = 0; i < mySegments.size(); i++) {
232 Segment segment = mySegments.get(i);
233 if (segment.name.equals(variableName)) {
234 return i;
237 return -1;
240 public String getTemplateText() {
241 parseSegments();
242 return myTemplateText;
245 public String getSegmentName(int i) {
246 parseSegments();
247 return mySegments.get(i).name;
250 public int getSegmentOffset(int i) {
251 parseSegments();
252 return mySegments.get(i).offset;
255 public int getSegmentsCount() {
256 parseSegments();
257 return mySegments.size();
260 public void parseSegments() {
261 if(!toParseSegments) {
262 return;
264 if(mySegments != null) {
265 return;
268 if (myString == null) myString = "";
269 myString = StringUtil.convertLineSeparators(myString);
270 mySegments = new ArrayList<Segment>();
271 StringBuilder buffer = new StringBuilder("");
272 TemplateTextLexer lexer = new TemplateTextLexer();
273 lexer.start(myString);
275 while(true){
276 IElementType tokenType = lexer.getTokenType();
277 if (tokenType == null) break;
278 int start = lexer.getTokenStart();
279 int end = lexer.getTokenEnd();
280 String token = myString.substring(start, end);
281 if (tokenType == TemplateTokenType.VARIABLE){
282 String name = token.substring(1, token.length() - 1);
283 Segment segment = new Segment(name, buffer.length());
284 mySegments.add(segment);
286 else if (tokenType == TemplateTokenType.ESCAPE_DOLLAR){
287 buffer.append("$");
289 else{
290 buffer.append(token);
292 lexer.advance();
294 myTemplateText = buffer.toString();
297 public void removeAllParsed() {
298 myVariables.clear();
299 mySegments = null;
302 public Variable addVariable(String name, String expression, String defaultValue, boolean isAlwaysStopAt) {
303 Variable variable = new Variable(name, expression, defaultValue, isAlwaysStopAt);
304 myVariables.add(variable);
305 return variable;
308 public int getVariableCount() {
309 return myVariables.size();
312 public String getVariableNameAt(int i) {
313 return myVariables.get(i).getName();
316 public String getExpressionStringAt(int i) {
317 return myVariables.get(i).getExpressionString();
320 public Expression getExpressionAt(int i) {
321 return myVariables.get(i).getExpression();
324 public String getDefaultValueStringAt(int i) {
325 return myVariables.get(i).getDefaultValueString();
328 public Expression getDefaultValueAt(int i) {
329 return myVariables.get(i).getDefaultValueExpression();
332 public boolean isAlwaysStopAt(int i) {
333 return myVariables.get(i).isAlwaysStopAt();
336 public String getKey() {
337 return myKey;
340 public void setKey(String key) {
341 myKey = key;
344 public String getString() {
345 parseSegments();
346 return myString;
349 public void setString(String string) {
350 myString = string;
353 public String getDescription() {
354 return myDescription;
357 public void setDescription(String description) {
358 myDescription = description;
361 public char getShortcutChar() {
362 return myShortcutChar;
365 public void setShortcutChar(char shortcutChar) {
366 myShortcutChar = shortcutChar;
369 public String getGroupName() {
370 return myGroupName;
373 public void setGroupName(String groupName) {
374 myGroupName = groupName;
377 public boolean isSelectionTemplate() {
378 for (Variable v : myVariables) {
379 if (v.getName().equals(SELECTION)) return true;
382 return false;
385 public boolean hasArgument() {
386 for (Variable v : myVariables) {
387 if (v.getName().equals(ARG)) return true;
389 return false;
392 public void setId(final String id) {
393 myId = id;
396 public Map<TemplateOptionalProcessor, Boolean> createOptions() {
397 Map<TemplateOptionalProcessor, Boolean> context = new LinkedHashMap<TemplateOptionalProcessor, Boolean>();
398 for (TemplateOptionalProcessor processor : Extensions.getExtensions(TemplateOptionalProcessor.EP_NAME)) {
399 context.put(processor, processor.isEnabled(this));
401 return context;
404 public Map<TemplateContextType, Boolean> createContext(){
406 Map<TemplateContextType, Boolean> context = new LinkedHashMap<TemplateContextType, Boolean>();
407 for (TemplateContextType processor : TemplateManagerImpl.getAllContextTypes()) {
408 context.put(processor, getTemplateContext().isEnabled(processor));
410 return context;
414 public boolean contextsEqual(TemplateImpl t){
415 for (TemplateContextType contextType : TemplateManagerImpl.getAllContextTypes()) {
416 if (getTemplateContext().isEnabled(contextType) != t.getTemplateContext().isEnabled(contextType)) {
417 return false;
420 return true;
423 public void applyOptions(final Map<TemplateOptionalProcessor, Boolean> context) {
424 for (Map.Entry<TemplateOptionalProcessor, Boolean> entry : context.entrySet()) {
425 entry.getKey().setEnabled(this, entry.getValue().booleanValue());
429 public void applyContext(final Map<TemplateContextType, Boolean> context) {
430 for (Map.Entry<TemplateContextType, Boolean> entry : context.entrySet()) {
431 getTemplateContext().setEnabled(entry.getKey(), entry.getValue().booleanValue());
435 private static class Segment {
436 public String name;
437 public int offset;
439 private Segment(String name, int offset) {
440 this.name = name;
441 this.offset = offset;