KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > gjt > sp > jedit > Mode


1 /*
2  * Mode.java - jEdit editing mode
3  * :tabSize=8:indentSize=8:noTabs=false:
4  * :folding=explicit:collapseFolds=1:
5  *
6  * Copyright (C) 1998, 1999, 2000 Slava Pestov
7  * Copyright (C) 1999 mike dillon
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22  */

23
24 package org.gjt.sp.jedit;
25
26 //{{{ Imports
27
import java.lang.reflect.Method JavaDoc;
28 import java.util.Hashtable JavaDoc;
29 import java.util.Collections JavaDoc;
30 import java.util.LinkedList JavaDoc;
31 import java.util.List JavaDoc;
32 import java.util.Map JavaDoc;
33 import java.util.regex.Pattern JavaDoc;
34 import java.util.regex.PatternSyntaxException JavaDoc;
35 import org.gjt.sp.jedit.indent.DeepIndentRule;
36 import org.gjt.sp.jedit.indent.IndentRule;
37 import org.gjt.sp.jedit.indent.IndentRuleFactory;
38 import org.gjt.sp.jedit.syntax.TokenMarker;
39 import org.gjt.sp.util.Log;
40 import org.gjt.sp.util.StandardUtilities;
41 //}}}
42

43 /**
44  * An edit mode defines specific settings for editing some type of file.
45  * One instance of this class is created for each supported edit mode.
46  *
47  * @author Slava Pestov
48  * @version $Id: Mode.java 8094 2006-11-17 06:52:04Z vanza $
49  */

