PageRenderTime 136ms CodeModel.GetById 122ms app.highlight 6ms RepoModel.GetById 0ms app.codeStats 1ms

/jEdit/tags/jedit-4-2-pre14/doc/users-guide/macro-basics.xml

#
XML | 785 lines | 673 code | 96 blank | 16 comment | 0 complexity | deae384049c2c37915f33fc8f8fb3b6c MD5 | raw file
  1<!-- jEdit 4.0 Macro Guide, (C) 2001, 2002 John Gellene          -->
  2<!--                                                             -->
  3<!-- jEdit buffer-local properties:                              -->
  4<!-- :indentSize=1:noTabs=yes:maxLineLen=72:tabSize=2:           -->
  5<!-- :xml.root=users-guide.xml:                                  -->
  6<!--                                                             -->
  7<!-- This file cover the introductory section of the macro guide -->
  8<!-- $Id: macro-basics.xml 4992 2004-03-17 05:15:52Z spestov $
  9 -->
 10
 11<chapter id="macro-basics"><title>Macro Basics</title>
 12
 13 <sect1 id="beanshell-intro"><title>Introducing BeanShell</title>
 14
 15  <para>
 16   Here is how BeanShell's author, Pat Niemeyer, describes his creation:
 17  </para>
 18
 19  <blockquote>
 20   <para>
 21    <quote>BeanShell is a small, free, embeddable, Java source
 22    interpreter with object scripting language features, written in
 23    Java. BeanShell executes standard Java statements and
 24    expressions, in addition to obvious scripting commands and
 25    syntax. BeanShell supports scripted objects as simple method
 26    closures like those in Perl and JavaScript.</quote>
 27   </para>
 28  </blockquote>
 29
 30  <para>
 31   You do not have to know anything about Java to begin writing your own
 32   jEdit macros. But if you know how to program in Java, you already know
 33   how to write BeanShell scripts.  The major strength of using
 34   BeanShell with a program written in Java is that it allows the user to
 35   customize the program's behavior using the same interfaces
 36   designed and used by the program itself. BeanShell can
 37   turn a well-designed application into a powerful, extensible toolkit.
 38  </para>
 39
 40  <para>
 41   This guide focuses on using BeanShell in macros. If you are interested
 42   in learning more about BeanShell generally, consult the <ulink
 43   url="http://www.beanshell.org">BeanShell web site</ulink>. Information
 44   on how to run and organize macros, whether included with the jEdit
 45   installation or written by you, can be found in
 46   <xref linkend="using-macros"/>.
 47  </para>
 48
 49 </sect1>
 50
 51 <sect1 id="single-macros"><title>Single Execution Macros</title>
 52  <para>
 53   As noted in <xref linkend="organizing-macros" />, you can save a BeanShell
 54   script of any length as a text file with the <filename>.bsh</filename>
 55   extension and run it from the <guimenu>Macros</guimenu> menu.
 56   There are three other ways jEdit lets you use BeanShell quickly,
 57   without saving a script to storage, on a <quote>one time only</quote>
 58   basis. You will find them in the <guimenu>Utilities</guimenu> menu.
 59  </para>
 60
 61  <para>
 62   <guimenu>Utilities</guimenu>&gt;<guisubmenu>BeanShell</guisubmenu>&gt;<guimenuitem>Evaluate BeanShell
 63   Expression</guimenuitem> displays a text input dialog
 64   that asks you to type a single line of BeanShell commands. You can type
 65   more than one BeanShell statement so long as each of them ends with a
 66   semicolon. If BeanShell successfully interprets your input, a message
 67   box will appear with the return value of the last statement.
 68  </para>
 69
 70  <para>
 71   <guimenu>Utilities</guimenu>&gt;<guisubmenu>BeanShell</guisubmenu>&gt;<guimenuitem>Evaluate For Selected
 72   Lines</guimenuitem> displays a text input dialog that asks you to
 73   type a single line of BeanShell commands. The commands are evaluated
 74   for each line of the selection. In addition to the standard set of
 75   variables described in <xref linkend="predefined-variables" />,
 76   this command defines the following:
 77  </para>
 78
 79  <itemizedlist>
 80   <listitem><para><varname>line</varname> - the line number, from the
 81   start of the buffer. The first line is numbered 0.
 82   </para></listitem>
 83   <listitem><para><varname>index</varname> - the line number, from the
 84   start of the selection. The first line is numbered 0.
 85   </para></listitem>
 86   <listitem><para><varname>text</varname> - the text of the line.
 87   </para></listitem>
 88  </itemizedlist>
 89
 90  <informalexample>
 91   <para>
 92    Try typing an expression like <userinput>(line + 1) + ": " + text</userinput>
 93    in the <guimenuitem>Evaluate For Selected Lines</guimenuitem> dialog
 94    box. This will add a line number to each selected line beginning with
 95    the number <userinput>1</userinput>.
 96   </para>
 97  </informalexample>
 98
 99  <para>
