## Index

- What's new

  - [2006/09/21] 1.0.4 released
  - [2006/03/12] 1.0.3 released
  - [2005/12/11] 1.0.2 released
  - [2005/12/02] 1.0.1 released
  - [2005/12/01] 1.0.0 released
  - [2005/10/11] 0.9.3 released
  - [2005/10/05] 0.9.2 released
- Requirements
- Download / Install / Setup
- Start and Restart el4r

- Programming EmacsRuby

  - Loading an EmacsRuby script
  - Converting names
  - Accessing EmacsLisp variables
  - Calling EmacsLisp functions
  - Defining EmacsLisp functions
  - Calling special forms
  - Calling defun-type macros
  - Defining advices
  - Output builtin functions
  - Using Emacs features in user-defined Class and Module.
  - Sample of ElApp
  - Sample of ElApp (smart defun)

- Making regression tests with Test::Unit

  - Command line options
- The `el4r' command
- EmacsRuby API Reference
- Accessing Ruby from EmacsLisp
- Examples

- Packaging EmacsRuby scripts

  - Directory Structure
  - The `autoload' Directory
  - Packaging with `setup.rb'
- Link

# Title: el4r - EmacsRuby engine - EmacsLisp for Ruby

    $Id: el4r.en.rd.r 1380 2006-09-21 07:23:15Z rubikitch $

El4r enables you to write Emacs programs in Ruby as well as in EmacsLisp. I call the Ruby language to manipulate Emacs `EmacsRuby'.

El4r and Test::Unit enables you to unit-test EmacsLisp/EmacsRuby programs automatically.

This program is originally written by Kaoru Shirai. I took over the development of el4r.

Latest Version: 1.0.4

## 1 What's new

### 1.1 [2006/09/21] 1.0.4 released

- Smart-defun: defun within ElApp subclass.

### 1.2 [2006/03/12] 1.0.3 released

- Interactive specification by Proc objects
- .xemacs/init.el support.
- manpages.

### 1.3 [2005/12/11] 1.0.2 released

- Fixed `el4r-rctool' bug on Windows. No changes except installer.

### 1.4 [2005/12/02] 1.0.1 released

- Adjusted to Emacs-snapshot.

### 1.5 [2005/12/01] 1.0.0 released

- Installer.
- Packaging policy.
- Fixed fatal error bug.
- Fixed defun-GC problem.
- Renamed: el4r-runtest.rb -> el4r-runtest
- New command: el4r

- New EmacsRuby functions.

  - define_minor_mode
  - define_derived_mode
  - eval_after_load

### 1.6 [2005/10/11] 0.9.3 released

- el4r-runtest.rb: Raise when the test-script file is not found.
- Now output builtin functions (p, print, puts ...) are usable in EmacsRuby.
- Fixed an error-handling bug.
- More stable.

### 1.7 [2005/10/05] 0.9.2 released

- ~/.el4rrc.rb contains all the el4r setting.
- Automatic configuration.
- Now el4r can be installed in arbitrary directory.
- A block is accepted in El4r::ELMethodsMixin#newbuf .
- New class: ElApp
- Works with Windows(WINE).
- Introduced el4r_load search path.
- New EmacsRuby library in el4r/ directory.

## 2 Requirements

- Ruby 1.8.2 or upper
- emacs21 / xemacs21

I'm using Debian GNU/Linux. El4r probably works in other GNU/Linux or Unices.

I have no Windows environment. But el4r works well with "ruby 1.8.2 (2004-12-25) [i386-mswin32]" and Meadow on WINE.

I want feedbacks and patches. Please send me the result of the following command.

    ruby bin/el4r-runtest testing/test-el4r.rb --batch -l testlog --emacs=[emacs binary name]

## 3 Download / Install / Setup

Since version 1.0.0, el4r introduced installer. If you got error when downloading, you must update Ruby. Here is the shell commands to download, install and setup. el4r-rctool setups and updates your dotfiles automatically.

To update older el4r (<= 0.9.1), you must remove these lines from ~/.emacs,

    (add-to-list 'load-path "~/src/el4r/elisp/")
    (require 'el4r)
    (el4r-boot)

and this line from ~/.el4r/init.rb by hand.

    el4r_load "el4r-mode.rb"

In newer el4r, el4r-rctool updates your dotfiles automatically.

    ruby -ropen-uri -e 'URI("http://www.rubyist.net/~rubikitch/archive/el4r-1.0.4.tar.gz").read.display' > el4r-1.0.4.tar.gz
    tar xzf el4r-1.0.4.tar.gz
    cd el4r-1.0.4
    ruby setup.rb

    ruby -S el4r-rctool -p
    ruby -S el4r-rctool -i

The diretory to put EmacsRuby scripts is ~/.el4r by default. The environment variable EL4R_HOME sets the directory to put EmacsRuby scripts.

- el4r-1.0.4.tar.gz

Victor Borja created Gentoo ebuild. Thanks.

Boris Daix created Debian package. Thanks. Put the following to your /etc/apt/sources.list:

    deb http://alysse.dyndns.org/~bdaix/debian/packages unstable/
    deb-src http://alysse.dyndns.org/~bdaix/debian/packages unstable/

## 4 Start and Restart el4r

To start or restart el4r, type

    M-x el4r-boot

in Emacs. After you installed el4r and restart emacs, el4r is already starting. You have to restart el4r when behavior becomes strange or you rewrite init.rb.

## 5 Programming EmacsRuby

When el4r is started, ~/.el4r/init.rb is automatically evaled by the context of el4r. When it is the context of el4r; you can access the EmacsLisp functions and variables in addition to usual Ruby. you can define EmacsLisp functions.

### 5.1 Loading an EmacsRuby script

The `el4r_load` method reads an EmacsRuby script in an argument in context of el4r. el4r_load's default search path is ~/.el4r -> ~/.el4r/site -> $el4r_root/el4r . External EmacsRuby scripts are installed in ~/.el4r/site .

Of course normal `load' is usable, too. In this case `load' read a script as a normal Ruby library not in context of el4r. In el4r, ~/.el4r (the directory specified in environment variable EL4R_HOME) is included in $: ($LOAD_PATH).

