All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.gjt.sp.jedit.jEdit Maven / Gradle / Ivy

Go to download

This project aims to build a command line tool that can create HTML view with syntax highlighted source code. It uses Jedit syntax highlighting engine and support all languages that are supported in JEdit. Which are currently: ActionScript, Ada 95, ANTLR, Apache HTTPD, APDL, AppleScript, ASP, Aspect-J, Assembly, AWK, B formal method, Batch, BBj, BCEL, BibTeX, C, C++, C#, CHILL, CIL, COBOL, ColdFusion, CSS, CVS Commit, D, DOxygen, DSSSL, Eiffel, EmbPerl, Erlang, Factor, Fortran, Foxpro, FreeMarker, Fortran, Gettext, Groovy, Haskell, HTML, Icon, IDL, Inform, INI, Inno Setup, Informix 4GL, Interlis, Io, Java, JavaScript, JCL, JHTML, JMK, JSP, Latex, Lilypond, Lisp, LOTOS, Lua, Makefile, Maple, ML, Modula-3, MoinMoin, MQSC, NetRexx, NQC, NSIS2, Objective C, ObjectRexx, Occam, Omnimark, Parrot, Pascal, Patch, Perl, PHP, Pike, PL-SQL, PL/I, Pop11, PostScript, Povray, PowerDynamo, Progress 4GL, Prolog, Properties, PSP, PV-WAVE, Pyrex, Python, REBOL, Redcode, Relax-NG, RelationalView, Rest, Rib, RPM spec, RTF, Ruby, Ruby-HTML, RView, S+, S#, SAS, Scheme, SDL/PL, SGML, Shell Script, SHTML, Smalltalk, SMI MIB, SQR, Squidconf, SVN Commit, Swig, TCL, TeX, Texinfo, TPL, Transact-SQL, UnrealScript, VBScript, Velocity, Verilog, VHDL, XML, XSL, ZPT

The newest version!
/*
 * jEdit.java - Main class of the jEdit editor
 * :tabSize=8:indentSize=8:noTabs=false:
 * :folding=explicit:collapseFolds=1:
 *
 * Copyright (C) 1998, 2005 Slava Pestov
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

package org.gjt.sp.jedit;

//{{{ Imports
import java.awt.Color;
import java.awt.Component;
import java.awt.DefaultKeyboardFocusManager;
import java.awt.Font;
import java.awt.Frame;
import java.awt.KeyboardFocusManager;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.KeyEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Writer;
import java.net.Authenticator;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.PasswordAuthentication;
import java.net.Socket;
import java.net.URL;
import java.net.URLDecoder;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.EventObject;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Vector;

import javax.swing.Box;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.LayoutFocusTraversalPolicy;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
import javax.swing.UIDefaults;
import javax.swing.UIManager;

import org.gjt.sp.jedit.bsh.UtilEvalError;
import org.gjt.sp.jedit.buffer.FoldHandler;
import org.gjt.sp.jedit.buffer.JEditBuffer;
import org.gjt.sp.jedit.buffer.KillRing;
import org.gjt.sp.jedit.bufferio.BufferIORequest;
import org.gjt.sp.jedit.gui.DefaultInputHandler;
import org.gjt.sp.jedit.gui.InputHandler;
import org.gjt.sp.jedit.io.VFS;
import org.gjt.sp.jedit.io.VFSManager;
import org.gjt.sp.jedit.msg.BufferUpdate;
import org.gjt.sp.jedit.msg.DynamicMenuChanged;
import org.gjt.sp.jedit.msg.EditorExitRequested;
import org.gjt.sp.jedit.msg.EditorExiting;
import org.gjt.sp.jedit.msg.PropertiesChanged;
import org.gjt.sp.jedit.msg.ViewUpdate;
import org.gjt.sp.jedit.syntax.ModeProvider;
import org.gjt.sp.jedit.syntax.TokenMarker;
import org.gjt.sp.jedit.syntax.XModeHandler;
import org.gjt.sp.jedit.textarea.JEditTextArea;
import org.gjt.sp.jedit.textarea.Selection;
import org.gjt.sp.jedit.textarea.TextArea;
import org.gjt.sp.jedit.visitors.JEditVisitor;
import org.gjt.sp.util.IOUtilities;
import org.gjt.sp.util.Log;
import org.gjt.sp.util.StandardUtilities;
import org.gjt.sp.util.SyntaxUtilities;
import org.gjt.sp.util.XMLUtilities;
import org.xml.sax.SAXParseException;

/**
 * The main class of the jEdit text editor.
 * @author Slava Pestov
 * @version $Id: jEdit.java 13207 2008-08-06 12:19:50Z kpouer $
 */
public class jEdit
{
	//{{{ getVersion() method
	/**
	 * Returns the jEdit version as a human-readable string.
	 */
	public static String getVersion()
	{
		return MiscUtilities.buildToVersion(getBuild());
	} //}}}

	//{{{ getBuild() method
	/**
	 * Returns the internal version. MiscUtilities.compareStrings() can be used
	 * to compare different internal versions.
	 */
	public static String getBuild()
	{
		// (major).(minor).(<99 = preX, 99 = final).(bug fix)
		return "04.03.15.00";
	} //}}}

