relisp 0.9.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +8 -0
- data/Manifest +2 -0
- data/examples/elisp_master/elisp_master.el +2 -0
- data/examples/elisp_master/ruby_slave +4 -0
- data/lib/relisp/editing_types.rb +228 -19
- data/lib/relisp/elisp_functions.rb +69 -0
- data/lib/relisp/programming_types.rb +141 -7
- data/lib/relisp/slaves.rb +3 -22
- data/lib/relisp.rb +4 -4
- data/setup.rb +0 -1
- data/src/relisp.el +7 -6
- data/test/test_editing_types.rb +102 -1
- data/test/test_elisp_functions.rb +39 -0
- data/test/test_programming_types.rb +41 -10
- data/test/test_slaves.rb +0 -6
- metadata +5 -2
data/CHANGELOG
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
== 0.9.1 / 2009-01-28
|
2
|
+
|
3
|
+
* 2 major enhancements
|
4
|
+
* Cons are now proxy objects. If the cons is a list, it can be
|
5
|
+
converted to a Relisp::List, a subclass of Array.
|
6
|
+
* Editing types are now subclasses of a Relisp::Proxy class that
|
7
|
+
takes care of creating the wrapping over the elisp variable.
|
8
|
+
|
1
9
|
== 0.9.0 / 2009-01-25
|
2
10
|
|
3
11
|
* 1 major enhancement
|
data/Manifest
CHANGED
@@ -8,11 +8,13 @@ examples/elisp_master/ruby_slave
|
|
8
8
|
examples/ruby_master/ruby_master_example
|
9
9
|
lib/relisp.rb
|
10
10
|
lib/relisp/editing_types.rb
|
11
|
+
lib/relisp/elisp_functions.rb
|
11
12
|
lib/relisp/programming_types.rb
|
12
13
|
lib/relisp/slaves.rb
|
13
14
|
setup.rb
|
14
15
|
src/relisp.el
|
15
16
|
src/relisp.elc
|
16
17
|
test/test_editing_types.rb
|
18
|
+
test/test_elisp_functions.rb
|
17
19
|
test/test_programming_types.rb
|
18
20
|
test/test_slaves.rb
|
@@ -13,6 +13,8 @@
|
|
13
13
|
(ruby-eval "sample_ruby_method3")
|
14
14
|
(member "ruby-created-buffer" (mapcar (lambda (a) (buffer-name a)) (buffer-list)))
|
15
15
|
|
16
|
+
(ruby-eval "sample_ruby_method4")
|
17
|
+
|
16
18
|
;; How to start the ruby slave without a file. The rest of the
|
17
19
|
;; commands will work fine with a slave started either way.
|
18
20
|
|
data/lib/relisp/editing_types.rb
CHANGED
@@ -42,45 +42,254 @@
|
|
42
42
|
|
43
43
|
module Relisp
|
44
44
|
|
45
|
-
#
|
46
|
-
#
|
45
|
+
# Proxy contains the code that creates a wrapper around a variable
|
46
|
+
# in emacs.
|
47
47
|
#
|
48
|
-
class
|
48
|
+
class Proxy
|
49
49
|
def self.from_elisp(object)
|
50
50
|
new(object[:variable], object[:slave])
|
51
51
|
end
|
52
52
|
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
|
58
|
-
|
53
|
+
# If the last argument is a Relisp::Slave, it gets pulled off and
|
54
|
+
# used as the slave; otherwise Relisp.default_slave is used. If
|
55
|
+
# the first argument is a Symbol, it is assumed to be the name of
|
56
|
+
# an elisp variable which needs a proxy. If the first argument
|
57
|
+
# isn't a Symbol, all of the arguments (except the last, if it was
|
58
|
+
# a Slave) are send off to the child to handle.
|
59
|
+
#
|
60
|
+
def initialize(*args)
|
61
|
+
@slave = if args.last.kind_of?(Relisp::Slave)
|
62
|
+
args.pop
|
63
|
+
else
|
64
|
+
Relisp.default_slave
|
65
|
+
end
|
59
66
|
|
60
|
-
if
|
61
|
-
@elisp_variable = @slave.get_permanent_variable(
|
67
|
+
if args[0].kind_of?(Symbol)
|
68
|
+
@elisp_variable = @slave.get_permanent_variable(args[0])
|
69
|
+
elisp_type= ""
|
70
|
+
self.class.to_s.split("::").last.split(//).each_with_index do |char, index|
|
71
|
+
unless index==0 || char == char.downcase
|
72
|
+
elisp_type << "-"
|
73
|
+
end
|
74
|
+
elisp_type << char.downcase
|
75
|
+
end
|
62
76
|
|
63
|
-
unless @slave.elisp_eval("(type-of #{@elisp_variable})") ==
|
64
|
-
raise ArgumentError, "#{@elisp_variable} isn't a
|
77
|
+
unless @slave.elisp_eval("(type-of #{@elisp_variable})") == elisp_type.to_sym
|
78
|
+
raise ArgumentError, "#{@elisp_variable} isn't a #{elisp_type}"
|
65
79
|
end
|
66
|
-
elsif var_or_name.kind_of?( String )
|
67
|
-
@slave.elisp_execute("(generate-new-buffer #{var_or_name.to_elisp})")
|
68
|
-
@elisp_variable = @slave.get_permanent_variable(Relisp::Slave::PREVIOUS_ELISP_RESULT)
|
69
80
|
else
|
70
|
-
|
81
|
+
@elisp_variable = @slave.new_elisp_variable
|
82
|
+
yield args
|
71
83
|
end
|
72
84
|
end
|
85
|
+
|
86
|
+
attr_reader :slave, :elisp_variable
|
73
87
|
|
74
88
|
def to_elisp
|
75
89
|
@elisp_variable
|
76
90
|
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# A proxy to an Emacs buffer.
|
94
|
+
#
|
95
|
+
class Buffer < Proxy
|
77
96
|
|
78
|
-
#
|
97
|
+
# _args_ can be any of these forms:
|
98
|
+
# * (_symbol_, <em>slave = Relisp.default_slave</em>)
|
99
|
+
# * (_string_, <em>slave = Relisp.default_slave</em>)
|
100
|
+
# * (<em>slave = Relisp.default_slave</em>)
|
79
101
|
#
|
102
|
+
# When a _symbol_ is given it is considered to be the name of a
|
103
|
+
# pre-existing bufer in the _slave_ process. Otherwise a new,
|
104
|
+
# buffer is created (<tt>generate-new-buffer</tt>). The name is
|
105
|
+
# _string_, if given, and a variant of "relisp-buffer" otherwise.
|
106
|
+
#
|
107
|
+
def initialize(*args)
|
108
|
+
super do |args|
|
109
|
+
name = args[0] ? args[0] : "relisp-buffer"
|
110
|
+
raise ArgumentError unless name.kind_of?(String)
|
111
|
+
@slave.elisp_execute( "(setq #{@elisp_variable} (generate-new-buffer #{name.to_elisp}))" )
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Return the name of Buffer, as a string (<tt>buffer-name</tt>).
|
80
116
|
def name
|
81
|
-
@slave.
|
117
|
+
@slave.buffer_name(@elisp_variable.value)
|
118
|
+
end
|
119
|
+
|
120
|
+
# Save the buffer in its visited file, if it has been modified.
|
121
|
+
#
|
122
|
+
def save
|
123
|
+
@slave.elisp_eval <<-EOM
|
124
|
+
(save-excursion
|
125
|
+
(set-buffer #{@elisp_variable})
|
126
|
+
(save-buffer))
|
127
|
+
EOM
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# A proxy to an Emacs marker.
|
132
|
+
#
|
133
|
+
class Marker < Proxy
|
134
|
+
|
135
|
+
# _args_ can be any of these forms:
|
136
|
+
# * (_symbol_, <em>slave = Relisp.default_slave</em>)
|
137
|
+
# * (<em>slave = Relisp.default_slave</em>)
|
138
|
+
#
|
139
|
+
# When a _symbol_ is given it is considered to be the name of a
|
140
|
+
# pre-existing marker in the _slave_ process. Otherwise a new,
|
141
|
+
# empty marker is created (<tt>make-marker</tt>).
|
142
|
+
#
|
143
|
+
def initialize(*args)
|
144
|
+
super do
|
145
|
+
@slave.elisp_execute( "(setq #{@elisp_variable} (make-marker))" )
|
146
|
+
end
|
82
147
|
end
|
148
|
+
|
149
|
+
# Return a newly allocated marker which does not point at any
|
150
|
+
# position (<tt>make-marker</tt>).
|
151
|
+
#
|
152
|
+
def self.make(slave = Relisp.default_slave)
|
153
|
+
slave.make_marker
|
154
|
+
end
|
155
|
+
|
83
156
|
end
|
84
157
|
|
158
|
+
# A proxy to an Emacs window
|
159
|
+
#
|
160
|
+
class Window < Proxy
|
161
|
+
|
162
|
+
# _args_ must be of the form (_symbol_, <em>slave =
|
163
|
+
# Relisp.default_slave</em>)
|
164
|
+
#
|
165
|
+
# The _symbol_ argument is considered to be the name of a
|
166
|
+
# pre-existing window in the _slave_ process.
|
167
|
+
#
|
168
|
+
def initialize(*args)
|
169
|
+
super do
|
170
|
+
raise ArgumentError, "Cannot create Window using 'new' method."
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# A proxy to an Emacs frame
|
176
|
+
#
|
177
|
+
class Frame < Proxy
|
178
|
+
|
179
|
+
# _args_ can be any of these forms:
|
180
|
+
# * (_symbol_, <em>slave = Relisp.default_slave</em>)
|
181
|
+
# * (<em>option_hash = {}</em>, <em>slave = Relisp.default_slave</em>)
|
182
|
+
# * (<em>slave = Relisp.default_slave</em>)
|
183
|
+
#
|
184
|
+
# When a _symbol_ is given it is considered to be the name of a
|
185
|
+
# pre-existing frame in the _slave_ process. Otherwise a new,
|
186
|
+
# frame is created using any options in (<tt>new-frame</tt>).
|
187
|
+
#
|
188
|
+
# The _option_hash_ can specify the following
|
189
|
+
# [<tt>:name =></tt> _string_]
|
190
|
+
# The frame should be named _string_.
|
191
|
+
# [<tt>:width =></tt> _fixnum_]
|
192
|
+
# The frame should be _fixnum_ characters in width.
|
193
|
+
# [<tt>:height =></tt> _fixnum_]
|
194
|
+
# The frame should be _fixnum_ text lines high.
|
195
|
+
#
|
196
|
+
# You cannot specify either :width or :height, you must use neither or both.
|
197
|
+
#
|
198
|
+
# [<tt>:minibuffer => true</tt>]
|
199
|
+
# The frame should have a minibuffer.
|
200
|
+
# [<tt>:minibuffer => nil</tt>]
|
201
|
+
# The frame should have no minibuffer.
|
202
|
+
# [<tt>:minibuffer => :only</tt>]
|
203
|
+
# The frame should contain only a minibuffer.
|
204
|
+
# [<tt>:minibuffer =></tt> _window_]
|
205
|
+
# The frame should use _window_ as its minibuffer window.
|
206
|
+
#
|
207
|
+
# [<tt>:"window-system" => nil</tt>]
|
208
|
+
# The frame should be displayed on a terminal device.
|
209
|
+
# [<tt>:"window-system" => :x</tt>]
|
210
|
+
# The frame should be displayed in an X window.
|
211
|
+
# [<tt>:terminal =></tt> _id_]
|
212
|
+
# The frame should use the terminal identified by _id_.
|
213
|
+
#
|
214
|
+
def initialize(*args)
|
215
|
+
super do |args|
|
216
|
+
hash = args[0]
|
217
|
+
alist = ""
|
218
|
+
if hash && hash.size > 1
|
219
|
+
alist << "'("
|
220
|
+
hash.each_pair do |key, val|
|
221
|
+
val = if val.kind_of?(Symbol)
|
222
|
+
val.value.to_elisp
|
223
|
+
else
|
224
|
+
val.to_elisp
|
225
|
+
end
|
226
|
+
alist << "(#{key} . #{val.to_s}) "
|
227
|
+
end
|
228
|
+
alist << ")"
|
229
|
+
end
|
230
|
+
|
231
|
+
@slave.elisp_execute( "(setq #{@elisp_variable} (new-frame #{alist}))" )
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
end
|
236
|
+
|
237
|
+
# A proxy to an Emacs window-configuration
|
238
|
+
#
|
239
|
+
class WindowConfiguration < Proxy
|
240
|
+
|
241
|
+
# _args_ must be of the form (_symbol_, <em>slave =
|
242
|
+
# Relisp.default_slave</em>)
|
243
|
+
#
|
244
|
+
# The _symbol_ argument is considered to be the name of a
|
245
|
+
# pre-existing window-configuration in the _slave_ process.
|
246
|
+
#
|
247
|
+
def initialize(*args)
|
248
|
+
super do
|
249
|
+
raise ArgumentError, "Cannot create WindowConfiguration using 'new' method."
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
# A proxy to an Emacs frame-configuration
|
255
|
+
#
|
256
|
+
class FrameConfiguration < Proxy
|
257
|
+
|
258
|
+
# _args_ must be of the form (_symbol_, <em>slave =
|
259
|
+
# Relisp.default_slave</em>)
|
260
|
+
#
|
261
|
+
# The _symbol_ argument is considered to be the name of a
|
262
|
+
# pre-existing frame-configuration in the _slave_ process.
|
263
|
+
#
|
264
|
+
def initialize(*args)
|
265
|
+
@elisp_type = :cons
|
266
|
+
@elisp_test_type_function = "frame-configuration-p"
|
267
|
+
|
268
|
+
super do
|
269
|
+
raise ArgumentError, "Cannot create FrameConfiguration using 'new' method."
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
|
275
|
+
# # A proxy to an Emacs [OBJECT]
|
276
|
+
# #
|
277
|
+
# class [CLASS] < Proxy
|
278
|
+
|
279
|
+
# # _args_ can be any of these forms:
|
280
|
+
# # * (_symbol_, <em>slave = Relisp.default_slave</em>)
|
281
|
+
# # * (<em>slave = Relisp.default_slave</em>)
|
282
|
+
# #
|
283
|
+
# # When a _symbol_ is given it is considered to be the name of a
|
284
|
+
# # pre-existing [TYPE] in the _slave_ process. Otherwise a new,
|
285
|
+
# # empty [TYPE] is created (<tt>[FUNCTION]</tt>).
|
286
|
+
# #
|
287
|
+
# def initialize(*args)
|
288
|
+
# super do
|
289
|
+
# @slave.elisp_execute( "(setq #{@elisp_variable} (FUNCTION))" )
|
290
|
+
# end
|
291
|
+
# end
|
292
|
+
# end
|
293
|
+
|
85
294
|
end
|
86
295
|
|
@@ -0,0 +1,69 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (C) 2009 <don@ohspite.net>
|
3
|
+
#
|
4
|
+
# This file is part of Relisp.
|
5
|
+
#
|
6
|
+
# Relisp is free software: you can redistribute it and/or modify it
|
7
|
+
# under the terms of the GNU General Public License as published by
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# Relisp is distributed in the hope that it will be useful, but
|
12
|
+
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14
|
+
# General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License
|
17
|
+
# along with this program. If not, see
|
18
|
+
# <http://www.gnu.org/licenses/>.
|
19
|
+
#++
|
20
|
+
#
|
21
|
+
#
|
22
|
+
|
23
|
+
module Relisp
|
24
|
+
class Slave
|
25
|
+
|
26
|
+
# Save point, mark, and current buffer; execute a block of code;
|
27
|
+
# restore those things.
|
28
|
+
#
|
29
|
+
# This does not simply call the <tt>save-excursion</tt> function
|
30
|
+
# in elisp, it is a rewrite to accept a ruby block.
|
31
|
+
def save_excursion
|
32
|
+
raise ArgumentError unless block_given?
|
33
|
+
begin
|
34
|
+
start_point = point()
|
35
|
+
start_mark = mark()
|
36
|
+
start_buffer = current_buffer()
|
37
|
+
start_active = elisp_execute( "mark-active" )
|
38
|
+
yield
|
39
|
+
ensure
|
40
|
+
set_buffer(start_buffer)
|
41
|
+
set(:"mark-active", start_active)
|
42
|
+
goto_char(start_point)
|
43
|
+
set_mark(start_mark)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
# Forward any missing method to elisp, writing the function and
|
50
|
+
# arguments in prefix notation (calling the +to_elisp+ method of
|
51
|
+
# each of the _args_).
|
52
|
+
#
|
53
|
+
# This automatically allows access to a large portion of elisp
|
54
|
+
# functions a rubyish way.
|
55
|
+
#
|
56
|
+
def method_missing(function, *args) # :doc:
|
57
|
+
function = function.to_s.gsub('_', '-')
|
58
|
+
unless elisp_eval("(functionp '#{function})")
|
59
|
+
raise NameError, "#{function} is not an elisp function"
|
60
|
+
end
|
61
|
+
|
62
|
+
elisp_eval('(' +
|
63
|
+
function + ' ' +
|
64
|
+
args.map{|a| a.to_elisp}.join(' ') +
|
65
|
+
')')
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
@@ -54,9 +54,9 @@
|
|
54
54
|
#
|
55
55
|
# Every type in the first group obviously matches a ruby class except
|
56
56
|
# for 'Cons' and 'Vector'. The types that have an analogous ruby
|
57
|
-
# class are mapped directly to that class. 'Cons'
|
58
|
-
#
|
59
|
-
#
|
57
|
+
# class are mapped directly to that class. 'Cons' is a kept in a
|
58
|
+
# proxy object in the same way as the editting data types. 'Vector'
|
59
|
+
# is mapped to a corresponding subclass of Array.
|
60
60
|
#
|
61
61
|
# Every ruby class that corresponds to a elisp data type is duplicated
|
62
62
|
# inside the Relisp module with the rubyized version of the elisp
|
@@ -110,10 +110,140 @@ module Relisp
|
|
110
110
|
def to_elisp
|
111
111
|
"'" + self.to_s
|
112
112
|
end
|
113
|
+
|
114
|
+
def value
|
115
|
+
VariableValue.new(self)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# This exists so that the value of a Relisp::Symbol type can be
|
120
|
+
# conveniently passed to elisp.
|
121
|
+
#
|
122
|
+
# @slave.buffer_name(@elisp_variable)
|
123
|
+
# => Relisp::ElispError: Wrong type argument: bufferp, --relisp--variable--1
|
124
|
+
# @slave.buffer_name(@elisp_variable.value)
|
125
|
+
# => "my buffer"
|
126
|
+
#
|
127
|
+
class VariableValue
|
128
|
+
def initialize(variable)
|
129
|
+
@variable = variable
|
130
|
+
end
|
131
|
+
|
132
|
+
def to_elisp
|
133
|
+
@variable.to_s
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
#
|
138
|
+
# class Cons < Proxy
|
139
|
+
# def self.from_elisp(object)
|
140
|
+
# slave = object[:slave]
|
141
|
+
# object_variable = slave.get_permanent_variable(object[:variable])
|
142
|
+
# car = slave.elisp_eval("(car #{object_variable})")
|
143
|
+
# cdr = slave.elisp_eval("(cdr #{object_variable})")
|
144
|
+
# new(car, cdr)
|
145
|
+
# end
|
146
|
+
|
147
|
+
# def initialize(car, cdr)
|
148
|
+
# @car = car
|
149
|
+
# @cdr = cdr
|
150
|
+
# end
|
151
|
+
|
152
|
+
# attr_accessor :car, :cdr
|
153
|
+
|
154
|
+
# def to_list
|
155
|
+
# end
|
156
|
+
|
157
|
+
# def inspect
|
158
|
+
# to_s
|
159
|
+
# end
|
160
|
+
|
161
|
+
# def to_s
|
162
|
+
# str = "(" + car.inspect
|
163
|
+
# if @cdr
|
164
|
+
# cdr = @cdr
|
165
|
+
# while cdr.kind_of?(Cons)
|
166
|
+
# str << " #{cdr.car.inspect}"
|
167
|
+
# cdr = cdr.cdr
|
168
|
+
# end
|
169
|
+
# str << " . #{cdr.inspect}" unless cdr == nil
|
170
|
+
# str << ")"
|
171
|
+
# end
|
172
|
+
# end
|
173
|
+
|
174
|
+
# def to_elisp
|
175
|
+
# str = "(cons #{@car.to_elisp} #{@cdr.to_elisp})"
|
176
|
+
# end
|
177
|
+
# end
|
178
|
+
|
179
|
+
# A proxy to an Emacs cons. If the cons is actually a list, the
|
180
|
+
# to_list method will convert it a subclass of Array so that all of
|
181
|
+
# the ruby Array stuff is available.
|
182
|
+
#
|
183
|
+
class Cons < Proxy
|
184
|
+
|
185
|
+
# _args_ must be of the form (_symbol_, <em>slave =
|
186
|
+
# Relisp.default_slave</em>)
|
187
|
+
#
|
188
|
+
# The _symbol_ argument is considered to be the name of a
|
189
|
+
# pre-existing window in the _slave_ process.
|
190
|
+
#
|
191
|
+
def initialize(*args)
|
192
|
+
super do
|
193
|
+
raise ArgumentError, "Cannot create Cons using 'new' method."
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def car
|
198
|
+
@slave.car(@elisp_variable.value)
|
199
|
+
end
|
200
|
+
|
201
|
+
def cdr
|
202
|
+
@slave.cdr(@elisp_variable.value)
|
203
|
+
end
|
204
|
+
|
205
|
+
# This function will NOT return true whenever the elisp function
|
206
|
+
# <tt>listp</tt> is true. The elisp function is true whenever the
|
207
|
+
# object is a cons cell, but this method is true only when the
|
208
|
+
# cons can be unambiguously translated to an array; this condition
|
209
|
+
# is satisfied when the object in question could have been written
|
210
|
+
# using the elisp function +list+.
|
211
|
+
#
|
212
|
+
def list?
|
213
|
+
current_cdr = cdr
|
214
|
+
while current_cdr.kind_of?(Cons)
|
215
|
+
current_cdr = current_cdr.cdr
|
216
|
+
end
|
217
|
+
if current_cdr.nil?
|
218
|
+
return true
|
219
|
+
else
|
220
|
+
return false
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
# Translate the cons cell into a Relisp::List, a subclass of
|
225
|
+
# Array. See list? for when this be done.
|
226
|
+
#
|
227
|
+
def to_list
|
228
|
+
list_array = []
|
229
|
+
list_array << car
|
230
|
+
current_cdr = cdr
|
231
|
+
while current_cdr.kind_of?(Cons)
|
232
|
+
list_array << current_cdr.car
|
233
|
+
current_cdr = current_cdr.cdr
|
234
|
+
end
|
235
|
+
|
236
|
+
if current_cdr.nil?
|
237
|
+
return Relisp::List.new(list_array)
|
238
|
+
else
|
239
|
+
return false
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
113
243
|
end
|
114
244
|
|
115
245
|
|
116
|
-
class
|
246
|
+
class List < Array
|
117
247
|
def self.from_elisp(object)
|
118
248
|
new(super(object))
|
119
249
|
end
|
@@ -173,7 +303,9 @@ module Relisp
|
|
173
303
|
(setq #{vals_var} (append #{vals_var} (list val)))) #{object_variable})" )
|
174
304
|
keys = slave.elisp_eval( keys_var )
|
175
305
|
vals = slave.elisp_eval( vals_var )
|
176
|
-
keys ||=
|
306
|
+
keys ||= nil
|
307
|
+
keys = keys.to_list
|
308
|
+
vals = vals.to_list
|
177
309
|
hash = Hash.new
|
178
310
|
keys.each_index do |i|
|
179
311
|
hash[keys[i]] = vals[i]
|
@@ -242,10 +374,10 @@ end
|
|
242
374
|
|
243
375
|
|
244
376
|
# The normal Array class is modified so that an array can be converted
|
245
|
-
# to either Relisp::
|
377
|
+
# to either Relisp::List or Relisp::Vector.
|
246
378
|
#
|
247
379
|
class Array
|
248
|
-
@@default_elisp_type = Relisp::
|
380
|
+
@@default_elisp_type = Relisp::List
|
249
381
|
|
250
382
|
# Converts either a 'cons' or 'vector' to a ruby array.
|
251
383
|
def self.from_elisp(object)
|
@@ -291,3 +423,5 @@ class Array
|
|
291
423
|
elisp_type.new(self).to_elisp
|
292
424
|
end
|
293
425
|
end
|
426
|
+
|
427
|
+
|
data/lib/relisp/slaves.rb
CHANGED
@@ -18,8 +18,7 @@
|
|
18
18
|
# <http://www.gnu.org/licenses/>.
|
19
19
|
#++
|
20
20
|
#
|
21
|
-
# TODO:
|
22
|
-
# * maybe catch Errno::EPIPE to see if slave died
|
21
|
+
# TODO: maybe catch Errno::EPIPE to see if slave died
|
23
22
|
|
24
23
|
module Relisp
|
25
24
|
|
@@ -158,25 +157,6 @@ module Relisp
|
|
158
157
|
end
|
159
158
|
end
|
160
159
|
|
161
|
-
# Forward any missing method to elisp, writing the function and
|
162
|
-
# arguments in prefix notation (calling the +to_elisp+ method of
|
163
|
-
# each of the _args_).
|
164
|
-
#
|
165
|
-
# This automatically allows access to a large portion of elisp
|
166
|
-
# functions a rubyish way.
|
167
|
-
#
|
168
|
-
def method_missing(function, *args) # :doc:
|
169
|
-
function = function.to_s.gsub('_', '-')
|
170
|
-
unless elisp_eval("(functionp '#{function})")
|
171
|
-
raise NameError, "#{function} is not an elisp function"
|
172
|
-
end
|
173
|
-
|
174
|
-
elisp_eval('(' +
|
175
|
-
function + ' ' +
|
176
|
-
args.map{|a| a.to_elisp}.join(' ') +
|
177
|
-
')')
|
178
|
-
end
|
179
|
-
|
180
160
|
public
|
181
161
|
|
182
162
|
# Creates a method in the slave that is a reference to the
|
@@ -327,11 +307,12 @@ module Relisp
|
|
327
307
|
@debug = true
|
328
308
|
puts
|
329
309
|
puts "-----------------"
|
330
|
-
yield
|
310
|
+
result = yield
|
331
311
|
ensure
|
332
312
|
@debug = debug_original_val
|
333
313
|
puts "-----------------"
|
334
314
|
end
|
315
|
+
return result
|
335
316
|
else
|
336
317
|
@debug = ! @debug
|
337
318
|
end
|
data/lib/relisp.rb
CHANGED
@@ -19,12 +19,12 @@
|
|
19
19
|
#++
|
20
20
|
|
21
21
|
module Relisp
|
22
|
-
VERSION = '0.9.
|
22
|
+
VERSION = '0.9.1'
|
23
23
|
|
24
24
|
class ElispError < RuntimeError; end
|
25
25
|
end
|
26
26
|
|
27
|
-
require 'relisp/slaves'
|
28
|
-
require 'relisp/programming_types'
|
29
27
|
require 'relisp/editing_types'
|
30
|
-
|
28
|
+
require 'relisp/elisp_functions.rb'
|
29
|
+
require 'relisp/programming_types'
|
30
|
+
require 'relisp/slaves'
|
data/setup.rb
CHANGED
data/src/relisp.el
CHANGED
@@ -69,12 +69,13 @@
|
|
69
69
|
|
70
70
|
(defun relisp-log (text)
|
71
71
|
"Insert TEXT at the end of `relisp-buffer-name', unless emacs is the slave."
|
72
|
-
(
|
73
|
-
(
|
74
|
-
|
75
|
-
(
|
76
|
-
|
77
|
-
|
72
|
+
(save-excursion
|
73
|
+
(when relisp-emacs-master-p
|
74
|
+
(get-buffer-create relisp-buffer-name)
|
75
|
+
(unless (string-match (relisp-endofmessage-regexp) (relisp-strip text))
|
76
|
+
(set-buffer relisp-buffer-name)
|
77
|
+
(goto-char (point-max))
|
78
|
+
(insert text "\n")))))
|
78
79
|
|
79
80
|
(defun relisp-write-to-ruby (message)
|
80
81
|
"Send MESSAGE to the ruby process."
|
data/test/test_editing_types.rb
CHANGED
@@ -7,6 +7,34 @@ require 'relisp'
|
|
7
7
|
|
8
8
|
|
9
9
|
module TestRelisp
|
10
|
+
class TestProxy < Test::Unit::TestCase
|
11
|
+
def setup
|
12
|
+
@emacs = Relisp::ElispSlave.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_class_from_elisp
|
16
|
+
test_buffer_name = "*relisp-test-buffer*"
|
17
|
+
buffer = @emacs.elisp_eval( "(create-file-buffer \"#{test_buffer_name}\") " )
|
18
|
+
assert_kind_of Relisp::Buffer, buffer
|
19
|
+
buffer_names = @emacs.elisp_eval( '(buffer-list)' ).to_list.map { |buffer| buffer.name }
|
20
|
+
assert buffer_names.include?(test_buffer_name)
|
21
|
+
end
|
22
|
+
|
23
|
+
# This is really tested in all of the other classes.
|
24
|
+
def test_initialize
|
25
|
+
new_buffer = Relisp::Buffer.new("new-buffer")
|
26
|
+
assert_kind_of Relisp::Buffer, new_buffer
|
27
|
+
assert_equal "new-buffer", new_buffer.name
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_to_elisp
|
31
|
+
test_buffer_name = "*relisp-test-buffer*"
|
32
|
+
buffer = @emacs.elisp_eval( "(create-file-buffer \"#{test_buffer_name}\") " )
|
33
|
+
assert_equal :buffer, @emacs.elisp_eval("(type-of #{buffer.to_elisp})")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
|
10
38
|
class TestBuffer < Test::Unit::TestCase
|
11
39
|
def setup
|
12
40
|
@emacs = Relisp::ElispSlave.new
|
@@ -16,7 +44,7 @@ module TestRelisp
|
|
16
44
|
test_buffer_name = "*relisp-test-buffer*"
|
17
45
|
buffer = @emacs.elisp_eval( "(create-file-buffer \"#{test_buffer_name}\") " )
|
18
46
|
assert_kind_of Relisp::Buffer, buffer
|
19
|
-
buffer_names = @emacs.elisp_eval( '(buffer-list)' ).map { |buffer| buffer.name }
|
47
|
+
buffer_names = @emacs.elisp_eval( '(buffer-list)' ).to_list.map { |buffer| buffer.name }
|
20
48
|
assert buffer_names.include?(test_buffer_name)
|
21
49
|
end
|
22
50
|
|
@@ -24,6 +52,8 @@ module TestRelisp
|
|
24
52
|
new_buffer = Relisp::Buffer.new("new-buffer")
|
25
53
|
assert_kind_of Relisp::Buffer, new_buffer
|
26
54
|
assert_equal "new-buffer", new_buffer.name
|
55
|
+
found_buffer = @emacs.get_buffer(new_buffer.name)
|
56
|
+
assert_kind_of Relisp::Buffer, found_buffer
|
27
57
|
end
|
28
58
|
|
29
59
|
def test_to_elisp
|
@@ -37,7 +67,78 @@ module TestRelisp
|
|
37
67
|
buffer = @emacs.elisp_eval( "(create-file-buffer \"#{test_buffer_name}\") " )
|
38
68
|
assert_equal test_buffer_name, buffer.name
|
39
69
|
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class TestMarker < Test::Unit::TestCase
|
73
|
+
def setup
|
74
|
+
@emacs = Relisp::ElispSlave.new
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_class_from_elisp
|
78
|
+
assert_kind_of Relisp::Marker, @emacs.point_marker
|
79
|
+
assert @emacs.elisp_eval( "(equal #{@emacs.point_marker.to_elisp} (point-marker))" )
|
80
|
+
assert_kind_of Relisp::Marker, Relisp::Marker.new
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_class_make
|
84
|
+
assert_kind_of Relisp::Marker, Relisp::Marker.make
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_to_elisp
|
88
|
+
assert_equal :marker, @emacs.elisp_eval( "(type-of #{@emacs.point_marker.to_elisp})" )
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class TestWindow < Test::Unit::TestCase
|
93
|
+
def setup
|
94
|
+
@emacs = Relisp::ElispSlave.new
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_class_from_elisp
|
98
|
+
assert_kind_of Relisp::Window, @emacs.selected_window
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
class TestFrame < Test::Unit::TestCase
|
103
|
+
def setup
|
104
|
+
@emacs = Relisp::ElispSlave.new
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_class_from_elisp
|
108
|
+
assert_kind_of Relisp::Frame, @emacs.selected_frame
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_initialize
|
112
|
+
new_frame = Relisp::Frame.new
|
113
|
+
assert_kind_of Relisp::Frame, new_frame
|
114
|
+
assert_equal :frame, @emacs.elisp_eval( "(type-of #{new_frame.to_elisp})")
|
115
|
+
new_frame = Relisp::Frame.new({:width => 30, :height => 20})
|
116
|
+
assert_kind_of Relisp::Frame, new_frame
|
117
|
+
assert_equal :frame, @emacs.elisp_eval( "(type-of #{new_frame.to_elisp})")
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
class TestWindowConfiguration < Test::Unit::TestCase
|
122
|
+
def setup
|
123
|
+
@emacs = Relisp::ElispSlave.new
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_class_from_elisp
|
127
|
+
assert_kind_of Relisp::WindowConfiguration, @emacs.current_window_configuration
|
128
|
+
end
|
129
|
+
end
|
40
130
|
|
131
|
+
class TestFrameConfiguration < Test::Unit::TestCase
|
132
|
+
def setup
|
133
|
+
@emacs = Relisp::ElispSlave.new
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_class_from_elisp
|
137
|
+
# assert_kind_of Relisp::WindowConfiguration, @emacs.current_frame_configuration
|
138
|
+
assert_kind_of Relisp::Cons, @emacs.current_frame_configuration
|
139
|
+
assert_equal :"frame-configuration", @emacs.current_frame_configuration.car
|
140
|
+
end
|
41
141
|
end
|
142
|
+
|
42
143
|
end
|
43
144
|
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# Code Generated by ZenTest v. 3.11.1
|
2
|
+
|
3
|
+
require 'test/unit' unless defined? $ZENTEST and $ZENTEST
|
4
|
+
|
5
|
+
$:.unshift File.dirname(__FILE__) + "/../lib"
|
6
|
+
require 'relisp'
|
7
|
+
|
8
|
+
module TestRelisp
|
9
|
+
class TestSlave < Test::Unit::TestCase
|
10
|
+
# setup done in test_slaves.rb
|
11
|
+
# def setup
|
12
|
+
# @emacs = Relisp::ElispSlave.new
|
13
|
+
# end
|
14
|
+
|
15
|
+
def test_save_excursion
|
16
|
+
# TODO: test mark, mark-active
|
17
|
+
start_point = @emacs.point
|
18
|
+
start_buffer = @emacs.current_buffer
|
19
|
+
@emacs.save_excursion do
|
20
|
+
@emacs.insert("move along")
|
21
|
+
assert_not_equal start_point, @emacs.point
|
22
|
+
buffer = Relisp::Buffer.new("--relisp--test--", @emacs)
|
23
|
+
@emacs.switch_to_buffer(buffer)
|
24
|
+
assert_not_equal start_buffer.name, @emacs.current_buffer.name
|
25
|
+
end
|
26
|
+
assert_equal start_point, @emacs.point
|
27
|
+
assert_equal start_buffer.name, @emacs.current_buffer.name
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_method_missing
|
31
|
+
assert_equal 6, @emacs.+(1, 2, 3)
|
32
|
+
assert_raise NameError do
|
33
|
+
@emacs.utter_nonsense
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
@@ -22,7 +22,7 @@ class TestArray < Test::Unit::TestCase
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def test_class_from_elisp
|
25
|
-
assert "if from_elisp works for Vector and
|
25
|
+
assert "if from_elisp works for Vector and List, then this works"
|
26
26
|
end
|
27
27
|
|
28
28
|
def test_class_default_elisp_type_equals
|
@@ -31,12 +31,12 @@ class TestArray < Test::Unit::TestCase
|
|
31
31
|
end
|
32
32
|
Array.default_elisp_type = Relisp::Vector
|
33
33
|
assert_equal Relisp::Vector, Array.default_elisp_type
|
34
|
-
Array.default_elisp_type = Relisp::
|
35
|
-
assert_equal Relisp::
|
34
|
+
Array.default_elisp_type = Relisp::List
|
35
|
+
assert_equal Relisp::List, Array.default_elisp_type
|
36
36
|
end
|
37
37
|
|
38
38
|
def test_to_elisp
|
39
|
-
Array.default_elisp_type = Relisp::
|
39
|
+
Array.default_elisp_type = Relisp::List
|
40
40
|
assert_equal :cons, @emacs.elisp_eval( "(type-of #{[1, 2, 3].to_elisp})" )
|
41
41
|
Array.default_elisp_type = Relisp::Vector
|
42
42
|
assert_equal :vector, @emacs.elisp_eval( "(type-of #{[1, 2, 3].to_elisp})" )
|
@@ -53,7 +53,7 @@ class TestArray < Test::Unit::TestCase
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def test_elisp_type_equals
|
56
|
-
Array.default_elisp_type = Relisp::
|
56
|
+
Array.default_elisp_type = Relisp::List
|
57
57
|
array = [1, 2, 3]
|
58
58
|
assert_equal :cons, @emacs.elisp_eval( "(type-of #{array.to_elisp})" )
|
59
59
|
array.elisp_type = Relisp::Vector
|
@@ -124,18 +124,49 @@ module TestRelisp
|
|
124
124
|
@emacs = Relisp::ElispSlave.new
|
125
125
|
end
|
126
126
|
|
127
|
+
def test_car
|
128
|
+
result = @emacs.elisp_eval( "'(1 2 3)" )
|
129
|
+
assert_equal 1, result.car
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_cdr
|
133
|
+
result = @emacs.elisp_eval( "'(1 2 3)" )
|
134
|
+
assert_equal @emacs.elisp_eval( "'(2 3)" ).to_list, result.cdr.to_list
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_list_eh
|
138
|
+
result = @emacs.elisp_eval( "'(1 2 3)" )
|
139
|
+
assert result.list?
|
140
|
+
result = @emacs.elisp_eval( "'(1 . 2)" )
|
141
|
+
assert ! result.list?
|
142
|
+
end
|
143
|
+
|
144
|
+
def test_to_list
|
145
|
+
result = @emacs.elisp_eval( "'(1 2 3)" ).to_list
|
146
|
+
assert_equal [1, 2, 3], result
|
147
|
+
result = @emacs.elisp_eval( "'(1 . 2)" )
|
148
|
+
assert ! result.to_list
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
152
|
+
|
153
|
+
class TestList < Test::Unit::TestCase
|
154
|
+
def setup
|
155
|
+
@emacs = Relisp::ElispSlave.new
|
156
|
+
end
|
157
|
+
|
127
158
|
def test_class_from_elisp
|
128
|
-
Array.default_elisp_type = Relisp::
|
129
|
-
result = @emacs.elisp_eval( "'(1 \"string\" 3 [4 5] )" )
|
130
|
-
|
131
|
-
assert_equal Relisp::
|
159
|
+
Array.default_elisp_type = Relisp::List
|
160
|
+
result = @emacs.elisp_eval( "'(1 \"string\" 3 [4 5] )" ).to_list
|
161
|
+
assert_kind_of Array, result
|
162
|
+
assert_equal Relisp::List, result.class
|
132
163
|
assert_equal "string", result[1]
|
133
164
|
assert_equal [4, 5], result[3]
|
134
165
|
end
|
135
166
|
|
136
167
|
def test_to_elisp
|
137
168
|
list = [1,2,'a',[4,5]]
|
138
|
-
list.elisp_type = Relisp::
|
169
|
+
list.elisp_type = Relisp::List
|
139
170
|
assert @emacs.elisp_eval( "(equal (list 1 2 \"a\" (list 4 5)) #{list.to_elisp})" )
|
140
171
|
assert @emacs.elisp_eval( "(equal (list 1 2 \"a\" (list 4 5)) (ruby-eval \"[1, 2, 'a', [4, 5]]\"))" )
|
141
172
|
assert_equal 1, @emacs.elisp_eval( "(car #{list.to_elisp})" )
|
data/test/test_slaves.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: relisp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Don
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-01-
|
12
|
+
date: 2009-01-28 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -41,6 +41,7 @@ files:
|
|
41
41
|
- examples/ruby_master/ruby_master_example
|
42
42
|
- lib/relisp.rb
|
43
43
|
- lib/relisp/editing_types.rb
|
44
|
+
- lib/relisp/elisp_functions.rb
|
44
45
|
- lib/relisp/programming_types.rb
|
45
46
|
- lib/relisp/slaves.rb
|
46
47
|
- setup.rb
|
@@ -60,6 +61,7 @@ files:
|
|
60
61
|
- tasks/svn.rake
|
61
62
|
- tasks/test.rake
|
62
63
|
- test/test_editing_types.rb
|
64
|
+
- test/test_elisp_functions.rb
|
63
65
|
- test/test_programming_types.rb
|
64
66
|
- test/test_slaves.rb
|
65
67
|
has_rdoc: true
|
@@ -107,4 +109,5 @@ summary: Call ruby from emacs and call elisp from ruby. If you never did you sho
|
|
107
109
|
test_files:
|
108
110
|
- test/test_editing_types.rb
|
109
111
|
- test/test_programming_types.rb
|
112
|
+
- test/test_elisp_functions.rb
|
110
113
|
- test/test_slaves.rb
|