PageRenderTime 36ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/jEdit/tags/jedit-4-2-pre4/org/gjt/sp/jedit/Macros.java

#
Java | 927 lines | 534 code | 106 blank | 287 comment | 70 complexity | da8b944241c77de83dc35cdd2eacadc7 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
  1. /*
  2. * Macros.java - Macro manager
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 1999, 2003 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. package org.gjt.sp.jedit;
  24. //{{{ Imports
  25. import gnu.regexp.RE;
  26. import javax.swing.*;
  27. import java.awt.*;
  28. import java.io.*;
  29. import java.util.*;
  30. import org.gjt.sp.jedit.msg.*;
  31. import org.gjt.sp.util.Log;
  32. //}}}
  33. /**
  34. * This class records and runs macros.<p>
  35. *
  36. * It also contains a few methods useful for displaying output messages
  37. * or obtaining input from a macro:
  38. *
  39. * <ul>
  40. * <li>{@link #confirm(Component,String,int)}</li>
  41. * <li>{@link #confirm(Component,String,int,int)}</li>
  42. * <li>{@link #error(Component,String)}</li>
  43. * <li>{@link #input(Component,String)}</li>
  44. * <li>{@link #input(Component,String,String)}</li>
  45. * <li>{@link #message(Component,String)}</li>
  46. * </ul>
  47. *
  48. * Note that plugins should not use the above methods. Call
  49. * the methods in the {@link GUIUtilities} class instead.
  50. *
  51. * @author Slava Pestov
  52. * @version $Id: Macros.java 4743 2003-05-29 19:52:42Z spestov $
  53. */
  54. public class Macros
  55. {
  56. //{{{ showRunScriptDialog() method
  57. /**
  58. * Prompts for one or more files to run as macros
  59. * @param view The view
  60. * @since jEdit 4.0pre7
  61. */
  62. public static void showRunScriptDialog(View view)
  63. {
  64. String[] paths = GUIUtilities.showVFSFileDialog(view,
  65. null,JFileChooser.OPEN_DIALOG,true);
  66. if(paths != null)
  67. {
  68. Buffer buffer = view.getBuffer();
  69. try
  70. {
  71. buffer.beginCompoundEdit();
  72. file_loop: for(int i = 0; i < paths.length; i++)
  73. runScript(view,paths[i],false);
  74. }
  75. finally
  76. {
  77. buffer.endCompoundEdit();
  78. }
  79. }
  80. } //}}}
  81. //{{{ runScript() method
  82. /**
  83. * Runs the specified script.
  84. * Unlike the {@link BeanShell#runScript(View,String,Reader,boolean)}
  85. * method, this method can run scripts supported
  86. * by any registered macro handler.
  87. * @param view The view
  88. * @param path The VFS path of the script
  89. * @param ignoreUnknown If true, then unknown file types will be
  90. * ignored; otherwise, a warning message will be printed and they will
  91. * be evaluated as BeanShell scripts.
  92. *
  93. * @since jEdit 4.1pre2
  94. */
  95. public static void runScript(View view, String path, boolean ignoreUnknown)
  96. {
  97. Handler handler = getHandlerForPathName(path);
  98. if(handler != null)
  99. {
  100. try
  101. {
  102. Macro newMacro = handler.createMacro(
  103. MiscUtilities.getFileName(path), path);
  104. newMacro.invoke(view);
  105. }
  106. catch (Exception e)
  107. {
  108. Log.log(Log.ERROR, Macros.class, e);
  109. return;
  110. }
  111. return;
  112. }
  113. // only executed if above loop falls
  114. // through, ie there is no handler for
  115. // this file
  116. if(ignoreUnknown)
  117. {
  118. Log.log(Log.NOTICE,Macros.class,path +
  119. ": Cannot find a suitable macro handler");
  120. }
  121. else
  122. {
  123. Log.log(Log.ERROR,Macros.class,path +
  124. ": Cannot find a suitable macro handler, "
  125. + "assuming BeanShell");
  126. getHandler("beanshell").createMacro(
  127. path,path).invoke(view);
  128. }
  129. } //}}}
  130. //{{{ message() method
  131. /**
  132. * Utility method that can be used to display a message dialog in a macro.
  133. * @param comp The component to show the dialog on behalf of, this
  134. * will usually be a view instance
  135. * @param message The message
  136. * @since jEdit 2.7pre2
  137. */
  138. public static void message(Component comp, String message)
  139. {
  140. GUIUtilities.hideSplashScreen();
  141. JOptionPane.showMessageDialog(comp,message,
  142. jEdit.getProperty("macro-message.title"),
  143. JOptionPane.INFORMATION_MESSAGE);
  144. } //}}}
  145. //{{{ error() method
  146. /**
  147. * Utility method that can be used to display an error dialog in a macro.
  148. * @param comp The component to show the dialog on behalf of, this
  149. * will usually be a view instance
  150. * @param message The message
  151. * @since jEdit 2.7pre2
  152. */
  153. public static void error(Component comp, String message)
  154. {
  155. GUIUtilities.hideSplashScreen();
  156. JOptionPane.showMessageDialog(comp,message,
  157. jEdit.getProperty("macro-message.title"),
  158. JOptionPane.ERROR_MESSAGE);
  159. } //}}}
  160. //{{{ input() method
  161. /**
  162. * Utility method that can be used to prompt for input in a macro.
  163. * @param comp The component to show the dialog on behalf of, this
  164. * will usually be a view instance
  165. * @param prompt The prompt string
  166. * @since jEdit 2.7pre2
  167. */
  168. public static String input(Component comp, String prompt)
  169. {
  170. GUIUtilities.hideSplashScreen();
  171. return input(comp,prompt,null);
  172. } //}}}
  173. //{{{ input() method
  174. /**
  175. * Utility method that can be used to prompt for input in a macro.
  176. * @param comp The component to show the dialog on behalf of, this
  177. * will usually be a view instance
  178. * @param prompt The prompt string
  179. * @since jEdit 3.1final
  180. */
  181. public static String input(Component comp, String prompt, String defaultValue)
  182. {
  183. GUIUtilities.hideSplashScreen();
  184. return (String)JOptionPane.showInputDialog(comp,prompt,
  185. jEdit.getProperty("macro-input.title"),
  186. JOptionPane.QUESTION_MESSAGE,null,null,defaultValue);
  187. } //}}}
  188. //{{{ confirm() method
  189. /**
  190. * Utility method that can be used to ask for confirmation in a macro.
  191. * @param comp The component to show the dialog on behalf of, this
  192. * will usually be a view instance
  193. * @param prompt The prompt string
  194. * @param buttons The buttons to display - for example,
  195. * JOptionPane.YES_NO_CANCEL_OPTION
  196. * @since jEdit 4.0pre2
  197. */
  198. public static int confirm(Component comp, String prompt, int buttons)
  199. {
  200. GUIUtilities.hideSplashScreen();
  201. return JOptionPane.showConfirmDialog(comp,prompt,
  202. jEdit.getProperty("macro-confirm.title"),buttons,
  203. JOptionPane.QUESTION_MESSAGE);
  204. } //}}}
  205. //{{{ confirm() method
  206. /**
  207. * Utility method that can be used to ask for confirmation in a macro.
  208. * @param comp The component to show the dialog on behalf of, this
  209. * will usually be a view instance
  210. * @param prompt The prompt string
  211. * @param buttons The buttons to display - for example,
  212. * JOptionPane.YES_NO_CANCEL_OPTION
  213. * @param type The dialog type - for example,
  214. * JOptionPane.WARNING_MESSAGE
  215. */
  216. public static int confirm(Component comp, String prompt, int buttons, int type)
  217. {
  218. GUIUtilities.hideSplashScreen();
  219. return JOptionPane.showConfirmDialog(comp,prompt,
  220. jEdit.getProperty("macro-confirm.title"),buttons,type);
  221. } //}}}
  222. //{{{ loadMacros() method
  223. /**
  224. * Rebuilds the macros list, and sends a MacrosChanged message
  225. * (views update their Macros menu upon receiving it)
  226. * @since jEdit 2.2pre4
  227. */
  228. public static void loadMacros()
  229. {
  230. macroActionSet.removeAllActions();
  231. macroHierarchy.removeAllElements();
  232. macroHash.clear();
  233. if(jEdit.getJEditHome() != null)
  234. {
  235. systemMacroPath = MiscUtilities.constructPath(
  236. jEdit.getJEditHome(),"macros");
  237. loadMacros(macroHierarchy,"",new File(systemMacroPath));
  238. }
  239. String settings = jEdit.getSettingsDirectory();
  240. if(settings != null)
  241. {
  242. userMacroPath = MiscUtilities.constructPath(
  243. settings,"macros");
  244. loadMacros(macroHierarchy,"",new File(userMacroPath));
  245. }
  246. EditBus.send(new DynamicMenuChanged("macros"));
  247. } //}}}
  248. //{{{ registerHandler() method
  249. /**
  250. * Adds a macro handler to the handlers list
  251. * @since jEdit 4.0pre6
  252. */
  253. public static void registerHandler(Handler handler)
  254. {
  255. if (getHandler(handler.getName()) != null)
  256. {
  257. Log.log(Log.ERROR, Macros.class, "Cannot register more than one macro handler with the same name");
  258. return;
  259. }
  260. Log.log(Log.DEBUG,Macros.class,"Registered " + handler.getName()
  261. + " macro handler");
  262. macroHandlers.add(handler);
  263. } //}}}
  264. //{{{ getHandlers() method
  265. /**
  266. * Returns an array containing the list of registered macro handlers
  267. * @since jEdit 4.0pre6
  268. */
  269. public static Handler[] getHandlers()
  270. {
  271. Handler[] handlers = new Handler[macroHandlers.size()];
  272. return (Handler[])macroHandlers.toArray(handlers);
  273. } //}}}
  274. //{{{ getHandlerForFileName() method
  275. /**
  276. * Returns the macro handler suitable for running the specified file
  277. * name, or null if there is no suitable handler.
  278. * @since jEdit 4.1pre3
  279. */
  280. public static Handler getHandlerForPathName(String pathName)
  281. {
  282. for (int i = 0; i < macroHandlers.size(); i++)
  283. {
  284. Handler handler = (Handler)macroHandlers.get(i);
  285. if (handler.accept(pathName))
  286. return handler;
  287. }
  288. return null;
  289. } //}}}
  290. //{{{ getHandler() method
  291. /**
  292. * Returns the macro handler with the specified name, or null if
  293. * there is no registered handler with that name.
  294. * @since jEdit 4.0pre6
  295. */
  296. public static Handler getHandler(String name)
  297. {
  298. Handler handler = null;
  299. for (int i = 0; i < macroHandlers.size(); i++)
  300. {
  301. handler = (Handler)macroHandlers.get(i);
  302. if (handler.getName().equals(name)) return handler;
  303. }
  304. return null;
  305. }
  306. //}}}
  307. //{{{ getMacroHierarchy() method
  308. /**
  309. * Returns a vector hierarchy with all known macros in it.
  310. * Each element of this vector is either a macro name string,
  311. * or another vector. If it is a vector, the first element is a
  312. * string label, the rest are again, either macro name strings
  313. * or vectors.
  314. * @since jEdit 2.6pre1
  315. */
  316. public static Vector getMacroHierarchy()
  317. {
  318. return macroHierarchy;
  319. } //}}}
  320. //{{{ getMacroActionSet() method
  321. /**
  322. * Returns an action set with all known macros in it.
  323. * @since jEdit 4.0pre1
  324. */
  325. public static ActionSet getMacroActionSet()
  326. {
  327. return macroActionSet;
  328. } //}}}
  329. //{{{ getMacro() method
  330. /**
  331. * Returns the macro with the specified name.
  332. * @param macro The macro's name
  333. * @since jEdit 2.6pre1
  334. */
  335. public static Macro getMacro(String macro)
  336. {
  337. return (Macro)macroHash.get(macro);
  338. } //}}}
  339. //{{{ Macro class
  340. /**
  341. * Encapsulates the macro's label, name and path.
  342. * @since jEdit 2.2pre4
  343. */
  344. public static class Macro extends EditAction
  345. {
  346. //{{{ Macro constructor
  347. public Macro(Handler handler, String name, String label, String path)
  348. {
  349. // in case macro file name has a space in it.
  350. // spaces break the view.toolBar property, for instance,
  351. // since it uses spaces to delimit action names.
  352. super(name.replace(' ','_'));
  353. this.handler = handler;
  354. this.label = label;
  355. this.path = path;
  356. jEdit.setTemporaryProperty(getName() + ".label",label);
  357. jEdit.setTemporaryProperty(getName() + ".mouse-over",
  358. handler.getLabel() + " - " + path);
  359. } //}}}
  360. //{{{ getHandler() method
  361. public Handler getHandler()
  362. {
  363. return handler;
  364. }
  365. //}}}
  366. //{{{ getPath() method
  367. public String getPath()
  368. {
  369. return path;
  370. } //}}}
  371. //{{{ invoke() method
  372. public void invoke(View view)
  373. {
  374. if(view == null)
  375. handler.runMacro(null,this);
  376. else
  377. {
  378. Buffer buffer = view.getBuffer();
  379. try
  380. {
  381. buffer.beginCompoundEdit();
  382. handler.runMacro(view,this);
  383. }
  384. finally
  385. {
  386. buffer.endCompoundEdit();
  387. }
  388. }
  389. } //}}}
  390. //{{{ getCode() method
  391. public String getCode()
  392. {
  393. return "Macros.getMacro(\"" + getName() + "\").invoke(view);";
  394. } //}}}
  395. //{{{ macroNameToLabel() method
  396. public static String macroNameToLabel(String macroName)
  397. {
  398. int index = macroName.lastIndexOf('/');
  399. return macroName.substring(index + 1).replace('_', ' ');
  400. }
  401. //}}}
  402. //{{{ Private members
  403. private Handler handler;
  404. private String path;
  405. private String label;
  406. //}}}
  407. } //}}}
  408. //{{{ recordTemporaryMacro() method
  409. /**
  410. * Starts recording a temporary macro.
  411. * @param view The view
  412. * @since jEdit 2.7pre2
  413. */
  414. public static void recordTemporaryMacro(View view)
  415. {
  416. String settings = jEdit.getSettingsDirectory();
  417. if(settings == null)
  418. {
  419. GUIUtilities.error(view,"no-settings",new String[0]);
  420. return;
  421. }
  422. if(view.getMacroRecorder() != null)
  423. {
  424. GUIUtilities.error(view,"already-recording",new String[0]);
  425. return;
  426. }
  427. Buffer buffer = jEdit.openFile(null,settings + File.separator
  428. + "macros","Temporary_Macro.bsh",true,null);
  429. if(buffer == null)
  430. return;
  431. buffer.remove(0,buffer.getLength());
  432. buffer.insert(0,jEdit.getProperty("macro.temp.header"));
  433. recordMacro(view,buffer,true);
  434. } //}}}
  435. //{{{ recordMacro() method
  436. /**
  437. * Starts recording a macro.
  438. * @param view The view
  439. * @since jEdit 2.7pre2
  440. */
  441. public static void recordMacro(View view)
  442. {
  443. String settings = jEdit.getSettingsDirectory();
  444. if(settings == null)
  445. {
  446. GUIUtilities.error(view,"no-settings",new String[0]);
  447. return;
  448. }
  449. if(view.getMacroRecorder() != null)
  450. {
  451. GUIUtilities.error(view,"already-recording",new String[0]);
  452. return;
  453. }
  454. String name = GUIUtilities.input(view,"record",null);
  455. if(name == null)
  456. return;
  457. name = name.replace(' ','_');
  458. Buffer buffer = jEdit.openFile(null,null,
  459. MiscUtilities.constructPath(settings,"macros",
  460. name + ".bsh"),true,null);
  461. if(buffer == null)
  462. return;
  463. buffer.remove(0,buffer.getLength());
  464. buffer.insert(0,jEdit.getProperty("macro.header"));
  465. recordMacro(view,buffer,false);
  466. } //}}}
  467. //{{{ stopRecording() method
  468. /**
  469. * Stops a recording currently in progress.
  470. * @param view The view
  471. * @since jEdit 2.7pre2
  472. */
  473. public static void stopRecording(View view)
  474. {
  475. Recorder recorder = view.getMacroRecorder();
  476. if(recorder == null)
  477. GUIUtilities.error(view,"macro-not-recording",null);
  478. else
  479. {
  480. view.setMacroRecorder(null);
  481. if(!recorder.temporary)
  482. view.setBuffer(recorder.buffer);
  483. recorder.dispose();
  484. }
  485. } //}}}
  486. //{{{ runTemporaryMacro() method
  487. /**
  488. * Runs the temporary macro.
  489. * @param view The view
  490. * @since jEdit 2.7pre2
  491. */
  492. public static void runTemporaryMacro(View view)
  493. {
  494. String settings = jEdit.getSettingsDirectory();
  495. if(settings == null)
  496. {
  497. GUIUtilities.error(view,"no-settings",new String[0]);
  498. return;
  499. }
  500. String path = MiscUtilities.constructPath(
  501. jEdit.getSettingsDirectory(),"macros",
  502. "Temporary_Macro.bsh");
  503. Handler handler = getHandler("beanshell");
  504. Macro temp = handler.createMacro(path,path);
  505. Buffer buffer = view.getBuffer();
  506. try
  507. {
  508. buffer.beginCompoundEdit();
  509. temp.invoke(view);
  510. }
  511. finally
  512. {
  513. /* I already wrote a comment expaining this in
  514. * Macro.invoke(). */
  515. if(buffer.insideCompoundEdit())
  516. buffer.endCompoundEdit();
  517. }
  518. } //}}}
  519. //{{{ Private members
  520. //{{{ Static variables
  521. private static String systemMacroPath;
  522. private static String userMacroPath;
  523. private static ArrayList macroHandlers;
  524. private static ActionSet macroActionSet;
  525. private static Vector macroHierarchy;
  526. private static Hashtable macroHash;
  527. //}}}
  528. //{{{ Class initializer
  529. static
  530. {
  531. macroHandlers = new ArrayList();
  532. registerHandler(new BeanShellHandler());
  533. macroActionSet = new ActionSet(jEdit.getProperty("action-set.macros"));
  534. jEdit.addActionSet(macroActionSet);
  535. macroHierarchy = new Vector();
  536. macroHash = new Hashtable();
  537. } //}}}
  538. //{{{ loadMacros() method
  539. private static void loadMacros(Vector vector, String path, File directory)
  540. {
  541. File[] macroFiles = directory.listFiles();
  542. if(macroFiles == null || macroFiles.length == 0)
  543. return;
  544. for(int i = 0; i < macroFiles.length; i++)
  545. {
  546. File file = macroFiles[i];
  547. String fileName = file.getName();
  548. if(file.isHidden())
  549. {
  550. /* do nothing! */
  551. continue;
  552. }
  553. else if(file.isDirectory())
  554. {
  555. String submenuName = fileName.replace('_',' ');
  556. Vector submenu = null;
  557. //{{{ try to merge with an existing menu first
  558. for(int j = 0; j < vector.size(); j++)
  559. {
  560. Object obj = vector.get(j);
  561. if(obj instanceof Vector)
  562. {
  563. Vector vec = (Vector)obj;
  564. if(((String)vec.get(0)).equals(submenuName))
  565. {
  566. submenu = vec;
  567. break;
  568. }
  569. }
  570. } //}}}
  571. if(submenu == null)
  572. {
  573. submenu = new Vector();
  574. submenu.addElement(submenuName);
  575. vector.addElement(submenu);
  576. }
  577. loadMacros(submenu,path + fileName + '/',file);
  578. }
  579. else
  580. {
  581. Handler handler = getHandlerForPathName(file.getPath());
  582. if(handler == null)
  583. continue;
  584. try
  585. {
  586. Macro newMacro = handler.createMacro(
  587. path + fileName, file.getPath());
  588. vector.addElement(newMacro.getName());
  589. macroActionSet.addAction(newMacro);
  590. macroHash.put(newMacro.getName(),newMacro);
  591. }
  592. catch (Exception e)
  593. {
  594. Log.log(Log.ERROR, Macros.class, e);
  595. macroHandlers.remove(handler);
  596. }
  597. }
  598. }
  599. } //}}}
  600. //{{{ recordMacro() method
  601. /**
  602. * Starts recording a macro.
  603. * @param view The view
  604. * @param buffer The buffer to record to
  605. * @param temporary True if this is a temporary macro
  606. * @since jEdit 3.0pre5
  607. */
  608. private static void recordMacro(View view, Buffer buffer, boolean temporary)
  609. {
  610. Handler handler = getHandler("beanshell");
  611. String path = buffer.getPath();
  612. view.setMacroRecorder(new Recorder(view,buffer,temporary));
  613. // setting the message to 'null' causes the status bar to check
  614. // if a recording is in progress
  615. view.getStatus().setMessage(null);
  616. } //}}}
  617. //}}}
  618. //{{{ Recorder class
  619. /**
  620. * Handles macro recording.
  621. */
  622. public static class Recorder implements EBComponent
  623. {
  624. View view;
  625. Buffer buffer;
  626. boolean temporary;
  627. boolean lastWasInput;
  628. //{{{ Recorder constructor
  629. public Recorder(View view, Buffer buffer, boolean temporary)
  630. {
  631. this.view = view;
  632. this.buffer = buffer;
  633. this.temporary = temporary;
  634. EditBus.addToBus(this);
  635. } //}}}
  636. //{{{ record() method
  637. public void record(String code)
  638. {
  639. if(lastWasInput)
  640. {
  641. lastWasInput = false;
  642. append("\");");
  643. }
  644. append("\n");
  645. append(code);
  646. } //}}}
  647. //{{{ record() method
  648. public void record(int repeat, String code)
  649. {
  650. if(repeat == 1)
  651. record(code);
  652. else
  653. {
  654. record("for(int i = 1; i <= " + repeat + "; i++)\n"
  655. + "{\n"
  656. + code + "\n"
  657. + "}");
  658. }
  659. } //}}}
  660. //{{{ record() method
  661. public void record(int repeat, char ch)
  662. {
  663. // record \n and \t on lines specially so that auto indent
  664. // can take place
  665. if(ch == '\n')
  666. record(repeat,"textArea.userInput(\'\\n\');");
  667. else if(ch == '\t')
  668. record(repeat,"textArea.userInput(\'\\t\');");
  669. else
  670. {
  671. StringBuffer buf = new StringBuffer();
  672. for(int i = 0; i < repeat; i++)
  673. buf.append(ch);
  674. String charStr = MiscUtilities.charsToEscapes(buf.toString());
  675. if(lastWasInput)
  676. append(charStr);
  677. else
  678. {
  679. append("\ntextArea.setSelectedText(\"" + charStr);
  680. lastWasInput = true;
  681. }
  682. }
  683. } //}}}
  684. //{{{ handleMessage() method
  685. public void handleMessage(EBMessage msg)
  686. {
  687. if(msg instanceof BufferUpdate)
  688. {
  689. BufferUpdate bmsg = (BufferUpdate)msg;
  690. if(bmsg.getWhat() == BufferUpdate.CLOSED)
  691. {
  692. if(bmsg.getBuffer() == buffer)
  693. stopRecording(view);
  694. }
  695. }
  696. } //}}}
  697. //{{{ append() method
  698. private void append(String str)
  699. {
  700. buffer.insert(buffer.getLength(),str);
  701. } //}}}
  702. //{{{ dispose() method
  703. private void dispose()
  704. {
  705. if(lastWasInput)
  706. {
  707. lastWasInput = false;
  708. append("\");");
  709. }
  710. for(int i = 0; i < buffer.getLineCount(); i++)
  711. {
  712. buffer.indentLine(i,true);
  713. }
  714. EditBus.removeFromBus(this);
  715. // setting the message to 'null' causes the status bar to
  716. // check if a recording is in progress
  717. view.getStatus().setMessage(null);
  718. } //}}}
  719. } //}}}
  720. //{{{ Handler class
  721. /**
  722. * Encapsulates creating and invoking macros in arbitrary scripting languages
  723. * @since jEdit 4.0pre6
  724. */
  725. public static abstract class Handler
  726. {
  727. //{{{ getName() method
  728. public String getName()
  729. {
  730. return name;
  731. } //}}}
  732. //{{{ getLabel() method
  733. public String getLabel()
  734. {
  735. return label;
  736. } //}}}
  737. //{{{ accept() method
  738. public boolean accept(String path)
  739. {
  740. return filter.isMatch(MiscUtilities.getFileName(path));
  741. } //}}}
  742. //{{{ createMacro() method
  743. public abstract Macro createMacro(String macroName, String path);
  744. //}}}
  745. //{{{ runMacro() method
  746. /**
  747. * Runs the specified macro.
  748. * @param view The view - may be null.
  749. * @param macro The macro.
  750. */
  751. public abstract void runMacro(View view, Macro macro);
  752. //}}}
  753. //{{{ runMacro() method
  754. /**
  755. * Runs the specified macro. This method is optional; it is
  756. * called if the specified macro is a startup script. The
  757. * default behavior is to simply call {@link #runMacro(View,Macros.Macro)}.
  758. *
  759. * @param view The view - may be null.
  760. * @param macro The macro.
  761. * @param ownNamespace A hint indicating whenever functions and
  762. * variables defined in the script are to be self-contained, or
  763. * made available to other scripts. The macro handler may ignore
  764. * this parameter.
  765. * @since jEdit 4.1pre3
  766. */
  767. public void runMacro(View view, Macro macro, boolean ownNamespace)
  768. {
  769. runMacro(view,macro);
  770. } //}}}
  771. //{{{ Handler constructor
  772. protected Handler(String name)
  773. {
  774. this.name = name;
  775. label = jEdit.getProperty("macro-handler."
  776. + name + ".label", name);
  777. try
  778. {
  779. filter = new RE(MiscUtilities.globToRE(
  780. jEdit.getProperty(
  781. "macro-handler." + name + ".glob")));
  782. }
  783. catch (Exception e)
  784. {
  785. throw new InternalError("Missing or invalid glob for handler " + name);
  786. }
  787. } //}}}
  788. //{{{ Private members
  789. private String name;
  790. private String label;
  791. private RE filter;
  792. //}}}
  793. } //}}}
  794. //{{{ BeanShellHandler class
  795. static class BeanShellHandler extends Handler
  796. {
  797. //{{{ BeanShellHandler constructor
  798. BeanShellHandler()
  799. {
  800. super("beanshell");
  801. } //}}}
  802. //{{{ createMacro() method
  803. public Macro createMacro(String macroName, String path)
  804. {
  805. // Remove '.bsh'
  806. macroName = macroName.substring(0, macroName.length() - 4);
  807. return new Macro(this, macroName,
  808. Macro.macroNameToLabel(macroName), path);
  809. } //}}}
  810. //{{{ runMacro() method
  811. public void runMacro(View view, Macro macro)
  812. {
  813. BeanShell.runScript(view,macro.getPath(),null,true);
  814. } //}}}
  815. //{{{ runMacro() method
  816. public void runMacro(View view, Macro macro, boolean ownNamespace)
  817. {
  818. BeanShell.runScript(view,macro.getPath(),null,ownNamespace);
  819. } //}}}
  820. } //}}}
  821. }