	//{{{ main() method
	/**
	 * The main method of the jEdit application.
	 * This should never be invoked directly.
	 * @param args The command line arguments
	 */
	public static void main(String[] args)
	{
		//{{{ Check for Java 1.5 or later
		String javaVersion = System.getProperty("java.version");
		if(javaVersion.compareTo("1.5") < 0)
		{
			System.err.println("You are running Java version "
				+ javaVersion + '.');
			System.err.println("jEdit requires Java 1.5 or later.");
			System.exit(1);
		} //}}}

		// later on we need to know if certain code is called from
		// the main thread
		mainThread = Thread.currentThread();

		settingsDirectory = ".jedit";

		// MacOS users expect the app to keep running after all windows
		// are closed
		background = OperatingSystem.isMacOS();

		//{{{ Parse command line
		boolean endOpts = false;
		int level = Log.WARNING;
		String portFile = "server";
		boolean restore = true;
		boolean newView = true;
		boolean newPlainView = false;
		boolean gui = true; // open initial view?
		boolean loadPlugins = true;
		boolean runStartupScripts = true;
		boolean quit = false;
		boolean wait = false;
		String userDir = System.getProperty("user.dir");

		// script to run
		String scriptFile = null;

		for(int i = 0; i < args.length; i++)
		{
			String arg = args[i];
			if(arg == null)
				continue;
			else if(arg.length() == 0)
				args[i] = null;
			else if(arg.startsWith("-") && !endOpts)
			{
				if(arg.equals("--"))
					endOpts = true;
				else if(arg.equals("-usage"))
				{
					version();
					System.err.println();
					usage();
					System.exit(1);
				}
				else if(arg.equals("-version"))
				{
					version();
					System.exit(1);
				}
				else if(arg.startsWith("-log="))
				{
					try
					{
						level = Integer.parseInt(arg.substring("-log=".length()));
					}
					catch(NumberFormatException nf)
					{
						System.err.println("Malformed option: " + arg);
					}
				}
				else if(arg.equals("-nosettings"))
					settingsDirectory = null;
				else if(arg.startsWith("-settings="))
					settingsDirectory = arg.substring(10);
				else if(arg.startsWith("-noserver"))
					portFile = null;
				else if(arg.equals("-server"))
					portFile = "server";
				else if(arg.startsWith("-server="))
					portFile = arg.substring(8);
				else if(arg.startsWith("-background"))
					background = true;
				else if(arg.startsWith("-nobackground"))
					background = false;
				else if(arg.equals("-gui"))
					gui = true;
				else if(arg.equals("-nogui"))
					gui = false;
				else if(arg.equals("-newview"))
					newView = true;
				else if(arg.equals("-newplainview"))
					newPlainView = true;
				else if(arg.equals("-reuseview"))
					newPlainView = newView = false;
				else if(arg.equals("-restore"))
					restore = true;
				else if(arg.equals("-norestore"))
					restore = false;
				else if(arg.equals("-plugins"))
					loadPlugins = true;
				else if(arg.equals("-noplugins"))
					loadPlugins = false;
				else if(arg.equals("-startupscripts"))
					runStartupScripts = true;
				else if(arg.equals("-nostartupscripts"))
					runStartupScripts = false;
				else if(arg.startsWith("-run="))
					scriptFile = arg.substring(5);
				else if(arg.equals("-wait"))
					wait = true;
				else if(arg.equals("-quit"))
					quit = true;
				else
				{
					System.err.println("Unknown option: "
						+ arg);
					usage();
					System.exit(1);
				}
				args[i] = null;
			}
		} //}}}

		//{{{ We need these initializations very early on
		if(settingsDirectory != null)
		{
			settingsDirectory = MiscUtilities.constructPath(
				System.getProperty("user.home"),
				settingsDirectory);
			settingsDirectory = MiscUtilities.resolveSymlinks(
				settingsDirectory);
		}

		if(settingsDirectory != null && portFile != null)
			portFile = MiscUtilities.constructPath(settingsDirectory,portFile);
		else
			portFile = null;

		Log.init(true,level);
		//}}}

		//{{{ Try connecting to another running jEdit instance
		if(portFile != null && new File(portFile).exists())
		{
			try
			{
				BufferedReader in = new BufferedReader(new FileReader(portFile));
				String check = in.readLine();
				if(!check.equals("b"))
					throw new Exception("Wrong port file format");

				int port = Integer.parseInt(in.readLine());
				int key = Integer.parseInt(in.readLine());

				Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),port);
				DataOutputStream out = new DataOutputStream(
					socket.getOutputStream());
				out.writeInt(key);

				String script;
				if(quit)
				{
					script = "socket.close();\n"
						+ "jEdit.exit(null,true);\n";
				}
				else
				{
					script = makeServerScript(wait,restore,
						newView,newPlainView,args,
						scriptFile);
				}

				out.writeUTF(script);

				Log.log(Log.DEBUG,jEdit.class,"Waiting for server");
				// block until its closed
				try
				{
					socket.getInputStream().read();
				}
				catch(Exception e)
				{
				}

				in.close();
				out.close();

				System.exit(0);
			}
			catch(Exception e)
			{
				// ok, this one seems to confuse newbies
				// endlessly, so log it as NOTICE, not
				// ERROR
				Log.log(Log.NOTICE,jEdit.class,"An error occurred"
					+ " while connecting to the jEdit server instance.");
				Log.log(Log.NOTICE,jEdit.class,"This probably means that"
					+ " jEdit crashed and/or exited abnormally");
				Log.log(Log.NOTICE,jEdit.class,"the last time it was run.");
				Log.log(Log.NOTICE,jEdit.class,"If you don't"
					+ " know what this means, don't worry.");
				Log.log(Log.NOTICE,jEdit.class,e);
			}
		}

		if(quit)
		{
			// if no server running and user runs jedit -quit,
			// just exit
			System.exit(0);
		} //}}}

		//{{{ Initialize settings directory
		Writer stream;
		if(settingsDirectory != null)
		{
			File _settingsDirectory = new File(settingsDirectory);
			if(!_settingsDirectory.exists())
				_settingsDirectory.mkdirs();
			File _macrosDirectory = new File(settingsDirectory,"macros");
			if(!_macrosDirectory.exists())
				_macrosDirectory.mkdir();

			String logPath = MiscUtilities.constructPath(
				settingsDirectory,"activity.log");

			backupSettingsFile(new File(logPath));

			try
			{
				stream = new BufferedWriter(new FileWriter(logPath));

				// Write a warning message:
				String lineSep = System.getProperty("line.separator");
				stream.write("Log file created on " + new Date());
				stream.write(lineSep);
				stream.write("IMPORTANT:");
				stream.write(lineSep);
				stream.write("Because updating this file after "
					+ "every log message would kill");
				stream.write(lineSep);
				stream.write("performance, it will be *incomplete* "
					+ "unless you invoke the");
				stream.write(lineSep);
				stream.write("Utilities->Troubleshooting->Update "
					+ "Activity Log on Disk command!");
				stream.write(lineSep);
			}
			catch(Exception e)
			{
				e.printStackTrace();
				stream = null;
			}
		}
		else
		{
			stream = null;
		} //}}}

		Log.setLogWriter(stream);

		Log.log(Log.NOTICE,jEdit.class,"jEdit version " + getVersion());
		Log.log(Log.MESSAGE,jEdit.class,"Settings directory is "
			+ settingsDirectory);

		//{{{ Get things rolling
		initMisc();
		initSystemProperties();

		if(jEditHome != null)
			initSiteProperties();

		initUserProperties();

		
		///Options.SIMPLIFIED_KEY_HANDLING = jEdit.getBooleanProperty("newkeyhandling");
		//}}}

		//{{{ Initialize server
		if(portFile != null)
		{
		}
		else
		{
			if(background)
			{
				background = false;
				Log.log(Log.WARNING,jEdit.class,"You cannot specify both the"
					+ " -background and -noserver switches");
			}
		} //}}}

		//{{{ Do more stuff
		VFSManager.init();
		initResources();
		if(loadPlugins)
		{
			initPlugins();
		}

		BufferHistory.load();
		KillRing.setInstance(new JEditKillRing());
		KillRing.getInstance().load();
		propertiesChanged();


		// Buffer sort
		sortBuffers = getBooleanProperty("sortBuffers");
		sortByName = getBooleanProperty("sortByName");

		reloadModes();

		//}}}


		if(runStartupScripts && jEditHome != null)
		{
			String path = MiscUtilities.constructPath(jEditHome,"startup");
			File file = new File(path);
			if(file.exists())
			{
				runStartupScripts(file);
			}
		}

		if(runStartupScripts && settingsDirectory != null)
		{
			String path = MiscUtilities.constructPath(settingsDirectory,"startup");
			File file = new File(path);
			if (file.exists())
			{
				runStartupScripts(file);
			}
			else
			{
				file.mkdirs();
			}
		}

		// Open files, create the view and hide the splash screen.
		SyntaxUtilities.propertyManager = jEdit.propertyManager;
		finishStartup(gui,restore,userDir,args);
	} //}}}

	//{{{ Property methods

	//{{{ getProperties() method
	/**
	 * Returns the properties object which contains all known
	 * jEdit properties. Note that as of jEdit 4.2pre10, this returns a
	 * new collection, not the existing properties instance.
	 * @since jEdit 3.1pre4
	 */
	public static Properties getProperties()
	{
		return propMgr.getProperties();
	} //}}}

	//{{{ getProperty() method
	/**
	 * Fetches a property, returning null if it's not defined.
	 * @param name The property
	 */
	public static String getProperty(String name)
	{
		return propMgr.getProperty(name);
	} //}}}

	//{{{ getProperty() method
	/**
	 * Fetches a property, returning the default value if it's not
	 * defined.
	 * @param name The property
	 * @param def The default value
	 */
	public static String getProperty(String name, String def)
	{
		String value = propMgr.getProperty(name);
		if(value == null)
			return def;
		else
			return value;
	} //}}}

	//{{{ getProperty() method
	/**
	 * Returns the property with the specified name.

* * The elements of the args array are substituted * into the value of the property in place of strings of the * form {n}, where n is an index * in the array.

* * You can find out more about this feature by reading the * documentation for the format method of the * java.text.MessageFormat class. * * @param name The property * @param args The positional parameters */ public static String getProperty(String name, Object[] args) { if(name == null) return null; if(args == null) return getProperty(name); else { String value = getProperty(name); if(value == null) return null; else return MessageFormat.format(value,args); } } //}}} //{{{ getBooleanProperty() method /** * Returns the value of a boolean property. * @param name The property */ public static boolean getBooleanProperty(String name) { return getBooleanProperty(name,false); } //}}} //{{{ getBooleanProperty() method /** * Returns the value of a boolean property. * @param name The property * @param def The default value */ public static boolean getBooleanProperty(String name, boolean def) { String value = getProperty(name); if(value == null) return def; else if(value.equals("true") || value.equals("yes") || value.equals("on")) return true; else if(value.equals("false") || value.equals("no") || value.equals("off")) return false; else return def; } //}}} //{{{ getIntegerProperty() method /** * Returns the value of an integer property. * @param name The property */ public static int getIntegerProperty(String name) { return getIntegerProperty(name,0); } //}}} //{{{ getIntegerProperty() method /** * Returns the value of an integer property. * @param name The property * @param def The default value * @since jEdit 4.0pre1 */ public static int getIntegerProperty(String name, int def) { String value = getProperty(name); if(value == null) return def; else { try { return Integer.parseInt(value.trim()); } catch(NumberFormatException nf) { return def; } } } //}}} //{{{ getDoubleProperty() method public static double getDoubleProperty(String name, double def) { String value = getProperty(name); if(value == null) return def; else { try { return Double.parseDouble(value.trim()); } catch(NumberFormatException nf) { return def; } } } //}}} //{{{ getFontProperty() method /** * Returns the value of a font property. The family is stored * in the name property, the font size is stored * in the namesize property, and the font style is * stored in namestyle. For example, if * name is view.gutter.font, the * properties will be named view.gutter.font, * view.gutter.fontsize, and * view.gutter.fontstyle. * * @param name The property * @since jEdit 4.0pre1 */ public static Font getFontProperty(String name) { return getFontProperty(name,null); } //}}} //{{{ getFontProperty() method /** * Returns the value of a font property. The family is stored * in the name property, the font size is stored * in the namesize property, and the font style is * stored in namestyle. For example, if * name is view.gutter.font, the * properties will be named view.gutter.font, * view.gutter.fontsize, and * view.gutter.fontstyle. * * @param name The property * @param def The default value * @since jEdit 4.0pre1 */ public static Font getFontProperty(String name, Font def) { String family = getProperty(name); String sizeString = getProperty(name + "size"); String styleString = getProperty(name + "style"); if(family == null || sizeString == null || styleString == null) return def; else { int size, style; try { size = Integer.parseInt(sizeString); } catch(NumberFormatException nf) { return def; } try { style = Integer.parseInt(styleString); } catch(NumberFormatException nf) { return def; } return new Font(family,style,size); } } //}}} //{{{ getColorProperty() method /** * Returns the value of a color property. * @param name The property name * @since jEdit 4.0pre1 */ public static Color getColorProperty(String name) { return getColorProperty(name,Color.black); } //}}} //{{{ getColorProperty() method /** * Returns the value of a color property. * @param name The property name * @param def The default value * @since jEdit 4.0pre1 */ public static Color getColorProperty(String name, Color def) { String value = getProperty(name); if(value == null) return def; else return SyntaxUtilities.parseColor(value, def); } //}}} //{{{ setColorProperty() method /** * Sets the value of a color property. * @param name The property name * @param value The value * @since jEdit 4.0pre1 */ public static void setColorProperty(String name, Color value) { setProperty(name, SyntaxUtilities.getColorHexString(value)); } //}}} //{{{ setProperty() method /** * Sets a property to a new value. * @param name The property * @param value The new value */ public static void setProperty(String name, String value) { propMgr.setProperty(name,value); } //}}} //{{{ setTemporaryProperty() method /** * Sets a property to a new value. Properties set using this * method are not saved to the user properties list. * @param name The property * @param value The new value * @since jEdit 2.3final */ public static void setTemporaryProperty(String name, String value) { propMgr.setTemporaryProperty(name,value); } //}}} //{{{ setBooleanProperty() method /** * Sets a boolean property. * @param name The property * @param value The value */ public static void setBooleanProperty(String name, boolean value) { setProperty(name,value ? "true" : "false"); } //}}} //{{{ setIntegerProperty() method /** * Sets the value of an integer property. * @param name The property * @param value The value * @since jEdit 4.0pre1 */ public static void setIntegerProperty(String name, int value) { setProperty(name,String.valueOf(value)); } //}}} //{{{ setDoubleProperty() method public static void setDoubleProperty(String name, double value) { setProperty(name,String.valueOf(value)); } //}}} //{{{ setFontProperty() method /** * Sets the value of a font property. The family is stored * in the name property, the font size is stored * in the namesize property, and the font style is * stored in namestyle. For example, if * name is view.gutter.font, the * properties will be named view.gutter.font, * view.gutter.fontsize, and * view.gutter.fontstyle. * * @param name The property * @param value The value * @since jEdit 4.0pre1 */ public static void setFontProperty(String name, Font value) { setProperty(name,value.getFamily()); setIntegerProperty(name + "size",value.getSize()); setIntegerProperty(name + "style",value.getStyle()); } //}}} //{{{ unsetProperty() method /** * Unsets (clears) a property. * @param name The property */ public static void unsetProperty(String name) { propMgr.unsetProperty(name); } //}}} //{{{ resetProperty() method /** * Resets a property to its default value. * @param name The property * * @since jEdit 2.5pre3 */ public static void resetProperty(String name) { propMgr.resetProperty(name); } //}}} //{{{ propertiesChanged() method /** * Reloads various settings from the properties. */ public static void propertiesChanged() { initKeyBindings(); saveCaret = getBooleanProperty("saveCaret"); UIDefaults defaults = UIManager.getDefaults(); // give all text areas the same font Font font = getFontProperty("view.font"); //defaults.put("TextField.font",font); defaults.put("TextArea.font",font); defaults.put("TextPane.font",font); // Enable/Disable tooltips ToolTipManager.sharedInstance().setEnabled( jEdit.getBooleanProperty("showTooltips")); initProxy(); // we do this here instead of adding buffers to the bus. Buffer buffer = buffersFirst; while(buffer != null) { buffer.resetCachedProperties(); buffer.propertiesChanged(); buffer = buffer.next; } KillRing.getInstance().propertiesChanged(getIntegerProperty("history",25)); EditBus.send(new PropertiesChanged(null)); } //}}} //}}} //{{{ Plugin management methods //{{{ getNotLoadedPluginJARs() method /** * Returns a list of plugin JARs pathnames that are not currently loaded * by examining the user and system plugin directories. * @since jEdit 3.2pre1 */ public static String[] getNotLoadedPluginJARs() { List returnValue = new ArrayList(); if(jEditHome != null) { String systemPluginDir = MiscUtilities .constructPath(jEditHome,"jars"); String[] list = new File(systemPluginDir).list(); if(list != null) getNotLoadedPluginJARs(returnValue,systemPluginDir,list); } if(settingsDirectory != null) { String userPluginDir = MiscUtilities .constructPath(settingsDirectory,"jars"); String[] list = new File(userPluginDir).list(); if(list != null) { getNotLoadedPluginJARs(returnValue, userPluginDir,list); } } String[] _returnValue = new String[returnValue.size()]; returnValue.toArray(_returnValue); return _returnValue; } //}}} //{{{ addPluginJARsFromDirectory() method /** * Loads all plugins in a directory. * @param directory The directory * @since jEdit 4.2pre1 */ private static void addPluginJARsFromDirectory(String directory) { Log.log(Log.NOTICE,jEdit.class,"Loading plugins from " + directory); File file = new File(directory); if(!(file.exists() && file.isDirectory())) return; String[] plugins = file.list(); if(plugins == null) return; for(int i = 0; i < plugins.length; i++) { String plugin = plugins[i]; if(!plugin.toLowerCase().endsWith(".jar")) continue; String path = MiscUtilities.constructPath(directory,plugin); if (jEdit.getBooleanProperty("plugin-blacklist."+plugin)) continue; // remove this when 4.1 plugin API is deprecated if(plugin.equals("EditBuddy.jar") || plugin.equals("PluginManager.jar") || plugin.equals("Firewall.jar") || plugin.equals("Tidy.jar") || plugin.equals("DragAndDrop.jar")) { pluginError(path,"plugin-error.obsolete",null); continue; } } } //}}} //}}} //{{{ Action methods //{{{ getActionContext() method /** * Returns the action context used to store editor actions. * @since jEdit 4.2pre1 */ public static ActionContext getActionContext() { return actionContext; } //}}} //{{{ getActionNames() method /** * Returns all registered action names. */ public static String[] getActionNames() { return actionContext.getActionNames(); } //}}} //}}} //{{{ Edit mode methods //{{{ reloadModes() method /** * Reloads all edit modes. * @since jEdit 3.2pre2 */ public static void reloadModes() { /* Try to guess the eventual size to avoid unnecessary * copying */ ModeProvider.instance.removeAll(); //{{{ Load the global catalog if(jEditHome == null) loadModeCatalog("/modes/catalog",true); else { loadModeCatalog(MiscUtilities.constructPath(jEditHome, "modes","catalog"),false); } //}}} //{{{ Load user catalog if(settingsDirectory != null) { File userModeDir = new File(MiscUtilities.constructPath( settingsDirectory,"modes")); if(!userModeDir.exists()) userModeDir.mkdirs(); File userCatalog = new File(MiscUtilities.constructPath( settingsDirectory,"modes","catalog")); if(!userCatalog.exists()) { // create dummy catalog FileWriter out = null; try { out = new FileWriter(userCatalog); out.write(jEdit.getProperty("defaultCatalog")); } catch(IOException io) { Log.log(Log.ERROR,jEdit.class,io); } finally { IOUtilities.closeQuietly(out); } } loadModeCatalog(userCatalog.getPath(),false); } //}}} Buffer buffer = buffersFirst; while(buffer != null) { // This reloads the token marker and sends a message // which causes edit panes to repaint their text areas buffer.setMode(); buffer = buffer.next; } } //}}} //{{{ getMode() method /** * Returns the edit mode with the specified name. * @param name The edit mode */ public static Mode getMode(String name) { return ModeProvider.instance.getMode(name); } //}}} //{{{ getModes() method /** * Returns an array of installed edit modes. */ public static Mode[] getModes() { return ModeProvider.instance.getModes(); } //}}} //}}} //{{{ Buffer creation methods //{{{ openFiles() method /** * Opens the file names specified in the argument array. This * handles +line and +marker arguments just like the command * line parser. * @param parent The parent directory * @param args The file names to open * @since jEdit 3.2pre4 */ public static Buffer openFiles(View view, String parent, String[] args) { Buffer retVal = null; Buffer lastBuffer = null; for(int i = 0; i < args.length; i++) { String arg = args[i]; if(arg == null) continue; else if(arg.startsWith("+line:") || arg.startsWith("+marker:")) { if(lastBuffer != null) gotoMarker(view,lastBuffer,arg); continue; } lastBuffer = openFile(null,parent,arg,false,null); if(retVal == null && lastBuffer != null) retVal = lastBuffer; } if(view != null && retVal != null) view.setBuffer(retVal,true); return retVal; } //}}} //{{{ openFile() methods /** * Opens a file. Note that as of jEdit 2.5pre1, this may return * null if the buffer could not be opened. * @param view The view to open the file in * @param path The file path * * @return the buffer, or null if jEdit was unable to load it * * @since jEdit 2.4pre1 */ public static Buffer openFile(View view, String path) { return openFile(view,null,path,false,new Hashtable()); } /** * @deprecated The openFile() forms with the readOnly parameter * should not be used. The readOnly prameter is no longer supported. */ @Deprecated public static Buffer openFile(View view, String parent, String path, boolean readOnly, boolean newFile) { return openFile(view,parent,path,newFile,new Hashtable()); } /** * @deprecated The openFile() forms with the readOnly parameter * should not be used. The readOnly prameter is no longer supported. */ @Deprecated public static Buffer openFile(View view, String parent, String path, boolean readOnly, boolean newFile, Hashtable props) { return openFile(view,parent,path,newFile,props); } /** * Opens a file. This may return null if the buffer could not be * opened for some reason. * @param view The view to open the file in. If it is null, the file * will be opened and added to the bufferSet of the current edit pane, * but not selected * @param parent The parent directory of the file * @param path The path name of the file * @param newFile True if the file should not be loaded from disk * be prompted if it should be reloaded * @param props Buffer-local properties to set in the buffer * * @return the buffer, or null if jEdit was unable to load it * * @since jEdit 3.2pre10 */ public static Buffer openFile(View view, String parent, String path, boolean newFile, Hashtable props) { if(view != null && parent == null) parent = view.getBuffer().getDirectory(); try { URL u = new URL(path); if (u.getProtocol().equals("file")) path = URLDecoder.decode(u.getPath()); } catch (MalformedURLException mue) { path = MiscUtilities.constructPath(parent,path); } if(props == null) props = new Hashtable(); composeBufferPropsFromHistory(props, path); Buffer newBuffer; synchronized (editBusOrderingLock) { synchronized(bufferListLock) { Buffer buffer = getBuffer(path); if(buffer != null) { if(view != null) view.setBuffer(buffer,true); return buffer; } newBuffer = new Buffer(path,newFile,false,props); if(!newBuffer.load(view,false)) return null; addBufferToList(newBuffer); } EditBus.send(new BufferUpdate(newBuffer,view,BufferUpdate.CREATED)); } if(view != null) view.setBuffer(newBuffer,true); return newBuffer; } //}}} //{{{ openTemporary() methods /** * Opens a temporary buffer. A temporary buffer is like a normal * buffer, except that an event is not fired, the the buffer is * not added to the buffers list. * * @param view The view to open the file in * @param parent The parent directory of the file * @param path The path name of the file * @param newFile True if the file should not be loaded from disk * * @return the buffer, or null if jEdit was unable to load it * * @since jEdit 3.2pre10 */ public static Buffer openTemporary(View view, String parent, String path, boolean newFile) { return openTemporary(view, parent, path, newFile, null); } /** * Opens a temporary buffer. A temporary buffer is like a normal * buffer, except that an event is not fired, the the buffer is * not added to the buffers list. * * @param view The view to open the file in * @param parent The parent directory of the file * @param path The path name of the file * @param newFile True if the file should not be loaded from disk * @param props Buffer-local properties to set in the buffer * * @return the buffer, or null if jEdit was unable to load it * * @since jEdit 4.3pre10 */ public static Buffer openTemporary(View view, String parent, String path, boolean newFile, Hashtable props) { if(view != null && parent == null) parent = view.getBuffer().getDirectory(); if(MiscUtilities.isURL(path)) { if(MiscUtilities.getProtocolOfURL(path).equals("file")) path = path.substring(5); } path = MiscUtilities.constructPath(parent,path); if(props == null) props = new Hashtable(); composeBufferPropsFromHistory(props, path); synchronized(bufferListLock) { Buffer buffer = getBuffer(path); if(buffer != null) return buffer; buffer = new Buffer(path,newFile,true,props); buffer.setBooleanProperty(Buffer.ENCODING_AUTODETECT, true); if(!buffer.load(view,false)) return null; else return buffer; } } //}}} //{{{ commitTemporary() method /** * Adds a temporary buffer to the buffer list. This must be done * before allowing the user to interact with the buffer in any * way. * @param buffer The buffer */ public static void commitTemporary(Buffer buffer) { if(!buffer.isTemporary()) return; addBufferToList(buffer); buffer.commitTemporary(); // send full range of events to avoid breaking plugins EditBus.send(new BufferUpdate(buffer,null,BufferUpdate.CREATED)); EditBus.send(new BufferUpdate(buffer,null,BufferUpdate.LOAD_STARTED)); EditBus.send(new BufferUpdate(buffer,null,BufferUpdate.LOADED)); } //}}} //{{{ newFile() method /** * Creates a new `untitled' file. * * @param view The view to create the file in * * @return the new buffer */ public static Buffer newFile(View view) { String path; if(view != null && view.getBuffer() != null) { path = view.getBuffer().getDirectory(); VFS vfs = VFSManager.getVFSForPath(path); // don't want 'New File' to create a read only buffer // if current file is on SQL VFS or something if((vfs.getCapabilities() & VFS.WRITE_CAP) == 0) path = System.getProperty("user.home"); } else path = null; return newFile(view,path); } //}}} //{{{ newFile() method /** * Creates a new `untitled' file. * @param view The view to create the file in * @param dir The directory to create the file in * * @return the new buffer * * @since jEdit 3.1pre2 */ public static Buffer newFile(View view, String dir) { // Find the highest Untitled-n file int untitledCount = getNextUntitledBufferId(); return openFile(view,dir,"Untitled-" + untitledCount,true,null); } //}}} //}}} //{{{ Buffer management methods //{{{ closeBuffer() method /** * Closes a buffer. If there are unsaved changes, the user is * prompted if they should be saved first. * @param view The view * @param buffer The buffer * @return True if the buffer was really closed, false otherwise */ public static boolean closeBuffer(View view, Buffer buffer) { if(buffer.isDirty()) { Object[] args = { buffer.getName() }; } _closeBuffer(view,buffer); return true; } //}}} //{{{ _closeBuffer() method /** * Closes the buffer, even if it has unsaved changes. * @param view The view, may be null * @param buffer The buffer * * @exception NullPointerException if the buffer is null * * @since jEdit 2.2pre1 */ public static void _closeBuffer(View view, Buffer buffer) { if(buffer.isClosed()) { // can happen if the user presses C+w twice real // quick and the buffer has unsaved changes return; } if(!buffer.isNewFile()) { Integer _caret = (Integer)buffer.getProperty(Buffer.CARET); int caret = _caret == null ? 0 : _caret.intValue(); BufferHistory.setEntry(buffer.getPath(),caret, (Selection[])buffer.getProperty(Buffer.SELECTION), buffer.getStringProperty(JEditBuffer.ENCODING), buffer.getMode().getName()); } String path = buffer.getSymlinkPath(); if((VFSManager.getVFSForPath(path).getCapabilities() & VFS.CASE_INSENSITIVE_CAP) != 0) { path = path.toLowerCase(); } EditBus.send(new BufferUpdate(buffer,view,BufferUpdate.CLOSING)); bufferHash.remove(path); removeBufferFromList(buffer); buffer.close(); EditBus.send(new BufferUpdate(buffer,view,BufferUpdate.CLOSED)); if(jEdit.getBooleanProperty("persistentMarkers")) buffer.updateMarkersFile(view); } //}}} //{{{ closeAllBuffers() methods /** * Closes all open buffers. * @param view The view * * @return true if all buffers were closed, false otherwise */ public static boolean closeAllBuffers(View view) { return closeAllBuffers(view,false); } /** * Closes all open buffers. * @param view The view * @param isExiting This must be false unless this method is * being called by the exit() method * * @return true if all buffers were closed, false otherwise */ public static boolean closeAllBuffers(View view, boolean isExiting) { boolean dirty = false; boolean saveRecent = !(isExiting && jEdit.getBooleanProperty("restore")); Buffer buffer = buffersFirst; while(buffer != null) { if(buffer.isDirty()) { dirty = true; break; } buffer = buffer.next; } // Wait for pending I/O requests if(VFSManager.errorOccurred()) return false; // close remaining buffers (the close dialog only deals with // dirty ones) buffer = buffersFirst; // zero it here so that BufferTabs doesn't have any problems buffersFirst = buffersLast = null; bufferHash.clear(); bufferCount = 0; while(buffer != null) { if(!buffer.isNewFile() && saveRecent) { Integer _caret = (Integer)buffer.getProperty(Buffer.CARET); int caret = _caret == null ? 0 : _caret.intValue(); BufferHistory.setEntry(buffer.getPath(),caret, (Selection[])buffer.getProperty(Buffer.SELECTION), buffer.getStringProperty(JEditBuffer.ENCODING), buffer.getMode().getName()); } buffer.close(); if(jEdit.getBooleanProperty("persistentMarkers")) buffer.updateMarkersFile(view); buffer = buffer.next; } return true; } //}}} //{{{ saveAllBuffers() method /** * Saves all open buffers. * @param view The view * @since jEdit 4.2pre1 */ public static void saveAllBuffers(View view) { saveAllBuffers(view,jEdit.getBooleanProperty("confirmSaveAll")); } //}}} //{{{ saveAllBuffers() method /** * Saves all open buffers. * @param view The view * @param confirm If true, a confirmation dialog will be shown first * @since jEdit 2.7pre2 */ public static void saveAllBuffers(View view, boolean confirm) { Buffer current = view.getBuffer(); Buffer buffer = buffersFirst; while(buffer != null) { if(buffer.isDirty()) { if(buffer.isNewFile()) view.setBuffer(buffer,true); buffer.save(view,null,true,true); } buffer = buffer.next; } view.setBuffer(current,true); } //}}} //{{{ reloadAllBuffers() method /** * Reloads all open buffers. * @param view The view * @param confirm If true, a confirmation dialog will be shown first * if any buffers are dirty * @since jEdit 2.7pre2 */ public static void reloadAllBuffers(View view, boolean confirm) { boolean hasDirty = false; Buffer[] buffers = jEdit.getBuffers(); for(int i = 0; i < buffers.length && !hasDirty; i++) hasDirty = !buffers[i].isUntitled() && buffers[i].isDirty(); for(int i = 0; i < buffers.length; i++) { Buffer buffer = buffers[i]; if (buffer.isUntitled()) continue; buffer.load(view,true); } } //}}} //{{{ _getBuffer() method /** * Returns the buffer with the specified path name. The path name * must be an absolute, canonical, path. * * @param path The path name * * @return the searched buffer, or null if it is not already open * * @see MiscUtilities#constructPath(String,String) * @see MiscUtilities#resolveSymlinks(String) * @see #getBuffer(String) * * @since jEdit 4.2pre7 */ public static Buffer _getBuffer(String path) { // paths on case-insensitive filesystems are stored as lower // case in the hash. if((VFSManager.getVFSForPath(path).getCapabilities() & VFS.CASE_INSENSITIVE_CAP) != 0) { path = path.toLowerCase(); } synchronized(bufferListLock) { return bufferHash.get(path); } } //}}} //{{{ getBuffer() method /** * Returns the buffer with the specified path name. The path name * must be an absolute path. This method automatically resolves * symbolic links. If performance is critical, cache the canonical * path and call {@link #_getBuffer(String)} instead. * * @param path The path name * * @return the searched buffer, or null if it is not already open * * @see MiscUtilities#constructPath(String,String) * @see MiscUtilities#resolveSymlinks(String) */ public static Buffer getBuffer(String path) { return _getBuffer(MiscUtilities.resolveSymlinks(path)); } //}}} //{{{ getBuffers() method /** * Returns an array of open buffers. * @return an array of all open buffers */ public static Buffer[] getBuffers() { synchronized(bufferListLock) { Buffer[] buffers = new Buffer[bufferCount]; Buffer buffer = buffersFirst; for(int i = 0; i < bufferCount; i++) { buffers[i] = buffer; buffer = buffer.next; } return buffers; } } //}}} //{{{ getBufferCount() method /** * Returns the number of open buffers. */ public static int getBufferCount() { return bufferCount; } //}}} //{{{ getFirstBuffer() method /** * Returns the first buffer. */ public static Buffer getFirstBuffer() { return buffersFirst; } //}}} //{{{ getLastBuffer() method /** * Returns the last buffer. * @return the last buffer */ public static Buffer getLastBuffer() { return buffersLast; } //}}} //{{{ getPropertyManager() method /** * @return the propertyManager * @since jEdit 4.3pre15 */ public static JEditPropertyManager getPropertyManager() { return propertyManager; } //}}} //{{{ checkBufferStatus() methods /** * Checks each buffer's status on disk and shows the dialog box * informing the user that buffers changed on disk, if necessary. * @param view The view * @since jEdit 4.2pre1 */ public static void checkBufferStatus(View view) { checkBufferStatus(view,false); } /** * Checks buffer status on disk and shows the dialog box * informing the user that buffers changed on disk, if necessary. * @param view The view * @param currentBuffer indicates whether to check only the current buffer * @since jEdit 4.2pre1 */ public static void checkBufferStatus(View view, boolean currentBuffer) { // still need to call the status check even if the option is // off, so that the write protection is updated if it changes // on disk // auto reload changed buffers? boolean autoReload = getBooleanProperty("autoReload"); // the problem with this is that if we have two edit panes // looking at the same buffer and the file is reloaded both // will jump to the same location Buffer buffer; buffer = buffersFirst; int[] states = new int[bufferCount]; int i = 0; boolean notifyFileChanged = false; while(buffer != null) { if(currentBuffer && buffer != view.getBuffer()) { buffer = buffer.next; i++; continue; } states[i] = buffer.checkFileStatus(view); switch(states[i]) { case Buffer.FILE_CHANGED: if(buffer.getAutoReload()) { if(buffer.isDirty()) notifyFileChanged = true; else buffer.load(view,true); } else // no automatic reload even if general setting is true autoReload = false; // don't notify user if "do nothing" was chosen if(buffer.getAutoReloadDialog()) notifyFileChanged = true; break; case Buffer.FILE_DELETED: notifyFileChanged = true; break; } buffer = buffer.next; i++; } } //}}} //}}} //{{{ View methods //{{{ getInputHandler() method /** * Returns the current input handler (key binding to action mapping) * @see org.gjt.sp.jedit.gui.InputHandler */ public static InputHandler getInputHandler() { return inputHandler; } //}}} /* public static void newViewTest() { long time = System.currentTimeMillis(); for(int i = 0; i < 30; i++) { Buffer b = newFile(null); b.insert(0,"x"); new View(b,null,false); } System.err.println(System.currentTimeMillis() - time); } */ //{{{ newView() methods /** * Creates a new view. * @param view An existing view * @since jEdit 3.2pre2 */ public static View newView(View view) { return newView(view,null,false); } /** * Creates a new view of a buffer. * @param view An existing view * @param buffer The buffer */ public static View newView(View view, Buffer buffer) { return newView(view,buffer,false); } /** * Creates a new view of a buffer. * @param view An existing view * @param buffer The buffer * @param plainView If true, the view will not have dockable windows or * tool bars. * * @since 4.1pre2 */ public static View newView(View view, Buffer buffer, boolean plainView) { View.ViewConfig config; if(view != null && (plainView == view.isPlainView())) { config = view.getViewConfig(); config.x -= 20; config.y += 20; } else { config = new View.ViewConfig(plainView); } return newView(view,buffer,config); } /** * Creates a new view. * @param view An existing view * @param buffer A buffer to display, or null * @param config Encapsulates the view geometry, split configuration * and if the view is a plain view * @since jEdit 4.2pre1 */ public static View newView(View view, Buffer buffer, View.ViewConfig config) { return null; } //}}} //{{{ closeView() method /** * Closes a view. * * jEdit will exit if this was the last open view. */ public static void closeView(View view) { closeView(view,true); } //}}} //{{{ getViews() method /** * Returns an array of all open views. */ public static View[] getViews() { return new View[0]; } //}}} //{{{ getViewCount() method /** * Returns the number of open views. */ public static int getViewCount() { return 0; } //}}} //{{{ getFirstView() method /** * Returns the first view. */ public static View getFirstView() { return viewsFirst; } //}}} //{{{ getLastView() method /** * Returns the last view. */ public static View getLastView() { return viewsLast; } //}}} //{{{ getActiveView() method /** * Returns the currently focused view. * @since jEdit 4.1pre1 */ public static View getActiveView() { if(activeView == null) { // eg user just closed a view and didn't focus another return viewsFirst; } else return activeView; } //}}} //}}} //{{{ Miscellaneous methods //{{{ isMainThread() method /** * Returns true if the currently running thread is the main thread. * @since jEdit 4.2pre1 */ public static boolean isMainThread() { return Thread.currentThread() == mainThread; } //}}} //{{{ isBackgroundMode() method /** * Returns true if jEdit was started with the -background * command-line switch. * @since jEdit 4.0pre4 */ public static boolean isBackgroundModeEnabled() { return background; } //}}} //{{{ showMemoryStatusDialog() method /** * Performs garbage collection and displays a dialog box showing * memory status. * @param view The view * @since jEdit 4.0pre1 */ public static void showMemoryDialog(View view) { Runtime rt = Runtime.getRuntime(); int before = (int) (rt.freeMemory() / 1024); System.gc(); int after = (int) (rt.freeMemory() / 1024); int total = (int) (rt.totalMemory() / 1024); JProgressBar progress = new JProgressBar(0,total); progress.setValue(total - after); progress.setStringPainted(true); progress.setString(jEdit.getProperty("memory-status.use", new Object[] { total - after, total })); Object[] message = new Object[4]; message[0] = getProperty("memory-status.gc", new Object[] { after - before }); message[1] = Box.createVerticalStrut(12); message[2] = progress; message[3] = Box.createVerticalStrut(6); JOptionPane.showMessageDialog(view,message, jEdit.getProperty("memory-status.title"), JOptionPane.INFORMATION_MESSAGE); } //}}} //{{{ getJEditHome() method /** * Returns the jEdit install directory. */ public static String getJEditHome() { return jEditHome; } //}}} //{{{ getSettingsDirectory() method /** * Returns the path of the directory where user-specific settings * are stored. This will be null if jEdit was * started with the -nosettings command-line switch; do not * blindly use this method without checking for a null * return value first. */ public static String getSettingsDirectory() { return settingsDirectory; } //}}} //{{{ getJARCacheDirectory() method /** * Returns the directory where plugin cache files are stored. * @since jEdit 4.2pre1 */ public static String getJARCacheDirectory() { return jarCacheDirectory; } //}}} //{{{ backupSettingsFile() method /** * Backs up the specified file in the settings directory. * You should call this on any settings files your plugin * writes. * @param file The file * @since jEdit 4.0pre1 */ public static void backupSettingsFile(File file) { if(settingsDirectory == null) return; String backupDir = MiscUtilities.constructPath( settingsDirectory,"settings-backup"); File dir = new File(backupDir); if(!dir.exists()) dir.mkdirs(); // ... sweet. saveBackup() will create backupDir if it // doesn't exist. MiscUtilities.saveBackup(file,5,null,"~",backupDir); } //}}} //{{{ saveSettings() method /** * Saves all user preferences to disk. */ public static void saveSettings() { if(settingsDirectory == null) return; BufferHistory.save(); KillRing.getInstance().save(); File file1 = new File(MiscUtilities.constructPath( settingsDirectory,"#properties#save#")); File file2 = new File(MiscUtilities.constructPath( settingsDirectory,"properties")); if(file2.exists() && file2.lastModified() != propsModTime) { Log.log(Log.WARNING,jEdit.class,file2 + " changed" + " on disk; will not save user properties"); } else { backupSettingsFile(file2); try { OutputStream out = new FileOutputStream(file1); propMgr.saveUserProps(out); file2.delete(); file1.renameTo(file2); } catch(IOException io) { Log.log(Log.ERROR,jEdit.class,io); } propsModTime = file2.lastModified(); } } //}}} // {{{ createTextArea() method /** * Create a standalone TextArea. * * @return a textarea * @since 4.3pre13 */ public static TextArea createTextArea() { final TextArea textArea = TextArea._createTextArea(true, propertyManager); return textArea; } // }}} //{{{ exit() method /** * Exits cleanly from jEdit, prompting the user if any unsaved files * should be saved first. * @param view The view from which this exit was called * @param reallyExit If background mode is enabled and this parameter * is true, then jEdit will close all open views instead of exiting * entirely. */ public static void exit(View view, boolean reallyExit) { // Close dialog, view.close() call need a view... if(view == null) view = activeView; // Create a new EditorExitRequested EditorExitRequested eer = new EditorExitRequested(view); // Send EditorExitRequested EditBus.send(eer); // Check if the ExitRequest has been cancelled // if so, do not proceed anymore in the exiting if (eer.hasBeenExitCancelled()) { Log.log(Log.MESSAGE, jEdit.class, "Exit has been cancelled"); return; } // Even if reallyExit is false, we still exit properly // if background mode is off reallyExit |= !background; // Close all buffers if(!closeAllBuffers(view,reallyExit)) return; // If we are running in background mode and // reallyExit was not specified, then return here. if(!reallyExit) { // in this case, we can't directly call // view.close(); we have to call closeView() // for all open views view = viewsFirst; while(view != null) { closeView(view,false); } // Save settings in case user kills the backgrounded // jEdit process saveSettings(); } else { // Save view properties here if(view != null) { view.close(); removeViewFromList(view); } // Send EditorExiting EditBus.send(new EditorExiting(null)); // Save settings saveSettings(); // Close activity log stream Log.closeStream(); // Byebye... System.exit(0); } } //}}} //{{{ visit() method /** * Visit the views, editpanes and textareas * @param visitor the visitor * @since jEdit 4.3pre13 */ public static void visit(JEditVisitor visitor) { View view = jEdit.getFirstView(); while (view != null) { visitor.visit(view); view.visit(visitor); view = view.getNext(); } } //}}} //}}} //{{{ Package-private members //{{{ updatePosition() method /** * If buffer sorting is enabled, this repositions the buffer. */ static void updatePosition(String oldPath, Buffer buffer) { if((VFSManager.getVFSForPath(oldPath).getCapabilities() & VFS.CASE_INSENSITIVE_CAP) != 0) { oldPath = oldPath.toLowerCase(); } bufferHash.remove(oldPath); String path = buffer.getSymlinkPath(); if((VFSManager.getVFSForPath(path).getCapabilities() & VFS.CASE_INSENSITIVE_CAP) != 0) { path = path.toLowerCase(); } bufferHash.put(path,buffer); if(sortBuffers) { removeBufferFromList(buffer); addBufferToList(buffer); } } //}}} //{{{ loadMode() method /** * Loads an XML-defined edit mode from the specified reader. * @param mode The edit mode */ /* package-private */ static void loadMode(Mode mode) { Object o = mode.getProperty("file"); if (o instanceof URL) { mode.setProperty("file",((URL)o).toExternalForm().substring(5)); } final String fileName = (String)mode.getProperty("file"); XModeHandler xmh = new XModeHandler(mode.getName()) { @Override public void error(String what, Object subst) { String msg; Object line = ""; if(subst == null) msg = jEdit.getProperty("xmode-error." + what); else { msg = jEdit.getProperty("xmode-error." + what, new String[] { subst.toString() }); if(subst instanceof Throwable) Log.log(Log.ERROR,this,subst); if (subst instanceof SAXParseException) { line = ((SAXParseException)subst).getLineNumber(); } } Object[] args = { fileName, line, null, msg }; } @Override public TokenMarker getTokenMarker(String modeName) { Mode mode = getMode(modeName); if(mode == null) return null; else return mode.getTokenMarker(); } }; ModeProvider.instance.loadMode(mode, xmh); } //}}} //{{{ addPluginProps() method static void addPluginProps(Properties map) { propMgr.addPluginProps(map); } //}}} //{{{ removePluginProps() method static void removePluginProps(Properties map) { propMgr.removePluginProps(map); } //}}} //{{{ pluginError() method /** * * @param messageProp - a property of a message to print * @param args a list of arguments whch correspond to {0} and {1} in the string to print. */ static void pluginError(String path, String messageProp, Object[] args) { synchronized(pluginErrorLock) { if(startupDone) { SwingUtilities.invokeLater(new Runnable() { public void run() { showPluginErrorDialog(); } }); } } } //}}} //{{{ setActiveView() method static void setActiveView(View view) { jEdit.activeView = view; } //}}} //{{{ getActiveViewInternal() method /** * Returns the internal active view, which might be null. * * @since 4.3pre10 */ public static View getActiveViewInternal() { return activeView; } //}}} //}}} //{{{ Private members //{{{ Static variables private static String jEditHome; private static String settingsDirectory; private static String jarCacheDirectory; private static long propsModTime; private static PropertyManager propMgr; private static boolean background; private static ActionContext actionContext; private static final Object pluginErrorLock = new Object(); private static boolean saveCaret; private static InputHandler inputHandler; // buffer link list private static boolean sortBuffers; private static boolean sortByName; private static int bufferCount; private static Buffer buffersFirst; private static Buffer buffersLast; private static Map bufferHash = new HashMap(); // makes openTemporary() thread-safe private static final Object bufferListLock = new Object(); private static final Object editBusOrderingLock = new Object(); // view link list private static int viewCount; private static View viewsFirst; private static View viewsLast; private static View activeView; private static boolean startupDone; private static Thread mainThread; //}}} private jEdit() {} //{{{ usage() method private static void usage() { System.out.println("Usage: jedit [] []"); System.out.println(" +marker:: Positions caret" + " at marker "); System.out.println(" +line:: Positions caret" + " at line number "); System.out.println(" +line:,: Positions caret" + " at line number and column number "); System.out.println(" --: End of options"); System.out.println(" -background: Run in background mode"); System.out.println(" -nobackground: Disable background mode (default)"); System.out.println(" -gui: Only if running in background mode; open initial view (default)"); System.out.println(" -nogui: Only if running in background mode; don't open initial view"); System.out.println(" -log=: Log messages with level equal to or higher than this to"); System.out.println(" standard error. must be between 1 and 9. Default is 7."); System.out.println(" -newplainview: Client instance opens a new plain view"); System.out.println(" -newview: Client instance opens a new view (default)"); System.out.println(" -plugins: Load plugins (default)"); System.out.println(" -noplugins: Don't load any plugins"); System.out.println(" -restore: Restore previously open files (default)"); System.out.println(" -norestore: Don't restore previously open files"); System.out.println(" -reuseview: Client instance reuses existing view"); System.out.println(" -quit: Quit a running instance"); System.out.println(" -run=