/*
* BeanShell.java - BeanShell scripting support
* :tabSize=4:indentSize=4:noTabs=false:
* :folding=explicit:collapseFolds=1:
*
* Copyright (C) 2000, 2004 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.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import org.gjt.sp.jedit.bsh.BshMethod;
import org.gjt.sp.jedit.bsh.EvalError;
import org.gjt.sp.jedit.bsh.Interpreter;
import org.gjt.sp.jedit.bsh.NameSpace;
import org.gjt.sp.jedit.bsh.UtilEvalError;
import org.gjt.sp.jedit.gui.BeanShellErrorDialog;
import org.gjt.sp.jedit.io.VFSManager;
import org.gjt.sp.jedit.textarea.JEditTextArea;
import org.gjt.sp.jedit.textarea.Selection;
import org.gjt.sp.util.Log;
import org.gjt.sp.util.TaskManager;
//}}}
/**
* BeanShell is jEdit's extension language.<p>
*
* When run from jEdit, BeanShell code has access to the following predefined
* variables:
*
* <ul>
* <li><code>view</code> - the currently active {@link View}.</li>
* <li><code>editPane</code> - the currently active {@link EditPane}.</li>
* <li><code>textArea</code> - the edit pane's {@link JEditTextArea}.</li>
* <li><code>buffer</code> - the edit pane's {@link Buffer}.</li>
* <li><code>wm</code> - the view's {@link
* org.gjt.sp.jedit.gui.DockableWindowManager}.</li>
* <li><code>scriptPath</code> - the path name of the currently executing
* BeanShell script.</li>
* </ul>
*
* @author Slava Pestov
* @version $Id: BeanShell.java 25350 2020-07-02 06:54:09Z kpouer $
*/
public class BeanShell
{
private static final BeanShellFacade<View> bsh = new MyBeanShellFacade();
static void init()
{
Log.log(Log.MESSAGE, BeanShell.class, "Beanshell Init");
}
//{{{ evalSelection() method
/**
* Evaluates the text selected in the specified text area.
* @param view The view
* @param textArea The text area
* @since jEdit 2.7pre2
*/
public static void evalSelection(View view, JEditTextArea textArea)
{
bsh.evalSelection(view, textArea);
} //}}}
//{{{ showEvaluateDialog() method
/**
* Prompts for a BeanShell expression to evaluate.
* @param view the View
* @since jEdit 2.7pre2
*/
public static void showEvaluateDialog(View view)
{
String command = GUIUtilities.input(view,"beanshell-eval-input",null);
if(command != null)
{
if(!command.endsWith(";"))
command += ";";
int repeat = view.getInputHandler().getRepeatCount();
if(view.getMacroRecorder() != null)
{
view.getMacroRecorder().record(repeat,command);
}
Object returnValue = null;
try
{
for(int i = 0; i < repeat; i++)
{
returnValue = bsh._eval(view,bsh.getNameSpace(),command);
}
}
catch(Throwable e)
{
Log.log(Log.ERROR,BeanShell.class,e);
bsh.handleException(view,null,e);
}
if(returnValue != null)
{
String[] args = { returnValue.toString() };
GUIUtilities.message(view,"beanshell-eval",args);
}
}
} //}}}
//{{{ showEvaluateLinesDialog() method
/**
* Evaluates the specified script for each selected line.
* @param view The view
* @since jEdit 4.0pre1
*/
public static void showEvaluateLinesDialog(View view)
{
String command = GUIUtilities.input(view,"beanshell-eval-line",null);
JEditTextArea textArea = view.getTextArea();
Buffer buffer = view.getBuffer();
if(command == null || command.isEmpty())
return;
Selection[] selection = textArea.getSelection();
if(selection.length == 0)
{
javax.swing.UIManager.getLookAndFeel().provideErrorFeedback(null);
return;
}
if(!command.endsWith(";"))
command += ";";
String script = "int[] lines = textArea.getSelectedLines();\n"
+ "for(int i = 0; i < lines.length; i++)\n"
+ "{\n"
+ "line = lines[i];\n"
+ "index = line - lines[0];\n"
+ "start = buffer.getLineStartOffset(line);\n"
+ "end = buffer.getLineEndOffset(line);\n"
+ "text = buffer.getText(start,end - start - 1);\n"
+ "newText = " + command + '\n'
+ "if(newText != null)\n"
+ "{\n"
+ "buffer.remove(start,end - start - 1);\n"
+ "buffer.insert(start,String.valueOf(newText));\n"
+ "}\n"
+ "}\n";
if(view.getMacroRecorder() != null)
view.getMacroRecorder().record(1,script);
try
{
buffer.beginCompoundEdit();
bsh.eval(view,script);
}
finally
{
buffer.endCompoundEdit();
}
textArea.selectNone();
} //}}}
//{{{ runScript() method
/**
* Runs a BeanShell script. Errors are shown in a dialog box.<p>
*
* If the <code>in</code> parameter is non-null, the script is
* read from that stream; otherwise it is read from the file identified
* by <code>path</code>.<p>
*
* The <code>scriptPath</code> BeanShell variable is set to the path
* name of the script.
*
* @param view The view. Within the script, references to
* <code>buffer</code>, <code>textArea</code> and <code>editPane</code>
* are determined with reference to this parameter.
* @param path The script file's VFS path.
* @param in The reader to read the script from, or <code>null</code>.
* @param ownNamespace If set to <code>false</code>, methods and
* variables defined in the script will be available to all future
* uses of BeanShell; if set to <code>true</code>, they will be lost as
* soon as the script finishes executing. jEdit uses a value of
* <code>false</code> when running startup scripts, and a value of
* <code>true</code> when running all other macros.
*
* @since jEdit 4.0pre7
*/
public static void runScript(View view, String path, Reader in,
boolean ownNamespace)
{
try
{
_runScript(view,path,in,ownNamespace);
}
catch(Throwable e)
{
Log.log(Log.ERROR,BeanShell.class,e);
bsh.handleException(view,path,e);
}
} //}}}
//{{{ runScript() method
/**
* Runs a BeanShell script. Errors are shown in a dialog box.<p>
*
* If the <code>in</code> parameter is non-null, the script is
* read from that stream; otherwise it is read from the file identified
* by <code>path</code>.<p>
*
* The <code>scriptPath</code> BeanShell variable is set to the path
* name of the script.
*
* @param view The view. Within the script, references to
* <code>buffer</code>, <code>textArea</code> and <code>editPane</code>
* are determined with reference to this parameter.
* @param path The script file's VFS path.
* @param in The reader to read the script from, or <code>null</code>.
* @param namespace The namespace to run the script in.
*
* @since jEdit 4.2pre5
*/
public static void runScript(View view, String path, Reader in,
NameSpace namespace)
{
try
{
_runScript(view,path,in,namespace);
}
catch(Throwable e)
{
Log.log(Log.ERROR,BeanShell.class,e);
bsh.handleException(view,path,e);
}
} //}}}
//{{{ _runScript() method
/**
* Runs a BeanShell script. Errors are passed to the caller.<p>
*
* If the <code>in</code> parameter is non-null, the script is
* read from that stream; otherwise it is read from the file identified
* by <code>path</code>.<p>
*
* The <code>scriptPath</code> BeanShell variable is set to the path
* name of the script.
*
* @param view The view. Within the script, references to
* <code>buffer</code>, <code>textArea</code> and <code>editPane</code>
* are determined with reference to this parameter.
* @param path The script file's VFS path.
* @param in The reader to read the script from, or <code>null</code>.
* @param ownNamespace If set to <code>false</code>, methods and
* variables defined in the script will be available to all future
* uses of BeanShell; if set to <code>true</code>, they will be lost as
* soon as the script finishes executing. jEdit uses a value of
* <code>false</code> when running startup scripts, and a value of
* <code>true</code> when running all other macros.
* @exception Exception instances are thrown when various BeanShell errors
* occur
* @since jEdit 4.0pre7
*/
public static void _runScript(View view, String path, Reader in,
boolean ownNamespace) throws Exception
{
_runScript(view,path,in,ownNamespace
? new NameSpace(bsh.getNameSpace(),"namespace")
: bsh.getNameSpace());
} //}}}
//{{{ _runScript() method
/**
* Runs a BeanShell script. Errors are passed to the caller.<p>
*
* If the <code>in</code> parameter is non-null, the script is
* read from that stream; otherwise it is read from the file identified
* by <code>path</code>.<p>
*
* The <code>scriptPath</code> BeanShell variable is set to the path
* name of the script.
*
* @param view The view. Within the script, references to
* <code>buffer</code>, <code>textArea</code> and <code>editPane</code>
* are determined with reference to this parameter.
* @param path The script file's VFS path.
* @param in The reader to read the script from, or <code>null</code>.
* @param namespace The namespace to run the script in.
* @exception Exception instances are thrown when various BeanShell errors
* occur
* @since jEdit 4.2pre5
*/
public static void _runScript(View view, String path, Reader in,
NameSpace namespace) throws Exception
{
Log.log(Log.MESSAGE,BeanShell.class,"Running script " + path);
Interpreter interp = BeanShellFacade.createInterpreter(namespace);
try
{
if(in == null)
{
Buffer buffer = jEdit.openTemporary(null,
null,path,false);
if(!buffer.isLoaded())
TaskManager.instance.waitForIoTasks();
in = new StringReader(buffer.getText(0,
buffer.getLength()));
}
bsh.setupDefaultVariables(namespace,view);
interp.set("scriptPath",path);
running = true;
interp.eval(in,namespace,path);
}
catch(Exception e)
{
BeanShellFacade.unwrapException(e);
}
finally
{
running = false;
try
{
// no need to do this for macros!
if(namespace == bsh.getNameSpace())
{
bsh.resetDefaultVariables(namespace);
interp.unset("scriptPath");
}
}
catch(EvalError e)
{
// do nothing
}
}
} //}}}
//{{{ eval() method
/**
* Evaluates the specified BeanShell expression. Errors are reported in
* a dialog box.
* @param view The view. Within the script, references to
* <code>buffer</code>, <code>textArea</code> and <code>editPane</code>
* are determined with reference to this parameter.
* @param namespace The namespace
* @param command The expression
* @return an object
* @since jEdit 4.0pre8
*/
public static Object eval(View view, NameSpace namespace, String command)
{
return bsh.eval(view, namespace, command);
} //}}}
//{{{ _eval() method
/**
* Evaluates the specified BeanShell expression. Unlike
* <code>eval()</code>, this method passes any exceptions to the caller.
*
* @param view The view. Within the script, references to
* <code>buffer</code>, <code>textArea</code> and <code>editPane</code>
* are determined with reference to this parameter.
* @param namespace The namespace
* @param command The expression
* @return the object
* @exception Exception instances are thrown when various BeanShell
* errors occur
* @since jEdit 3.2pre7
*/
public static Object _eval(View view, NameSpace namespace, String command)
throws Exception
{
return bsh._eval(view, namespace, command);
} //}}}
//{{{ cacheBlock() method
/**
* Caches a block of code, returning a handle that can be passed to
* runCachedBlock().
* @param id An identifier. If null, a unique identifier is generated
* @param code The code
* @param namespace If true, the namespace will be set
* @return a bsh method
* @exception Exception instances are thrown when various BeanShell errors
* occur
* @since jEdit 4.1pre1
*/
public static BshMethod cacheBlock(String id, String code, boolean namespace)
throws Exception
{
return bsh.cacheBlock(id, code, namespace);
} //}}}
//{{{ runCachedBlock() method
/**
* Runs a cached block of code in the specified namespace. Faster than
* evaluating the block each time.
* @param method The method instance returned by cacheBlock()
* @param view The view
* @param namespace The namespace to run the code in
* @return an object
* @exception Exception instances are thrown when various BeanShell
* errors occur
* @since jEdit 4.1pre1
*/
public static Object runCachedBlock(BshMethod method, View view,
NameSpace namespace) throws Exception
{
return bsh.runCachedBlock(method, view, namespace);
} //}}}
//{{{ isScriptRunning() method
/**
* @return if a BeanShell script or macro is currently running.
* @since jEdit 2.7pre2
*/
public static boolean isScriptRunning()
{
return running;
} //}}}
//{{{ getNameSpace() method
/**
* @return the global namespace.
* @since jEdit 3.2pre5
*/
public static NameSpace getNameSpace()
{
return bsh.getNameSpace();
} //}}}
//{{{ Package-private members
//{{{ resetClassManager() method
/**
* Causes BeanShell internal structures to drop references to cached
* Class instances.
*/
static void resetClassManager()
{
bsh.resetClassManager();
} //}}}
//}}}
//{{{ Private members
//{{{ Static variables
private static boolean running;
//}}}
//}}}
/**
* The BeanshellFacade that is used by jEdit.
*/
private static class MyBeanShellFacade extends BeanShellFacade<View>
{
private MyBeanShellFacade()
{
classManager.setClassLoader(new JARClassLoader());
}
@Override
protected void init()
{
super.init();
global.importPackage("org.gjt.sp.jedit.browser");
global.importPackage("org.gjt.sp.jedit.bufferset");
global.importPackage("org.gjt.sp.jedit.statusbar");
global.importPackage("org.gjt.sp.jedit.gui");
global.importPackage("org.gjt.sp.jedit.help");
global.importPackage("org.gjt.sp.jedit.io");
global.importPackage("org.gjt.sp.jedit.menu");
global.importPackage("org.gjt.sp.jedit.msg");
global.importPackage("org.gjt.sp.jedit.options");
global.importPackage("org.gjt.sp.jedit.pluginmgr");
global.importPackage("org.gjt.sp.jedit.print");
global.importPackage("org.gjt.sp.jedit.search");
global.importPackage("org.jedit.io");
}
@Override
protected void setupDefaultVariables(NameSpace namespace, View view) throws UtilEvalError
{
if(view != null)
{
EditPane editPane = view.getEditPane();
setVariable(namespace, "view", view);
setVariable(namespace, "editPane",editPane);
setVariable(namespace, "buffer",editPane.getBuffer());
setVariable(namespace, "textArea",editPane.getTextArea());
setVariable(namespace, "wm",view.getDockableWindowManager());
}
}
@Override
protected void resetDefaultVariables(NameSpace namespace) throws UtilEvalError
{
namespace.setVariable("view",null, false);
namespace.setVariable("editPane",null, false);
namespace.setVariable("buffer",null, false);
namespace.setVariable("textArea",null, false);
namespace.setVariable("wm",null, false);
}
@Override
protected void handleException(View view, String path, Throwable t)
{
if(t instanceof IOException)
{
VFSManager.error(view,path,"ioerror.read-error",
new String[] { t.toString() });
}
else
new BeanShellErrorDialog(view,t);
}
}
}
¤ Dauer der Verarbeitung: 0.19 Sekunden
(vorverarbeitet)
¤
|
Haftungshinweis
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.
|