### 5.2 Converting names

There is a difference in the custom of how to name the name in Ruby and EmacsLisp.

In Ruby "_" is usually used as an end of a word while in EmacsLisp "-" is. Therefore to specify a function / a variable of EmacsLisp side in Ruby, el4r substitute "-" for "_".

Example:

    find_file -> find-file

In addition, a letter set to be able to use for a function name, a variable name and a symbol name is different from Ruby in EmacsLisp. EmacsLisp can use a letter of many kinds. That is, the thing which cannot be expressed in Ruby comes out. Don't worry. In this case it can be specified by String.

Example:

    # call `se/make-summary-buffer' function
    funcall("se/make-summary-buffer")

### 5.3 Accessing EmacsLisp variables

To access an EmacsLisp variable you can use `elvar` object. This object is like Struct.

Example:

    elvar.a_string = "Hello"            # (setq a-string "Hello")
    elvar["a-string"] = "Hi"            # (setq a-string "Hi")
    elvar["*an/odd+variable!*"] = 10    # (setq *an/odd+variable!* 10)

### 5.4 Calling EmacsLisp functions

An el4r object calls a function of EmacsLisp when calling a method the object do not know(method_missing).

Example:

    buffer_string             # (buffer-string)
    find_file("~/.emacs")     # (find-file "~/.emacs")
    funcall("1+1")            # (1+1)

### 5.5 Defining EmacsLisp functions

EmacsRuby can define an EmacsLisp function.

The function's arguments are the iterator's arguments.

Example:

    defun(:my_command2,
          :interactive => "d", :docstring => "description...") { |point|
      insert_string("Current point is #{point}."); newline
    }

