PageRenderTime 111ms CodeModel.GetById 66ms app.highlight 19ms RepoModel.GetById 9ms app.codeStats 1ms

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

#
XML | 781 lines | 670 code | 95 blank | 16 comment | 0 complexity | 17b26e7a05005f715dceb9e9f9a554ed 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 4777 2003-06-11 23:55:39Z 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 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 an open text
344    file. The variable <varname>buffer</varname> is predefined as the
345    current, visible buffer being edited.
346   </para></listitem>
347   <listitem><para><varname>view</varname> -
348   A <ulink url="../api/org/gjt/sp/jedit/View.html">View</ulink>
349   represents a top-level window, extending Java's <classname>JFrame</classname>
350   class, that
351   contains the various visible components of the program, including the
352   text area, menu bar, toolbar, and any docked windows.
353   The variable <varname>view</varname> is defined
354   as the current, active <ulink url="../api/org/gjt/sp/jedit/View.html">View</ulink> object.
355   </para>
356   <para>
357   This variable has the same value as calling:
358   </para>
359   <programlisting>jEdit.getActiveView()</programlisting>
360   </listitem>
361   <listitem><para><varname>editPane</varname> -
362    an <ulink url="../api/org/gjt/sp/jedit/EditPane.html">EditPane</ulink> object contains a text area and
363    buffer switcher. A view can be split to display multiple
364    buffers, each in its own edit pane. Among other things, the
365    <ulink url="../api/org/gjt/sp/jedit/EditPane.html">EditPane</ulink> class contains methods for selecting
366    the buffer to edit.
367   </para>
368   <para>
369    Most of the time your macros will manipulate the <varname>buffer</varname>
370    or the <varname>textArea</varname>. Sometimes you will need to use
371    <varname>view</varname> as a parameter in a method call. You will probably
372    only need to use <varname>editPane</varname> if your macros work with
373    split views.
374   </para>
375   <para>
376   This variable has the same value as calling:
377   </para>
378   <programlisting>view.getEditPane()</programlisting>
379   </listitem>
380   <listitem><para><varname>textArea</varname> -
381    a <ulink url="../api/org/gjt/sp/jedit/textarea/JEditTextArea.html">JEditTextArea</ulink> is the visible component that
382    displays the file being edited. It is derived from the
383    <classname>JComponent</classname> class. The variable
384    <varname>textArea</varname> represents the current
385    <ulink url="../api/org/gjt/sp/jedit/textarea/JEditTextArea.html">JEditTextArea</ulink> object, which in turn displays
386    the current buffer.
387   </para>
388   <para>
389   This variable has the same value as calling:
390   </para>
391   <programlisting>editPane.getTextArea()</programlisting></listitem>
392   <listitem><para><varname>scriptPath</varname> - set to the full path
393   of the script currently being executed.
394   </para></listitem>
395  </itemizedlist>
396
397  <para>
398   Note that these variables are set at the beginning of macro
399   execution. If the macro switches views, buffers or edit panes,
400   the variables will be out of date. In that case, you can use
401   the method calls equivalent to the values of the variables.
402  </para>
403
404 </sect1>
405
406 <sect1 id="helpful-methods"><title>Helpful Methods in the
407  Macros Class</title>
408
409  <para>
410   Including <function>message()</function>, there are five static methods
411   in the <ulink url="../api/org/gjt/sp/jedit/Macros.html">Macros</ulink> class that allow you to converse
412   easily with your macros. They all encapsulate calls to methods of the
413   Java platform's <classname>JOptionPane</classname> class.
414  </para>
415
416  <itemizedlist>
417
418    <listitem>
419      <funcsynopsis>
420         <funcprototype>
421           <funcdef>public static void <function>message</function></funcdef>
422           <paramdef>Component <parameter>comp</parameter></paramdef>
423           <paramdef>String <parameter>message</parameter></paramdef>
424         </funcprototype>
425       </funcsynopsis>
426     </listitem>
427
428     <listitem>
429       <funcsynopsis>
430         <funcprototype>
431          <funcdef>public static void <function>error</function></funcdef>
432          <paramdef>Component <parameter>comp</parameter></paramdef>
433          <paramdef>String <parameter>message</parameter></paramdef>
434         </funcprototype>
435       </funcsynopsis>
436     </listitem>
437
438     <listitem>
439      <funcsynopsis>
440        <funcprototype>
441          <funcdef>public static String <function>input</function></funcdef>
442          <paramdef>Component <parameter>comp</parameter></paramdef>
443          <paramdef>String <parameter>prompt</parameter></paramdef>
444        </funcprototype>
445      </funcsynopsis>
446     </listitem>
447
448     <listitem>
449      <funcsynopsis>
450        <funcprototype>
451          <funcdef>public static String <function>input</function></funcdef>
452          <paramdef>Component <parameter>comp</parameter></paramdef>
453          <paramdef>String <parameter>prompt</parameter></paramdef>
454          <paramdef>String <parameter>defaultValue</parameter></paramdef>
455        </funcprototype>
456      </funcsynopsis>
457     </listitem>
458
459     <listitem>
460      <funcsynopsis>
461        <funcprototype>
462          <funcdef>public static int <function>confirm</function></funcdef>
463          <paramdef>Component <parameter>comp</parameter></paramdef>
464          <paramdef>String <parameter>prompt</parameter></paramdef>
465          <paramdef>int <parameter>buttons</parameter></paramdef>
466        </funcprototype>
467      </funcsynopsis>
468     </listitem>
469
470  </itemizedlist>
471
472  <para>
473    The format of these four <glossterm>declarations</glossterm> provides a
474    concise reference to the way in which the methods may be used. The
475    keyword <function>public</function> means that the method can be used
476    outside the <ulink url="../api/org/gjt/sp/jedit/Macros.html">Macros</ulink> class. The alternatives are
477    <function>private</function> and <function>protected</function>. For
478    purposes of BeanShell, you just have to know that BeanShell can only use
479    public methods of other Java classes. The keyword
480    <function>static</function> we have already discussed. It means that the
481    method does not operate on a particular object. You call a static
482    function using the name of the class (like
483    <ulink url="../api/org/gjt/sp/jedit/Macros.html">Macros</ulink>) rather than the name of a particular
484    object (like <varname>view</varname>). The third word is the type of the
485    value returned by the method. The keyword <function>void</function> is
486    Java's way of saying the the method does not have a return value.
487  </para>
488
489  <para>
490   The <function>error()</function> method works just like
491   <function>message()</function> but displays an error icon in the message
492   box. The <function>input()</function> method furnishes a text field for
493   input, an <guilabel>OK</guilabel> button and a
494   <guilabel>Cancel</guilabel> button. If <guilabel>Cancel</guilabel> is pressed,
495   the method returns <constant>null</constant>. If <guilabel>OK</guilabel>
496   is pressed, a <classname>String</classname> containing the contents of
497   the text field is returned. Note that there are two forms of the
498   <function>input()</function> method; the first form with two parameters
499   displays an empty input field, the other forms lets you specify an initial,
500   default input value.
501  </para>
502
503  <para>
504   For those without Java experience, it is important to know that
505   <constant>null</constant> is <emphasis>not</emphasis> the same as an
506   empty, <quote>zero-length</quote> <classname>String</classname>. It is
507   Java's way of saying that there is no object associated with this
508   variable. Whenever you seek to use a return value from
509   <function>input()</function> in your macro, you should test it to see if
510   it is <constant>null</constant>. In most cases, you will
511   want to exit gracefully from the script with a
512   <function>return</function> statement, because the presence of a null
513   value for an input variable usually means that the user intended to
514   cancel macro execution. BeanShell will complain if you call any
515   methods on a <constant>null</constant> object.
516  </para>
517
518  <para>
519   The <function>confirm()</function> method in the
520   <ulink url="../api/org/gjt/sp/jedit/Macros.html">Macros</ulink> class is a little more complex. The
521   <varname>buttons</varname> parameter has an <classname>int</classname>
522   type, and the usual way to supply a value is to use one of
523   the predefined values taken from Java's
524   <classname>JOptionPane</classname> class. You can choose among
525   <constant>JOptionPane.YES_NO_OPTION</constant>,
526   <constant>JOptionPane.YES_NO_CANCEL_OPTION</constant>, or
527   <constant>JOptionPane.OK_CANCEL_OPTION</constant>. The return
528   value of the method is also an <classname>int</classname>, and should be tested
529   against the value of other predefined constants:
530   <constant>JOptionPane.YES_OPTION</constant>,
531   <constant>JOptionPane.NO_OPTION</constant>,
532   <constant>JOptionPane.OK_OPTION</constant> or
533   <constant>JOptionPane.CANCEL_OPTION</constant>.
534  </para>
535
536  <para>
537   We've looked at using <function>Macros.message()</function>. To
538   use the other methods, you would write something like the
539   following:
540  </para>
541
542  <informalexample><!-- <title>Using <function>Macros.error()</function> and
543  <function>Macros.input()</function></title> -->
544   <programlisting>Macros.error(view, "Goodbye, cruel world!");
545
546String result = Macros.input(view, "Type something here.");
547
548String result = Macros.input(view, "When were you born?",
549    "I don't remember, I was very young at the time");
550
551int result = Macros.confirm("Do you really want to learn"
552    + " about BeanShell?",JOptionPane.YES_NO_OPTION);
553    </programlisting>
554  </informalexample>
555
556  <para>
557    In the last three examples, placing the word <classname>String</classname>
558    or <classname>int</classname>
559    before the variable name <varname>result</varname> tells BeanShell that
560    the variable refers to an integer or a <classname>String</classname> object, even
561    before a particular value is assigned to the variable.
562    In BeanShell, this <glossterm>declaration</glossterm> of the
563    <glossterm>type</glossterm> of <varname>result</varname> is not
564    necessary; BeanShell can figure it out when the macro runs. This can be
565    helpful if you are not comfortable with specifying types and classes;
566    just use your variables and let BeanShell worry about it.
567  </para>
568
569  <para>
570   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"/>.
571  </para>
572
573  </sect1>
574
575  <sect1 id="dynamic-typing"><title>BeanShell Dynamic Typing</title>
576
577  <para>
578    Without an explicit <glossterm>type declaration</glossterm> like
579    <classname>String</classname> <varname>result</varname>, BeanShell
580    variables can change their type at runtime depending on the object or
581    data assigned to it. This dynamic typing allows you to write code like
582    this (if you really wanted to):
583  </para>
584
585  <informalexample><!-- <title>Dynamic typing of variables</title> -->
586   <programlisting>// note: no type declaration
587result = Macros.input(view, <quote>Type something here.</quote>);
588
589// this is our predefined, current View
590result = view;
591
592// this is an <quote>int</quote> (for integer);
593// in Java and BeanShell, int is one of a small number
594// of <quote>primitive</quote> data types which are not classes
595result = 14;</programlisting>
596  </informalexample>
597
598  <para>
599    However, if you first declared <varname>result</varname> to be type
600    <classname>String</classname> and and then tried these reassignments,
601    BeanShell would complain. While avoiding explicit type declaration makes
602    writing macro code simpler, using them can act as a check to make sure you are
603    not using the wrong variable type of object at a later point in your
604    script. It also makes it easier (if you are so inclined) to take a
605    BeanShell <quote>prototype</quote> and incorporate it in a Java program.
606  </para>
607
608  <para>
609    One last thing before we bury our first macro. The double slashes in the
610    examples just above signify that everything following them on that line
611    should be ignored by BeanShell as a comment. As in Java and C/C++, you
612    can also embed comments in your BeanShell code by setting them off with
613    pairs of <userinput>/* */</userinput>, as in the following example:
614  </para>
615
616
617  <informalexample>
618   <programlisting>/* This is a long comment that covers several lines
619and will be totally ignored by BeanShell regardless of how
620many lines it covers */</programlisting>
621  </informalexample>
622 </sect1>
623
624 <sect1 id="something-useful"><title>Now For Something Useful</title>
625
626  <para>
627    Here is a macro that inserts the path of the current buffer in
628    the text:
629  </para>
630
631
632  <informalexample>
633  <!-- <title>Insert buffer path in text</title> -->
634   <programlisting>String newText = buffer.getPath();
635textArea.setSelectedText(newText);</programlisting>
636  </informalexample>
637
638  <para>
639    Unlike in our first macro example, here we are calling class methods on
640    particular objects. First, we call <function>getPath()</function> on the
641    current <ulink url="../api/org/gjt/sp/jedit/Buffer.html">Buffer</ulink> object to get the full path of the
642    text file currently being edited. Next, we call
643    <function>setSelectedText()</function> on the current text display
644    component, specifying the text to be inserted as a parameter.
645  </para>
646
647  <para>
648    In precise terms, the <function>setSelectedText()</function> method
649    substitutes the contents of the <classname>String</classname>
650    parameter for a range of selected text that includes the current caret
651    position. If no text is selected at the caret position, the effect
652    of this operation is simply to insert the new text at that position.
653  </para>
654
655  <para>
656    Here's a few alternatives to the full file path that you could
657    use to insert various useful things:
658  </para>
659
660
661  <informalexample><!-- <title>Items to use with
662  <function>setSelectedText()</function></title> -->
663<programlisting>// the file name (without full path)
664String newText = buffer.getName();
665
666// today's date
667import java.text.DateFormat;
668
669String newText = DateFormat.getDateInstance()
670    .format(new Date());
671
672// a line count for the current buffer
673String newText = "This file contains "
674    + textArea.getLineCount() + " lines.";</programlisting>
675</informalexample>
676
677  <para>
678    Here are brief comments on each:
679  </para>
680
681  <itemizedlist>
682   <listitem>
683    <para>
684      In the first, the call to <function>getName()</function> invokes
685      another method of the <ulink url="../api/org/gjt/sp/jedit/Buffer.html">Buffer</ulink> class.
686    </para>
687   </listitem>
688
689   <listitem>
690    <para>
691      The syntax of the second example chains the results of
692      several methods. You could write it this way:
693    </para>
694
695<programlisting>import java.text.DateFormat;
696Date d = new Date();
697DateFormat df = DateFormat.getDateInstance();
698String result = df.format(d);
699</programlisting>
700
701   <para>
702	  Taking the pieces in order:
703   </para>
704
705   <itemizedlist>
706	   <listitem>
707	     <para>
708         A Java <classname>Date</classname> object is created using the
709         <function>new</function> keyword. The empty parenthesis after
710         <classname>Date</classname> signify a call on the <glossterm>
711         constructor method</glossterm> of <classname>Date</classname> having no
712         parameters; here, a <classname>Date</classname> is created representing
713         the current date and time.
714       </para>
715	   </listitem>
716
717	   <listitem>
718	     <para>
719         <function>DateFormat.getDateInstance()</function> is a static method
720         that creates and returns a <classname>DateFormat</classname> object. As
721         the name implies, <classname>DateFormat</classname> is a Java class
722         that takes <classname>Date</classname> objects and produces readable
723         text. The method <function>getDateInstance()</function> returns a
724         <classname>DateFormat</classname> object that parses and formats dates.
725         It will use the default <glossterm>locale</glossterm> or text format
726         specified in the user's Java installation.
727       </para>
728	  </listitem>
729
730	  <listitem>
731	    <para>
732        Finally, <classname>DateFormat.format()</classname> is called on the
733        new <classname>DateFormat</classname> object using the
734        <classname>Date</classname> object as a parameter. The result is a
735        <classname>String</classname> containing the date in the default
736        locale.
737      </para>
738	  </listitem>
739
740    <listitem>
741      <para>
742        Note that the <classname>Date</classname> class is contained in
743        the <literal>java.util</literal> package, so an explicit import
744        statement is not required. However, <classname>DateFormat</classname>
745        is part of the <literal>java.text</literal> package, which is
746        not automatically imported, so an explicit
747        <function>import</function> statement must be used.
748      </para>
749    </listitem>
750	</itemizedlist>
751
752   </listitem>
753
754   <listitem>
755    <para>
756    The third example shows three items of note:
757	 <itemizedlist>
758	  <listitem>
759	   <para>
760       <function>getLineCount()</function> is a method in jEdit's
761       <ulink url="../api/org/gjt/sp/jedit/textarea/JEditTextArea.html">JEditTextArea</ulink> class. It returns an
762       <classname>int</classname> representing the number of lines in the
763       current text buffer. We call it on <varname>textArea</varname>, the
764       pre-defined, current <ulink url="../api/org/gjt/sp/jedit/textarea/JEditTextArea.html">JEditTextArea</ulink> object.
765      </para>
766	  </listitem>
767
768	  <listitem>
769	   <para>
770       The use of the <function>+</function> operator (which can be chained,
771       as here) appends objects and string
772       literals to return a single, concatenated <classname>String</classname>.
773       </para>
774	  </listitem>
775	 </itemizedlist>
776   </para>
777   </listitem>
778  </itemizedlist>
779 </sect1>
780
781</chapter>