100    The BeanShell expression you enter will be evaluated and substituted in place of
101    the entire text of a selected line.  If you want to leave the line's current
102    text as an element of the modified line, you must include the defined variable
103    <userinput>text</userinput> as part of the BeanShell expression that you enter.
104  </para>
105
106  <para>
107   <guimenu>Utilities</guimenu>&gt;<guisubmenu>BeanShell</guisubmenu>&gt;<guimenuitem>Evaluate Selection</guimenuitem>
108   evaluates the selected text as a BeanShell script and
109   replaces it with the return value of the statement.
110  </para>
111
112  <para>
113    Using <guimenuitem>Evaluate Selection</guimenuitem> is an
114    easy way to do arithmetic calculations inline while editing. BeanShell
115    uses numbers and arithmetic operations in an ordinary, intuitive way.
116  </para>
117
118  <informalexample>
119   <para>
120    Try typing an expression like <userinput>(3745*856)+74</userinput>
121    in the buffer, select it, and choose
122    <guimenu>Utilities</guimenu>&gt;<guisubmenu>BeanShell</guisubmenu>&gt;<guimenuitem>Evaluate
123    Selection</guimenuitem>. The selected text will be replaced by the
124    answer, <userinput>3205794</userinput>.
125
126    <!-- Irrelevant? -->
127    <!-- Since this is a text file
128    and not a spreadsheet, the original values that BeanShell evaluated are
129    not retained or saved as part of the buffer's contents. -->
130   </para>
131  </informalexample>
132
133  <sidebar><title>Console plugin</title>
134   <para>
135    You can also do
136    the same thing using the BeanShell interpreter option of the
137    <application>Console</application> plugin.
138   </para>
139  </sidebar>
140
141 </sect1>
142
143 <sect1 id="first-example" ><title>The Mandatory First Example</title>
144  <informalexample><!-- <title>A first one-line macro</title> -->
145   <programlisting>Macros.message(view, "Hello world!");</programlisting>
146  </informalexample>
147  <para>
148   Running this one line script causes jEdit to display a message
149   box (more precisely, a <classname>JOptionPane</classname> object) with
150   the traditional beginner's message and an <guilabel>OK</guilabel> button.
151   Let's see what is happening here.
152  </para>
153  <para>
154   This statement calls a static method (or function) named
155   <function>message</function> in jEdit's <ulink
156		url="../api/org/gjt/sp/jedit/Macros.html">Macros</ulink>
157   class. If you don't know anything about classes or static methods or
158   Java (or C++, which employs the same concept), you will need to gain
159   some understanding of a few terms. Obviously this is not the place for
160   academic precision, but if you are entirely new to object-oriented
161   programming, here are a few skeleton ideas to help you with BeanShell.
162  </para>
163  <itemizedlist>
164   <listitem>
165    <para>
166     An <glossterm>object</glossterm> is a collection of data that can be
167     initialized, accessed and manipulated in certain defined ways.
168    </para>
169   </listitem>
170
171   <listitem>
172    <para>
173     A <glossterm>class</glossterm> is a specification of what data an object
174     contains and what methods can be used to work with the data. A Java
175     application consists of one or more classes (in the case of jEdit ,over
176     600 classes) written by the programmer that defines the application's
177     behavior. A BeanShell macro uses these classes, along with built-in
178     classes that are supplied with the Java platform, to define its own
179     behavior.
180    </para>
181   </listitem>
182
183   <listitem>
184    <para>
185     A <glossterm>subclass</glossterm> (or child class) is a class which
186     uses (or <quote>inherits</quote>) the data and methods of its parent
187     class along with additions or modifications that alter the subclass's
188     behavior.  Classes are typically organized in hierarchies of parent
189     and child classes to organize program code, to define common
190     behavior in shared parent class code, and to specify the types of
191     similar behavior that child classes will perform in their own specific ways.
192    </para>
193   </listitem>
194
195   <listitem>
196    <para>
197     A <glossterm>method</glossterm> (or function) is a procedure that works
198     with data in a particular object, other data (including other objects)
199     supplied as <glossterm>parameters</glossterm>, or both. Methods
200     typically are applied to a particular object which is an
201     <glossterm>instance</glossterm> of the class to which the method
202     belongs.
203    </para>
204   </listitem>
205
206   <listitem>
207    <para>
208     A <glossterm>static method</glossterm> differs from other methods
209     in that it does not deal with the data in a particular object but is
210     included within a class for the sake of convenience.
211    </para>
212   </listitem>
213
214  </itemizedlist>
215
216  <para>
217   Java has a rich set of classes defined as part of the Java platform.
218   Like all Java applications, jEdit is organized as a set of classes that
219   are themselves derived from the Java platform's classes. We will refer
220   to <firstterm>Java classes</firstterm> and <firstterm>jEdit
221   classes</firstterm> to make this distinction. Some of jEdit's classes
222   (such as those dealing with regular expressions and XML) are derived
223   from or make use of classes in other open-source Java packages. Except
224   for BeanShell itself, we won't be discussing them in this guide.
225  </para>
226
227  <para>
228   In our one line script, the static method
229   <function>Macros.message()</function> has two parameters because that is
230   the way the method is defined in the <ulink url="../api/org/gjt/sp/jedit/Macros.html">Macros</ulink>
231   class. You must specify both parameters when you call the function. The
232   first parameter, <parameter>view</parameter>, is a variable naming
233   the current, active <ulink url="../api/org/gjt/sp/jedit/View.html">View</ulink> object. Information
234   about pre-defined variables can be found in <xref linkend="predefined-variables" />.
235  </para>
236
237  <para>
238   The second parameter, which appears to be quoted text, is a
239   <glossterm>string literal</glossterm> - a sequence of characters of
240   fixed length and content. Behind the scenes, BeanShell and Java take
241   this string literal and use it to create a <classname>String</classname>
242   object. Normally, if you want to create an object in Java or BeanShell,
243   you must construct the object using the <function>new</function> keyword
244   and a <firstterm>constructor</firstterm> method that is part of the
245   object's class. We'll show an example of that later. However, both Java
246   and BeanShell let you use a string literal anytime a method's parameter
247   calls for a <classname>String</classname>.
248  </para>
249
250  <para>
251   If you are a Java programmer, you might wonder about a few things
252   missing from this one line program. There is no class definition, for
253   example. You can think of a BeanShell script as an implicit definition
254   of a <function>main()</function> method in an anonymous class. That is
255   in fact how BeanShell is implemented; the class is derived from
256   a BeanShell class called <ulink url="../api/bsh/XThis.html">XThis</ulink>. If you
257   don't find that helpful, just think of a script as one or more blocks of
258   procedural statements conforming to Java syntax rules. You will also get
259   along fine (for the most part) with C or C++ syntax if you leave out
260   anything to do with pointers or memory management - Java and BeanShell
261   do not have pointers and deal with memory management automatically.
262  </para>
263
264  <para>
265    Another missing item from a Java perspective is a
266    <function>package</function> statement. In Java, such a statement is
267    used to bundle together a number of files so that their classes become
268    visible to one another. Packages are not part of BeanShell,
269    and you don't need to know anything about them to write
270    BeanShell macros.
271  </para>
272
273  <para>
274    Finally, there are no <function>import</function> statements in this
275    script. In Java, an <function>import</function> statement makes public
276    classes from other packages visible within the file in which the
277    statement occurs without having to specify a fully
278    qualified class name. Without an import statement or a fully qualified
279    name, Java cannot identify most classes using a single name as an identifier.
280  </para>
281
282  <para>
283   jEdit automatically imports a number of commonly-used packages into the
284   namespace of every BeanShell script. Because of this, the script output
285   of a recorded macro does not contain <function>import</function>
286   statements. For the same reason, most BeanShell scripts you write will
287   not require <function>import</function> statements.
288  </para>
289
290  <para>
291    Java requires <literal>import</literal> statement to be located
292    at the beginning of a source file. BeanShell allows you to place
293    <literal>import</literal>
294    statements anywhere in a script, including inside a block of
295    statements. The <literal>import</literal> statement will cover all names
296    used following the statement in the enclosing block.
297  </para>
298
299  <para>
300    If you try to use a class that is not imported without its
301    fully-qualified name, the BeanShell interpreter will complain with an
302    error message relating to the offending line of code.
303  </para>
304
305  <sidebar>
306   <para>
307    Here is the full list of packages automatically imported by jEdit:
308   </para>
309   <programlisting>java.awt
310java.awt.event
311java.net
312java.util
313java.io
314java.lang
315javax.swing
316javax.swing.event
317org.gjt.sp.jedit
318org.gjt.sp.jedit.browser
319org.gjt.sp.jedit.buffer
320org.gjt.sp.jedit.gui
321org.gjt.sp.jedit.help
322org.gjt.sp.jedit.io
323org.gjt.sp.jedit.msg
324org.gjt.sp.jedit.options
325org.gjt.sp.jedit.pluginmgr
326org.gjt.sp.jedit.print
327org.gjt.sp.jedit.search
328org.gjt.sp.jedit.syntax
329org.gjt.sp.jedit.textarea
330org.gjt.sp.util</programlisting>
331  </sidebar>
332 </sect1>
333
334 <sect1 id="predefined-variables"><title>Predefined Variables in BeanShell</title>
335
336  <para>
337   The following variables are always available for use in
338   BeanShell scripts:
339  </para>
340
341  <itemizedlist>
342   <listitem><para><varname>buffer</varname> -
343    a <ulink url="../api/org/gjt/sp/jedit/Buffer.html">Buffer</ulink> object represents the contents of the currently visible open text
344    file.
345   </para></listitem>
346   <listitem><para><varname>view</varname> -
347   A <ulink url="../api/org/gjt/sp/jedit/View.html">View</ulink>
348   represents the current top-level editor window, extending Java's <classname>JFrame</classname>
349   class, that
350   contains the various visible components of the program, including the
351   text area, menu bar, toolbar, and any docked windows.
352   </para>
353   <para>
354   This variable has the same value as the return value of:
355   </para>
356   <programlisting>jEdit.getActiveView()</programlisting>
357   </listitem>
358   <listitem><para><varname>editPane</varname> -
359    an <ulink url="../api/org/gjt/sp/jedit/EditPane.html">EditPane</ulink> object contains a text area and
360    buffer switcher. A view can be split to display edit panes. Among other things, the
361    <ulink url="../api/org/gjt/sp/jedit/EditPane.html">EditPane</ulink> class contains methods for selecting
362    the buffer to edit.
363   </para>
364   <para>
365    Most of the time your macros will manipulate the <varname>buffer</varname>
366    or the <varname>textArea</varname>. Sometimes you will need to use
367    <varname>view</varname> as a parameter in a method call. You will probably
368    only need to use <varname>editPane</varname> if your macros work with
369    split views.
370   </para>
371   <para>
372   This variable has the same value as the return value of:
373   </para>
374   <programlisting>view.getEditPane()</programlisting>
375   </listitem>
376   <listitem><para><varname>textArea</varname> -
377    a <ulink url="../api/org/gjt/sp/jedit/textarea/JEditTextArea.html">JEditTextArea</ulink> is the visible component that
378    displays the current buffer.
379   </para>
380   <para>
381   This variable has the same value as the return value of:
382   </para>
383   <programlisting>editPane.getTextArea()</programlisting></listitem>
384   
385   <listitem><para><varname>wm</varname> -
386    a <ulink url="../api/org/gjt/sp/jedit/gui/DockableWindowManager.html">DockableWindowManager</ulink> is the visible component that
387    manages dockable windows in the current view. This class is discussed in detail in <xref linkend="writing-plugins-part"/>. This object is useful for writing macros that interface with, open, or close plugin windows.
388   </para>
389   <para>
390   This variable has the same value the return value of:
391   </para>
392   <programlisting>view.getDockableWindowManager()</programlisting></listitem>
393   <listitem><para><varname>scriptPath</varname> - set to the full path
394   of the script currently being executed.
395   </para></listitem>
396   <listitem><para><varname>scriptPath</varname> - set to the full path
397   of the script currently being executed.
398   </para></listitem>
399  </itemizedlist>
400
401  <para>
402   Note that these variables are set at the beginning of macro
403   execution. If the macro switches views, buffers or edit panes,
404   the variable values will be out of date. In that case, you can use
405   the equivalent method calls.
406  </para>
407
408 </sect1>
409
410 <sect1 id="helpful-methods"><title>Helpful Methods in the
411  Macros Class</title>
412
413  <para>
414   Including <function>message()</function>, there are five static methods
415   in the <ulink url="../api/org/gjt/sp/jedit/Macros.html">Macros</ulink> class that allow you to converse
416   easily with your macros. They all encapsulate calls to methods of the
417   Java platform's <classname>JOptionPane</classname> class.
418  </para>
419
420  <itemizedlist>
421
422    <listitem>
423      <funcsynopsis>
424         <funcprototype>
425           <funcdef>public static void <function>message</function></funcdef>
426           <paramdef>Component <parameter>comp</parameter></paramdef>
427           <paramdef>String <parameter>message</parameter></paramdef>
428         </funcprototype>
429       </funcsynopsis>
430     </listitem>
431
432     <listitem>
433       <funcsynopsis>
434         <funcprototype>
435          <funcdef>public static void <function>error</function></funcdef>
436          <paramdef>Component <parameter>comp</parameter></paramdef>
437          <paramdef>String <parameter>message</parameter></paramdef>
438         </funcprototype>
439       </funcsynopsis>
440     </listitem>
441
442     <listitem>
443      <funcsynopsis>
444        <funcprototype>
445          <funcdef>public static String <function>input</function></funcdef>
446          <paramdef>Component <parameter>comp</parameter></paramdef>
447          <paramdef>String <parameter>prompt</parameter></paramdef>
448        </funcprototype>
449      </funcsynopsis>
450     </listitem>
451
452     <listitem>
453      <funcsynopsis>
454        <funcprototype>
455          <funcdef>public static String <function>input</function></funcdef>
456          <paramdef>Component <parameter>comp</parameter></paramdef>
457          <paramdef>String <parameter>prompt</parameter></paramdef>
458          <paramdef>String <parameter>defaultValue</parameter></paramdef>
459        </funcprototype>
460      </funcsynopsis>
461     </listitem>
462
463     <listitem>
464      <funcsynopsis>
465        <funcprototype>
466          <funcdef>public static int <function>confirm</function></funcdef>
467          <paramdef>Component <parameter>comp</parameter></paramdef>
468          <paramdef>String <parameter>prompt</parameter></paramdef>
469          <paramdef>int <parameter>buttons</parameter></paramdef>
470        </funcprototype>
471      </funcsynopsis>
472     </listitem>
473
474  </itemizedlist>
475
476  <para>
477    The format of these four <glossterm>declarations</glossterm> provides a
478    concise reference to the way in which the methods may be used. The
479    keyword <function>public</function> means that the method can be used
480    outside the <ulink url="../api/org/gjt/sp/jedit/Macros.html">Macros</ulink> class. The alternatives are
481    <function>private</function> and <function>protected</function>. For
482    purposes of BeanShell, you just have to know that BeanShell can only use
483    public methods of other Java classes. The keyword
484    <function>static</function> we have already discussed. It means that the
485    method does not operate on a particular object. You call a static
486    function using the name of the class (like
487    <ulink url="../api/org/gjt/sp/jedit/Macros.html">Macros</ulink>) rather than the name of a particular
488    object (like <varname>view</varname>). The third word is the type of the
489    value returned by the method. The keyword <function>void</function> is
490    Java's way of saying the the method does not have a return value.
491  </para>
492
493  <para>
494   The <function>error()</function> method works just like
495   <function>message()</function> but displays an error icon in the message
496   box. The <function>input()</function> method furnishes a text field for
497   input, an <guilabel>OK</guilabel> button and a
498   <guilabel>Cancel</guilabel> button. If <guilabel>Cancel</guilabel> is pressed,
499   the method returns <constant>null</constant>. If <guilabel>OK</guilabel>
500   is pressed, a <classname>String</classname> containing the contents of
501   the text field is returned. Note that there are two forms of the
502   <function>input()</function> method; the first form with two parameters
503   displays an empty input field, the other forms lets you specify an initial,
504   default input value.
505  </para>
506
507  <para>
508   For those without Java experience, it is important to know that
509   <constant>null</constant> is <emphasis>not</emphasis> the same as an
510   empty, <quote>zero-length</quote> <classname>String</classname>. It is
511   Java's way of saying that there is no object associated with this
512   variable. Whenever you seek to use a return value from
513   <function>input()</function> in your macro, you should test it to see if
514   it is <constant>null</constant>. In most cases, you will
515   want to exit gracefully from the script with a
516   <function>return</function> statement, because the presence of a null
517   value for an input variable usually means that the user intended to
518   cancel macro execution. BeanShell will complain if you call any
519   methods on a <constant>null</constant> object.
520  </para>
521
522  <para>
523   The <function>confirm()</function> method in the
524   <ulink url="../api/org/gjt/sp/jedit/Macros.html">Macros</ulink> class is a little more complex. The
525   <varname>buttons</varname> parameter has an <classname>int</classname>
526   type, and the usual way to supply a value is to use one of
527   the predefined values taken from Java's
528   <classname>JOptionPane</classname> class. You can choose among
529   <constant>JOptionPane.YES_NO_OPTION</constant>,
530   <constant>JOptionPane.YES_NO_CANCEL_OPTION</constant>, or
531   <constant>JOptionPane.OK_CANCEL_OPTION</constant>. The return
532   value of the method is also an <classname>int</classname>, and should be tested
533   against the value of other predefined constants:
534   <constant>JOptionPane.YES_OPTION</constant>,
535   <constant>JOptionPane.NO_OPTION</constant>,
536   <constant>JOptionPane.OK_OPTION</constant> or
537   <constant>JOptionPane.CANCEL_OPTION</constant>.
538  </para>
539
540  <para>
541   We've looked at using <function>Macros.message()</function>. To
542   use the other methods, you would write something like the
543   following:
544  </para>
545
546  <informalexample><!-- <title>Using <function>Macros.error()</function> and
547  <function>Macros.input()</function></title> -->
548   <programlisting>Macros.error(view, "Goodbye, cruel world!");
549
550String result = Macros.input(view, "Type something here.");
551
552String result = Macros.input(view, "When were you born?",
553    "I don't remember, I was very young at the time");
554
555int result = Macros.confirm("Do you really want to learn"
556    + " about BeanShell?",JOptionPane.YES_NO_OPTION);
557    </programlisting>
558  </informalexample>
559
560  <para>
561    In the last three examples, placing the word <classname>String</classname>
562    or <classname>int</classname>
563    before the variable name <varname>result</varname> tells BeanShell that
564    the variable refers to an integer or a <classname>String</classname> object, even
565    before a particular value is assigned to the variable.
566    In BeanShell, this <glossterm>declaration</glossterm> of the
567    <glossterm>type</glossterm> of <varname>result</varname> is not
568    necessary; BeanShell can figure it out when the macro runs. This can be
569    helpful if you are not comfortable with specifying types and classes;
570    just use your variables and let BeanShell worry about it.
571  </para>
572
573  <para>
574   Note that macros are not limited to using these methods for presenting a user interface. In fact, full-blown user interfaces using the Java Swing APIs are also possible, and will be covered later on in <xref linkend="dialog-macro"/>.
575  </para>
576
577  </sect1>
578
579  <sect1 id="dynamic-typing"><title>BeanShell Dynamic Typing</title>
580
581  <para>
582    Without an explicit <glossterm>type declaration</glossterm> like
583    <classname>String</classname> <varname>result</varname>, BeanShell
584    variables can change their type at runtime depending on the object or
585    data assigned to it. This dynamic typing allows you to write code like
586    this (if you really wanted to):
587  </para>
588
589  <informalexample><!-- <title>Dynamic typing of variables</title> -->
590   <programlisting>// note: no type declaration
591result = Macros.input(view, <quote>Type something here.</quote>);
592
593// this is our predefined, current View
594result = view;
595
596// this is an <quote>int</quote> (for integer);
597// in Java and BeanShell, int is one of a small number
598// of <quote>primitive</quote> data types which are not classes
599result = 14;</programlisting>
600  </informalexample>
601
602  <para>
603    However, if you first declared <varname>result</varname> to be type
604    <classname>String</classname> and and then tried these reassignments,
605    BeanShell would complain. While avoiding explicit type declaration makes
606    writing macro code simpler, using them can act as a check to make sure you are
607    not using the wrong variable type of object at a later point in your
608    script. It also makes it easier (if you are so inclined) to take a
609    BeanShell <quote>prototype</quote> and incorporate it in a Java program.
610  </para>
611
612  <para>
613    One last thing before we bury our first macro. The double slashes in the
614    examples just above signify that everything following them on that line
615    should be ignored by BeanShell as a comment. As in Java and C/C++, you
616    can also embed comments in your BeanShell code by setting them off with
617    pairs of <userinput>/* */</userinput>, as in the following example:
618  </para>
619
620
621  <informalexample>
622   <programlisting>/* This is a long comment that covers several lines
623and will be totally ignored by BeanShell regardless of how
624many lines it covers */</programlisting>
625  </informalexample>
626 </sect1>
627
628 <sect1 id="something-useful"><title>Now For Something Useful</title>
629
630  <para>
631    Here is a macro that inserts the path of the current buffer in
632    the text:
633  </para>
634
635
636  <informalexample>
637  <!-- <title>Insert buffer path in text</title> -->
638   <programlisting>String newText = buffer.getPath();
639textArea.setSelectedText(newText);</programlisting>
640  </informalexample>
641
642  <para>
643    Unlike in our first macro example, here we are calling class methods on
644    particular objects. First, we call <function>getPath()</function> on the
645    current <ulink url="../api/org/gjt/sp/jedit/Buffer.html">Buffer</ulink> object to get the full path of the
646    text file currently being edited. Next, we call
647    <function>setSelectedText()</function> on the current text display
648    component, specifying the text to be inserted as a parameter.
649  </para>
650
651  <para>
652    In precise terms, the <function>setSelectedText()</function> method
653    substitutes the contents of the <classname>String</classname>
654    parameter for a range of selected text that includes the current caret
655    position. If no text is selected at the caret position, the effect
656    of this operation is simply to insert the new text at that position.
657  </para>
658
659  <para>
660    Here's a few alternatives to the full file path that you could
661    use to insert various useful things:
662  </para>
663
664
665  <informalexample><!-- <title>Items to use with
666  <function>setSelectedText()</function></title> -->
667<programlisting>// the file name (without full path)
668String newText = buffer.getName();
669
670// today's date
671import java.text.DateFormat;
672
673String newText = DateFormat.getDateInstance()
674    .format(new Date());
675
676// a line count for the current buffer
677String newText = "This file contains "
678    + textArea.getLineCount() + " lines.";</programlisting>
679</informalexample>
680
681  <para>
682    Here are brief comments on each:
683  </para>
684
685  <itemizedlist>
686   <listitem>
687    <para>
688      In the first, the call to <function>getName()</function> invokes
689      another method of the <ulink url="../api/org/gjt/sp/jedit/Buffer.html">Buffer</ulink> class.
690    </para>
691   </listitem>
692
693   <listitem>
694    <para>
695      The syntax of the second example chains the results of
696      several methods. You could write it this way:
697    </para>
698
699<programlisting>import java.text.DateFormat;
700Date d = new Date();
701DateFormat df = DateFormat.getDateInstance();
702String result = df.format(d);
703</programlisting>
704
705   <para>
706	  Taking the pieces in order:
707   </para>
708
709   <itemizedlist>
710	   <listitem>
711	     <para>
712         A Java <classname>Date</classname> object is created using the
713         <function>new</function> keyword. The empty parenthesis after
714         <classname>Date</classname> signify a call on the <glossterm>
715         constructor method</glossterm> of <classname>Date</classname> having no
716         parameters; here, a <classname>Date</classname> is created representing
717         the current date and time.
718       </para>
719	   </listitem>
720
721	   <listitem>
722	     <para>
723         <function>DateFormat.getDateInstance()</function> is a static method
724         that creates and returns a <classname>DateFormat</classname> object. As
725         the name implies, <classname>DateFormat</classname> is a Java class
726         that takes <classname>Date</classname> objects and produces readable
727         text. The method <function>getDateInstance()</function> returns a
728         <classname>DateFormat</classname> object that parses and formats dates.
729         It will use the default <glossterm>locale</glossterm> or text format
730         specified in the user's Java installation.
731       </para>
732	  </listitem>
733
734	  <listitem>
735	    <para>
736        Finally, <classname>DateFormat.format()</classname> is called on the
737        new <classname>DateFormat</classname> object using the
738        <classname>Date</classname> object as a parameter. The result is a
739        <classname>String</classname> containing the date in the default
740        locale.
741      </para>
742	  </listitem>
743
744    <listitem>
745      <para>
746        Note that the <classname>Date</classname> class is contained in
747        the <literal>java.util</literal> package, so an explicit import
748        statement is not required. However, <classname>DateFormat</classname>
749        is part of the <literal>java.text</literal> package, which is
750        not automatically imported, so an explicit
751        <function>import</function> statement must be used.
752      </para>
753    </listitem>
754	</itemizedlist>
755
756   </listitem>
757
758   <listitem>
759    <para>
760    The third example shows three items of note:
761	 <itemizedlist>
762	  <listitem>
763	   <para>
764       <function>getLineCount()</function> is a method in jEdit's
765       <ulink url="../api/org/gjt/sp/jedit/textarea/JEditTextArea.html">JEditTextArea</ulink> class. It returns an
766       <classname>int</classname> representing the number of lines in the
767       current text buffer. We call it on <varname>textArea</varname>, the
768       pre-defined, current <ulink url="../api/org/gjt/sp/jedit/textarea/JEditTextArea.html">JEditTextArea</ulink> object.
769      </para>
770	  </listitem>
771
772	  <listitem>
773	   <para>
774       The use of the <function>+</function> operator (which can be chained,
775       as here) appends objects and string
776       literals to return a single, concatenated <classname>String</classname>.
777       </para>
778	  </listitem>
779	 </itemizedlist>
780   </para>
781   </listitem>
782  </itemizedlist>
783 </sect1>
784
785</chapter>