/jEdit/tags/jedit-4-3-pre5/doc/users-guide/macro-basics.xml
XML | 785 lines | 673 code | 96 blank | 16 comment | 0 complexity | f56bfef3c4d58a0ccaab63f1fe0efbb6 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
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 5136 2004-10-17 04:36:32Z 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>><guisubmenu>BeanShell</guisubmenu>><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>><guisubmenu>BeanShell</guisubmenu>><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>><guisubmenu>BeanShell</guisubmenu>><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>><guisubmenu>BeanShell</guisubmenu>><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(view, "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>