>>>>> "PK" == Paul Kinnucan <[EMAIL PROTECTED]> writes:


PK> Yep. I'm looking forward to seeing what Nick comes up with.

Here's the package documentation that I have so far.  I plan to expand
more on the later sections.  I'm also willing to package up what code
I have and send that along, but I don't want to spam the list with a
.zip attachment.

Title: JDEE Universal Communication Interface (JUCI)

JUCI (pronounced `juicy') is YABA (Yet Another Bloody Anagram) for the JDEE Universal Communication Interface. The intent of JUCI is to provide a standard programming convention and infrastructure for managing and integrating communication between Elisp and Java programs through the BeanShell.

Overview

JUCI provides two-way communication between Elisp code running in Emacs and Java code running in the beanshell. This means that not only can Java code be executed in a uniform manner by Elisp code, but Java code has the ability to call back to Elisp code, retrieving user input, querying the current buffer position or filename, or any other conceivable information. This is achieved by spawning a separate, parallel thread to execute Java code so that if the code wishes to call back to Elisp, the foreground beanshell prompting thread can still be free to receive the result of that evaluation.

The two threads work together through the JUCI Connection which is shared between the two.

Using JUCI

Calling Java from Elisp is straightforward; you create a Java interface containing the methods you wish to call from Elisp and an implementation of that interface that has a default constructor:

package my.util;

public interface Helper {
  Object doSomething(Object arg);
}

public class HelperImpl implements Helper {
  public HelperImpl() {}

  public Object doSomething(Object arg) {
    // ...
  }
}

On the Elisp side, all you would need to do is declare a function like this:

(defun my-util-helper-do-something (arg)
  (jde-juci-invoke-java "my.util.HelperImpl" "doSomething"))

For Java code that calls Elisp, you declare just an interface. On the Elisp side, you implement that interface by creating a function with a name following certain conventions (see below) and a matching argument list:

package my.util;

public interface Prompt {
  String getUserInput(String prompt);
}

;; Elisp implementation of above interface
(defun my-util-prompt-get-user-input (prompt)
  (read-from-minibuffer prompt))

// Java client code that invokes Elisp implementation

Prompt prompt = (Prompt) jde.juci.ConnectionFactory.getConnection(my.util.Prompt.class);
String result = promt.getUserInput("Your name: ");

This will cause emacs to enter the minibuffer, capture the user-entered string, and return it to the Java code.

JUCI naming conventions

Components of JUCI

  • Java components (jde.juci package)
    • Connection
    • ConnectionFactory
    • ConnectionImpl
    • LispWriter
    • Symbol/Cons/Quoted
  • Elisp components (jde-juci.el Elisp package)
    • jde-juci-invoke-java
    • jde-juci-invoke-elisp
    • jde-juci-bshify-object

Conversion of objects between Elisp and Java

Debugging


This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

Reply via email to