$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
New EmacsRuby functions.
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]
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/
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.
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.
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).
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")
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)
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)
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 }
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
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
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 }
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
.
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.
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
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
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.
--batch
option, after the test is executed it ends immediately. (emacs -batch)Test::Unit::TestCase
includes and extends ElMixin
. So the el4r methods and the EmacsLisp functions can be called in Test::Unit::TestCase
class. 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
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.
`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.
Please look at the RDoc documents in doc/.
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.
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.
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'.
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.
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.