A Proc object can be specified to attribute `interactive'. It must return Array or List(EmacsLisp) in this case.

Example:

    interactive_proc = lambda { [1+1, 1] }
    defun(:my_command3,
          :interactive => interactive_proc) { |a, b|
      sum = a + b
    }

### 5.6 Calling special forms

The way to call Special Form like save-excursion and with-current-buffer is a little special.

`with(function_name, arguments) {...}`

Example:

    with(:save_excursion) do
      goto_char 1
      re_search_forward('^\\(.+\\)$')
    end
    match_string 1

### 5.7 Calling defun-type macros

Calling defun-type macro (such as `define-minor-mode' and `define-derived-mode') by `with' is bad, because the function body is GCed. To deal with this problem, el4r defines `define_minor_mode' and `define_derived_mode'. To define defun-type macro in el4r, use `with_preserved_block'.

Example:

    define_derived_mode(:foo_mode, :fundamental_mode, "FOO", "doc") do
      @passed = true
    end

    define_minor_mode(:a_minor_mode, "test minor mode") do
      @passed = true
    end

### 5.8 Defining advices

El4r can define an EmacsLisp advice by using `defadvice`.

Example:

    # define a function
    defun(:adtest3){ 1 }
    # now define an advice
    defadvice(:adtest3, :around, :adv3, :activate,
              :docstring=>"test advice", :interactive=>true) {
      ad_do_it
      elvar.ad_return_value = 2
    }

### 5.9 Output builtin functions

The output of output builtin functions (p, print, printf ...) are inserted into *el4r:output* buffer. This feature is useful for debug.

Internally, `$>` is an El4r::El4rOutput object in EmacsRuby. El4r::El4rOutput#write inserts a string into *el4r:output* buffer. Output builtin functions always call `write`.

### 5.10 Using Emacs features in user-defined Class and Module.

You might want to do object oriented programming to one of the reasons to introduce EmacsRuby. First of all, it is a class definition as for object oriented programming. Because a user-defined class is not a context of el4r, you might not be able to call EmacsLisp? It worries and is useless.

In a user-defined class or module, the following statement enables you to call EmacsLisp.

    include ElMixin

ElApp class is a Class version of ElMixin. You can pass a Hash parameter to ElApp.

### 5.11 Sample of ElApp

In older version of el4r, you must defun in a instance method of ElApp's subclass.

    class Foo < ElApp
      def initialize(x)
        elvar.v = x[:value]
        defun(:twice_v) do
          elvar.v *= 2
        end

        defun(:str0) do
          do_str0 x[:str]
        end
      end

      def do_str0(str)
        (str*2).capitalize
      end
    end

### 5.12 Sample of ElApp (smart defun)

Since version 1.0.4, you can directly defun in ElApp's subclass.

    class SmartDefunSample < ElApp
      def my_square(x)
        x*x
      end

      defun(:testdefun, :interactive=>true) do |x|
        # This block is evaluated within a context of the SmartDefunSample INSTANCE.
        # Not a context of the SmartDefunSample class!!
        x ||= 16
        elvar.val = my_square(x)  # call an instance method.
      end
    end

## 6 Making regression tests with Test::Unit

There is a strong test environment named Test::Unit in one of the big advantages to use Ruby. The test program of EmacsLisp/EmacsRuby should independently start up Emacs. Because the operation of Emacs may influence the entire Emacs session, the malfunctioned test program can destroy the edit environment at the worst. Another Emacs session for the test enables you to test at ease because there is no adverse effect in the edit environment even though an accident happens there. I prepared a mini environment for the test for such reasons.

el4r-runtest newly starts up Emacs, tests with Test::Unit(RUNIT), and displays the result.

- With `--batch` option, after the test is executed it ends immediately. (emacs -batch)
- El4r version of `Test::Unit::TestCase` includes and extends `ElMixin`. So the el4r methods and the EmacsLisp functions can be called in `Test::Unit::TestCase` class.
- Because it is a mini environment, the key operation has been simplified.
- You can exit it also with `q` and `M-k` in addition to `C-x C-c`.
- The test can be executed with `C-c` again.
- The log is displayed with `l` or `C-l`.
- It scrolls by `SPACE` and `b`.
- Any configuration files of Emacs is not read (--no-init-file,--no-site-file).
- It doesn't read ~/.el4r/init.rb.
- Please load the EmacsLisp file that should be loaded on the test script side.

The test class concretely becomes such feeling. `el_require` and `el_load` can be used for the part of `el4r_lisp_eval`.

    require 'test/unit'
    class TestXXXX < Test::Unit::TestCase
      el4r_lisp_eval %((progn
        some initialization
      ))

      def setup
        #
      end

      def teardown
        #
      end

      def test_xxxx
        #
      end
    end

### 6.1 Command line options

    Usage: el4r-runtest [options] file
        -Q, --init                       load site-start.el and .emacs
        -b, --batch                      batch mode
        -i                               interactive mode
        -e, --emacs=EMACS                set emacs binary [default: ]
            --ruby=RUBY                  set ruby binary [default: ]
        -I load-path                     set load-path
        -r, --el4r-root=DIR              el4r package root directory [for debug]
        -n, --name=NAME                  Runs tests matching NAME.
                                         (patterns may be used).
        -t, --testcase=TESTCASE          Runs tests in TestCases matching TESTCASE.
                                         (patterns may be used).
        -v                               verbose output
            --nw                         don't communicate with X, ignoring $DISPLAY
                                         (emacs -nw)
        -d, --debug                      debug output
        -l, --log=LOGFILE                Specify a log file.
            --show                       Show the test information only, for diagnosis.

`--batch` and `--nw` are the options of Emacs. `-n` and `-t` are the options of Test::Unit. With `-d` the backtraces contains the line of el4r-instance.

## 7 The `el4r' command

