[Japanese] [English]


Index


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

1.2 [2006/03/12] 1.0.3 released

1.3 [2005/12/11] 1.0.2 released

1.4 [2005/12/02] 1.0.1 released

1.5 [2005/12/01] 1.0.0 released

1.6 [2005/10/11] 0.9.3 released

1.7 [2005/10/05] 0.9.2 released

2 Requirements

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.

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.

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


Back to Top

Valid XHTML 1.0!
rubikitch(rubikitch __nos_pam__ At __nos_pam__ ruby-lang DoT org)

Mail Form
Name Mail
URL