KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * Macros.java - Macro manager
3  * :tabSize=8:indentSize=8:noTabs=false:
4  * :folding=explicit:collapseFolds=1:
5  *
6  * Copyright (C) 1999, 2004 Slava Pestov
7  * Portions copyright (C) 2002 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 javax.swing.*;
28 import java.awt.*;
29 import java.io.*;
30 import java.util.*;
31 import java.util.regex.Pattern JavaDoc;
32 import org.gjt.sp.jedit.msg.*;
33 import org.gjt.sp.util.Log;
34 import org.gjt.sp.util.StandardUtilities;
35 //}}}
36

37 /**
38  * This class records and runs macros.<p>
39  *
40  * It also contains a few methods useful for displaying output messages
41  * or obtaining input from a macro:
42  *
43  * <ul>
44  * <li>{@link #confirm(Component,String,int)}</li>
45  * <li>{@link #confirm(Component,String,int,int)}</li>
46  * <li>{@link #error(Component,String)}</li>
47  * <li>{@link #input(Component,String)}</li>
48  * <li>{@link #input(Component,String,String)}</li>
49  * <li>{@link #message(Component,String)}</li>
50  * </ul>
51  *
52  * Note that plugins should not use the above methods. Call
53  * the methods in the {@link GUIUtilities} class instead.
54  *
55  * @author Slava Pestov
56  * @version $Id: Macros.java 6808 2006-08-26 23:22:57Z vanza $
57  */

