PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/jEdit/tags/jedit-4-0-pre5/doc/users-guide/simple-macros.xml

#
XML | 616 lines | 530 code | 74 blank | 12 comment | 0 complexity | 561773487aed243df754e77e0f5fb9d4 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 3.2 Macro Guide, (C) 2001 John Gellene -->
  2. <!-- jEdit buffer-local properties: -->
  3. <!-- :indentSize=1:noTabs=yes:maxLineLen=72:tabSize=2: -->
  4. <!-- Tue Jun 19 18:36:20 EDT 2001 @983 /Internet Time/ -->
  5. <!-- This file covers the chapter "A few simple macros", -->
  6. <!-- which introduces BeanShell through a "Hello world" script. -->
  7. <!-- It provides a little background on Java syntax and -->
  8. <!-- class structure. A few simple methods and macros are also -->
  9. <!-- discussed. -->
  10. <chapter id="simple-macros"><title>A Few Simple Macros</title>
  11. <sect1 id="first-example"><title>The Mandatory First Example</title>
  12. <informalexample><!-- <title>A first one-line macro</title> -->
  13. <programlisting>Macros.message(view, "Hello world!");</programlisting>
  14. </informalexample>
  15. <para>
  16. Running this one line script causes jEdit to display a message
  17. box (more precisely, a <classname>JOptionPane</classname> object) with
  18. the traditional beginner's message and an <guilabel>OK</guilabel> button.
  19. Let's see what is happening here.
  20. </para>
  21. <para>
  22. This statement calls a static method (or function) named
  23. <function>message</function> in jEdit's <classname>Macros</classname>
  24. class. If you don't know anything about classes or static methods or
  25. Java (or C++, which employs the same concept), you will need to gain
  26. some understanding of a few terms. Obviously this is not the place for
  27. academic precision, but if you are entirely new to object-oriented
  28. programming, here are a few skeleton ideas to help you with BeanShell.
  29. </para>
  30. <itemizedlist>
  31. <listitem>
  32. <para>
  33. An <glossterm>object</glossterm> is a collection of data that can be
  34. initialized, accessed and manipulated in certain defined ways.
  35. </para>
  36. </listitem>
  37. <listitem>
  38. <para>
  39. A <glossterm>class</glossterm> is a specification of what data an object
  40. contains and what methods can be used to work with the data. A Java
  41. application consists of one or more classes (in the case of jEdit over
  42. 200 classes) written by the programmer that defines the application's
  43. behavior. A BeanShell macro uses these classes, along with built-in
  44. classes that are supplied with the Java platform, to define its own
  45. behavior.
  46. </para>
  47. </listitem>
  48. <listitem>
  49. <para>
  50. A <glossterm>subclass</glossterm> (or child class) is a class which
  51. uses (or <quote>inherits</quote>) the data and methods of its parent
  52. class along with additions or modifications that alter the subclass's
  53. behavior. Classes are typically organized in hierarchies of parent
  54. and child classes to organize program code, to define common
  55. behavior in shared parent class code, and to specify the types of
  56. similar behavior that child classes will perform in their own specific ways.
  57. </para>
  58. </listitem>
  59. <listitem>
  60. <para>
  61. A <glossterm>method</glossterm> (or function) is a procedure that works
  62. with data in a particular object, other data (including other objects)
  63. supplied as <glossterm>parameters</glossterm>, or both. Methods
  64. typically are applied to a particular object which is an
  65. <glossterm>instance</glossterm> of the class to which the method
  66. belongs.
  67. </para>
  68. </listitem>
  69. <listitem>
  70. <para>
  71. A <glossterm>static method</glossterm> differs from other methods
  72. in that it does not deal with the data in a particular object but is
  73. included within a class for the sake of convenience.
  74. </para>
  75. </listitem>
  76. </itemizedlist>
  77. <para>
  78. Java has a rich set of classes defined as part of the Java platform.
  79. Like all Java applications, jEdit is organized as a set of classes that
  80. are themselves derived from the Java platform's classes. We will refer
  81. to <firstterm>Java classes</firstterm> and <firstterm>jEdit
  82. classes</firstterm> to make this distinction. Some of jEdit's classes
  83. (such as those dealing with regular expressions and XML) are derived
  84. from or make use of classes in other open-source Java packages. Except
  85. for BeanShell itself, we won't be discussing them in this guide.
  86. </para>
  87. <para>
  88. In our one line script, the static method
  89. <function>Macros.message()</function> has two parameters because that is
  90. the way the method is defined in the <classname>Macros</classname>
  91. class. You must specify both parameters when you call the function. The
  92. first parameter, <parameter>view</parameter>, is a a variable naming a
  93. <classname>View</classname> object - an instance of jEdit's
  94. <classname>View</classname> class. A <classname>View</classname>
  95. represents a <quote>parent</quote> or top-level frame window that
  96. contains the various visible components of the program, including the
  97. text area, menu bar, toolbar, and any docked windows. It is a
  98. subclass of Java's <classname>JFrame</classname> class.
  99. With jEdit, you can create and display multiple views simultaneously.
  100. The variable <varname>view</varname> is predefined for purposes of
  101. BeanShell as the current, active <classname>View</classname> object.
  102. This is in fact the variable you want to specify as the first parameter.
  103. Normally you would not want to associate a message box with anything
  104. other than the current <classname>View</classname>.
  105. </para>
  106. <para>
  107. The second parameter, which appears to be quoted text, is a
  108. <glossterm>string literal</glossterm> - a sequence of characters of
  109. fixed length and content. Behind the scenes, BeanShell and Java take
  110. this string literal and use it to create a <classname>String</classname>
  111. object. Normally, if you want to create an object in Java or BeanShell,
  112. you must construct the object using the <function>new</function> keyword
  113. and a <firstterm>constructor</firstterm> method that is part of the
  114. object's class. We'll show an example of that later. However, both Java
  115. and BeanShell let you use a string literal anytime a method's parameter
  116. calls for a <classname>String</classname>.
  117. </para>
  118. <para>
  119. If you are a Java programmer, you might wonder about a few things
  120. missing from this one line program. There is no class definition, for
  121. example. You can think of a BeanShell script as an implicit definition
  122. of a <function>main()</function> method in an anonymous class. That is
  123. in fact how BeanShell is implemented; the class is derived from
  124. a BeanShell class called <classname>XThis</classname>. If you
  125. don't find that helpful, just think of a script as one or more blocks of
  126. procedural statements conforming to Java syntax rules. You will also get
  127. along fine (for the most part) with C or C++ syntax if you leave out
  128. anything to do with pointers or memory management - Java and BeanShell
  129. do not have pointers and deal with memory management automatically.
  130. </para>
  131. <para>
  132. Another missing item from a Java perspective is a
  133. <function>package</function> statement. In Java, such a statement is
  134. used to bundle together a number of files so that their classes become
  135. visible to one another. Packages are not part of BeanShell,
  136. and you don't need to know anything about them to write
  137. BeanShell macros.
  138. </para>
  139. <para>
  140. Finally, there are no <function>import</function> statements in this
  141. script. In Java, an <function>import</function> statement makes public
  142. classes from other packages visible within the file in which the
  143. statement occurs without having to specify a fully
  144. qualified class name. Without an import statement or a fully qualified
  145. name, Java cannot identify most classes using a single name as an identifier.
  146. </para>
  147. <para>
  148. jEdit automatically imports a number of commonly-used packages into the
  149. namespace of every BeanShell script. Because of this, the script output
  150. of a recorded macro does not contain <function>import</function>
  151. statements. For the same reason, most BeanShell scripts you write will
  152. not require <function>import</function> statements.
  153. </para>
  154. <para>
  155. Java requires <literal>import</literal> statement at the beginning of a
  156. source file. BeanShell allows you to place <literal>import</literal>
  157. statements anywhere in a script, including inside of block of
  158. statements. The <literal>import</literal> statement will cover all names
  159. used following the statement in the enclosing block.
  160. </para>
  161. <para>
  162. If you try to use a class that is not imported without its
  163. fully-qualified name, the BeanShell interpreter will complain with an
  164. error message relating to the offending line of code.
  165. </para>
  166. <sidebar>
  167. <para>
  168. Here is the full list of packages automatically imported by jEdit:
  169. </para>
  170. <programlisting>java.awt
  171. java.awt.event
  172. java.net
  173. java.util
  174. java.io
  175. java.lang
  176. javax.swing
  177. javax.swing.event
  178. org.gjt.sp.jedit
  179. org.gjt.sp.jedit.browser
  180. org.gjt.sp.jedit.gui
  181. org.gjt.sp.jedit.io
  182. org.gjt.sp.jedit.msg
  183. org.gjt.sp.jedit.options
  184. org.gjt.sp.jedit.pluginmgr
  185. org.gjt.sp.jedit.search
  186. org.gjt.sp.jedit.syntax
  187. org.gjt.sp.jedit.textarea
  188. org.gjt.sp.util</programlisting>
  189. </sidebar>
  190. </sect1>
  191. <sect1 id="helpful-methods"><title>Helpful Methods in the
  192. Macros Class</title>
  193. <para>
  194. Including <function>message()</function>, there are five static methods
  195. in the <classname>Macros</classname> class that allow you to converse
  196. easily with your macros. They all encapsulate calls to methods of the
  197. Java platform's <classname>JOptionPane</classname> class.
  198. </para>
  199. <itemizedlist>
  200. <listitem>
  201. <funcsynopsis>
  202. <funcprototype>
  203. <funcdef>public static void <function>message</function></funcdef>
  204. <paramdef>Component <parameter>comp</parameter></paramdef>
  205. <paramdef>String <parameter>message</parameter></paramdef>
  206. </funcprototype>
  207. </funcsynopsis>
  208. </listitem>
  209. <listitem>
  210. <funcsynopsis>
  211. <funcprototype>
  212. <funcdef>public static void <function>error</function></funcdef>
  213. <paramdef>Component <parameter>comp</parameter></paramdef>
  214. <paramdef>String <parameter>message</parameter></paramdef>
  215. </funcprototype>
  216. </funcsynopsis>
  217. </listitem>
  218. <listitem>
  219. <funcsynopsis>
  220. <funcprototype>
  221. <funcdef>public static String <function>input</function></funcdef>
  222. <paramdef>Component <parameter>comp</parameter></paramdef>
  223. <paramdef>String <parameter>prompt</parameter></paramdef>
  224. </funcprototype>
  225. </funcsynopsis>
  226. </listitem>
  227. <listitem>
  228. <funcsynopsis>
  229. <funcprototype>
  230. <funcdef>public static String <function>input</function></funcdef>
  231. <paramdef>Component <parameter>comp</parameter></paramdef>
  232. <paramdef>String <parameter>prompt</parameter></paramdef>
  233. <paramdef>String <parameter>defaultValue</parameter></paramdef>
  234. </funcprototype>
  235. </funcsynopsis>
  236. </listitem>
  237. <listitem>
  238. <funcsynopsis>
  239. <funcprototype>
  240. <funcdef>public static int <function>confirm</function></funcdef>
  241. <paramdef>Component <parameter>comp</parameter></paramdef>
  242. <paramdef>String <parameter>prompt</parameter></paramdef>
  243. <paramdef>int <parameter>buttons</parameter></paramdef>
  244. </funcprototype>
  245. </funcsynopsis>
  246. </listitem>
  247. </itemizedlist>
  248. <para>
  249. The format of these four <glossterm>declarations</glossterm> provides a
  250. concise reference to the way in which the methods may be used. The
  251. keyword <function>public</function> means that the method can be used
  252. outside the <classname>Macros</classname> class. The alternatives are
  253. <function>private</function> and <function>protected</function>. For
  254. purposes of BeanShell, you just have to know that BeanShell can only use
  255. public methods of other Java classes. The keyword
  256. <function>static</function> we have already discussed. It means that the
  257. method does not operate on a particular object. You call a static
  258. function using the name of the class (like
  259. <classname>Macros</classname>) rather than the name of a particular
  260. object (like <varname>view</varname>). The third word is the type of the
  261. value returned by the method. The keyword <function>void</function> is
  262. Java's way of saying the the method does not have a return value.
  263. </para>
  264. <para>
  265. The <function>error()</function> method works just like
  266. <function>message()</function> but displays an error icon in the message
  267. box. The <function>input()</function> method furnishes a text field for
  268. input, an <guilabel>OK</guilabel> button and a
  269. <guilabel>Cancel</guilabel> button. If <quote>Cancel</quote> is pressed,
  270. the method returns <constant>null</constant>. If <guilabel>OK</guilabel>
  271. is pressed, a <classname>String</classname> containing the contents of
  272. the text field is returned. Note that there are two forms of the
  273. <function>input()</function> method; the first form with two parameters
  274. displays an empty input field, the other lets you specify an initial
  275. default value.
  276. </para>
  277. <para>
  278. The <function>confirm()</function> method is the trickiest. The
  279. <varname>buttons</varname> parameter should either be
  280. <constant>JOptionPane.YES_NO_OPTION</constant>,
  281. <constant>JOptionPane.YES_NO_CANCEL_OPTION</constant>, or
  282. <constant>JOptionPane.OK_CANCEL_OPTION</constant>. The return
  283. value of the method is one of
  284. <constant>JOptionPane.YES_OPTION</constant>,
  285. <constant>JOptionPane.NO_OPTION</constant>,
  286. <constant>JOptionPane.OK_OPTION</constant> or
  287. <constant>JOptionPane.CANCEL_OPTION</constant>.
  288. </para>
  289. <para>
  290. For those without Java experience, it is important to know that
  291. <constant>null</constant> is <emphasis>not</emphasis> the same as an
  292. empty, <quote>zero-length</quote> <classname>String</classname>. It is
  293. Java's way of saying that there is no object associated with this
  294. variable. Whenever you seek to use a return value from
  295. <function>input()</function> in your macro, you should test it to see if
  296. it is <constant>null</constant>. In most cases, you will
  297. want to exit gracefully from the script with a
  298. <function>return</function> statement, because the presence of a null
  299. value for an input variable usually means that the user intended to
  300. cancel macro execution. BeanShell will complain if you call any
  301. methods on a <constant>null</constant> object.
  302. </para>
  303. <para>
  304. We've looked at using <function>Macros.message()</function>. To
  305. use the other methods, you would write something like the
  306. following:
  307. </para>
  308. <informalexample><!-- <title>Using <function>Macros.error()</function> and
  309. <function>Macros.input()</function></title> -->
  310. <programlisting>Macros.error(view, "Goodbye, cruel world!");
  311. String result = Macros.input(view, "Type something here.");
  312. String result = Macros.input(view, "What is your name?",
  313. "John Gellene");</programlisting>
  314. </informalexample>
  315. <para>
  316. In the last two examples, placing the word <classname>String</classname>
  317. before the variable name <varname>result</varname> tells BeanShell that
  318. the variable refers to a <classname>String</classname> object, even
  319. before a particular <classname>String</classname> object is assigned to
  320. it. In BeanShell, this <glossterm>declaration</glossterm> of the
  321. <glossterm>type</glossterm> of <varname>result</varname> is not
  322. necessary; BeanShell can figure it out when the macro runs. This can be
  323. helpful if you are not comfortable with types and classes; just use your
  324. variables and let BeanShell worry about it.
  325. </para>
  326. <para>
  327. Without an explicit <glossterm>type declaration</glossterm> like
  328. <classname>String</classname> <varname>result</varname>, BeanShell
  329. variables can change their type at runtime depending on the object or
  330. data assigned to it. This dynamic typing allows you to write code like
  331. this (if you really wanted to):
  332. </para>
  333. <informalexample><!-- <title>Dynamic typing of variables</title> -->
  334. <programlisting>// note: no type declaration
  335. result = Macros.input(view, <quote>Type something here.</quote>);
  336. // this is our predefined, current View
  337. result = view;
  338. // this is an <quote>int</quote> (for integer);
  339. // in Java and BeanShell, int is one of a small number
  340. // of <quote>primitive</quote> data types which are not classes
  341. result = 14;</programlisting>
  342. </informalexample>
  343. <para>
  344. However, if you first declared <varname>result</varname> to be type
  345. <classname>String</classname> and and then tried these reassignments,
  346. BeanShell would complain.
  347. </para>
  348. <para>
  349. One last thing before we bury our first macro. The double slashes in the
  350. examples just above signify that everything following them on that line
  351. should be ignored by BeanShell as a comment. As in Java and C/C++, you
  352. can also embed comments in your BeanShell code by setting them off with
  353. pairs of <userinput>/* */</userinput>, as in the following example:
  354. </para>
  355. <informalexample>
  356. <programlisting>/* This is a long comment that covers several lines
  357. and will be totally ignored by BeanShell regardless of how
  358. many lines it covers */</programlisting>
  359. </informalexample>
  360. </sect1>
  361. <sect1 id="something-useful"><title>Now For Something Useful</title>
  362. <para>
  363. Here is a macro that inserts the path of the current buffer in
  364. the text:
  365. </para>
  366. <informalexample>
  367. <!-- <title>Insert buffer path in text</title> -->
  368. <programlisting>String newText = buffer.getPath();
  369. textArea.setSelectedText(newText);</programlisting>
  370. </informalexample>
  371. <para>
  372. Two of the new names we see here, <varname>buffer</varname> and
  373. <varname>textArea</varname>, are predefined variables like
  374. <varname>view</varname>. The variable <varname>buffer</varname>
  375. represents a jEdit <varname>Buffer</varname> object, and
  376. <varname>textArea</varname> represents a
  377. <classname>JEditTextArea</classname> object.
  378. </para>
  379. <itemizedlist>
  380. <listitem>
  381. <para>
  382. A <classname>Buffer</classname> represents the contents of an open text
  383. file. It is derived from Java's <classname>PlainDocument</classname>
  384. class. The variable <varname>buffer</varname> is predefined as the
  385. current buffer.
  386. </para>
  387. </listitem>
  388. <listitem>
  389. <para>
  390. A <classname>JEditTextArea</classname> is the visible component that
  391. displays the file being edited. It is derived from the
  392. <classname>JComponent</classname> class. The variable
  393. <varname>textArea</varname> represents the current
  394. <classname>JEditTextArea</classname> object, which in turn displays
  395. the current buffer.
  396. </para>
  397. </listitem>
  398. </itemizedlist>
  399. <para>
  400. Unlike in our first macro example, here we are calling class methods on
  401. particular objects. First, we call <function>getPath()</function> on the
  402. current <classname>Buffer</classname> object to get the full path of the
  403. text file currently being edited. Next, we call
  404. <function>setSelectedText()</function> on the current text display
  405. component, specifying the text to be inserted as a parameter.
  406. </para>
  407. <para>
  408. In precise terms, the <function>setSelectedText()</function> method
  409. substitutes the contents of the <classname>String</classname>
  410. parameter for a range of selected text that includes the current caret
  411. position. If no text is selected at the caret position, the effect
  412. of this operation is simply to insert the new text at that position.
  413. </para>
  414. <para>
  415. Here's a few alternatives to the full file path that you could
  416. use to insert various useful things:
  417. </para>
  418. <informalexample><!-- <title>Items to use with
  419. <function>setSelectedText()</function></title> -->
  420. <programlisting>// the file name (without full path)
  421. String newText = buffer.getName();
  422. // today's date
  423. import java.text.DateFormat;
  424. String newText = DateFormat.getDateInstance()
  425. .format(new Date());
  426. // a line count for the current buffer
  427. String newText = "This file contains "
  428. + textArea.getLineCount() + " lines.";</programlisting>
  429. </informalexample>
  430. <para>
  431. Here are brief comments on each:
  432. </para>
  433. <itemizedlist>
  434. <listitem>
  435. <para>
  436. In the first, the call to <function>getName()</function> invokes
  437. another method of the <classname>Buffer</classname> class.
  438. </para>
  439. </listitem>
  440. <listitem>
  441. <para>
  442. The syntax of the second example chains the results of
  443. several methods. You could write it this way:
  444. </para>
  445. <programlisting>import java.text.DateFormat;
  446. Date d = new Date();
  447. DateFormat df = DateFormat.getDateInstance();
  448. String result = df.format(d);
  449. </programlisting>
  450. <para>
  451. Taking the pieces in order:
  452. </para>
  453. <itemizedlist>
  454. <listitem>
  455. <para>
  456. A Java <classname>Date</classname> object is created using the
  457. <function>new</function> keyword. The empty parenthesis after
  458. <classname>Date</classname> signify a call on the <glossterm>
  459. constructor method</glossterm> of <classname>Date</classname> having no
  460. parameters; here, a <classname>Date</classname> is created representing
  461. the current date and time.
  462. </para>
  463. </listitem>
  464. <listitem>
  465. <para>
  466. <function>DateFormat.getDateInstance()</function> is a static method
  467. that creates and returns a <classname>DateFormat</classname> object. As
  468. the name implies, <classname>DateFormat</classname> is a Java class
  469. that takes <classname>Date</classname> objects and produces readable
  470. text. The method <function>getDateInstance()</function> returns a
  471. <classname>DateFormat</classname> object that parses and formats dates.
  472. It will use the default <glossterm>locale</glossterm> or text format
  473. specified in the user's Java installation.
  474. </para>
  475. </listitem>
  476. <listitem>
  477. <para>
  478. Finally, <classname>DateFormat.format()</classname> is called on the
  479. new <classname>DateFormat</classname> object using the
  480. <classname>Date</classname> object as a parameter. The result is a
  481. <classname>String</classname> containing the date in the default
  482. locale.
  483. </para>
  484. </listitem>
  485. <listitem>
  486. <para>
  487. Note that the <classname>Date</classname> class is contained in
  488. the <literal>java.util</literal> package, so an explicit import
  489. statement is not required. However, <classname>DateFormat</classname>
  490. is part of the <literal>java.text</literal> package, which is
  491. not automatically imported, so an explicit
  492. <function>import</function> statement must be used.
  493. </para>
  494. </listitem>
  495. </itemizedlist>
  496. </listitem>
  497. <listitem>
  498. <para>
  499. The third example shows three items of note:
  500. <itemizedlist>
  501. <listitem>
  502. <para>
  503. <function>getLineCount()</function> is a method in jEdit's
  504. <classname>JEditTextArea</classname> class. It returns an
  505. <type>int</type> representing the number of lines in the
  506. current text buffer. We call it on <varname>textArea</varname>, the
  507. pre-defined, current <classname>JEditTextArea</classname> object.
  508. </para>
  509. </listitem>
  510. <listitem>
  511. <para>
  512. The use of the <function>+</function> operator (which can be chained,
  513. as here) appends objects and string
  514. literals to return a single, concatenated <classname>String</classname>.
  515. </para>
  516. </listitem>
  517. </itemizedlist>
  518. </para>
  519. </listitem>
  520. </itemizedlist>
  521. <sidebar><title>The other pre-defined variable</title>
  522. <para>
  523. In addition to <varname>view</varname>, <varname>buffer</varname> and
  524. <varname>textArea</varname>, there is one more pre-defined variable
  525. available for use in macros -- <varname>editPane</varname>. That
  526. variable is set to the current <classname>EditPane</classname> instance.
  527. An <classname>EditPane</classname> object contains a text area and
  528. buffer switcher. A view can be split to display multiple
  529. buffers, each in its own edit pane. Among other things, the
  530. <classname>EditPane</classname> class contains methods for selecting
  531. the buffer to edit.
  532. </para>
  533. <para>
  534. Most of the time your macros will manipulate the <varname>buffer</varname>
  535. or the <varname>textArea</varname>. Sometimes you will need to use
  536. <varname>view</varname> as a parameter in a method call. You will probably
  537. only need to use <varname>editPane</varname> if your macros work with
  538. split views.
  539. </para>
  540. </sidebar>
  541. </sect1>
  542. </chapter>