50 public class Mode
51 {
52     //{{{ Mode constructor
53
/**
54      * Creates a new edit mode.
55      *
56      * @param name The name used in mode listings and to query mode
57      * properties
58      * @see #getProperty(String)
59      */

60     public Mode(String JavaDoc name)
61     {
62         this.name = name;
63         props = new Hashtable JavaDoc<String JavaDoc, Object JavaDoc>();
64     } //}}}
65

66     //{{{ init() method
67
/**
68      * Initializes the edit mode. Should be called after all properties
69      * are loaded and set.
70      */

71     public void init()
72     {
73         try
74         {
75             String JavaDoc filenameGlob = (String JavaDoc)getProperty("filenameGlob");
76             if(filenameGlob != null && filenameGlob.length() != 0)
77             {
78                 filenameRE = Pattern.compile(StandardUtilities.globToRE(filenameGlob),
79                                  Pattern.CASE_INSENSITIVE);
80             }
81
82             String JavaDoc firstlineGlob = (String JavaDoc)getProperty("firstlineGlob");
83             if(firstlineGlob != null && firstlineGlob.length() != 0)
84             {
85                 firstlineRE = Pattern.compile(StandardUtilities.globToRE(firstlineGlob),
86                                   Pattern.CASE_INSENSITIVE);
87             }
88         }
89         catch(PatternSyntaxException JavaDoc re)
90         {
91             Log.log(Log.ERROR,this,"Invalid filename/firstline"
92                 + " globs in mode " + name);
93             Log.log(Log.ERROR,this,re);
94         }
95
96         // Fix for this bug:
97
// -- Put a mode into the user dir with the same name as one
98
// on the system dir.
99
// -- Reload edit modes.
100
// -- Old mode from system dir still used for highlighting
101
// until jEdit restart.
102
marker = null;
103     } //}}}
104

105     //{{{ getTokenMarker() method
106
/**
107      * Returns the token marker for this mode.
108      */

109     public TokenMarker getTokenMarker()
110     {
111         loadIfNecessary();
112         return marker;
113     } //}}}
114

115     //{{{ setTokenMarker() method
116
/**
117      * Sets the token marker for this mode.
118      * @param marker The new token marker
119      */

120     public void setTokenMarker(TokenMarker marker)
121     {
122         this.marker = marker;
123     } //}}}
124

125     //{{{ loadIfNecessary() method
126
/**
127      * Loads the mode from disk if it hasn't been loaded already.
128      * @since jEdit 2.5pre3
129      */

130     public void loadIfNecessary()
131     {
132         if(marker == null)
133         {
134             jEdit.loadMode(this);
135             if (marker == null)
136                 Log.log(Log.ERROR, this, "Mode not correctly loaded, token marker is still null");
137         }
138     } //}}}
139

140     //{{{ getProperty() method
141
/**
142      * Returns a mode property.
143      * @param key The property name
144      *
145      * @since jEdit 2.2pre1
146      */

147     public Object JavaDoc getProperty(String JavaDoc key)
148     {
149         String JavaDoc prefix = "mode." + name + '.';
150
151         //if(jEdit.getBooleanProperty(prefix + "customSettings"))
152
//{
153
String JavaDoc property = jEdit.getProperty(prefix + key);
154             if(property != null)
155             {
156                 Object JavaDoc value;
157                 try
158                 {
159                     value = new Integer JavaDoc(property);
160                 }
161                 catch(NumberFormatException JavaDoc nf)
162                 {
163                     value = property;
164                 }
165                 return value;
166             }
167         //}
168

169         Object JavaDoc value = props.get(key);
170         if(value != null)
171             return value;
172
173         String JavaDoc global = jEdit.getProperty("buffer." + key);
174         if(global != null)
175         {
176             try
177             {
178                 return new Integer JavaDoc(global);
179             }
180             catch(NumberFormatException JavaDoc nf)
181             {
182                 return global;
183             }
184         }
185         else
186             return null;
187     } //}}}
188

189     //{{{ getBooleanProperty() method
190
/**
191      * Returns the value of a boolean property.
192      * @param key The property name
193      *
194      * @since jEdit 2.5pre3
195      */

196     public boolean getBooleanProperty(String JavaDoc key)
197     {
198         Object JavaDoc value = getProperty(key);
199         if("true".equals(value) || "on".equals(value) || "yes".equals(value))
200             return true;
201         else
202             return false;
203     } //}}}
204

205     //{{{ setProperty() method
206
/**
207      * Sets a mode property.
208      * @param key The property name
209      * @param value The property value
210      */

211     public void setProperty(String JavaDoc key, Object JavaDoc value)
212     {
213         props.put(key,value);
214     } //}}}
215

216     //{{{ unsetProperty() method
217
/**
218      * Unsets a mode property.
219      * @param key The property name
220      * @since jEdit 3.2pre3
221      */

222     public void unsetProperty(String JavaDoc key)
223     {
224         props.remove(key);
225     } //}}}
226

227     //{{{ setProperties() method
228
/**
229      * Should only be called by <code>XModeHandler</code>.
230      * @since jEdit 4.0pre3
231      */

232     public void setProperties(Map JavaDoc props)
233     {
234         if(props == null)
235             props = new Hashtable JavaDoc<String JavaDoc, Object JavaDoc>();
236
237         // need to carry over file name and first line globs because they are
238
// not given to us by the XMode handler, but instead are filled in by
239
// the catalog loader.
240
String JavaDoc filenameGlob = (String JavaDoc)this.props.get("filenameGlob");
241         String JavaDoc firstlineGlob = (String JavaDoc)this.props.get("firstlineGlob");
242         String JavaDoc filename = (String JavaDoc)this.props.get("file");
243         this.props = props;
244         if(filenameGlob != null)
245             props.put("filenameGlob",filenameGlob);
246         if(firstlineGlob != null)
247             props.put("firstlineGlob",firstlineGlob);
248         if(filename != null)
249             props.put("file",filename);
250     } //}}}
251

252     //{{{ accept() method
253
/**
254      * Returns if the edit mode is suitable for editing the specified
255      * file. The buffer name and first line is checked against the
256      * file name and first line globs, respectively.
257      * @param fileName The buffer's name
258      * @param firstLine The first line of the buffer
259      *
260      * @since jEdit 3.2pre3
261      */

262     public boolean accept(String JavaDoc fileName, String JavaDoc firstLine)
263     {
264         if(filenameRE != null && filenameRE.matcher(fileName).matches())
265             return true;
266
267         if(firstlineRE != null && firstlineRE.matcher(firstLine).matches())
268             return true;
269
270         return false;
271     } //}}}
272

273     //{{{ getName() method
274
/**
275      * Returns the internal name of this edit mode.
276      */

277     public String JavaDoc getName()
278     {
279         return name;
280     } //}}}
281

282     //{{{ toString() method
283
/**
284      * Returns a string representation of this edit mode.
285      */

286     public String JavaDoc toString()
287     {
288         return name;
289     } //}}}
290

291     //{{{ Indent rules
292

293     public synchronized List JavaDoc<IndentRule> getIndentRules()
294     {
295         if (indentRules == null)
296         {
297             initIndentRules();
298         }
299         return indentRules;
300     }
301
302     public synchronized boolean isElectricKey(char ch)
303     {
304         if (electricKeys == null)
305         {
306             String JavaDoc[] props = {
307                 "indentOpenBrackets",
308                 "indentCloseBrackets",
309                 "electricKeys"
310             };
311
312             StringBuilder JavaDoc buf = new StringBuilder JavaDoc();
313             for(int i = 0; i < props.length; i++)
314             {
315                 String JavaDoc prop = (String JavaDoc) getProperty(props[i]);
316                 if (prop != null)
317                     buf.append(prop);
318             }
319
320             electricKeys = buf.toString();
321         }
322
323         return (electricKeys.indexOf(ch) >= 0);
324     }
325
326     private void initIndentRules()
327     {
328         List JavaDoc<IndentRule> rules = new LinkedList JavaDoc<IndentRule>();
329
330         String JavaDoc[] regexpProps = {
331             "indentNextLine",
332             "indentNextLines"
333         };
334
335         for(int i = 0; i < regexpProps.length; i++)
336         {
337             IndentRule rule = createRegexpIndentRule(regexpProps[i]);
338             if(rule != null)
339                 rules.add(rule);
340         }
341
342         String JavaDoc[] bracketProps = {
343             "indentOpenBracket",
344             "indentCloseBracket",
345             "unalignedOpenBracket",
346             "unalignedCloseBracket",
347         };
348
349         for(int i = 0; i < bracketProps.length; i++)
350         {
351             createBracketIndentRules(bracketProps[i], rules);
352         }
353
354         String JavaDoc[] finalProps = {
355             "unindentThisLine",
356             "unindentNextLines"
357         };
358
359         for(int i = 0; i < finalProps.length; i++)
360         {
361             IndentRule rule = createRegexpIndentRule(finalProps[i]);
362             if(rule != null)
363                 rules.add(rule);
364         }
365
366         if (getBooleanProperty("deepIndent"))
367             rules.add(new DeepIndentRule());
368
369         indentRules = Collections.unmodifiableList(rules);
370     }
371
372     private IndentRule createRegexpIndentRule(String JavaDoc prop)
373     {
374         String JavaDoc value = (String JavaDoc) getProperty(prop);
375
376         try
377         {
378             if(value != null)
379             {
380                 Method JavaDoc m = IndentRuleFactory.class.getMethod(
381                     prop,new Class JavaDoc[] { String JavaDoc.class });
382                 return (IndentRule)m.invoke(null, value);
383             }
384         }
385         catch(Exception JavaDoc e)
386         {
387             Log.log(Log.ERROR,this,"Bad indent rule " + prop
388                 + '=' + value + ':');
389             Log.log(Log.ERROR,this,e);
390         }
391
392         return null;
393     }
394
395     private void createBracketIndentRules(String JavaDoc prop,
396                         List JavaDoc<IndentRule> rules)
397     {
398         String JavaDoc value = (String JavaDoc) getProperty(prop + 's');
399
400         try
401         {
402             if(value != null)
403             {
404                 for(int i = 0; i < value.length(); i++)
405                 {
406                     char ch = value.charAt(i);
407
408                     Method JavaDoc m = IndentRuleFactory.class.getMethod(
409                         prop,new Class JavaDoc[] { char.class });
410                     rules.add((IndentRule) m.invoke(null, ch));
411                 }
412             }
413         }
414         catch(Exception JavaDoc e)
415         {
416             Log.log(Log.ERROR,this,"Bad indent rule " + prop
417                 + '=' + value + ':');
418             Log.log(Log.ERROR,this,e);
419         }
420     }
421
422     //}}}
423

424     //{{{ Private members
425
private String JavaDoc name;
426     private Map JavaDoc<String JavaDoc, Object JavaDoc> props;
427     private Pattern JavaDoc firstlineRE;
428     private Pattern JavaDoc filenameRE;
429     private TokenMarker marker;
430     private List JavaDoc<IndentRule> indentRules;
431     private String JavaDoc electricKeys;
432     //}}}
433
}
434
Popular Tags