58 public class Macros
59 {
60     //{{{ showRunScriptDialog() method
61
/**
62      * Prompts for one or more files to run as macros
63      * @param view The view
64      * @since jEdit 4.0pre7
65      */

66     public static void showRunScriptDialog(View view)
67     {
68         String JavaDoc[] paths = GUIUtilities.showVFSFileDialog(view,
69             null,JFileChooser.OPEN_DIALOG,true);
70         if(paths != null)
71         {
72             Buffer buffer = view.getBuffer();
73             try
74             {
75                 buffer.beginCompoundEdit();
76
77 file_loop: for(int i = 0; i < paths.length; i++)
78                     runScript(view,paths[i],false);
79             }
80             finally
81             {
82                 buffer.endCompoundEdit();
83             }
84         }
85     } //}}}
86

87     //{{{ runScript() method
88
/**
89      * Runs the specified script.
90      * Unlike the {@link BeanShell#runScript(View,String,Reader,boolean)}
91      * method, this method can run scripts supported
92      * by any registered macro handler.
93      * @param view The view
94      * @param path The VFS path of the script
95      * @param ignoreUnknown If true, then unknown file types will be
96      * ignored; otherwise, a warning message will be printed and they will
97      * be evaluated as BeanShell scripts.
98      *
99      * @since jEdit 4.1pre2
100      */

101     public static void runScript(View view, String JavaDoc path, boolean ignoreUnknown)
102     {
103         Handler handler = getHandlerForPathName(path);
104         if(handler != null)
105         {
106             try
107             {
108                 Macro newMacro = handler.createMacro(
109                     MiscUtilities.getFileName(path), path);
110                 newMacro.invoke(view);
111             }
112             catch (Exception JavaDoc e)
113             {
114                 Log.log(Log.ERROR, Macros.class, e);
115                 return;
116             }
117             return;
118         }
119
120         // only executed if above loop falls
121
// through, ie there is no handler for
122
// this file
123
if(ignoreUnknown)
124         {
125             Log.log(Log.NOTICE,Macros.class,path +
126                 ": Cannot find a suitable macro handler");
127         }
128         else
129         {
130             Log.log(Log.ERROR,Macros.class,path +
131                 ": Cannot find a suitable macro handler, "
132                 + "assuming BeanShell");
133             getHandler("beanshell").createMacro(
134                 path,path).invoke(view);
135         }
136     } //}}}
137

138     //{{{ message() method
139
/**
140      * Utility method that can be used to display a message dialog in a macro.
141      * @param comp The component to show the dialog on behalf of, this
142      * will usually be a view instance
143      * @param message The message
144      * @since jEdit 2.7pre2
145      */

146     public static void message(Component comp, String JavaDoc message)
147     {
148         GUIUtilities.hideSplashScreen();
149
150         JOptionPane.showMessageDialog(comp,message,
151             jEdit.getProperty("macro-message.title"),
152             JOptionPane.INFORMATION_MESSAGE);
153     } //}}}
154

155     //{{{ error() method
156
/**
157      * Utility method that can be used to display an error dialog in a macro.
158      * @param comp The component to show the dialog on behalf of, this
159      * will usually be a view instance
160      * @param message The message
161      * @since jEdit 2.7pre2
162      */

163     public static void error(Component comp, String JavaDoc message)
164     {
165         GUIUtilities.hideSplashScreen();
166
167         JOptionPane.showMessageDialog(comp,message,
168             jEdit.getProperty("macro-message.title"),
169             JOptionPane.ERROR_MESSAGE);
170     } //}}}
171

172     //{{{ input() method
173
/**
174      * Utility method that can be used to prompt for input in a macro.
175      * @param comp The component to show the dialog on behalf of, this
176      * will usually be a view instance
177      * @param prompt The prompt string
178      * @since jEdit 2.7pre2
179      */

180     public static String JavaDoc input(Component comp, String JavaDoc prompt)
181     {
182         GUIUtilities.hideSplashScreen();
183
184         return input(comp,prompt,null);
185     } //}}}
186

187     //{{{ input() method
188
/**
189      * Utility method that can be used to prompt for input in a macro.
190      * @param comp The component to show the dialog on behalf of, this
191      * will usually be a view instance
192      * @param prompt The prompt string
193      * @since jEdit 3.1final
194      */

195     public static String JavaDoc input(Component comp, String JavaDoc prompt, String JavaDoc defaultValue)
196     {
197         GUIUtilities.hideSplashScreen();
198
199         return (String JavaDoc)JOptionPane.showInputDialog(comp,prompt,
200             jEdit.getProperty("macro-input.title"),
201             JOptionPane.QUESTION_MESSAGE,null,null,defaultValue);
202     } //}}}
203

204     //{{{ confirm() method
205
/**
206      * Utility method that can be used to ask for confirmation in a macro.
207      * @param comp The component to show the dialog on behalf of, this
208      * will usually be a view instance
209      * @param prompt The prompt string
210      * @param buttons The buttons to display - for example,
211      * JOptionPane.YES_NO_CANCEL_OPTION
212      * @since jEdit 4.0pre2
213      */

214     public static int confirm(Component comp, String JavaDoc prompt, int buttons)
215     {
216         GUIUtilities.hideSplashScreen();
217
218         return JOptionPane.showConfirmDialog(comp,prompt,
219             jEdit.getProperty("macro-confirm.title"),buttons,
220             JOptionPane.QUESTION_MESSAGE);
221     } //}}}
222

223     //{{{ confirm() method
224
/**
225      * Utility method that can be used to ask for confirmation in a macro.
226      * @param comp The component to show the dialog on behalf of, this
227      * will usually be a view instance
228      * @param prompt The prompt string
229      * @param buttons The buttons to display - for example,
230      * JOptionPane.YES_NO_CANCEL_OPTION
231      * @param type The dialog type - for example,
232      * JOptionPane.WARNING_MESSAGE
233      */

234     public static int confirm(Component comp, String JavaDoc prompt, int buttons, int type)
235     {
236         GUIUtilities.hideSplashScreen();
237
238         return JOptionPane.showConfirmDialog(comp,prompt,
239             jEdit.getProperty("macro-confirm.title"),buttons,type);
240     } //}}}
241

242     //{{{ loadMacros() method
243
/**
244      * Rebuilds the macros list, and sends a MacrosChanged message
245      * (views update their Macros menu upon receiving it)
246      * @since jEdit 2.2pre4
247      */

248     public static void loadMacros()
249     {
250         macroActionSet.removeAllActions();
251         macroHierarchy.removeAllElements();
252         macroHash.clear();
253
254         // since subsequent macros with the same name are ignored,
255
// load user macros first so that they override the system
256
// macros.
257
String JavaDoc settings = jEdit.getSettingsDirectory();
258
259         if(settings != null)
260         {
261             userMacroPath = MiscUtilities.constructPath(
262                 settings,"macros");
263             loadMacros(macroHierarchy,"",new File(userMacroPath));
264         }
265
266         if(jEdit.getJEditHome() != null)
267         {
268             systemMacroPath = MiscUtilities.constructPath(
269                 jEdit.getJEditHome(),"macros");
270             loadMacros(macroHierarchy,"",new File(systemMacroPath));
271         }
272
273         EditBus.send(new DynamicMenuChanged("macros"));
274     } //}}}
275

276     //{{{ registerHandler() method
277
/**
278      * Adds a macro handler to the handlers list
279      * @since jEdit 4.0pre6
280      */

281     public static void registerHandler(Handler handler)
282     {
283         if (getHandler(handler.getName()) != null)
284         {
285             Log.log(Log.ERROR, Macros.class, "Cannot register more than one macro handler with the same name");
286             return;
287         }
288
289         Log.log(Log.DEBUG,Macros.class,"Registered " + handler.getName()
290             + " macro handler");
291         macroHandlers.add(handler);
292     } //}}}
293

294     //{{{ getHandlers() method
295
/**
296      * Returns an array containing the list of registered macro handlers
297      * @since jEdit 4.0pre6
298      */

299     public static Handler[] getHandlers()
300     {
301         Handler[] handlers = new Handler[macroHandlers.size()];
302         return (Handler[])macroHandlers.toArray(handlers);
303     } //}}}
304

305     //{{{ getHandlerForFileName() method
306
/**
307      * Returns the macro handler suitable for running the specified file
308      * name, or null if there is no suitable handler.
309      * @since jEdit 4.1pre3
310      */

311     public static Handler getHandlerForPathName(String JavaDoc pathName)
312     {
313         for (int i = 0; i < macroHandlers.size(); i++)
314         {
315             Handler handler = (Handler)macroHandlers.get(i);
316             if (handler.accept(pathName))
317                 return handler;
318         }
319
320         return null;
321     } //}}}
322

323     //{{{ getHandler() method
324
/**
325      * Returns the macro handler with the specified name, or null if
326      * there is no registered handler with that name.
327      * @since jEdit 4.0pre6
328      */

329     public static Handler getHandler(String JavaDoc name)
330     {
331         Handler handler = null;
332         for (int i = 0; i < macroHandlers.size(); i++)
333         {
334             handler = (Handler)macroHandlers.get(i);
335             if (handler.getName().equals(name)) return handler;
336         }
337
338         return null;
339     }
340     //}}}
341

342     //{{{ getMacroHierarchy() method
343
/**
344      * Returns a vector hierarchy with all known macros in it.
345      * Each element of this vector is either a macro name string,
346      * or another vector. If it is a vector, the first element is a
347      * string label, the rest are again, either macro name strings
348      * or vectors.
349      * @since jEdit 2.6pre1
350      */

351     public static Vector getMacroHierarchy()
352     {
353         return macroHierarchy;
354     } //}}}
355

356     //{{{ getMacroActionSet() method
357
/**
358      * Returns an action set with all known macros in it.
359      * @since jEdit 4.0pre1
360      */

361     public static ActionSet getMacroActionSet()
362     {
363         return macroActionSet;
364     } //}}}
365

366     //{{{ getMacro() method
367
/**
368      * Returns the macro with the specified name.
369      * @param macro The macro's name
370      * @since jEdit 2.6pre1
371      */

372     public static Macro getMacro(String JavaDoc macro)
373     {
374         return (Macro)macroHash.get(macro);
375     } //}}}
376

377     //{{{ getLastMacro() method
378
/**
379      * @since jEdit 4.3pre1
380      */

381     public static Macro getLastMacro()
382     {
383         return lastMacro;
384     } //}}}
385

386     //{{{ setLastMacro() method
387
/**
388      * @since jEdit 4.3pre1
389      */

390     public static void setLastMacro(Macro macro)
391     {
392         lastMacro = macro;
393     } //}}}
394

395     //{{{ Macro class
396
/**
397      * Encapsulates the macro's label, name and path.
398      * @since jEdit 2.2pre4
399      */

400     public static class Macro extends EditAction
401     {
402         //{{{ Macro constructor
403
public Macro(Handler handler, String JavaDoc name, String JavaDoc label, String JavaDoc path)
404         {
405             super(name);
406             this.handler = handler;
407             this.label = label;
408             this.path = path;
409         } //}}}
410

411         //{{{ getHandler() method
412
public Handler getHandler()
413         {
414             return handler;
415         }
416         //}}}
417

418         //{{{ getPath() method
419
public String JavaDoc getPath()
420         {
421             return path;
422         } //}}}
423

424         //{{{ invoke() method
425
public void invoke(View view)
426         {
427             setLastMacro(this);
428
429             if(view == null)
430                 handler.runMacro(null,this);
431             else
432             {
433                 try
434                 {
435                     view.getBuffer().beginCompoundEdit();
436                     handler.runMacro(view,this);
437                 }
438                 finally
439                 {
440                     view.getBuffer().endCompoundEdit();
441                 }
442             }
443         } //}}}
444

445         //{{{ getCode() method
446
public String JavaDoc getCode()
447         {
448             return "Macros.getMacro(\"" + getName() + "\").invoke(view);";
449         } //}}}
450

451         //{{{ macroNameToLabel() method
452
public static String JavaDoc macroNameToLabel(String JavaDoc macroName)
453         {
454             int index = macroName.lastIndexOf('/');
455             return macroName.substring(index + 1).replace('_', ' ');
456         }
457         //}}}
458

459         //{{{ Private members
460
private Handler handler;
461         private String JavaDoc path;
462         String JavaDoc label;
463         //}}}
464
} //}}}
465

466     //{{{ recordTemporaryMacro() method
467
/**
468      * Starts recording a temporary macro.
469      * @param view The view
470      * @since jEdit 2.7pre2
471      */

472     public static void recordTemporaryMacro(View view)
473     {
474         String JavaDoc settings = jEdit.getSettingsDirectory();
475
476         if(settings == null)
477         {
478             GUIUtilities.error(view,"no-settings",new String JavaDoc[0]);
479             return;
480         }
481         if(view.getMacroRecorder() != null)
482         {
483             GUIUtilities.error(view,"already-recording",new String JavaDoc[0]);
484             return;
485         }
486
487         Buffer buffer = jEdit.openFile(null,settings + File.separator
488             + "macros","Temporary_Macro.bsh",true,null);
489
490         if(buffer == null)
491             return;
492
493         buffer.remove(0,buffer.getLength());
494         buffer.insert(0,jEdit.getProperty("macro.temp.header"));
495
496         recordMacro(view,buffer,true);
497     } //}}}
498

499     //{{{ recordMacro() method
500
/**
501      * Starts recording a macro.
502      * @param view The view
503      * @since jEdit 2.7pre2
504      */

505     public static void recordMacro(View view)
506     {
507         String JavaDoc settings = jEdit.getSettingsDirectory();
508
509         if(settings == null)
510         {
511             GUIUtilities.error(view,"no-settings",new String JavaDoc[0]);
512             return;
513         }
514
515         if(view.getMacroRecorder() != null)
516         {
517             GUIUtilities.error(view,"already-recording",new String JavaDoc[0]);
518             return;
519         }
520
521         String JavaDoc name = GUIUtilities.input(view,"record",null);
522         if(name == null)
523             return;
524
525         name = name.replace(' ','_');
526
527         Buffer buffer = jEdit.openFile(null,null,
528             MiscUtilities.constructPath(settings,"macros",
529             name + ".bsh"),true,null);
530
531         if(buffer == null)
532             return;
533
534         buffer.remove(0,buffer.getLength());
535         buffer.insert(0,jEdit.getProperty("macro.header"));
536
537         recordMacro(view,buffer,false);
538     } //}}}
539

540     //{{{ stopRecording() method
541
/**
542      * Stops a recording currently in progress.
543      * @param view The view
544      * @since jEdit 2.7pre2
545      */

546     public static void stopRecording(View view)
547     {
548         Recorder recorder = view.getMacroRecorder();
549
550         if(recorder == null)
551             GUIUtilities.error(view,"macro-not-recording",null);
552         else
553         {
554             view.setMacroRecorder(null);
555             if(!recorder.temporary)
556                 view.setBuffer(recorder.buffer);
557             recorder.dispose();
558         }
559     } //}}}
560

561     //{{{ runTemporaryMacro() method
562
/**
563      * Runs the temporary macro.
564      * @param view The view
565      * @since jEdit 2.7pre2
566      */

567     public static void runTemporaryMacro(View view)
568     {
569         String JavaDoc settings = jEdit.getSettingsDirectory();
570
571         if(settings == null)
572         {
573             GUIUtilities.error(view,"no-settings",null);
574             return;
575         }
576
577         String JavaDoc path = MiscUtilities.constructPath(
578             jEdit.getSettingsDirectory(),"macros",
579             "Temporary_Macro.bsh");
580
581         if(jEdit.getBuffer(path) == null)
582         {
583             GUIUtilities.error(view,"no-temp-macro",null);
584             return;
585         }
586
587         Handler handler = getHandler("beanshell");
588         Macro temp = handler.createMacro(path,path);
589
590         Buffer buffer = view.getBuffer();
591
592         try
593         {
594             buffer.beginCompoundEdit();
595             temp.invoke(view);
596         }
597         finally
598         {
599             /* I already wrote a comment expaining this in
600              * Macro.invoke(). */

601             if(buffer.insideCompoundEdit())
602                 buffer.endCompoundEdit();
603         }
604     } //}}}
605

606     //{{{ Private members
607

608     //{{{ Static variables
609
private static String JavaDoc systemMacroPath;
610     private static String JavaDoc userMacroPath;
611
612     private static ArrayList macroHandlers;
613
614     private static ActionSet macroActionSet;
615     private static Vector macroHierarchy;
616     private static Hashtable macroHash;
617
618     private static Macro lastMacro;
619     //}}}
620

621     //{{{ Class initializer
622
static
623     {
624         macroHandlers = new ArrayList();
625         registerHandler(new BeanShellHandler());
626         macroActionSet = new ActionSet(jEdit.getProperty("action-set.macros"));
627         jEdit.addActionSet(macroActionSet);
628         macroHierarchy = new Vector();
629         macroHash = new Hashtable();
630     } //}}}
631

632     //{{{ loadMacros() method
633
private static void loadMacros(Vector vector, String JavaDoc path, File directory)
634     {
635         lastMacro = null;
636
637         File[] macroFiles = directory.listFiles();
638         if(macroFiles == null || macroFiles.length == 0)
639             return;
640
641         for(int i = 0; i < macroFiles.length; i++)
642         {
643             File file = macroFiles[i];
644             String JavaDoc fileName = file.getName();
645             if(file.isHidden())
646             {
647                 /* do nothing! */
648                 continue;
649             }
650             else if(file.isDirectory())
651             {
652                 String JavaDoc submenuName = fileName.replace('_',' ');
653                 Vector submenu = null;
654                 //{{{ try to merge with an existing menu first
655
for(int j = 0; j < vector.size(); j++)
656                 {
657                     Object JavaDoc obj = vector.get(j);
658                     if(obj instanceof Vector)
659                     {
660                         Vector vec = (Vector)obj;
661                         if(((String JavaDoc)vec.get(0)).equals(submenuName))
662                         {
663                             submenu = vec;
664                             break;
665                         }
666                     }
667                 } //}}}
668
if(submenu == null)
669                 {
670                     submenu = new Vector();
671                     submenu.addElement(submenuName);
672                     vector.addElement(submenu);
673                 }
674
675                 loadMacros(submenu,path + fileName + '/',file);
676             }
677             else
678             {
679                 addMacro(file,path,vector);
680             }
681         }
682     } //}}}
683

684     //{{{ addMacro() method
685
private static void addMacro(File file, String JavaDoc path, Vector vector)
686     {
687         String JavaDoc fileName = file.getName();
688         Handler handler = getHandlerForPathName(file.getPath());
689
690         if(handler == null)
691             return;
692
693         try
694         {
695             // in case macro file name has a space in it.
696
// spaces break the view.toolBar property, for instance,
697
// since it uses spaces to delimit action names.
698
String JavaDoc macroName = (path + fileName).replace(' ','_');
699             Macro newMacro = handler.createMacro(macroName,
700                 file.getPath());
701             // ignore if already added.
702
// see comment in loadMacros().
703
if(macroHash.get(newMacro.getName()) != null)
704                 return;
705
706             vector.addElement(newMacro.getName());
707             jEdit.setTemporaryProperty(newMacro.getName()
708                 + ".label",
709                 newMacro.label);
710             jEdit.setTemporaryProperty(newMacro.getName()
711                 + ".mouse-over",
712                 handler.getLabel() + " - " + file.getPath());
713             macroActionSet.addAction(newMacro);
714             macroHash.put(newMacro.getName(),newMacro);
715         }
716         catch (Exception JavaDoc e)
717         {
718             Log.log(Log.ERROR, Macros.class, e);
719             macroHandlers.remove(handler);
720         }
721     } //}}}
722

723     //{{{ recordMacro() method
724
/**
725      * Starts recording a macro.
726      * @param view The view
727      * @param buffer The buffer to record to
728      * @param temporary True if this is a temporary macro
729      * @since jEdit 3.0pre5
730      */

731     private static void recordMacro(View view, Buffer buffer, boolean temporary)
732     {
733         view.setMacroRecorder(new Recorder(view,buffer,temporary));
734
735         // setting the message to 'null' causes the status bar to check
736
// if a recording is in progress
737
view.getStatus().setMessage(null);
738     } //}}}
739

740     //}}}
741

742     //{{{ Recorder class
743
/**
744      * Handles macro recording.
745      */

746     public static class Recorder implements EBComponent
747     {
748         View view;
749         Buffer buffer;
750         boolean temporary;
751
752         boolean lastWasInput;
753         boolean lastWasOverwrite;
754         int overwriteCount;
755
756         //{{{ Recorder constructor
757
public Recorder(View view, Buffer buffer, boolean temporary)
758         {
759             this.view = view;
760             this.buffer = buffer;
761             this.temporary = temporary;
762             EditBus.addToBus(this);
763         } //}}}
764

765         //{{{ record() method
766
public void record(String JavaDoc code)
767         {
768             flushInput();
769
770             append("\n");
771             append(code);
772         } //}}}
773

774         //{{{ record() method
775
public void record(int repeat, String JavaDoc code)
776         {
777             if(repeat == 1)
778                 record(code);
779             else
780             {
781                 record("for(int i = 1; i <= " + repeat + "; i++)\n"
782                     + "{\n"
783                     + code + "\n"
784                     + "}");
785             }
786         } //}}}
787

788         //{{{ recordInput() method
789
/**
790          * @since jEdit 4.2pre5
791          */

792         public void recordInput(int repeat, char ch, boolean overwrite)
793         {
794             // record \n and \t on lines specially so that auto indent
795
// can take place
796
if(ch == '\n')
797                 record(repeat,"textArea.userInput(\'\\n\');");
798             else if(ch == '\t')
799                 record(repeat,"textArea.userInput(\'\\t\');");
800             else
801             {
802                 StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
803                 for(int i = 0; i < repeat; i++)
804                     buf.append(ch);
805                 recordInput(buf.toString(),overwrite);
806             }
807         } //}}}
808

809         //{{{ recordInput() method
810
/**
811          * @since jEdit 4.2pre5
812          */

813         public void recordInput(String JavaDoc str, boolean overwrite)
814         {
815             String JavaDoc charStr = MiscUtilities.charsToEscapes(str);
816
817             if(overwrite)
818             {
819                 if(lastWasOverwrite)
820                 {
821                     overwriteCount++;
822                     append(charStr);
823                 }
824                 else
825                 {
826                     flushInput();
827                     overwriteCount = 1;
828                     lastWasOverwrite = true;
829                     append("\ntextArea.setSelectedText(\"" + charStr);
830                 }
831             }
832             else
833             {
834                 if(lastWasInput)
835                     append(charStr);
836                 else
837                 {
838                     flushInput();
839                     lastWasInput = true;
840                     append("\ntextArea.setSelectedText(\"" + charStr);
841                 }
842             }
843         } //}}}
844

845         //{{{ handleMessage() method
846
public void handleMessage(EBMessage msg)
847         {
848             if(msg instanceof BufferUpdate)
849             {
850                 BufferUpdate bmsg = (BufferUpdate)msg;
851                 if(bmsg.getWhat() == BufferUpdate.CLOSED)
852                 {
853                     if(bmsg.getBuffer() == buffer)
854                         stopRecording(view);
855                 }
856             }
857         } //}}}
858

859         //{{{ append() method
860
private void append(String JavaDoc str)
861         {
862             buffer.insert(buffer.getLength(),str);
863         } //}}}
864

865         //{{{ dispose() method
866
private void dispose()
867         {
868             flushInput();
869
870             for(int i = 0; i < buffer.getLineCount(); i++)
871             {
872                 buffer.indentLine(i,true);
873             }
874
875             EditBus.removeFromBus(this);
876
877             // setting the message to 'null' causes the status bar to
878
// check if a recording is in progress
879
view.getStatus().setMessage(null);
880         } //}}}
881

882         //{{{ flushInput() method
883
/**
884          * We try to merge consecutive inputs. This helper method is
885          * called when something other than input is to be recorded.
886          */

887         private void flushInput()
888         {
889             if(lastWasInput)
890             {
891                 lastWasInput = false;
892                 append("\");");
893             }
894
895             if(lastWasOverwrite)
896             {
897                 lastWasOverwrite = false;
898                 append("\");\n");
899                 append("offset = buffer.getLineEndOffset("
900                     + "textArea.getCaretLine()) - 1;\n");
901                 append("buffer.remove(textArea.getCaretPosition(),"
902                     + "Math.min(" + overwriteCount
903                     + ",offset - "
904                     + "textArea.getCaretPosition()));");
905             }
906         } //}}}
907
} //}}}
908

909     //{{{ Handler class
910
/**
911      * Encapsulates creating and invoking macros in arbitrary scripting languages
912      * @since jEdit 4.0pre6
913      */

914     public static abstract class Handler
915     {
916         //{{{ getName() method
917
public String JavaDoc getName()
918         {
919             return name;
920         } //}}}
921

922         //{{{ getLabel() method
923
public String JavaDoc getLabel()
924         {
925             return label;
926         } //}}}
927

928         //{{{ accept() method
929
public boolean accept(String JavaDoc path)
930         {
931             return filter.matcher(MiscUtilities.getFileName(path)).matches();
932         } //}}}
933

934         //{{{ createMacro() method
935
public abstract Macro createMacro(String JavaDoc macroName, String JavaDoc path);
936         //}}}
937

938         //{{{ runMacro() method
939
/**
940          * Runs the specified macro.
941          * @param view The view - may be null.
942          * @param macro The macro.
943          */

944         public abstract void runMacro(View view, Macro macro);
945         //}}}
946

947         //{{{ runMacro() method
948
/**
949          * Runs the specified macro. This method is optional; it is
950          * called if the specified macro is a startup script. The
951          * default behavior is to simply call {@link #runMacro(View,Macros.Macro)}.
952          *
953          * @param view The view - may be null.
954          * @param macro The macro.
955          * @param ownNamespace A hint indicating whenever functions and
956          * variables defined in the script are to be self-contained, or
957          * made available to other scripts. The macro handler may ignore
958          * this parameter.
959          * @since jEdit 4.1pre3
960          */

961         public void runMacro(View view, Macro macro, boolean ownNamespace)
962         {
963             runMacro(view,macro);
964         } //}}}
965

966         //{{{ Handler constructor
967
protected Handler(String JavaDoc name)
968         {
969             this.name = name;
970             label = jEdit.getProperty("macro-handler."
971                 + name + ".label", name);
972             try
973             {
974                 filter = Pattern.compile(StandardUtilities.globToRE(
975                     jEdit.getProperty(
976                     "macro-handler." + name + ".glob")));
977             }
978             catch (Exception JavaDoc e)
979             {
980                 throw new InternalError JavaDoc("Missing or invalid glob for handler " + name);
981             }
982         } //}}}
983

984         //{{{ Private members
985
private String JavaDoc name;
986         private String JavaDoc label;
987         private Pattern JavaDoc filter;
988         //}}}
989
} //}}}
990

991     //{{{ BeanShellHandler class
992
static class BeanShellHandler extends Handler
993     {
994         //{{{ BeanShellHandler constructor
995
BeanShellHandler()
996         {
997             super("beanshell");
998         } //}}}
999

1000        //{{{ createMacro() method
1001
public Macro createMacro(String JavaDoc macroName, String JavaDoc path)
1002        {
1003            // Remove '.bsh'
1004
macroName = macroName.substring(0, macroName.length() - 4);
1005
1006            return new Macro(this, macroName,
1007                Macro.macroNameToLabel(macroName), path);
1008        } //}}}
1009

1010        //{{{ runMacro() method
1011
public void runMacro(View view, Macro macro)
1012        {
1013            BeanShell.runScript(view,macro.getPath(),null,true);
1014        } //}}}
1015

1016        //{{{ runMacro() method
1017
public void runMacro(View view, Macro macro, boolean ownNamespace)
1018        {
1019            BeanShell.runScript(view,macro.getPath(),null,ownNamespace);
1020        } //}}}
1021
} //}}}
1022
}
1023
Popular Tags