`el4r' command invokes a new Emacs and execute the EmacsRuby script specified. The usage is almost the same as `el4r-runtest'.

    Usage: el4r [options] file
        -Q, --init                       load site-start.el and .emacs
        -b, --batch                      batch mode
        -i                               interactive mode
        -e, --emacs=EMACS                set emacs binary [default: ]
            --ruby=RUBY                  set ruby binary [default: ]
        -I load-path                     set load-path
        -r, --el4r-root=DIR              el4r package root directory [for debug]
            --nw                         don't communicate with X, ignoring $DISPLAY
                                         (emacs -nw)
        -d, --debug                      debug output
        -l, --log=LOGFILE                Specify a log file.
            --show                       Show the test information only, for diagnosis.

## 8 EmacsRuby API Reference

Please look at the RDoc documents in doc/.

## 9 Accessing Ruby from EmacsLisp

El4r also enables EmacsLisp to access Ruby. The `el4r-ruby-eval` function is used in the EmacsLisp program to access Ruby. The only argument is Ruby expression to evaluate. However, it is wise to make it see from EmacsLisp by `defun` and `elvar` when you want to use the program in EmacsRuby.

To access EmacsRuby interactively. Please type

    M-x el4r-ruby-eval-prompt

To evaluate the EmacsRuby type of the entire buffer. Please type

    M-x el4r-ruby-eval-buffer

In the region. Please type

    M-x el4r-ruby-eval-region

Moreover, when examples/el4r-mode.rb is loaded (It is loaded by initialization), the *ruby-scratch* buffer is made. Like the *scratch* buffer enter an EmacsRuby expression and it is evaled by typing `C-j`.

## 10 Examples

Please look at examples/el4r-mode.rb about the example of making major-mode in EmacsRuby.

Please look at testing/test-el4r.rb about the use example of each method. The test program is specifications. A correct usage and the value that should be expected, etc. it talks about many.

## 11 Packaging EmacsRuby scripts

### 11.1 Directory Structure

El4r and EmacsRuby scripts can be installd system-widely since version 1.0.0. Here is the directory structure if you use Ruby 1.8.

    site_ruby/1.8/el4r/                    # normal libraries used by el4r
    site_ruby/1.8/el4r/emacsruby/          # EmacsRuby scripts
    site_ruby/1.8/el4r/emacsruby/autoload/ # EmacsRuby scripts executed when el4r starts

Normal libraries are loaded by `load' / `requre' normally. EmacsRuby scripts are loaded by `el4r_load'.

### 11.2 The `autoload' Directory

EmacsRuby scripts in `autoload' directory are automatically executed when el4r starts. This directory is used to initialize EmacsRuby scripts.

To use autoload feature file name must begin from two digits.

    00init.rb
    50langhelp.rb
    70el4r-mode.rb

If you locate these files, these are loaded ascending order.

This operation is almost the same as Debian Emacs policy.

### 11.3 Packaging with `setup.rb'

setup.rb ease packaging EmacsRuby scripts. If you distribute EmacsRuby scripts, layout files as below.

    bin/                         # executables
    lib/el4r/                    # normal libraries used by el4r
    lib/el4r/emacsruby/          # EmacsRuby scripts
    lib/el4r/emacsruby/autoload/ # EmacsRuby scripts executed when el4r starts
    ext/                         # Ruby extensions
    data/                        # data

`el4r-mode.rb' and langhelp are packaged in this methodology.

## 12 Link

- Pymacs(so to speak EmacsPython)
- langhelp(Integrated help system in EmacsRuby)