PageRenderTime 50ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/jEdit/tags/jedit-4-5-pre1/org/gjt/sp/jedit/jEdit.java

#
Java | 2602 lines | 1497 code | 276 blank | 829 comment | 316 complexity | 4f3bb46130d1da504100e24028380e55 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

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

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