KickJava   Java API By Example, From Geeks To Geeks.

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


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

22
23 package org.gjt.sp.jedit;
24
25 //{{{ Imports
26
import java.io.*;
27 import java.util.*;
28 import org.gjt.sp.jedit.gui.AddAbbrevDialog;
29 import org.gjt.sp.jedit.textarea.*;
30 import org.gjt.sp.util.Log;
31 //}}}
32

33 /**
34  * Abbreviation manager.
35  * @author Slava Pestov
36  * @version $Id: Abbrevs.java 5337 2006-01-23 23:04:25Z ezust $
37  */

38 public class Abbrevs
39 {
40     public static final String JavaDoc ENCODING = "UTF8";
41
42     //{{{ getExpandOnInput() method
43
/**
44      * Returns if abbreviations should be expanded after the
45      * user finishes typing a word.
46      */

47     public static boolean getExpandOnInput()
48     {
49         return expandOnInput;
50     } //}}}
51

52     //{{{ setExpandOnInput() method
53
/**
54      * Sets if abbreviations should be expanded after the
55      * user finishes typing a word.
56      * @param expandOnInput If true, typing a non-alphanumeric character
57      * will automatically attempt to expand the current abbrev
58      */

59     public static void setExpandOnInput(boolean expandOnInput)
60     {
61         Abbrevs.expandOnInput = expandOnInput;
62     } //}}}
63

64     //{{{ expandAbbrev() method
65
/**
66      * Expands the abbrev at the caret position in the specified
67      * view.
68      * @param view The view
69      * @param add If true and abbrev not found, will ask user if
70      * it should be added
71      * @since jEdit 2.6pre4
72      */

73     public static boolean expandAbbrev(View view, boolean add)
74     {
75         //{{{ Figure out some minor things
76
Buffer buffer = view.getBuffer();
77         JEditTextArea textArea = view.getTextArea();
78         if(!buffer.isEditable())
79         {
80             view.getToolkit().beep();
81             return false;
82         }
83
84         int line = textArea.getCaretLine();
85         int lineStart = buffer.getLineStartOffset(line);
86         int caret = textArea.getCaretPosition();
87
88         String JavaDoc lineText = buffer.getLineText(line);
89         if(lineText.length() == 0)
90         {
91             if(add)
92                 view.getToolkit().beep();
93             return false;
94         }
95
96         int pos = caret - lineStart;
97         if(pos == 0)
98         {
99             if(add)
100                 view.getToolkit().beep();
101             return false;
102         } //}}}
103

104         // we reuse the 'pp' vector to save time
105
m_pp.removeAllElements();
106
107         int wordStart;
108         String JavaDoc abbrev;
109
110         //{{{ Handle abbrevs of the form abbrev#pos1#pos2#pos3#...
111
if(lineText.charAt(pos-1) == '#')
112         {
113             wordStart = lineText.indexOf('#');
114             wordStart = TextUtilities.findWordStart(lineText,wordStart,
115                 buffer.getStringProperty("noWordSep") + '#');
116
117             abbrev = lineText.substring(wordStart,pos - 1);
118
119             // positional parameters will be inserted where $1, $2, $3, ...
120
// occurs in the expansion
121

122             int lastIndex = 0;
123             for(int i = 0; i < abbrev.length(); i++)
124             {
125                 if(abbrev.charAt(i) == '#')
126                 {
127                     m_pp.addElement(abbrev.substring(lastIndex,i));
128                     lastIndex = i + 1;
129                 }
130             }
131
132             m_pp.addElement(abbrev.substring(lastIndex));
133
134             // the first element of pp is the abbrev itself
135
abbrev = (String JavaDoc)m_pp.elementAt(0);
136             m_pp.removeElementAt(0);
137         } //}}}
138
//{{{ Handle ordinary abbrevs
139
else
140         {
141             wordStart = TextUtilities.findWordStart(lineText,pos - 1,
142                 buffer.getStringProperty("noWordSep"));
143
144             abbrev = lineText.substring(wordStart,pos);
145         } //}}}
146

147         Expansion expand = expandAbbrev(buffer.getMode().getName(),
148             abbrev,(buffer.getBooleanProperty("noTabs") ?
149             buffer.getTabSize() : 0),m_pp);
150
151         //{{{ Maybe show add abbrev dialog
152
if(expand == null)
153         {
154             if(add)
155                 new AddAbbrevDialog(view,abbrev);
156
157             return false;
158         } //}}}
159
//{{{ Insert the expansion
160
else
161         {
162             buffer.remove(lineStart + wordStart,
163                 pos - wordStart);
164
165             int whitespace = buffer.insertIndented(
166                 lineStart + wordStart,
167                 expand.text);
168
169             int newlines = countNewlines(expand.text,
170                 expand.caretPosition);
171
172             if(expand.caretPosition != -1)
173             {
174                 textArea.setCaretPosition(lineStart + wordStart
175                     + expand.caretPosition
176                     + newlines * whitespace);
177             }
178             if(expand.posParamCount != m_pp.size())
179             {
180                 view.getStatus().setMessageAndClear(
181                     jEdit.getProperty(
182                     "view.status.incomplete-abbrev",
183                     new Integer JavaDoc[] { new Integer JavaDoc(m_pp.size()),
184                     new Integer JavaDoc(expand.posParamCount) }));
185             }
186
187             return true;
188         } //}}}
189
} //}}}
190

191     //{{{ getGlobalAbbrevs() method
192
/**
193      * Returns the global abbreviation set.
194      * @since jEdit 2.3pre1
195      */

196     public static Hashtable getGlobalAbbrevs()
197     {
198         if(!loaded)
199             load();
200
201         return globalAbbrevs;
202     } //}}}
203

204     //{{{ setGlobalAbbrevs() method
205
/**
206      * Sets the global abbreviation set.
207      * @param globalAbbrevs The new global abbrev set
208      * @since jEdit 2.3pre1
209      */

210     public static void setGlobalAbbrevs(Hashtable globalAbbrevs)
211     {
212         abbrevsChanged = true;
213         Abbrevs.globalAbbrevs = globalAbbrevs;
214     } //}}}
215

216     //{{{ getModeAbbrevs() method
217
/**
218      * Returns the mode-specific abbreviation set.
219      * @since jEdit 2.3pre1
220      */

221     public static Hashtable getModeAbbrevs()
222     {
223         if(!loaded)
224             load();
225
226         return modes;
227     } //}}}
228

229     //{{{ setModeAbbrevs() method
230
/**
231      * Sets the mode-specific abbreviation set.
232      * @param modes The new mode abbrev set
233      * @since jEdit 2.3pre1
234      */

235     public static void setModeAbbrevs(Hashtable modes)
236     {
237         abbrevsChanged = true;
238         Abbrevs.modes = modes;
239     } //}}}
240

241     //{{{ addGlobalAbbrev() method
242
/**
243      * Adds an abbreviation to the global abbreviation list.
244      * @param abbrev The abbreviation
245      * @param expansion The expansion
246      * @since jEdit 3.1pre1
247      */

248     public static void addGlobalAbbrev(String JavaDoc abbrev, String JavaDoc expansion)
249     {
250         if(!loaded)
251             load();
252
253         globalAbbrevs.put(abbrev,expansion);
254         abbrevsChanged = true;
255     } //}}}
256

257     //{{{ addModeAbbrev() method
258
/**
259      * Adds a mode-specific abbrev.
260      * @param mode The edit mode
261      * @param abbrev The abbrev
262      * @param expansion The expansion
263      * @since jEdit 3.1pre1
264      */

265     public static void addModeAbbrev(String JavaDoc mode, String JavaDoc abbrev, String JavaDoc expansion)
266     {
267         if(!loaded)
268             load();
269
270         Hashtable modeAbbrevs = (Hashtable)modes.get(mode);
271         if(modeAbbrevs == null)
272         {
273             modeAbbrevs = new Hashtable();
274             modes.put(mode,modeAbbrevs);
275         }
276         modeAbbrevs.put(abbrev,expansion);
277         abbrevsChanged = true;
278     } //}}}
279

280     //{{{ save() method
281
static void save()
282     {
283         jEdit.setBooleanProperty("view.expandOnInput",expandOnInput);
284
285         String JavaDoc settings = jEdit.getSettingsDirectory();
286         if(abbrevsChanged && settings != null)
287         {
288             File file1 = new File(MiscUtilities.constructPath(settings,"#abbrevs#save#"));
289             File file2 = new File(MiscUtilities.constructPath(settings,"abbrevs"));
290             if(file2.exists() && file2.lastModified() != abbrevsModTime)
291             {
292                 Log.log(Log.WARNING,Abbrevs.class,file2 + " changed on disk;"
293                     + " will not save abbrevs");
294             }
295             else
296             {
297                 jEdit.backupSettingsFile(file2);
298
299                 try
300                 {
301                     saveAbbrevs(new OutputStreamWriter(
302                         new FileOutputStream(file1),
303                         ENCODING));
304                     file2.delete();
305                     file1.renameTo(file2);
306                 }
307                 catch(Exception JavaDoc e)
308                 {
309                     Log.log(Log.ERROR,Abbrevs.class,"Error while saving " + file1);
310                     Log.log(Log.ERROR,Abbrevs.class,e);
311                 }
312                 abbrevsModTime = file2.lastModified();
313             }
314         }
315     } //}}}
316

317     //{{{ Private members
318

319     //{{{ Instance variables
320
private static boolean loaded;
321     private static boolean abbrevsChanged;
322     private static long abbrevsModTime;
323     private static boolean expandOnInput;
324     private static Hashtable globalAbbrevs;
325     private static Hashtable modes;
326     
327     /** Vector of Positional Parameters */
328     private static Vector m_pp = new Vector();
329     //}}}
330

331     private Abbrevs() {}
332
333     static
334     {
335         expandOnInput = jEdit.getBooleanProperty("view.expandOnInput");
336     }
337
338     //{{{ load() method
339
private static void load()
340     {
341         globalAbbrevs = new Hashtable();
342         modes = new Hashtable();
343
344         String JavaDoc settings = jEdit.getSettingsDirectory();
345         if(settings != null)
346         {
347             File file = new File(MiscUtilities.constructPath(settings,"abbrevs"));
348             abbrevsModTime = file.lastModified();
349
350             try
351             {
352                 loadAbbrevs(new InputStreamReader(
353                     new FileInputStream(file),ENCODING));
354                 loaded = true;
355             }
356             catch(FileNotFoundException fnf)
357             {
358             }
359             catch(Exception JavaDoc e)
360             {
361                 Log.log(Log.ERROR,Abbrevs.class,"Error while loading " + file);
362                 Log.log(Log.ERROR,Abbrevs.class,e);
363             }
364         }
365
366         // only load global abbrevs if user abbrevs file could not be loaded
367
if(!loaded)
368         {
369             try
370             {
371                 loadAbbrevs(new InputStreamReader(Abbrevs.class
372                     .getResourceAsStream("default.abbrevs"),
373                     ENCODING));
374             }
375             catch(Exception JavaDoc e)
376             {
377                 Log.log(Log.ERROR,Abbrevs.class,"Error while loading default.abbrevs");
378                 Log.log(Log.ERROR,Abbrevs.class,e);
379             }
380             loaded = true;
381         }
382     } //}}}
383

384     //{{{ countNewlines() method
385
private static int countNewlines(String JavaDoc s, int end)
386     {
387         int counter = 0;
388
389         for(int i = 0; i < end; i++)
390         {
391             if(s.charAt(i) == '\n')
392                 counter++;
393         }
394
395         return counter;
396     } //}}}
397

398     //{{{ expandAbbrev() method
399
private static Expansion expandAbbrev(String JavaDoc mode, String JavaDoc abbrev,
400         int softTabSize, Vector pp)
401     {
402         m_pp = pp;
403         if(!loaded)
404             load();
405
406         // try mode-specific abbrevs first
407
String JavaDoc expand = null;
408         Hashtable modeAbbrevs = (Hashtable)modes.get(mode);
409         if(modeAbbrevs != null)
410             expand = (String JavaDoc)modeAbbrevs.get(abbrev);
411
412         if(expand == null)
413             expand = (String JavaDoc)globalAbbrevs.get(abbrev);
414
415         if(expand == null)
416             return null;
417         else
418             return new Expansion(expand,softTabSize,m_pp);
419     } //}}}
420

421     //{{{ loadAbbrevs() method
422
private static void loadAbbrevs(Reader _in) throws Exception JavaDoc
423     {
424         BufferedReader in = new BufferedReader(_in);
425
426         try
427         {
428             Hashtable currentAbbrevs = globalAbbrevs;
429
430             String JavaDoc line;
431             while((line = in.readLine()) != null)
432             {
433                 int index = line.indexOf('|');
434
435                 if(line.length() == 0)
436                     continue;
437                 else if(line.startsWith("[") && index == -1)
438                 {
439                     if(line.equals("[global]"))
440                         currentAbbrevs = globalAbbrevs;
441                     else
442                     {
443                         String JavaDoc mode = line.substring(1,
444                             line.length() - 1);
445                         currentAbbrevs = (Hashtable)modes.get(mode);
446                         if(currentAbbrevs == null)
447                         {
448                             currentAbbrevs = new Hashtable();
449                             modes.put(mode,currentAbbrevs);
450                         }
451                     }
452                 }
453                 else if(index != -1)
454                 {
455                     currentAbbrevs.put(line.substring(0,index),
456                         line.substring(index + 1));
457                 }
458             }
459         }
460         finally
461         {
462             in.close();
463         }
464     } //}}}
465

466     //{{{ saveAbbrevs() method
467
private static void saveAbbrevs(Writer _out) throws Exception JavaDoc
468     {
469         BufferedWriter out = new BufferedWriter(_out);
470         String JavaDoc lineSep = System.getProperty("line.separator");
471
472         // write global abbrevs
473
out.write("[global]");
474         out.write(lineSep);
475
476         saveAbbrevs(out,globalAbbrevs);
477
478         // write mode abbrevs
479
Enumeration keys = modes.keys();
480         Enumeration values = modes.elements();
481         while(keys.hasMoreElements())
482         {
483             out.write('[');
484             out.write((String JavaDoc)keys.nextElement());
485             out.write(']');
486             out.write(lineSep);
487             saveAbbrevs(out,(Hashtable)values.nextElement());
488         }
489
490         out.close();
491     } //}}}
492

493     //{{{ saveAbbrevs() method
494
private static void saveAbbrevs(Writer out, Hashtable abbrevs)
495         throws Exception JavaDoc
496     {
497         String JavaDoc lineSep = System.getProperty("line.separator");
498
499         Enumeration keys = abbrevs.keys();
500         Enumeration values = abbrevs.elements();
501         while(keys.hasMoreElements())
502         {
503             String JavaDoc abbrev = (String JavaDoc)keys.nextElement();
504             out.write(abbrev);
505             out.write('|');
506             out.write(values.nextElement().toString());
507             out.write(lineSep);
508         }
509     } //}}}
510

511     //}}}
512

513     //{{{ Expansion class
514
static class Expansion
515     {
516         String JavaDoc text;
517         int caretPosition = -1;
518         int lineCount;
519
520         // number of positional parameters in abbreviation expansion
521
int posParamCount;
522
523         //{{{ Expansion constructor
524
Expansion(String JavaDoc text, int softTabSize, Vector pp)
525         {
526             StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
527             boolean backslash = false;
528
529             for(int i = 0; i < text.length(); i++)
530             {
531                 char ch = text.charAt(i);
532                 //{{{ Handle backslash
533
if(backslash)
534                 {
535                     backslash = false;
536
537                     if(ch == '|')
538                         caretPosition = buf.length();
539                     else if(ch == 'n')
540                     {
541                         buf.append('\n');
542                         lineCount++;
543                     }
544                     else if(ch == 't')
545                     {
546                         if(softTabSize == 0)
547                             buf.append('\t');
548                         else
549                         {
550                             for(int j = 0; j < softTabSize; j++)
551                                 buf.append(' ');
552                         }
553                     }
554                     else
555                         buf.append(ch);
556                 }
557                 else if(ch == '\\')
558                     backslash = true;
559                 //}}}
560
//{{{ Handle $
561
else if(ch == '$')
562                 {
563                     if(i != text.length() - 1)
564                     {
565                         ch = text.charAt(i + 1);
566                         if(Character.isDigit(ch) && ch != '0')
567                         {
568                             i++;
569
570                             int pos = ch - '0';
571                             posParamCount = Math.max(pos,posParamCount);
572                             // $n is 1-indexed, but vector
573
// contents is zero indexed
574
if(pos <= pp.size())
575                                 buf.append(pp.elementAt(pos - 1));
576                         }
577                         else
578                         {
579                             // $key will be $key, for
580
// example
581
buf.append('$');
582                         }
583                     }
584                     else
585                         buf.append('$'); // $ at end is literal
586
} //}}}
587
else
588                     buf.append(ch);
589             }
590
591             this.text = buf.toString();
592         } //}}}
593
} //}}}
594
}
595
Popular Tags