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

#
Java | 2605 lines | 1486 code | 277 blank | 842 comment | 312 complexity | 83c743e46aaa2ebf3aa558213aeca58e MD5 | raw file

✨ Summary

Large files are truncated, but you can click here to view the full file

  1. /*
  2. * jEdit.java - Main class of the jEdit editor
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 1998, 2005 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. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  20. */
  21. package org.gjt.sp.jedit;
  22. //{{{ Imports
  23. import org.gjt.sp.jedit.visitors.JEditVisitor;
  24. import java.awt.Color;
  25. import java.awt.Component;
  26. import java.awt.DefaultKeyboardFocusManager;
  27. import java.awt.Font;
  28. import java.awt.Frame;
  29. import java.awt.KeyboardFocusManager;
  30. import java.awt.Toolkit;
  31. import java.awt.Window;
  32. import org.gjt.sp.jedit.View.ViewConfig;
  33. import org.gjt.sp.jedit.bsh.UtilEvalError;
  34. import javax.swing.*;
  35. import java.awt.event.KeyEvent;
  36. import java.io.*;
  37. import java.net.*;
  38. import java.text.MessageFormat;
  39. import java.util.*;
  40. import org.xml.sax.SAXParseException;
  41. import org.gjt.sp.jedit.bufferio.BufferIORequest;
  42. import org.gjt.sp.jedit.buffer.KillRing;
  43. import org.gjt.sp.jedit.buffer.JEditBuffer;
  44. import org.gjt.sp.jedit.buffer.FoldHandler;
  45. import org.gjt.sp.jedit.msg.*;
  46. import org.gjt.sp.jedit.gui.*;
  47. import org.gjt.sp.jedit.help.HelpViewer;
  48. import org.gjt.sp.jedit.io.*;
  49. import org.gjt.sp.jedit.pluginmgr.PluginManager;
  50. import org.gjt.sp.jedit.search.SearchAndReplace;
  51. import org.gjt.sp.jedit.syntax.ModeProvider;
  52. import org.gjt.sp.jedit.syntax.TokenMarker;
  53. import org.gjt.sp.jedit.syntax.XModeHandler;
  54. import org.gjt.sp.jedit.textarea.*;
  55. import org.gjt.sp.jedit.visitors.SaveCaretInfoVisitor;
  56. import org.gjt.sp.jedit.bufferset.BufferSetManager;
  57. import org.gjt.sp.jedit.bufferset.BufferSet;
  58. import org.gjt.sp.util.Log;
  59. import org.gjt.sp.util.StandardUtilities;
  60. import org.gjt.sp.util.XMLUtilities;
  61. import org.gjt.sp.util.IOUtilities;
  62. import org.gjt.sp.util.SyntaxUtilities;
  63. //}}}
  64. /**
  65. * The main class of the jEdit text editor.
  66. * @author Slava Pestov
  67. * @version $Id: jEdit.java 17128 2010-01-28 23:26:49Z Vampire0 $
  68. */
  69. public class jEdit
  70. {
  71. //{{{ getVersion() method
  72. /**
  73. * Returns the jEdit version as a human-readable string.
  74. */
  75. public static String getVersion()
  76. {
  77. return MiscUtilities.buildToVersion(getBuild());
  78. } //}}}
  79. //{{{ getBuild() method
  80. /**
  81. * Returns the internal version. MiscUtilities.compareStrings() can be used
  82. * to compare different internal versions.
  83. */
  84. public static String getBuild()
  85. {
  86. // (major).(minor).(<99 = preX, 99 = "final").(bug fix)
  87. return "04.03.99.02";
  88. } //}}}
  89. //{{{ main() method
  90. /**
  91. * The main method of the jEdit application.
  92. * This should never be invoked directly.
  93. * @param args The command line arguments
  94. */
  95. public static void main(String[] args)
  96. {
  97. //{{{ Check for Java 1.5 or later
  98. String javaVersion = System.getProperty("java.version");
  99. if(javaVersion.compareTo("1.5") < 0)
  100. {
  101. System.err.println("You are running Java version "
  102. + javaVersion + '.');
  103. System.err.println("jEdit requires Java 1.5 or later.");
  104. System.exit(1);
  105. } //}}}
  106. startupDone.add(false);
  107. // later on we need to know if certain code is called from
  108. // the main thread
  109. mainThread = Thread.currentThread();
  110. settingsDirectory = ".jedit";
  111. // On mac, different rules (should) apply
  112. if(OperatingSystem.isMacOS())
  113. settingsDirectory = "Library/jEdit";
  114. // MacOS users expect the app to keep running after all windows
  115. // are closed
  116. background = OperatingSystem.isMacOS();
  117. //{{{ Parse command line
  118. boolean endOpts = false;
  119. int level = Log.WARNING;
  120. String portFile = "server";
  121. boolean restore = true;
  122. boolean newView = true;
  123. boolean newPlainView = false;
  124. boolean gui = true; // open initial view?
  125. boolean loadPlugins = true;
  126. boolean runStartupScripts = true;
  127. boolean quit = false;
  128. boolean wait = false;
  129. boolean shouldRelocateSettings = true;
  130. String userDir = System.getProperty("user.dir");
  131. // script to run
  132. String scriptFile = null;
  133. for(int i = 0; i < args.length; i++)
  134. {
  135. String arg = args[i];
  136. if(arg == null)
  137. continue;
  138. else if(arg.length() == 0)
  139. args[i] = null;
  140. else if(arg.startsWith("-") && !endOpts)
  141. {
  142. if(arg.equals("--"))
  143. endOpts = true;
  144. else if(arg.equals("-usage"))
  145. {
  146. version();
  147. System.err.println();
  148. usage();
  149. System.exit(1);
  150. }
  151. else if(arg.equals("-version"))
  152. {
  153. version();
  154. System.exit(1);
  155. }
  156. else if(arg.startsWith("-log="))
  157. {
  158. try
  159. {
  160. level = Integer.parseInt(arg.substring("-log=".length()));
  161. }
  162. catch(NumberFormatException nf)
  163. {
  164. System.err.println("Malformed option: " + arg);
  165. }
  166. }
  167. else if(arg.equals("-nosettings"))
  168. settingsDirectory = null;
  169. else if(arg.startsWith("-settings="))
  170. {
  171. settingsDirectory = arg.substring(10);
  172. shouldRelocateSettings = false;
  173. }
  174. else if(arg.startsWith("-noserver"))
  175. portFile = null;
  176. else if(arg.equals("-server"))
  177. portFile = "server";
  178. else if(arg.startsWith("-server="))
  179. portFile = arg.substring(8);
  180. else if(arg.startsWith("-background"))
  181. background = true;
  182. else if(arg.startsWith("-nobackground"))
  183. background = false;
  184. else if(arg.equals("-gui"))
  185. gui = true;
  186. else if(arg.equals("-nogui"))
  187. gui = false;
  188. else if(arg.equals("-newview"))
  189. newView = true;
  190. else if(arg.equals("-newplainview"))
  191. newPlainView = true;
  192. else if(arg.equals("-reuseview"))
  193. newPlainView = newView = false;
  194. else if(arg.equals("-restore"))
  195. restore = true;
  196. else if(arg.equals("-norestore"))
  197. restore = false;
  198. else if(arg.equals("-plugins"))
  199. loadPlugins = true;
  200. else if(arg.equals("-noplugins"))
  201. loadPlugins = false;
  202. else if(arg.equals("-startupscripts"))
  203. runStartupScripts = true;
  204. else if(arg.equals("-nostartupscripts"))
  205. runStartupScripts = false;
  206. else if(arg.startsWith("-run="))
  207. scriptFile = arg.substring(5);
  208. else if(arg.equals("-wait"))
  209. wait = true;
  210. else if(arg.equals("-quit"))
  211. quit = true;
  212. else
  213. {
  214. System.err.println("Unknown option: "
  215. + arg);
  216. usage();
  217. System.exit(1);
  218. }
  219. args[i] = null;
  220. }
  221. } //}}}
  222. //{{{ We need these initializations very early on
  223. if(settingsDirectory != null)
  224. {
  225. settingsDirectory = MiscUtilities.constructPath(
  226. System.getProperty("user.home"),
  227. settingsDirectory);
  228. settingsDirectory = MiscUtilities.resolveSymlinks(
  229. settingsDirectory);
  230. }
  231. if(settingsDirectory != null && portFile != null)
  232. portFile = MiscUtilities.constructPath(settingsDirectory,portFile);
  233. else
  234. portFile = null;
  235. Log.init(true,level);
  236. //}}}
  237. //{{{ Try connecting to another running jEdit instance
  238. if(portFile != null && new File(portFile).exists())
  239. {
  240. try
  241. {
  242. BufferedReader in = new BufferedReader(new FileReader(portFile));
  243. String check = in.readLine();
  244. if(!check.equals("b"))
  245. throw new Exception("Wrong port file format");
  246. int port = Integer.parseInt(in.readLine());
  247. int key = Integer.parseInt(in.readLine());
  248. Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),port);
  249. DataOutputStream out = new DataOutputStream(
  250. socket.getOutputStream());
  251. out.writeInt(key);
  252. String script;
  253. if(quit)
  254. {
  255. script = "socket.close();\n"
  256. + "jEdit.exit(null,true);\n";
  257. }
  258. else
  259. {
  260. script = makeServerScript(wait,restore,
  261. newView,newPlainView,args,
  262. scriptFile);
  263. }
  264. out.writeUTF(script);
  265. Log.log(Log.DEBUG,jEdit.class,"Waiting for server");
  266. // block until its closed
  267. try
  268. {
  269. socket.getInputStream().read();
  270. }
  271. catch(Exception e)
  272. {
  273. }
  274. in.close();
  275. out.close();
  276. System.exit(0);
  277. }
  278. catch(Exception e)
  279. {
  280. // ok, this one seems to confuse newbies
  281. // endlessly, so log it as NOTICE, not
  282. // ERROR
  283. Log.log(Log.NOTICE,jEdit.class,"An error occurred"
  284. + " while connecting to the jEdit server instance.");
  285. Log.log(Log.NOTICE,jEdit.class,"This probably means that"
  286. + " jEdit crashed and/or exited abnormally");
  287. Log.log(Log.NOTICE,jEdit.class,"the last time it was run.");
  288. Log.log(Log.NOTICE,jEdit.class,"If you don't"
  289. + " know what this means, don't worry.");
  290. Log.log(Log.NOTICE,jEdit.class,e);
  291. }
  292. }
  293. if(quit)
  294. {
  295. // if no server running and user runs jedit -quit,
  296. // just exit
  297. System.exit(0);
  298. } //}}}
  299. // don't show splash screen if there is a file named
  300. // 'nosplash' in the settings directory
  301. if(!new File(settingsDirectory,"nosplash").exists())
  302. GUIUtilities.showSplashScreen();
  303. //{{{ Mac settings migration code. Should eventually be removed
  304. if(OperatingSystem.isMacOS() && shouldRelocateSettings && settingsDirectory != null)
  305. {
  306. relocateSettings();
  307. }
  308. // }}}
  309. //{{{ Initialize settings directory
  310. Writer stream;
  311. if(settingsDirectory != null)
  312. {
  313. File _settingsDirectory = new File(settingsDirectory);
  314. if(!_settingsDirectory.exists())
  315. _settingsDirectory.mkdirs();
  316. File _macrosDirectory = new File(settingsDirectory,"macros");
  317. if(!_macrosDirectory.exists())
  318. _macrosDirectory.mkdir();
  319. String logPath = MiscUtilities.constructPath(
  320. settingsDirectory,"activity.log");
  321. backupSettingsFile(new File(logPath));
  322. try
  323. {
  324. stream = new BufferedWriter(new FileWriter(logPath));
  325. // Write a warning message:
  326. String lineSep = System.getProperty("line.separator");
  327. stream.write("Log file created on " + new Date());
  328. stream.write(lineSep);
  329. stream.write("IMPORTANT:");
  330. stream.write(lineSep);
  331. stream.write("Because updating this file after "
  332. + "every log message would kill");
  333. stream.write(lineSep);
  334. stream.write("performance, it will be *incomplete* "
  335. + "unless you invoke the");
  336. stream.write(lineSep);
  337. stream.write("Utilities->Troubleshooting->Update "
  338. + "Activity Log on Disk command!");
  339. stream.write(lineSep);
  340. }
  341. catch(Exception e)
  342. {
  343. e.printStackTrace();
  344. stream = null;
  345. }
  346. }
  347. else
  348. {
  349. stream = null;
  350. } //}}}
  351. Log.setLogWriter(stream);
  352. Log.log(Log.NOTICE,jEdit.class,"jEdit version " + getVersion());
  353. Log.log(Log.MESSAGE,jEdit.class,"Settings directory is "
  354. + settingsDirectory);
  355. //{{{ Get things rolling
  356. GUIUtilities.advanceSplashProgress("init");
  357. initMisc();
  358. GUIUtilities.advanceSplashProgress("init system properties");
  359. initSystemProperties();
  360. GUIUtilities.advanceSplashProgress("init beanshell");
  361. BeanShell.init();
  362. GUIUtilities.advanceSplashProgress("loading site properties");
  363. if(jEditHome != null)
  364. initSiteProperties();
  365. GUIUtilities.advanceSplashProgress("loading user properties");
  366. initUserProperties();
  367. GUIUtilities.advanceSplashProgress("init GUI");
  368. GUIUtilities.init();
  369. globalBufferSet = new BufferSet();
  370. bufferSetManager = new BufferSetManager();
  371. ///Options.SIMPLIFIED_KEY_HANDLING = jEdit.getBooleanProperty("newkeyhandling");
  372. //}}}
  373. //{{{ Initialize server
  374. if(portFile != null)
  375. {
  376. GUIUtilities.advanceSplashProgress("init server");
  377. server = new EditServer(portFile);
  378. if(!server.isOK())
  379. server = null;
  380. }
  381. else
  382. {
  383. GUIUtilities.advanceSplashProgress();
  384. if(background)
  385. {
  386. background = false;
  387. Log.log(Log.WARNING,jEdit.class,"You cannot specify both the"
  388. + " -background and -noserver switches");
  389. }
  390. } //}}}
  391. //{{{ Do more stuff
  392. GUIUtilities.advanceSplashProgress("init look and feel");
  393. initPLAF();
  394. GUIUtilities.advanceSplashProgress("init VFS Manager");
  395. VFSManager.init();
  396. GUIUtilities.advanceSplashProgress("init resources");
  397. initResources();
  398. SearchAndReplace.load();
  399. if(loadPlugins)
  400. {
  401. GUIUtilities.advanceSplashProgress("init plugins");
  402. initPlugins();
  403. }
  404. else
  405. GUIUtilities.advanceSplashProgress();
  406. Registers.setSaver(new JEditRegisterSaver());
  407. Registers.setListener(new JEditRegistersListener());
  408. GUIUtilities.advanceSplashProgress("init history model");
  409. HistoryModel.setSaver(new JEditHistoryModelSaver());
  410. HistoryModel.loadHistory();
  411. GUIUtilities.advanceSplashProgress("init buffer history");
  412. BufferHistory.load();
  413. GUIUtilities.advanceSplashProgress("init killring");
  414. KillRing.setInstance(new JEditKillRing());
  415. KillRing.getInstance().load();
  416. GUIUtilities.advanceSplashProgress("init various properties");
  417. propertiesChanged();
  418. GUIUtilities.advanceSplashProgress("init modes");
  419. // Buffer sort
  420. sortBuffers = getBooleanProperty("sortBuffers");
  421. sortByName = getBooleanProperty("sortByName");
  422. reloadModes();
  423. GUIUtilities.advanceSplashProgress("activate plugins");
  424. //}}}
  425. //{{{ Activate plugins that must be activated at startup
  426. for(int i = 0; i < jars.size(); i++)
  427. {
  428. jars.elementAt(i).activatePluginIfNecessary();
  429. } //}}}
  430. //{{{ Load macros and run startup scripts, after plugins and settings are loaded
  431. GUIUtilities.advanceSplashProgress("init macros");
  432. Macros.loadMacros();
  433. Macros.getMacroActionSet().initKeyBindings();
  434. if(runStartupScripts && jEditHome != null)
  435. {
  436. String path = MiscUtilities.constructPath(jEditHome,"startup");
  437. File file = new File(path);
  438. if(file.exists())
  439. {
  440. runStartupScripts(file);
  441. }
  442. else
  443. GUIUtilities.advanceSplashProgress();
  444. }
  445. else
  446. GUIUtilities.advanceSplashProgress("run startup scripts");
  447. if(runStartupScripts && settingsDirectory != null)
  448. {
  449. String path = MiscUtilities.constructPath(settingsDirectory,"startup");
  450. File file = new File(path);
  451. if (file.exists())
  452. {
  453. GUIUtilities.advanceSplashProgress("run startup scripts");
  454. runStartupScripts(file);
  455. }
  456. else
  457. {
  458. GUIUtilities.advanceSplashProgress();
  459. file.mkdirs();
  460. }
  461. }
  462. else
  463. {
  464. GUIUtilities.advanceSplashProgress();
  465. } //}}}
  466. //{{{ Run script specified with -run= parameter
  467. if(scriptFile != null)
  468. {
  469. GUIUtilities.advanceSplashProgress("run script file");
  470. scriptFile = MiscUtilities.constructPath(userDir,scriptFile);
  471. try
  472. {
  473. BeanShell.getNameSpace().setVariable("args",args);
  474. }
  475. catch(UtilEvalError e)
  476. {
  477. Log.log(Log.ERROR,jEdit.class,e);
  478. }
  479. BeanShell.runScript(null,scriptFile,null,false);
  480. }
  481. else
  482. {
  483. GUIUtilities.advanceSplashProgress();
  484. }
  485. //}}}
  486. GUIUtilities.advanceSplashProgress();
  487. // Create dynamic actions for switching to saved layouts.
  488. // The list of saved layouts is retrieved from the docking framework,
  489. // which can be provided by a plugin, so this must be called only after
  490. // the plugins are loaded.
  491. DockingLayoutManager.init();
  492. // Open files, create the view and hide the splash screen.
  493. SyntaxUtilities.propertyManager = jEdit.propertyManager;
  494. finishStartup(gui,restore,newPlainView,userDir,args);
  495. } //}}}
  496. //{{{ Property methods
  497. //{{{ getProperties() method
  498. /**
  499. * Returns the properties object which contains all known
  500. * jEdit properties. Note that as of jEdit 4.2pre10, this returns a
  501. * new collection, not the existing properties instance.
  502. * @since jEdit 3.1pre4
  503. */
  504. public static Properties getProperties()
  505. {
  506. return propMgr.getProperties();
  507. } //}}}
  508. //{{{ getProperty() method
  509. /**
  510. * Fetches a property, returning null if it's not defined.
  511. * @param name The property
  512. */
  513. public static String getProperty(String name)
  514. {
  515. return propMgr.getProperty(name);
  516. } //}}}
  517. //{{{ getProperty() method
  518. /**
  519. * Fetches a property, returning the default value if it's not
  520. * defined.
  521. * @param name The property
  522. * @param def The default value
  523. */
  524. public static String getProperty(String name, String def)
  525. {
  526. String value = propMgr.getProperty(name);
  527. if(value == null)
  528. return def;
  529. else
  530. return value;
  531. } //}}}
  532. //{{{ getProperty() method
  533. /**
  534. * Returns the property with the specified name.<p>
  535. *
  536. * The elements of the <code>args</code> array are substituted
  537. * into the value of the property in place of strings of the
  538. * form <code>{<i>n</i>}</code>, where <code><i>n</i></code> is an index
  539. * in the array.<p>
  540. *
  541. * You can find out more about this feature by reading the
  542. * documentation for the <code>format</code> method of the
  543. * <code>java.text.MessageFormat</code> class.
  544. *
  545. * @param name The property
  546. * @param args The positional parameters
  547. */
  548. public static String getProperty(String name, Object[] args)
  549. {
  550. if(name == null)
  551. return null;
  552. if(args == null)
  553. return getProperty(name);
  554. else
  555. {
  556. String value = getProperty(name);
  557. if(value == null)
  558. return null;
  559. else
  560. return MessageFormat.format(value,args);
  561. }
  562. } //}}}
  563. //{{{ getBooleanProperty() method
  564. /**
  565. * Returns the value of a boolean property.
  566. * @param name The property
  567. */
  568. public static boolean getBooleanProperty(String name)
  569. {
  570. return getBooleanProperty(name,false);
  571. } //}}}
  572. //{{{ getBooleanProperty() method
  573. /**
  574. * Returns the value of a boolean property.
  575. * @param name The property
  576. * @param def The default value
  577. */
  578. public static boolean getBooleanProperty(String name, boolean def)
  579. {
  580. String value = getProperty(name);
  581. return StandardUtilities.getBoolean(value, def);
  582. } //}}}
  583. //{{{ getIntegerProperty() method
  584. /**
  585. * Returns the value of an integer property.
  586. * @param name The property
  587. */
  588. public static int getIntegerProperty(String name)
  589. {
  590. return getIntegerProperty(name,0);
  591. } //}}}
  592. //{{{ getIntegerProperty() method
  593. /**
  594. * Returns the value of an integer property.
  595. * @param name The property
  596. * @param def The default value
  597. * @since jEdit 4.0pre1
  598. */
  599. public static int getIntegerProperty(String name, int def)
  600. {
  601. String value = getProperty(name);
  602. if(value == null)
  603. return def;
  604. else
  605. {
  606. try
  607. {
  608. return Integer.parseInt(value.trim());
  609. }
  610. catch(NumberFormatException nf)
  611. {
  612. return def;
  613. }
  614. }
  615. } //}}}
  616. //{{{ getDoubleProperty() method
  617. public static double getDoubleProperty(String name, double def)
  618. {
  619. String value = getProperty(name);
  620. if(value == null)
  621. return def;
  622. else
  623. {
  624. try
  625. {
  626. return Double.parseDouble(value.trim());
  627. }
  628. catch(NumberFormatException nf)
  629. {
  630. return def;
  631. }
  632. }
  633. }
  634. //}}}
  635. //{{{ getFontProperty() method
  636. /**
  637. * Returns the value of a font property. The family is stored
  638. * in the <code><i>name</i></code> property, the font size is stored
  639. * in the <code><i>name</i>size</code> property, and the font style is
  640. * stored in <code><i>name</i>style</code>. For example, if
  641. * <code><i>name</i></code> is <code>view.gutter.font</code>, the
  642. * properties will be named <code>view.gutter.font</code>,
  643. * <code>view.gutter.fontsize</code>, and
  644. * <code>view.gutter.fontstyle</code>.
  645. *
  646. * @param name The property
  647. * @since jEdit 4.0pre1
  648. */
  649. public static Font getFontProperty(String name)
  650. {
  651. return getFontProperty(name,null);
  652. } //}}}
  653. //{{{ getFontProperty() method
  654. /**
  655. * Returns the value of a font property. The family is stored
  656. * in the <code><i>name</i></code> property, the font size is stored
  657. * in the <code><i>name</i>size</code> property, and the font style is
  658. * stored in <code><i>name</i>style</code>. For example, if
  659. * <code><i>name</i></code> is <code>view.gutter.font</code>, the
  660. * properties will be named <code>view.gutter.font</code>,
  661. * <code>view.gutter.fontsize</code>, and
  662. * <code>view.gutter.fontstyle</code>.
  663. *
  664. * @param name The property
  665. * @param def The default value
  666. * @since jEdit 4.0pre1
  667. */
  668. public static Font getFontProperty(String name, Font def)
  669. {
  670. String family = getProperty(name);
  671. String sizeString = getProperty(name + "size");
  672. String styleString = getProperty(name + "style");
  673. if(family == null || sizeString == null || styleString == null)
  674. return def;
  675. else
  676. {
  677. int size, style;
  678. try
  679. {
  680. size = Integer.parseInt(sizeString);
  681. }
  682. catch(NumberFormatException nf)
  683. {
  684. return def;
  685. }
  686. try
  687. {
  688. style = Integer.parseInt(styleString);
  689. }
  690. catch(NumberFormatException nf)
  691. {
  692. return def;
  693. }
  694. return new Font(family,style,size);
  695. }
  696. } //}}}
  697. //{{{ getColorProperty() method
  698. /**
  699. * Returns the value of a color property.
  700. * @param name The property name
  701. * @since jEdit 4.0pre1
  702. */
  703. public static Color getColorProperty(String name)
  704. {
  705. return getColorProperty(name,Color.black);
  706. } //}}}
  707. //{{{ getColorProperty() method
  708. /**
  709. * Returns the value of a color property.
  710. * @param name The property name
  711. * @param def The default value
  712. * @since jEdit 4.0pre1
  713. */
  714. public static Color getColorProperty(String name, Color def)
  715. {
  716. String value = getProperty(name);
  717. if(value == null)
  718. return def;
  719. else
  720. return SyntaxUtilities.parseColor(value, def);
  721. } //}}}
  722. //{{{ setColorProperty() method
  723. /**
  724. * Sets the value of a color property.
  725. * @param name The property name
  726. * @param value The value
  727. * @since jEdit 4.0pre1
  728. */
  729. public static void setColorProperty(String name, Color value)
  730. {
  731. setProperty(name, SyntaxUtilities.getColorHexString(value));
  732. } //}}}
  733. //{{{ setProperty() method
  734. /**
  735. * Sets a property to a new value.
  736. * @param name The property
  737. * @param value The new value
  738. */
  739. public static void setProperty(String name, String value)
  740. {
  741. propMgr.setProperty(name,value);
  742. } //}}}
  743. //{{{ setTemporaryProperty() method
  744. /**
  745. * Sets a property to a new value. Properties set using this
  746. * method are not saved to the user properties list.
  747. * @param name The property
  748. * @param value The new value
  749. * @since jEdit 2.3final
  750. */
  751. public static void setTemporaryProperty(String name, String value)
  752. {
  753. propMgr.setTemporaryProperty(name,value);
  754. } //}}}
  755. //{{{ setBooleanProperty() method
  756. /**
  757. * Sets a boolean property.
  758. * @param name The property
  759. * @param value The value
  760. */
  761. public static void setBooleanProperty(String name, boolean value)
  762. {
  763. setProperty(name,value ? "true" : "false");
  764. } //}}}
  765. //{{{ setIntegerProperty() method
  766. /**
  767. * Sets the value of an integer property.
  768. * @param name The property
  769. * @param value The value
  770. * @since jEdit 4.0pre1
  771. */
  772. public static void setIntegerProperty(String name, int value)
  773. {
  774. setProperty(name,String.valueOf(value));
  775. } //}}}
  776. //{{{ setDoubleProperty() method
  777. public static void setDoubleProperty(String name, double value)
  778. {
  779. setProperty(name,String.valueOf(value));
  780. }
  781. //}}}
  782. //{{{ setFontProperty() method
  783. /**
  784. * Sets the value of a font property. The family is stored
  785. * in the <code><i>name</i></code> property, the font size is stored
  786. * in the <code><i>name</i>size</code> property, and the font style is
  787. * stored in <code><i>name</i>style</code>. For example, if
  788. * <code><i>name</i></code> is <code>view.gutter.font</code>, the
  789. * properties will be named <code>view.gutter.font</code>,
  790. * <code>view.gutter.fontsize</code>, and
  791. * <code>view.gutter.fontstyle</code>.
  792. *
  793. * @param name The property
  794. * @param value The value
  795. * @since jEdit 4.0pre1
  796. */
  797. public static void setFontProperty(String name, Font value)
  798. {
  799. setProperty(name,value.getFamily());
  800. setIntegerProperty(name + "size",value.getSize());
  801. setIntegerProperty(name + "style",value.getStyle());
  802. } //}}}
  803. //{{{ unsetProperty() method
  804. /**
  805. * Unsets (clears) a property.
  806. * @param name The property
  807. */
  808. public static void unsetProperty(String name)
  809. {
  810. propMgr.unsetProperty(name);
  811. } //}}}
  812. //{{{ resetProperty() method
  813. /**
  814. * Resets a property to its default value.
  815. * @param name The property
  816. *
  817. * @since jEdit 2.5pre3
  818. */
  819. public static void resetProperty(String name)
  820. {
  821. propMgr.resetProperty(name);
  822. } //}}}
  823. //{{{ propertiesChanged() method
  824. /**
  825. * Reloads various settings from the properties.
  826. */
  827. public static void propertiesChanged()
  828. {
  829. initKeyBindings();
  830. Autosave.setInterval(getIntegerProperty("autosave",30));
  831. saveCaret = getBooleanProperty("saveCaret");
  832. UIDefaults defaults = UIManager.getDefaults();
  833. // give all text areas the same font
  834. Font font = getFontProperty("view.font");
  835. //defaults.put("TextField.font",font);
  836. defaults.put("TextArea.font",font);
  837. defaults.put("TextPane.font",font);
  838. // Enable/Disable tooltips
  839. ToolTipManager.sharedInstance().setEnabled(
  840. jEdit.getBooleanProperty("showTooltips"));
  841. initProxy();
  842. // we do this here instead of adding buffers to the bus.
  843. Buffer buffer = buffersFirst;
  844. while(buffer != null)
  845. {
  846. buffer.resetCachedProperties();
  847. buffer.propertiesChanged();
  848. buffer = buffer.next;
  849. }
  850. HistoryModel.setMax(getIntegerProperty("history",25));
  851. KillRing.getInstance().propertiesChanged(getIntegerProperty("history",25));
  852. EditBus.send(new PropertiesChanged(null));
  853. } //}}}
  854. //}}}
  855. //{{{ Plugin management methods
  856. //{{{ getNotLoadedPluginJARs() method
  857. /**
  858. * Returns a list of plugin JARs pathnames that are not currently loaded
  859. * by examining the user and system plugin directories.
  860. * @since jEdit 3.2pre1
  861. */
  862. public static String[] getNotLoadedPluginJARs()
  863. {
  864. List<String> returnValue = new ArrayList<String>();
  865. if(jEditHome != null)
  866. {
  867. String systemPluginDir = MiscUtilities
  868. .constructPath(jEditHome,"jars");
  869. String[] list = new File(systemPluginDir).list();
  870. if(list != null)
  871. getNotLoadedPluginJARs(returnValue,systemPluginDir,list);
  872. }
  873. if(settingsDirectory != null)
  874. {
  875. String userPluginDir = MiscUtilities
  876. .constructPath(settingsDirectory,"jars");
  877. String[] list = new File(userPluginDir).list();
  878. if(list != null)
  879. {
  880. getNotLoadedPluginJARs(returnValue,
  881. userPluginDir,list);
  882. }
  883. }
  884. String[] _returnValue = new String[returnValue.size()];
  885. returnValue.toArray(_returnValue);
  886. return _returnValue;
  887. } //}}}
  888. //{{{ getPlugin() method
  889. /**
  890. * Returns the plugin with the specified class name.
  891. * Only works for plugins that were loaded.
  892. */
  893. public static EditPlugin getPlugin(String name)
  894. {
  895. return getPlugin(name, false);
  896. } //}}}
  897. //{{{ getPlugin(String, boolean) method
  898. /**
  899. * Returns the plugin with the specified class name.
  900. * If * <code>loadIfNecessary</code> is true, the plugin will be searched for,
  901. * loaded, and activated in case it has not yet been loaded.
  902. *
  903. * @param name the classname of the main Plugin class.
  904. * @param loadIfNecessary - loads plugin + dependencies if it is not loaded yet.
  905. * @since jEdit 4.2pre4
  906. */
  907. public static EditPlugin getPlugin(String name, boolean loadIfNecessary)
  908. {
  909. EditPlugin[] plugins = getPlugins();
  910. EditPlugin plugin = null;
  911. for(int i = 0; i < plugins.length; i++)
  912. {
  913. if(plugins[i].getClassName().equals(name))
  914. plugin = plugins[i];
  915. if(loadIfNecessary)
  916. {
  917. if(plugin instanceof EditPlugin.Deferred)
  918. {
  919. plugin.getPluginJAR().activatePlugin();
  920. plugin = plugin.getPluginJAR().getPlugin();
  921. break;
  922. }
  923. }
  924. }
  925. if (!loadIfNecessary) return plugin;
  926. String jarPath = PluginJAR.findPlugin(name);
  927. PluginJAR pjar = PluginJAR.load(jarPath, true);
  928. return pjar.getPlugin();
  929. } //}}}
  930. //{{{ getPlugins() method
  931. /**
  932. * Returns an array of installed plugins.
  933. */
  934. public static EditPlugin[] getPlugins()
  935. {
  936. List<EditPlugin> pluginList = new ArrayList<EditPlugin>();
  937. for(int i = 0; i < jars.size(); i++)
  938. {
  939. EditPlugin plugin = jars.elementAt(i).getPlugin();
  940. if(plugin != null)
  941. pluginList.add(plugin);
  942. }
  943. EditPlugin[] array = new EditPlugin[pluginList.size()];
  944. pluginList.toArray(array);
  945. return array;
  946. } //}}}
  947. //{{{ getPluginJARs() method
  948. /**
  949. * Returns an array of installed plugins.
  950. * @since jEdit 4.2pre1
  951. */
  952. public static PluginJAR[] getPluginJARs()
  953. {
  954. PluginJAR[] array = new PluginJAR[jars.size()];
  955. jars.copyInto(array);
  956. return array;
  957. } //}}}
  958. //{{{ getPluginJAR() method
  959. /**
  960. * Returns the JAR with the specified path name.
  961. * @param path The path name
  962. * @since jEdit 4.2pre1
  963. */
  964. public static PluginJAR getPluginJAR(String path)
  965. {
  966. for(int i = 0; i < jars.size(); i++)
  967. {
  968. PluginJAR jar = jars.elementAt(i);
  969. if(jar.getPath().equals(path))
  970. return jar;
  971. }
  972. return null;
  973. } //}}}
  974. //{{{ addPluginJAR() method
  975. /**
  976. * Loads the plugin JAR with the specified path. Some notes about this
  977. * method:
  978. *
  979. * <ul>
  980. * <li>Calling this at a time other than jEdit startup can have
  981. * unpredictable results if the plugin has not been updated for the
  982. * jEdit 4.2 plugin API.
  983. * <li>You must make sure yourself the plugin is not already loaded.
  984. * <li>After loading, you just make sure all the plugin's dependencies
  985. * are satisified before activating the plugin, using the
  986. * {@link PluginJAR#checkDependencies()} method.
  987. * </ul>
  988. *
  989. * @param path The JAR file path
  990. * @since jEdit 4.2pre1
  991. */
  992. public static void addPluginJAR(String path)
  993. {
  994. PluginJAR jar = new PluginJAR(new File(path));
  995. jars.addElement(jar);
  996. jar.init();
  997. jEdit.unsetProperty("plugin-blacklist."+MiscUtilities.getFileName(path));
  998. EditBus.send(new PluginUpdate(jar,PluginUpdate.LOADED,false));
  999. if(!isMainThread())
  1000. {
  1001. EditBus.send(new DynamicMenuChanged("plugins"));
  1002. initKeyBindings();
  1003. }
  1004. } //}}}
  1005. //{{{ addPluginJARsFromDirectory() method
  1006. /**
  1007. * Loads all plugins in a directory.
  1008. * @param directory The directory
  1009. * @since jEdit 4.2pre1
  1010. */
  1011. private static void addPluginJARsFromDirectory(String directory)
  1012. {
  1013. Log.log(Log.NOTICE,jEdit.class,"Loading plugins from "
  1014. + directory);
  1015. File file = new File(directory);
  1016. if(!(file.exists() && file.isDirectory()))
  1017. return;
  1018. String[] plugins = file.list();
  1019. if(plugins == null)
  1020. return;
  1021. for(int i = 0; i < plugins.length; i++)
  1022. {
  1023. String plugin = plugins[i];
  1024. if(!plugin.toLowerCase().endsWith(".jar"))
  1025. continue;
  1026. String path = MiscUtilities.constructPath(directory,plugin);
  1027. if (jEdit.getBooleanProperty("plugin-blacklist."+plugin))
  1028. continue;
  1029. // remove this when 4.1 plugin API is deprecated
  1030. if(plugin.equals("EditBuddy.jar")
  1031. || plugin.equals("PluginManager.jar")
  1032. || plugin.equals("Firewall.jar")
  1033. || plugin.equals("Tidy.jar")
  1034. || plugin.equals("DragAndDrop.jar"))
  1035. {
  1036. pluginError(path,"plugin-error.obsolete",null);
  1037. continue;
  1038. }
  1039. addPluginJAR(path);
  1040. }
  1041. } //}}}
  1042. //{{{ removePluginJAR() method
  1043. /**
  1044. * Unloads the given plugin JAR with the specified path. Note that
  1045. * calling this at a time other than jEdit shutdown can have
  1046. * unpredictable results if the plugin has not been updated for the
  1047. * jEdit 4.2 plugin API.
  1048. *
  1049. * @param jar The <code>PluginJAR</code> instance
  1050. * @param exit Set to true if jEdit is exiting; enables some
  1051. * shortcuts so the editor can close faster.
  1052. * @since jEdit 4.2pre1
  1053. */
  1054. public static void removePluginJAR(PluginJAR jar, boolean exit)
  1055. {
  1056. if(exit)
  1057. {
  1058. jar.uninit(true);
  1059. }
  1060. else
  1061. {
  1062. jar.uninit(false);
  1063. jars.removeElement(jar);
  1064. initKeyBindings();
  1065. }
  1066. EditBus.send(new PluginUpdate(jar,PluginUpdate.UNLOADED,exit));
  1067. if(!isMainThread() && !exit)
  1068. EditBus.send(new DynamicMenuChanged("plugins"));
  1069. } //}}}
  1070. //}}}
  1071. //{{{ Action methods
  1072. //{{{ getActionContext() method
  1073. /**
  1074. * Returns the action context used to store editor actions.
  1075. * @since jEdit 4.2pre1
  1076. */
  1077. public static ActionContext getActionContext()
  1078. {
  1079. return actionContext;
  1080. } //}}}
  1081. //{{{ addActionSet() method
  1082. /**
  1083. * Adds a new action set to jEdit's list of ActionSets (viewable from the shortcuts
  1084. * option pane). By default, each plugin has one ActionSet,
  1085. * but some plugins may create dynamic action sets, such as ProjectViewer and Console.
  1086. * These plugins must call removeActionSet() when the plugin is unloaded.
  1087. *
  1088. * @since jEdit 4.0pre1
  1089. * @see #removeActionSet(ActionSet)
  1090. */
  1091. public static void addActionSet(ActionSet actionSet)
  1092. {
  1093. actionContext.addActionSet(actionSet);
  1094. } //}}}
  1095. //{{{ removeActionSet() method
  1096. /**
  1097. * Removes an action set from jEdit's list.
  1098. * Plugins that add a dynamic action set must call this method at plugin
  1099. * unload time.
  1100. * @since jEdit 4.2pre1
  1101. */
  1102. public static void removeActionSet(ActionSet actionSet)
  1103. {
  1104. actionContext.removeActionSet(actionSet);
  1105. } //}}}
  1106. //{{{ getBuiltInActionSet() method
  1107. /**
  1108. * Returns the set of commands built into jEdit.
  1109. * @since jEdit 4.2pre1
  1110. */
  1111. public static ActionSet getBuiltInActionSet()
  1112. {
  1113. return builtInActionSet;
  1114. } //}}}
  1115. // {{{ getActionSets() method
  1116. /**
  1117. * Returns all registered action sets.
  1118. *
  1119. * @return the ActionSet(s)
  1120. * @since jEdit 4.0pre1
  1121. */
  1122. public static ActionSet[] getActionSets()
  1123. {
  1124. return actionContext.getActionSets();
  1125. } // }}}
  1126. //{{{ getAction() method
  1127. /**
  1128. * Returns the specified action.
  1129. * @param name The action name
  1130. */
  1131. public static EditAction getAction(String name)
  1132. {
  1133. return actionContext.getAction(name);
  1134. } //}}}
  1135. //{{{ getActionSetForAction() method
  1136. /**
  1137. * Returns the action set that contains the specified action.
  1138. *
  1139. * @param action The action
  1140. * @since jEdit 4.2pre1
  1141. */
  1142. public static ActionSet getActionSetForAction(String action)
  1143. {
  1144. return actionContext.getActionSetForAction(action);
  1145. } //}}}
  1146. //{{{ getActionSetForAction() method
  1147. /**
  1148. * @deprecated Use the form that takes a String instead
  1149. */
  1150. @Deprecated
  1151. public static ActionSet getActionSetForAction(EditAction action)
  1152. {
  1153. return actionContext.getActionSetForAction(action.getName());
  1154. } //}}}
  1155. //{{{ getActions() method
  1156. /**
  1157. * @deprecated Call getActionNames() instead
  1158. */
  1159. @Deprecated
  1160. public static EditAction[] getActions()
  1161. {
  1162. String[] names = actionContext.getActionNames();
  1163. EditAction[] actions = new EditAction[names.length];
  1164. for(int i = 0; i < actions.length; i++)
  1165. {
  1166. actions[i] = actionContext.getAction(names[i]);
  1167. if(actions[i] == null)
  1168. Log.log(Log.ERROR,jEdit.class,"wtf: " + names[i]);
  1169. }
  1170. return actions;
  1171. } //}}}
  1172. //{{{ getActionNames() method
  1173. /**
  1174. * Returns all registered action names.
  1175. */
  1176. public static String[] getActionNames()
  1177. {
  1178. return actionContext.getActionNames();
  1179. } //}}}
  1180. //}}}
  1181. //{{{ Edit mode methods
  1182. //{{{ reloadModes() method
  1183. /**
  1184. * Reloads all edit modes.
  1185. * @since jEdit 3.2pre2
  1186. */
  1187. public static void reloadModes()
  1188. {
  1189. /* Try to guess the eventual size to avoid unnecessary
  1190. * copying */
  1191. ModeProvider.instance.removeAll();
  1192. //{{{ Load the global catalog
  1193. if(jEditHome == null)
  1194. loadModeCatalog("/modes/catalog",true);
  1195. else
  1196. {
  1197. loadModeCatalog(MiscUtilities.constructPath(jEditHome,
  1198. "modes","catalog"),false);
  1199. } //}}}
  1200. //{{{ Load user catalog
  1201. if(settingsDirectory != null)
  1202. {
  1203. File userModeDir = new File(MiscUtilities.constructPath(
  1204. settingsDirectory,"modes"));
  1205. if(!userModeDir.exists())
  1206. userModeDir.mkdirs();
  1207. File userCatalog = new File(MiscUtilities.constructPath(
  1208. settingsDirectory,"modes","catalog"));
  1209. if(!userCatalog.exists())
  1210. {
  1211. // create dummy catalog
  1212. FileWriter out = null;
  1213. try
  1214. {
  1215. out = new FileWriter(userCatalog);
  1216. out.write(jEdit.getProperty("defaultCatalog"));
  1217. }
  1218. catch(IOException io)
  1219. {
  1220. Log.log(Log.ERROR,jEdit.class,io);
  1221. }
  1222. finally
  1223. {
  1224. IOUtilities.closeQuietly(out);
  1225. }
  1226. }
  1227. loadModeCatalog(userCatalog.getPath(),false);
  1228. } //}}}
  1229. Buffer buffer = buffersFirst;
  1230. while(buffer != null)
  1231. {
  1232. // This reloads the token marker and sends a message
  1233. // which causes edit panes to repaint their text areas
  1234. buffer.setMode();
  1235. buffer = buffer.next;
  1236. }
  1237. } //}}}
  1238. //{{{ getMode() method
  1239. /**
  1240. * Returns the edit mode with the specified name.
  1241. * @param name The edit mode
  1242. */
  1243. public static Mode getMode(String name)
  1244. {
  1245. return ModeProvider.instance.getMode(name);
  1246. } //}}}
  1247. //{{{ getModes() method
  1248. /**
  1249. * Returns an array of installed edit modes.
  1250. */
  1251. public static Mode[] getModes()
  1252. {
  1253. return ModeProvider.instance.getModes();
  1254. } //}}}
  1255. //}}}
  1256. //{{{ Buffer creation methods
  1257. //{{{ openFiles() method
  1258. /**
  1259. * Opens the file names specified in the argument array. This
  1260. * handles +line and +marker arguments just like the command
  1261. * line parser.
  1262. * @param parent The parent directory
  1263. * @param args The file names to open
  1264. * @since jEdit 3.2pre4
  1265. */
  1266. public static Buffer openFiles(View view, String parent, String[] args)
  1267. {
  1268. Buffer retVal = null;
  1269. Buffer lastBuffer = null;
  1270. for(int i = 0; i < args.length; i++)
  1271. {
  1272. String arg = args[i];
  1273. if(arg == null)
  1274. continue;
  1275. else if(arg.startsWith("+line:") || arg.startsWith("+marker:"))
  1276. {
  1277. if(lastBuffer != null)
  1278. gotoMarker(view,lastBuffer,arg);
  1279. continue;
  1280. }
  1281. lastBuffer = openFile((View)null,parent,arg,false,null);
  1282. if(retVal == null && lastBuffer != null)
  1283. retVal = lastBuffer;
  1284. }
  1285. if(view != null && retVal != null)
  1286. view.setBuffer(retVal,true);
  1287. return retVal;
  1288. } //}}}
  1289. //{{{ openFile() methods
  1290. /**
  1291. * Opens a file. Note that as of jEdit 2.5pre1, this may return
  1292. * null if the buffer could not be opened.
  1293. * @param view The view to open the file in
  1294. * @param path The file path
  1295. *
  1296. * @return the buffer, or null if jEdit was unable to load it
  1297. *
  1298. * @since jEdit 2.4pre1
  1299. */
  1300. public static Buffer openFile(View view, String path)
  1301. {
  1302. return openFile(view,null,path,false,new Hashtable());
  1303. }
  1304. /**
  1305. * @deprecated The openFile() forms with the readOnly parameter
  1306. * should not be used. The readOnly prameter is no longer supported.
  1307. */
  1308. @Deprecated
  1309. public static Buffer openFile(View view, String parent,
  1310. String path, boolean readOnly, boolean newFile)
  1311. {
  1312. return openFile(view,parent,path,newFile,new Hashtable());
  1313. }
  1314. /**
  1315. * @deprecated The openFile() forms with the readOnly parameter
  1316. * should not be used. The readOnly prameter is no longer supported.
  1317. */
  1318. @Deprecated
  1319. public static Buffer openFile(View view, String parent,
  1320. String path, boolean readOnly, boolean newFile,
  1321. Hashtable props)
  1322. {
  1323. return openFile(view,parent,path,newFile,props);
  1324. }
  1325. /**
  1326. * Opens a file. This may return null if the buffer could not be
  1327. * opened for some reason.
  1328. * @param view The view to open the file in. If it is null, the file
  1329. * will be opened and added to the bufferSet of the current edit pane,
  1330. * but not selected
  1331. * @param parent The parent directory of the file
  1332. * @param path The path name of the file
  1333. * @param newFile True if the file should not be loaded from disk
  1334. * be prompted if it should be reloaded
  1335. * @param props Buffer-local properties to set in the buffer
  1336. *
  1337. * @return the buffer, or null if jEdit was unable to load it
  1338. *
  1339. * @since jEdit 3.2pre10
  1340. */
  1341. public static Buffer openFile(View view, String parent,
  1342. String path, boolean newFile, Hashtable props)
  1343. {
  1344. return openFile(view == null ? null : view.getEditPane(), parent, path, newFile, props);
  1345. }
  1346. /**
  1347. * Opens a file. Note that as of jEdit 2.5pre1, this may return
  1348. * null if the buffer could not be opened.
  1349. * @param editPane the EditPane to open the file in.
  1350. * @param path The file path
  1351. *
  1352. * @return the buffer, or null if jEdit was unable to load it
  1353. *
  1354. * @since jEdit 4.3pre17
  1355. */
  1356. public static Buffer openFile(EditPane editPane, String path)
  1357. {
  1358. return openFile(editPane,null,path,false,new Hashtable());
  1359. }
  1360. /**
  1361. * Opens a file. This may return null if the buffer could not be
  1362. * opened for some reason.
  1363. * @param editPane the EditPane to open the file in.
  1364. * @param parent The parent directory of the file
  1365. * @param path The path name of the file
  1366. * @param newFile True if the file should not be loaded from disk
  1367. * be prompted if it should be reloaded
  1368. * @param props Buffer-local properties to set in the buffer
  1369. *
  1370. * @return the buffer, or null if jEdit was unable to load it
  1371. *
  1372. * @since jEdit 4.3pre17
  1373. */
  1374. public static Buffer openFile(EditPane editPane, String parent,
  1375. String path, boolean newFile, Hashtable props)
  1376. {
  1377. PerspectiveManager.setPerspectiveDirty(true);
  1378. if(editPane != null && parent == null && editPane.getBuffer() != null)
  1379. parent = editPane.getBuffer().getDirectory();
  1380. try
  1381. {
  1382. URL u = new URL(path);
  1383. if (u.getProtocol().equals("file"))
  1384. path = URLDecoder.decode(u.getPath());
  1385. }
  1386. catch (MalformedURLException mue)
  1387. {
  1388. path = MiscUtilities.constructPath(parent,path);
  1389. }
  1390. if(props == null)
  1391. props = new Hashtable();
  1392. composeBufferPropsFromHistory(props, path);
  1393. Buffer newBuffer;
  1394. synchronized (editBusOrderingLock)
  1395. {
  1396. View view = editPane == null ? null : editPane.getView();
  1397. synchronized(bufferListLock)
  1398. {
  1399. Buffer buffer = getBuffer(path);
  1400. if(buffer != null)
  1401. {
  1402. if(editPane != null)
  1403. editPane.setBuffer(buffer,true);
  1404. return buffer;
  1405. }
  1406. newBuffer = new Buffer(path,newFile,false,props);
  1407. if(!newBuffer.load(view,false))
  1408. return null;
  1409. addBufferToList(newBuffer);
  1410. if (editPane != null)
  1411. bufferSetManager.addBuffer(editPane.getBufferSet(), newBuffer);
  1412. else
  1413. bufferSetManager.addBuffer(jEdit.getActiveView(), newBuffer);
  1414. }
  1415. EditBus.send(new BufferUpdate(newBuffer,view,BufferUpdate.CREATED));
  1416. }
  1417. if(editPane != null)
  1418. editPane.setBuffer(newBuffer,true);
  1419. return newBuffer;
  1420. } //}}}
  1421. //{{{ openTemporary() methods
  1422. /**
  1423. * Opens a temporary buffer. A temporary buffer is like a normal
  1424. * buffer, except that an event is not fired, the the buffer is
  1425. * not added to the buffers list.
  1426. *
  1427. * @param view The view to open the file in
  1428. * @param parent The parent directory of the file
  1429. * @param path The path name of the file
  1430. * @param newFile True if the file should not be loaded from disk
  1431. *
  1432. * @return the buffer, or null if jEdit was unable to load it
  1433. *
  1434. * @since jEdit 3.2pre10
  1435. */
  1436. public static Buffer openTemporary(View view, String parent,
  1437. String path, boolean newFile)
  1438. {
  1439. return openTemporary(view, parent, path, newFile, null);
  1440. }
  1441. /**
  1442. * Opens a temporary buffer. A temporary buffer is like a normal
  1443. * buffer, except that an event is not fired, the the buffer is
  1444. * not added to the buffers list.
  1445. *
  1446. * @param view The view to open the file in
  1447. * @param parent The parent directory of the file
  1448. * @param path The path name of the file
  1449. * @param newFile True if the file should not be loaded from disk
  1450. * @param props Buffer-local properties to set in the buffer
  1451. *
  1452. * @return the buffer, or null if jEdit was unable to load it
  1453. *
  1454. * @since jEdit 4.3pre10
  1455. */
  1456. public static Buffer openTemporary(View view, String parent,
  1457. String path, boolean newFile, Hashtable props)
  1458. {
  1459. if(view != null && parent == null)
  1460. parent = view.getBuffer().getDirectory();
  1461. if(MiscUtilities.isURL(path))
  1462. {
  1463. if(MiscUtilities.getProtocolOfURL(path).equals("file"))
  1464. path = path.substring(5);
  1465. }
  1466. path = MiscUtilities.constructPath(parent,path);
  1467. if(props == null)
  1468. props = new Hashtable();
  1469. composeBufferPropsFromHistory(props, path);
  1470. synchronized(bufferListLock)
  1471. {
  1472. Buffer buffer = getBuffer(path);
  1473. if(buffer != null)
  1474. return buffer;
  1475. buffer = new Buffer(path,newFile,true,props);
  1476. buffer.setBooleanProperty(Buffer.ENCODING_AUTODETECT, true);
  1477. if(!buffer.load(view,false))
  1478. return null;
  1479. else
  1480. return buffer;
  1481. }
  1482. } //}}}
  1483. //{{{ commitTemporary() method
  1484. /**
  1485. * Adds a temporary buffer to the buffer list. This must be done
  1486. * before allowing the user to interact with the buffer in any
  1487. * way.
  1488. * @param buffer The buffer
  1489. */
  1490. public static void commitTemporary(Buffer buffer)
  1491. {
  1492. if(!buffer.isTemporary())
  1493. return;
  1494. PerspectiveManager.setPerspectiveDirty(true);
  1495. addBufferToList(buffer);
  1496. buffer.commitTemporary();
  1497. // send full range of events to avoid breaking plugins
  1498. EditBus.send(new BufferUpdate(buffer,null,BufferUpdate.CREATED));
  1499. EditBus.send(new BufferUpdate(buffer,null,BufferUpdate.LOAD_STARTED));
  1500. EditBus.send(new BufferUpdate(buffer,null,BufferUpdate.LOADED));
  1501. } //}}}
  1502. //{{{ newFile() methods
  1503. /**
  1504. * Creates a new `untitled' file.
  1505. *
  1506. * @param view The view to create the file in
  1507. *
  1508. * @return the new buffer
  1509. */
  1510. public static Buffer newFile(View view)
  1511. {
  1512. return newFile(view == null ? null : view.getEditPane());
  1513. }
  1514. /**
  1515. * Creates a new `untitled' file.
  1516. * @param view The view to create the file in
  1517. * @param dir The directory to create the file in
  1518. *
  1519. * @return the new buffer
  1520. *
  1521. * @since jEdit 3.1pre2
  1522. */
  1523. public static Buffer newFile(View view, String dir)
  1524. {
  1525. EditPane editPane = null;
  1526. if (view != null)
  1527. {
  1528. editPane = view.getEditPane();
  1529. }
  1530. else
  1531. {
  1532. View v = getActiveView();
  1533. if (v != null)
  1534. {
  1535. editPane = v.getEditPane();
  1536. }
  1537. }
  1538. return newFile(editPane, dir);
  1539. }
  1540. /**
  1541. * Creates a new `untitled' file.
  1542. *
  1543. * @param editPane The editPane to create the file in
  1544. *
  1545. * @return the new buffer
  1546. * @since jEdit 4.3pre17
  1547. */
  1548. public static Buffer newFile(EditPane editPane)
  1549. {
  1550. String path;
  1551. if(editPane != null && editPane.getBuffer() != null)
  1552. {
  1553. path = editPane.getBuffer().getDirectory();
  1554. VFS vfs = VFSManager.getVFSForPath(path);
  1555. // don't want 'New File' to create a read only buffer
  1556. // if current file is on SQL VFS or something
  1557. if((vfs.getCapabilities() & VFS.WRITE_CAP) == 0)
  1558. path = System.getProperty("user.home");
  1559. }
  1560. else
  1561. path = null;
  1562. return newFile(editPane,path);
  1563. }
  1564. /**
  1565. * Creates a new `untitled' file.
  1566. *
  1567. * @param editPane The editPane to create the file in
  1568. * @param dir The directory to create the file in
  1569. *
  1570. * @return the new buffer
  1571. *
  1572. * @since jEdit 4.3pre17
  1573. */
  1574. public static Buffer newFile(EditPane editPane, String dir)
  1575. {
  1576. if (editPane != null)
  1577. {
  1578. BufferSet bufferSet = editPane.getBufferSet();
  1579. Buffer[] buffers = bufferSet.getAllBuffers();
  1580. for (Buffer buf:buffers)
  1581. {
  1582. if (buf.isUntitled() && !buf.isDirty())
  1583. {
  1584. if (!MiscUtilities.getParentOfPath(buf.getPath()).equals(dir))
  1585. {
  1586. // Find the highest Untitled-n file
  1587. int untitledCount = getNextUntitledBufferId();
  1588. Buffer newBuffer = openFile(editPane,dir,"Untitled-" + untitledCount,true,null);
  1589. jEdit.closeBuffer(editPane, buf);
  1590. return newBuffer;
  1591. }
  1592. /* if "never mark untitled buffers dirty"
  1593. * is selected, we might have contents in non-dirty
  1594. * untitled buffers. We must clear those contents
  1595. * if user requested new file.
  1596. */
  1597. int l = buf.getLength();
  1598. if (l > 0)
  1599. buf.remove(0, l);
  1600. editPane.setBuffer(buf);
  1601. return buf;
  1602. }
  1603. }
  1604. }
  1605. // Find the highest Untitled-n file
  1606. int untitledCount = getNextUntitledBufferId();
  1607. return openFile(editPane,dir,"Untitled-" + untitledCount,true,null);
  1608. } //}}}
  1609. //}}}
  1610. //{{{ Buffer management methods
  1611. //{{{ closeBuffer() method
  1612. /**
  1613. * Closes a buffer. If there are unsaved changes, the user is
  1614. * prompted if they should be saved first.
  1615. * @param view The view
  1616. * @param buffer The buffer
  1617. * @return True if the buffer was really closed, false otherwise
  1618. */
  1619. public static boolean closeBuffer(View view, Buffer buffer)
  1620. {
  1621. // Wait for pending I/O requests
  1622. if(buffer.isPerformingIO())
  1623. {
  1624. VFSManager.waitForRequests();
  1625. if(VFSManager.errorOccurred())
  1626. return false;
  1627. }
  1628. if(buffer.isDirty())
  1629. {
  1630. Object[] args = { buffer.getName() };
  1631. int result = GUIUtilities.confirm(view,"notsaved",args,
  1632. JOptionPane.YES_NO_CANCEL_OPTION,
  1633. JOptionPane.WARNING_MESSAGE);
  1634. if(result == JOptionPane.YES_OPTION)
  1635. {
  1636. if(!buffer.save(view,null,true))
  1637. return false;
  1638. VFSManager.waitForRequests();
  1639. if(buffer.getBooleanProperty(BufferIORequest
  1640. .ERROR_OCCURRED))
  1641. {
  1642. return false;
  1643. }
  1644. }
  1645. else if(result != JOptionPane.NO_OPTION)
  1646. return false;
  1647. }
  1648. _closeBuffer(view,buffer);
  1649. return true;
  1650. } //}}}
  1651. //{{{ closeBuffer() method
  1652. /**
  1653. * Close a buffer.
  1654. * The buffer is first removed from the EditPane's bufferSet.
  1655. * If the buffer is not in any bufferSet after that, it is closed
  1656. * @param editPane the edit pane (it cannot be null)
  1657. * @param buffer the buffer (it cannot be null)
  1658. * @since jEdit 4.3pre15
  1659. */
  1660. public static void closeBuffer(EditPane editPane, Buffer buffer)
  1661. {
  1662. int bufferSetsCount = bufferSetManager.countBufferSets(buffer);
  1663. if (bufferSetsCount < 2)
  1664. {
  1665. closeBuffer(editPane.getView(), buffer);
  1666. }
  1667. else
  1668. {
  1669. bufferSetManager.removeBuffer(editPane, buffer);
  1670. }
  1671. } //}}}
  1672. //{{{ _closeBuffer() method
  1673. /**
  1674. * Closes the buffer, even if it has unsaved changes.
  1675. * @param view The view, may be null
  1676. * @param buffer The buffer
  1677. *
  1678. * @exception NullPointerException if the buffer is null
  1679. *
  1680. * @since jEdit 2.2pre1
  1681. */
  1682. public static void _closeBuffer(View view, Buffer buffer)
  1683. {
  1684. if(buffer.isClosed())
  1685. {
  1686. // can happen if the user presses C+w twice real
  1687. // quick and the buffer has unsaved changes
  1688. return;
  1689. }
  1690. PerspectiveManager.setPerspectiveDirty(true);
  1691. if(!buffer.isNewFile())
  1692. {
  1693. if(view != null)
  1694. view.getEditPane().saveCaretInfo();
  1695. Integer _caret = (Integer)buffer.getProperty(Buffer.CARET);
  1696. int caret = _caret == null ? 0 : _caret.intValue();
  1697. BufferHistory.setEntry(buffer.getPath(),caret,
  1698. (Selection[])buffer.getProperty(Buffer.SELECTION),
  1699. buffer.getStringProperty(JEditBuffer.ENCODING),
  1700. buffer.getMode().getName());
  1701. }
  1702. String path = buffer.getSymlinkPath();
  1703. if((VFSManager.getVFSForPath(path).getCapabilities()
  1704. & VFS.CASE_INSENSITIVE_CAP) != 0)
  1705. {
  1706. path = path.toLowerCase();
  1707. }
  1708. EditBus.send(new BufferUpdate(buffer,view,BufferUpdate.CLOSING));
  1709. bufferHash.remove(path);
  1710. removeBufferFromList(buffer);
  1711. buffer.close();
  1712. DisplayManager.bufferClosed(buffer);
  1713. bufferSetManager.removeBuffer(buffer);
  1714. EditBus.send(new BufferUpdate(buffer,view,BufferUpdate.CLOSED));
  1715. if(jEdit.getBooleanProperty("persistentMarkers"))
  1716. buffer.updateMarkersFile(view);
  1717. } //}}}
  1718. //{{{ closeAllBuffers() methods
  1719. /**
  1720. * Closes all open buffers.
  1721. * @param view The view
  1722. *
  1723. * @return true if al…

Large files are truncated, but you can click here to view the full file