xref: /vim-8.2.3635/src/if_ruby.c (revision 17fb0e89)
1 /* vi:set ts=8 sts=4 sw=4:
2  *
3  * VIM - Vi IMproved	by Bram Moolenaar
4  *
5  * Ruby interface by Shugo Maeda
6  *   with improvements by SegPhault (Ryan Paul)
7  *   with improvements by Jon Maken
8  *
9  * Do ":help uganda"  in Vim to read copying and usage conditions.
10  * Do ":help credits" in Vim to see a list of people who contributed.
11  * See README.txt for an overview of the Vim source code.
12  */
13 
14 #ifdef HAVE_CONFIG_H
15 # include "auto/config.h"
16 #endif
17 
18 #include <stdio.h>
19 #include <string.h>
20 
21 #ifdef _WIN32
22 # if !defined(DYNAMIC_RUBY_VER) || (DYNAMIC_RUBY_VER < 18)
23 #   define NT
24 # endif
25 # ifndef DYNAMIC_RUBY
26 #  define IMPORT /* For static dll usage __declspec(dllimport) */
27 #  define RUBYEXTERN __declspec(dllimport)
28 # endif
29 #endif
30 #ifndef RUBYEXTERN
31 # define RUBYEXTERN extern
32 #endif
33 
34 #ifdef DYNAMIC_RUBY
35 /*
36  * This is tricky.  In ruby.h there is (inline) function rb_class_of()
37  * definition.  This function use these variables.  But we want function to
38  * use dll_* variables.
39  */
40 # define rb_cFalseClass		(*dll_rb_cFalseClass)
41 # define rb_cFixnum		(*dll_rb_cFixnum)
42 # define rb_cNilClass		(*dll_rb_cNilClass)
43 # define rb_cSymbol		(*dll_rb_cSymbol)
44 # define rb_cTrueClass		(*dll_rb_cTrueClass)
45 # if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
46 /*
47  * On ver 1.8, all Ruby functions are exported with "__declspec(dllimport)"
48  * in ruby.h.  But it causes trouble for these variables, because it is
49  * defined in this file.  When defined this RUBY_EXPORT it modified to
50  * "extern" and be able to avoid this problem.
51  */
52 #  define RUBY_EXPORT
53 # endif
54 
55 #if !(defined(WIN32) || defined(_WIN64))
56 # include <dlfcn.h>
57 # define HINSTANCE void*
58 # define RUBY_PROC void*
59 # define load_dll(n) dlopen((n), RTLD_LAZY|RTLD_GLOBAL)
60 # define symbol_from_dll dlsym
61 # define close_dll dlclose
62 #else
63 # define RUBY_PROC FARPROC
64 # define load_dll vimLoadLib
65 # define symbol_from_dll GetProcAddress
66 # define close_dll FreeLibrary
67 #endif
68 
69 #endif  /* ifdef DYNAMIC_RUBY */
70 
71 /* suggested by Ariya Mizutani */
72 #if (_MSC_VER == 1200)
73 # undef _WIN32_WINNT
74 #endif
75 
76 #if (defined(RUBY_VERSION) && RUBY_VERSION >= 19) \
77     || (defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 19)
78 # define RUBY19_OR_LATER 1
79 #endif
80 
81 #if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 19
82 /* Ruby 1.9 defines a number of static functions which use rb_num2long and
83  * rb_int2big */
84 # define rb_num2long rb_num2long_stub
85 # define rb_int2big rb_int2big_stub
86 #endif
87 
88 #include <ruby.h>
89 #ifdef RUBY19_OR_LATER
90 # include <ruby/encoding.h>
91 #endif
92 
93 #undef off_t	/* ruby defines off_t as _int64, Mingw uses long */
94 #undef EXTERN
95 #undef _
96 
97 /* T_DATA defined both by Ruby and Mac header files, hack around it... */
98 #if defined(MACOS_X_UNIX) || defined(macintosh)
99 # define __OPENTRANSPORT__
100 # define __OPENTRANSPORTPROTOCOL__
101 # define __OPENTRANSPORTPROVIDERS__
102 #endif
103 
104 /*
105  * Backward compatiblity for Ruby 1.8 and earlier.
106  * Ruby 1.9 does not provide STR2CSTR, instead StringValuePtr is provided.
107  * Ruby 1.9 does not provide RXXX(s)->len and RXXX(s)->ptr, instead
108  * RXXX_LEN(s) and RXXX_PTR(s) are provided.
109  */
110 #ifndef StringValuePtr
111 # define StringValuePtr(s) STR2CSTR(s)
112 #endif
113 #ifndef RARRAY_LEN
114 # define RARRAY_LEN(s) RARRAY(s)->len
115 #endif
116 #ifndef RARRAY_PTR
117 # define RARRAY_PTR(s) RARRAY(s)->ptr
118 #endif
119 #ifndef RSTRING_LEN
120 # define RSTRING_LEN(s) RSTRING(s)->len
121 #endif
122 #ifndef RSTRING_PTR
123 # define RSTRING_PTR(s) RSTRING(s)->ptr
124 #endif
125 
126 #include "vim.h"
127 #include "version.h"
128 
129 #if defined(PROTO) && !defined(FEAT_RUBY)
130 /* Define these to be able to generate the function prototypes. */
131 # define VALUE int
132 # define RUBY_DATA_FUNC int
133 #endif
134 
135 static int ruby_initialized = 0;
136 static VALUE objtbl;
137 
138 static VALUE mVIM;
139 static VALUE cBuffer;
140 static VALUE cVimWindow;
141 static VALUE eDeletedBufferError;
142 static VALUE eDeletedWindowError;
143 
144 static int ensure_ruby_initialized(void);
145 static void error_print(int);
146 static void ruby_io_init(void);
147 static void ruby_vim_init(void);
148 
149 #if defined(DYNAMIC_RUBY) || defined(PROTO)
150 #ifdef PROTO
151 # define HINSTANCE int		/* for generating prototypes */
152 #endif
153 
154 /*
155  * Wrapper defines
156  */
157 #define rb_assoc_new			dll_rb_assoc_new
158 #define rb_cObject			(*dll_rb_cObject)
159 #define rb_check_type			dll_rb_check_type
160 #define rb_class_path			dll_rb_class_path
161 #define rb_data_object_alloc		dll_rb_data_object_alloc
162 #define rb_define_class_under		dll_rb_define_class_under
163 #define rb_define_const			dll_rb_define_const
164 #define rb_define_global_function	dll_rb_define_global_function
165 #define rb_define_method		dll_rb_define_method
166 #define rb_define_module		dll_rb_define_module
167 #define rb_define_module_function	dll_rb_define_module_function
168 #define rb_define_singleton_method	dll_rb_define_singleton_method
169 #define rb_define_virtual_variable	dll_rb_define_virtual_variable
170 #define rb_stdout			(*dll_rb_stdout)
171 #define rb_eArgError			(*dll_rb_eArgError)
172 #define rb_eIndexError			(*dll_rb_eIndexError)
173 #define rb_eRuntimeError		(*dll_rb_eRuntimeError)
174 #define rb_eStandardError		(*dll_rb_eStandardError)
175 #define rb_eval_string_protect		dll_rb_eval_string_protect
176 #define rb_global_variable		dll_rb_global_variable
177 #define rb_hash_aset			dll_rb_hash_aset
178 #define rb_hash_new			dll_rb_hash_new
179 #define rb_inspect			dll_rb_inspect
180 #define rb_int2inum			dll_rb_int2inum
181 #define rb_lastline_get			dll_rb_lastline_get
182 #define rb_lastline_set			dll_rb_lastline_set
183 #define rb_load_protect			dll_rb_load_protect
184 #ifndef RUBY19_OR_LATER
185 #define rb_num2long			dll_rb_num2long
186 #endif
187 #define rb_num2ulong			dll_rb_num2ulong
188 #define rb_obj_alloc			dll_rb_obj_alloc
189 #define rb_obj_as_string		dll_rb_obj_as_string
190 #define rb_obj_id			dll_rb_obj_id
191 #define rb_raise			dll_rb_raise
192 #define rb_str_cat			dll_rb_str_cat
193 #define rb_str_concat			dll_rb_str_concat
194 #define rb_str_new			dll_rb_str_new
195 #ifdef rb_str_new2
196 /* Ruby may #define rb_str_new2 to use rb_str_new_cstr. */
197 # define need_rb_str_new_cstr 1
198 /* Ruby's headers #define rb_str_new_cstr to make use of GCC's
199  * __builtin_constant_p extension. */
200 # undef rb_str_new_cstr
201 # define rb_str_new_cstr		dll_rb_str_new_cstr
202 #else
203 # define rb_str_new2			dll_rb_str_new2
204 #endif
205 #if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
206 # define rb_string_value		dll_rb_string_value
207 # define rb_string_value_ptr		dll_rb_string_value_ptr
208 # define rb_float_new			dll_rb_float_new
209 # define rb_ary_new			dll_rb_ary_new
210 # define rb_ary_push			dll_rb_ary_push
211 #else
212 # define rb_str2cstr			dll_rb_str2cstr
213 #endif
214 #ifdef RUBY19_OR_LATER
215 # define rb_errinfo			dll_rb_errinfo
216 #else
217 # define ruby_errinfo			(*dll_ruby_errinfo)
218 #endif
219 #define ruby_init			dll_ruby_init
220 #define ruby_init_loadpath		dll_ruby_init_loadpath
221 #ifdef WIN3264
222 # define NtInitialize			dll_NtInitialize
223 # if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
224 #  define rb_w32_snprintf		dll_rb_w32_snprintf
225 # endif
226 #endif
227 
228 #ifdef RUBY19_OR_LATER
229 # define ruby_script			dll_ruby_script
230 # define rb_enc_find_index		dll_rb_enc_find_index
231 # define rb_enc_find			dll_rb_enc_find
232 # define rb_enc_str_new			dll_rb_enc_str_new
233 # define rb_sprintf			dll_rb_sprintf
234 # define rb_require			dll_rb_require
235 # define ruby_init_stack		dll_ruby_init_stack
236 # define ruby_process_options		dll_ruby_process_options
237 #endif
238 
239 /*
240  * Pointers for dynamic link
241  */
242 static VALUE (*dll_rb_assoc_new) (VALUE, VALUE);
243 VALUE *dll_rb_cFalseClass;
244 VALUE *dll_rb_cFixnum;
245 VALUE *dll_rb_cNilClass;
246 static VALUE *dll_rb_cObject;
247 VALUE *dll_rb_cSymbol;
248 VALUE *dll_rb_cTrueClass;
249 static void (*dll_rb_check_type) (VALUE,int);
250 static VALUE (*dll_rb_class_path) (VALUE);
251 static VALUE (*dll_rb_data_object_alloc) (VALUE, void*, RUBY_DATA_FUNC, RUBY_DATA_FUNC);
252 static VALUE (*dll_rb_define_class_under) (VALUE, const char*, VALUE);
253 static void (*dll_rb_define_const) (VALUE,const char*,VALUE);
254 static void (*dll_rb_define_global_function) (const char*,VALUE(*)(),int);
255 static void (*dll_rb_define_method) (VALUE,const char*,VALUE(*)(),int);
256 static VALUE (*dll_rb_define_module) (const char*);
257 static void (*dll_rb_define_module_function) (VALUE,const char*,VALUE(*)(),int);
258 static void (*dll_rb_define_singleton_method) (VALUE,const char*,VALUE(*)(),int);
259 static void (*dll_rb_define_virtual_variable) (const char*,VALUE(*)(),void(*)());
260 static VALUE *dll_rb_stdout;
261 static VALUE *dll_rb_eArgError;
262 static VALUE *dll_rb_eIndexError;
263 static VALUE *dll_rb_eRuntimeError;
264 static VALUE *dll_rb_eStandardError;
265 static VALUE (*dll_rb_eval_string_protect) (const char*, int*);
266 static void (*dll_rb_global_variable) (VALUE*);
267 static VALUE (*dll_rb_hash_aset) (VALUE, VALUE, VALUE);
268 static VALUE (*dll_rb_hash_new) (void);
269 static VALUE (*dll_rb_inspect) (VALUE);
270 static VALUE (*dll_rb_int2inum) (long);
271 static VALUE (*dll_rb_int2inum) (long);
272 static VALUE (*dll_rb_lastline_get) (void);
273 static void (*dll_rb_lastline_set) (VALUE);
274 static void (*dll_rb_load_protect) (VALUE, int, int*);
275 static long (*dll_rb_num2long) (VALUE);
276 static unsigned long (*dll_rb_num2ulong) (VALUE);
277 static VALUE (*dll_rb_obj_alloc) (VALUE);
278 static VALUE (*dll_rb_obj_as_string) (VALUE);
279 static VALUE (*dll_rb_obj_id) (VALUE);
280 static void (*dll_rb_raise) (VALUE, const char*, ...);
281 #if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
282 static VALUE (*dll_rb_string_value) (volatile VALUE*);
283 #else
284 static char *(*dll_rb_str2cstr) (VALUE,int*);
285 #endif
286 static VALUE (*dll_rb_str_cat) (VALUE, const char*, long);
287 static VALUE (*dll_rb_str_concat) (VALUE, VALUE);
288 static VALUE (*dll_rb_str_new) (const char*, long);
289 #ifdef need_rb_str_new_cstr
290 /* Ruby may #define rb_str_new2 to use rb_str_new_cstr. */
291 static VALUE (*dll_rb_str_new_cstr) (const char*);
292 #else
293 static VALUE (*dll_rb_str_new2) (const char*);
294 #endif
295 #ifdef RUBY19_OR_LATER
296 static VALUE (*dll_rb_errinfo) (void);
297 #else
298 static VALUE *dll_ruby_errinfo;
299 #endif
300 static void (*dll_ruby_init) (void);
301 static void (*dll_ruby_init_loadpath) (void);
302 #ifdef WIN3264
303 static void (*dll_NtInitialize) (int*, char***);
304 # if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
305 static int (*dll_rb_w32_snprintf)(char*, size_t, const char*, ...);
306 # endif
307 #endif
308 #if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
309 static char * (*dll_rb_string_value_ptr) (volatile VALUE*);
310 static VALUE (*dll_rb_float_new) (double);
311 static VALUE (*dll_rb_ary_new) (void);
312 static VALUE (*dll_rb_ary_push) (VALUE, VALUE);
313 #endif
314 #ifdef RUBY19_OR_LATER
315 static VALUE (*dll_rb_int2big)(SIGNED_VALUE);
316 #endif
317 
318 #ifdef RUBY19_OR_LATER
319 static void (*dll_ruby_script) (const char*);
320 static int (*dll_rb_enc_find_index) (const char*);
321 static rb_encoding* (*dll_rb_enc_find) (const char*);
322 static VALUE (*dll_rb_enc_str_new) (const char*, long, rb_encoding*);
323 static VALUE (*dll_rb_sprintf) (const char*, ...);
324 static VALUE (*dll_rb_require) (const char*);
325 static void (*ruby_init_stack)(VALUE*);
326 static void* (*ruby_process_options)(int, char**);
327 #endif
328 
329 #ifdef RUBY19_OR_LATER
330 SIGNED_VALUE rb_num2long_stub(VALUE x)
331 {
332     return dll_rb_num2long(x);
333 }
334 VALUE rb_int2big_stub(SIGNED_VALUE x)
335 {
336     return dll_rb_int2big(x);
337 }
338 #endif
339 
340 static HINSTANCE hinstRuby = NULL; /* Instance of ruby.dll */
341 
342 /*
343  * Table of name to function pointer of ruby.
344  */
345 static struct
346 {
347     char *name;
348     RUBY_PROC *ptr;
349 } ruby_funcname_table[] =
350 {
351     {"rb_assoc_new", (RUBY_PROC*)&dll_rb_assoc_new},
352     {"rb_cFalseClass", (RUBY_PROC*)&dll_rb_cFalseClass},
353     {"rb_cFixnum", (RUBY_PROC*)&dll_rb_cFixnum},
354     {"rb_cNilClass", (RUBY_PROC*)&dll_rb_cNilClass},
355     {"rb_cObject", (RUBY_PROC*)&dll_rb_cObject},
356     {"rb_cSymbol", (RUBY_PROC*)&dll_rb_cSymbol},
357     {"rb_cTrueClass", (RUBY_PROC*)&dll_rb_cTrueClass},
358     {"rb_check_type", (RUBY_PROC*)&dll_rb_check_type},
359     {"rb_class_path", (RUBY_PROC*)&dll_rb_class_path},
360     {"rb_data_object_alloc", (RUBY_PROC*)&dll_rb_data_object_alloc},
361     {"rb_define_class_under", (RUBY_PROC*)&dll_rb_define_class_under},
362     {"rb_define_const", (RUBY_PROC*)&dll_rb_define_const},
363     {"rb_define_global_function", (RUBY_PROC*)&dll_rb_define_global_function},
364     {"rb_define_method", (RUBY_PROC*)&dll_rb_define_method},
365     {"rb_define_module", (RUBY_PROC*)&dll_rb_define_module},
366     {"rb_define_module_function", (RUBY_PROC*)&dll_rb_define_module_function},
367     {"rb_define_singleton_method", (RUBY_PROC*)&dll_rb_define_singleton_method},
368     {"rb_define_virtual_variable", (RUBY_PROC*)&dll_rb_define_virtual_variable},
369     {"rb_stdout", (RUBY_PROC*)&dll_rb_stdout},
370     {"rb_eArgError", (RUBY_PROC*)&dll_rb_eArgError},
371     {"rb_eIndexError", (RUBY_PROC*)&dll_rb_eIndexError},
372     {"rb_eRuntimeError", (RUBY_PROC*)&dll_rb_eRuntimeError},
373     {"rb_eStandardError", (RUBY_PROC*)&dll_rb_eStandardError},
374     {"rb_eval_string_protect", (RUBY_PROC*)&dll_rb_eval_string_protect},
375     {"rb_global_variable", (RUBY_PROC*)&dll_rb_global_variable},
376     {"rb_hash_aset", (RUBY_PROC*)&dll_rb_hash_aset},
377     {"rb_hash_new", (RUBY_PROC*)&dll_rb_hash_new},
378     {"rb_inspect", (RUBY_PROC*)&dll_rb_inspect},
379     {"rb_int2inum", (RUBY_PROC*)&dll_rb_int2inum},
380     {"rb_lastline_get", (RUBY_PROC*)&dll_rb_lastline_get},
381     {"rb_lastline_set", (RUBY_PROC*)&dll_rb_lastline_set},
382     {"rb_load_protect", (RUBY_PROC*)&dll_rb_load_protect},
383     {"rb_num2long", (RUBY_PROC*)&dll_rb_num2long},
384     {"rb_num2ulong", (RUBY_PROC*)&dll_rb_num2ulong},
385     {"rb_obj_alloc", (RUBY_PROC*)&dll_rb_obj_alloc},
386     {"rb_obj_as_string", (RUBY_PROC*)&dll_rb_obj_as_string},
387     {"rb_obj_id", (RUBY_PROC*)&dll_rb_obj_id},
388     {"rb_raise", (RUBY_PROC*)&dll_rb_raise},
389 #if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
390     {"rb_string_value", (RUBY_PROC*)&dll_rb_string_value},
391 #else
392     {"rb_str2cstr", (RUBY_PROC*)&dll_rb_str2cstr},
393 #endif
394     {"rb_str_cat", (RUBY_PROC*)&dll_rb_str_cat},
395     {"rb_str_concat", (RUBY_PROC*)&dll_rb_str_concat},
396     {"rb_str_new", (RUBY_PROC*)&dll_rb_str_new},
397 #ifdef need_rb_str_new_cstr
398     {"rb_str_new_cstr", (RUBY_PROC*)&dll_rb_str_new_cstr},
399 #else
400     {"rb_str_new2", (RUBY_PROC*)&dll_rb_str_new2},
401 #endif
402 #ifdef RUBY19_OR_LATER
403     {"rb_errinfo", (RUBY_PROC*)&dll_rb_errinfo},
404 #else
405     {"ruby_errinfo", (RUBY_PROC*)&dll_ruby_errinfo},
406 #endif
407     {"ruby_init", (RUBY_PROC*)&dll_ruby_init},
408     {"ruby_init_loadpath", (RUBY_PROC*)&dll_ruby_init_loadpath},
409 #ifdef WIN3264
410     {
411 # if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER < 19
412     "NtInitialize",
413 # else
414     "ruby_sysinit",
415 # endif
416 			(RUBY_PROC*)&dll_NtInitialize},
417 # if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
418     {"rb_w32_snprintf", (RUBY_PROC*)&dll_rb_w32_snprintf},
419 # endif
420 #endif
421 #if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
422     {"rb_string_value_ptr", (RUBY_PROC*)&dll_rb_string_value_ptr},
423     {"rb_float_new", (RUBY_PROC*)&dll_rb_float_new},
424     {"rb_ary_new", (RUBY_PROC*)&dll_rb_ary_new},
425     {"rb_ary_push", (RUBY_PROC*)&dll_rb_ary_push},
426 #endif
427 #ifdef RUBY19_OR_LATER
428     {"rb_int2big", (RUBY_PROC*)&dll_rb_int2big},
429     {"ruby_script", (RUBY_PROC*)&dll_ruby_script},
430     {"rb_enc_find_index", (RUBY_PROC*)&dll_rb_enc_find_index},
431     {"rb_enc_find", (RUBY_PROC*)&dll_rb_enc_find},
432     {"rb_enc_str_new", (RUBY_PROC*)&dll_rb_enc_str_new},
433     {"rb_sprintf", (RUBY_PROC*)&dll_rb_sprintf},
434     {"rb_require", (RUBY_PROC*)&dll_rb_require},
435     {"ruby_init_stack", (RUBY_PROC*)&dll_ruby_init_stack},
436     {"ruby_process_options", (RUBY_PROC*)&dll_ruby_process_options},
437 #endif
438     {"", NULL},
439 };
440 
441 /*
442  * Free ruby.dll
443  */
444     static void
445 end_dynamic_ruby()
446 {
447     if (hinstRuby)
448     {
449 	close_dll(hinstRuby);
450 	hinstRuby = NULL;
451     }
452 }
453 
454 /*
455  * Load library and get all pointers.
456  * Parameter 'libname' provides name of DLL.
457  * Return OK or FAIL.
458  */
459     static int
460 ruby_runtime_link_init(char *libname, int verbose)
461 {
462     int i;
463 
464     if (hinstRuby)
465 	return OK;
466     hinstRuby = load_dll(libname);
467     if (!hinstRuby)
468     {
469 	if (verbose)
470 	    EMSG2(_(e_loadlib), libname);
471 	return FAIL;
472     }
473 
474     for (i = 0; ruby_funcname_table[i].ptr; ++i)
475     {
476 	if (!(*ruby_funcname_table[i].ptr = symbol_from_dll(hinstRuby,
477 			ruby_funcname_table[i].name)))
478 	{
479 	    close_dll(hinstRuby);
480 	    hinstRuby = NULL;
481 	    if (verbose)
482 		EMSG2(_(e_loadfunc), ruby_funcname_table[i].name);
483 	    return FAIL;
484 	}
485     }
486     return OK;
487 }
488 
489 /*
490  * If ruby is enabled (there is installed ruby on Windows system) return TRUE,
491  * else FALSE.
492  */
493     int
494 ruby_enabled(verbose)
495     int		verbose;
496 {
497     return ruby_runtime_link_init(DYNAMIC_RUBY_DLL, verbose) == OK;
498 }
499 #endif /* defined(DYNAMIC_RUBY) || defined(PROTO) */
500 
501     void
502 ruby_end()
503 {
504 #ifdef DYNAMIC_RUBY
505     end_dynamic_ruby();
506 #endif
507 }
508 
509 void ex_ruby(exarg_T *eap)
510 {
511     int state;
512     char *script = NULL;
513 
514     script = (char *)script_get(eap, eap->arg);
515     if (!eap->skip && ensure_ruby_initialized())
516     {
517 	if (script == NULL)
518 	    rb_eval_string_protect((char *)eap->arg, &state);
519 	else
520 	    rb_eval_string_protect(script, &state);
521 	if (state)
522 	    error_print(state);
523     }
524     vim_free(script);
525 }
526 
527 /*
528  *  In Ruby 1.9 or later, ruby String object has encoding.
529  *  conversion buffer string of vim to ruby String object using
530  *  VIM encoding option.
531  */
532     static VALUE
533 vim_str2rb_enc_str(const char *s)
534 {
535 #ifdef RUBY19_OR_LATER
536     int isnum;
537     long lval;
538     char_u *sval;
539     rb_encoding *enc;
540 
541     isnum = get_option_value((char_u *)"enc", &lval, &sval, 0);
542     if (isnum == 0)
543     {
544 	enc = rb_enc_find((char *)sval);
545 	vim_free(sval);
546 	if (enc) {
547 	    return rb_enc_str_new(s, strlen(s), enc);
548 	}
549     }
550 #endif
551     return rb_str_new2(s);
552 }
553 
554     static VALUE
555 eval_enc_string_protect(const char *str, int *state)
556 {
557 #ifdef RUBY19_OR_LATER
558     int isnum;
559     long lval;
560     char_u *sval;
561     rb_encoding *enc;
562     VALUE v;
563 
564     isnum = get_option_value((char_u *)"enc", &lval, &sval, 0);
565     if (isnum == 0)
566     {
567 	enc = rb_enc_find((char *)sval);
568 	vim_free(sval);
569 	if (enc)
570 	{
571 	    v = rb_sprintf("#-*- coding:%s -*-\n%s", rb_enc_name(enc), str);
572 	    return rb_eval_string_protect(StringValuePtr(v), state);
573 	}
574     }
575 #endif
576     return rb_eval_string_protect(str, state);
577 }
578 
579 void ex_rubydo(exarg_T *eap)
580 {
581     int state;
582     linenr_T i;
583 
584     if (ensure_ruby_initialized())
585     {
586 	if (u_save(eap->line1 - 1, eap->line2 + 1) != OK)
587 	    return;
588 	for (i = eap->line1; i <= eap->line2; i++) {
589 	    VALUE line;
590 
591 	    line = vim_str2rb_enc_str((char *)ml_get(i));
592 	    rb_lastline_set(line);
593 	    eval_enc_string_protect((char *) eap->arg, &state);
594 	    if (state) {
595 		error_print(state);
596 		break;
597 	    }
598 	    line = rb_lastline_get();
599 	    if (!NIL_P(line)) {
600 		if (TYPE(line) != T_STRING) {
601 		    EMSG(_("E265: $_ must be an instance of String"));
602 		    return;
603 		}
604 		ml_replace(i, (char_u *) StringValuePtr(line), 1);
605 		changed();
606 #ifdef SYNTAX_HL
607 		syn_changed(i); /* recompute syntax hl. for this line */
608 #endif
609 	    }
610 	}
611 	check_cursor();
612 	update_curbuf(NOT_VALID);
613     }
614 }
615 
616 void ex_rubyfile(exarg_T *eap)
617 {
618     int state;
619 
620     if (ensure_ruby_initialized())
621     {
622 	rb_load_protect(rb_str_new2((char *) eap->arg), 0, &state);
623 	if (state) error_print(state);
624     }
625 }
626 
627 void ruby_buffer_free(buf_T *buf)
628 {
629     if (buf->b_ruby_ref)
630     {
631 	rb_hash_aset(objtbl, rb_obj_id((VALUE) buf->b_ruby_ref), Qnil);
632 	RDATA(buf->b_ruby_ref)->data = NULL;
633     }
634 }
635 
636 void ruby_window_free(win_T *win)
637 {
638     if (win->w_ruby_ref)
639     {
640 	rb_hash_aset(objtbl, rb_obj_id((VALUE) win->w_ruby_ref), Qnil);
641 	RDATA(win->w_ruby_ref)->data = NULL;
642     }
643 }
644 
645 static int ensure_ruby_initialized(void)
646 {
647     if (!ruby_initialized)
648     {
649 #ifdef DYNAMIC_RUBY
650 	if (ruby_enabled(TRUE))
651 	{
652 #endif
653 #ifdef _WIN32
654 	    /* suggested by Ariya Mizutani */
655 	    int argc = 1;
656 	    char *argv[] = {"gvim.exe"};
657 	    NtInitialize(&argc, &argv);
658 #endif
659 	    {
660 #ifdef RUBY19_OR_LATER
661 		RUBY_INIT_STACK;
662 #endif
663 		ruby_init();
664 	    }
665 #ifdef RUBY19_OR_LATER
666 	    {
667 		int dummy_argc = 2;
668 		char *dummy_argv[] = {"vim-ruby", "-e0"};
669 		ruby_process_options(dummy_argc, dummy_argv);
670 	    }
671 	    ruby_script("vim-ruby");
672 #else
673 	    ruby_init_loadpath();
674 #endif
675 	    ruby_io_init();
676 	    ruby_vim_init();
677 	    ruby_initialized = 1;
678 #ifdef DYNAMIC_RUBY
679 	}
680 	else
681 	{
682 	    EMSG(_("E266: Sorry, this command is disabled, the Ruby library could not be loaded."));
683 	    return 0;
684 	}
685 #endif
686     }
687     return ruby_initialized;
688 }
689 
690 static void error_print(int state)
691 {
692 #ifndef DYNAMIC_RUBY
693 #if !(defined(RUBY_VERSION) && RUBY_VERSION >= 19) \
694     && !(defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 19)
695     RUBYEXTERN VALUE ruby_errinfo;
696 #endif
697 #endif
698     VALUE eclass;
699     VALUE einfo;
700     char buff[BUFSIZ];
701 
702 #define TAG_RETURN	0x1
703 #define TAG_BREAK	0x2
704 #define TAG_NEXT	0x3
705 #define TAG_RETRY	0x4
706 #define TAG_REDO	0x5
707 #define TAG_RAISE	0x6
708 #define TAG_THROW	0x7
709 #define TAG_FATAL	0x8
710 #define TAG_MASK	0xf
711 
712     switch (state) {
713     case TAG_RETURN:
714 	EMSG(_("E267: unexpected return"));
715 	break;
716     case TAG_NEXT:
717 	EMSG(_("E268: unexpected next"));
718 	break;
719     case TAG_BREAK:
720 	EMSG(_("E269: unexpected break"));
721 	break;
722     case TAG_REDO:
723 	EMSG(_("E270: unexpected redo"));
724 	break;
725     case TAG_RETRY:
726 	EMSG(_("E271: retry outside of rescue clause"));
727 	break;
728     case TAG_RAISE:
729     case TAG_FATAL:
730 #ifdef RUBY19_OR_LATER
731 	eclass = CLASS_OF(rb_errinfo());
732 	einfo = rb_obj_as_string(rb_errinfo());
733 #else
734 	eclass = CLASS_OF(ruby_errinfo);
735 	einfo = rb_obj_as_string(ruby_errinfo);
736 #endif
737 	if (eclass == rb_eRuntimeError && RSTRING_LEN(einfo) == 0) {
738 	    EMSG(_("E272: unhandled exception"));
739 	}
740 	else {
741 	    VALUE epath;
742 	    char *p;
743 
744 	    epath = rb_class_path(eclass);
745 	    vim_snprintf(buff, BUFSIZ, "%s: %s",
746 		     RSTRING_PTR(epath), RSTRING_PTR(einfo));
747 	    p = strchr(buff, '\n');
748 	    if (p) *p = '\0';
749 	    EMSG(buff);
750 	}
751 	break;
752     default:
753 	vim_snprintf(buff, BUFSIZ, _("E273: unknown longjmp status %d"), state);
754 	EMSG(buff);
755 	break;
756     }
757 }
758 
759 static VALUE vim_message(VALUE self UNUSED, VALUE str)
760 {
761     char *buff, *p;
762 
763     str = rb_obj_as_string(str);
764     if (RSTRING_LEN(str) > 0)
765     {
766 	/* Only do this when the string isn't empty, alloc(0) causes trouble. */
767 	buff = ALLOCA_N(char, RSTRING_LEN(str));
768 	strcpy(buff, RSTRING_PTR(str));
769 	p = strchr(buff, '\n');
770 	if (p) *p = '\0';
771 	MSG(buff);
772     }
773     else
774     {
775 	MSG("");
776     }
777     return Qnil;
778 }
779 
780 static VALUE vim_set_option(VALUE self UNUSED, VALUE str)
781 {
782     do_set((char_u *)StringValuePtr(str), 0);
783     update_screen(NOT_VALID);
784     return Qnil;
785 }
786 
787 static VALUE vim_command(VALUE self UNUSED, VALUE str)
788 {
789     do_cmdline_cmd((char_u *)StringValuePtr(str));
790     return Qnil;
791 }
792 
793 #ifdef FEAT_EVAL
794 static VALUE vim_to_ruby(typval_T *tv)
795 {
796     VALUE result = Qnil;
797 
798     if (tv->v_type == VAR_STRING)
799     {
800 	result = rb_str_new2(tv->vval.v_string == NULL
801 					  ? "" : (char *)(tv->vval.v_string));
802     }
803     else if (tv->v_type == VAR_NUMBER)
804     {
805 	result = INT2NUM(tv->vval.v_number);
806     }
807 # ifdef FEAT_FLOAT
808     else if (tv->v_type == VAR_FLOAT)
809     {
810 	result = rb_float_new(tv->vval.v_float);
811     }
812 # endif
813     else if (tv->v_type == VAR_LIST)
814     {
815 	list_T      *list = tv->vval.v_list;
816 	listitem_T  *curr;
817 
818 	result = rb_ary_new();
819 
820 	if (list != NULL)
821 	{
822 	    for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
823 	    {
824 		rb_ary_push(result, vim_to_ruby(&curr->li_tv));
825 	    }
826 	}
827     }
828     else if (tv->v_type == VAR_DICT)
829     {
830 	result = rb_hash_new();
831 
832 	if (tv->vval.v_dict != NULL)
833 	{
834 	    hashtab_T   *ht = &tv->vval.v_dict->dv_hashtab;
835 	    long_u      todo = ht->ht_used;
836 	    hashitem_T  *hi;
837 	    dictitem_T  *di;
838 
839 	    for (hi = ht->ht_array; todo > 0; ++hi)
840 	    {
841 		if (!HASHITEM_EMPTY(hi))
842 		{
843 		    --todo;
844 
845 		    di = dict_lookup(hi);
846 		    rb_hash_aset(result, rb_str_new2((char *)hi->hi_key),
847 						     vim_to_ruby(&di->di_tv));
848 		}
849 	    }
850 	}
851     } /* else return Qnil; */
852 
853     return result;
854 }
855 #endif
856 
857 static VALUE vim_evaluate(VALUE self UNUSED, VALUE str)
858 {
859 #ifdef FEAT_EVAL
860     typval_T    *tv;
861     VALUE       result;
862 
863     tv = eval_expr((char_u *)StringValuePtr(str), NULL);
864     if (tv == NULL)
865     {
866 	return Qnil;
867     }
868     result = vim_to_ruby(tv);
869 
870     free_tv(tv);
871 
872     return result;
873 #else
874     return Qnil;
875 #endif
876 }
877 
878 static VALUE buffer_new(buf_T *buf)
879 {
880     if (buf->b_ruby_ref)
881     {
882 	return (VALUE) buf->b_ruby_ref;
883     }
884     else
885     {
886 	VALUE obj = Data_Wrap_Struct(cBuffer, 0, 0, buf);
887 	buf->b_ruby_ref = (void *) obj;
888 	rb_hash_aset(objtbl, rb_obj_id(obj), obj);
889 	return obj;
890     }
891 }
892 
893 static buf_T *get_buf(VALUE obj)
894 {
895     buf_T *buf;
896 
897     Data_Get_Struct(obj, buf_T, buf);
898     if (buf == NULL)
899 	rb_raise(eDeletedBufferError, "attempt to refer to deleted buffer");
900     return buf;
901 }
902 
903 static VALUE buffer_s_current()
904 {
905     return buffer_new(curbuf);
906 }
907 
908 static VALUE buffer_s_count()
909 {
910     buf_T *b;
911     int n = 0;
912 
913     for (b = firstbuf; b != NULL; b = b->b_next)
914     {
915 	/*  Deleted buffers should not be counted
916 	 *    SegPhault - 01/07/05 */
917 	if (b->b_p_bl)
918 	    n++;
919     }
920 
921     return INT2NUM(n);
922 }
923 
924 static VALUE buffer_s_aref(VALUE self UNUSED, VALUE num)
925 {
926     buf_T *b;
927     int n = NUM2INT(num);
928 
929     for (b = firstbuf; b != NULL; b = b->b_next)
930     {
931 	/*  Deleted buffers should not be counted
932 	 *    SegPhault - 01/07/05 */
933 	if (!b->b_p_bl)
934 	    continue;
935 
936 	if (n == 0)
937 	    return buffer_new(b);
938 
939 	n--;
940     }
941     return Qnil;
942 }
943 
944 static VALUE buffer_name(VALUE self)
945 {
946     buf_T *buf = get_buf(self);
947 
948     return buf->b_ffname ? rb_str_new2((char *)buf->b_ffname) : Qnil;
949 }
950 
951 static VALUE buffer_number(VALUE self)
952 {
953     buf_T *buf = get_buf(self);
954 
955     return INT2NUM(buf->b_fnum);
956 }
957 
958 static VALUE buffer_count(VALUE self)
959 {
960     buf_T *buf = get_buf(self);
961 
962     return INT2NUM(buf->b_ml.ml_line_count);
963 }
964 
965 static VALUE get_buffer_line(buf_T *buf, linenr_T n)
966 {
967     if (n <= 0 || n > buf->b_ml.ml_line_count)
968 	rb_raise(rb_eIndexError, "line number %ld out of range", (long)n);
969     return vim_str2rb_enc_str((char *)ml_get_buf(buf, n, FALSE));
970 }
971 
972 static VALUE buffer_aref(VALUE self, VALUE num)
973 {
974     buf_T *buf = get_buf(self);
975 
976     if (buf != NULL)
977 	return get_buffer_line(buf, (linenr_T)NUM2LONG(num));
978     return Qnil; /* For stop warning */
979 }
980 
981 static VALUE set_buffer_line(buf_T *buf, linenr_T n, VALUE str)
982 {
983     char	*line = StringValuePtr(str);
984     aco_save_T	aco;
985 
986     if (n > 0 && n <= buf->b_ml.ml_line_count && line != NULL)
987     {
988 	/* set curwin/curbuf for "buf" and save some things */
989 	aucmd_prepbuf(&aco, buf);
990 
991 	if (u_savesub(n) == OK) {
992 	    ml_replace(n, (char_u *)line, TRUE);
993 	    changed();
994 #ifdef SYNTAX_HL
995 	    syn_changed(n); /* recompute syntax hl. for this line */
996 #endif
997 	}
998 
999 	/* restore curwin/curbuf and a few other things */
1000 	aucmd_restbuf(&aco);
1001 	/* Careful: autocommands may have made "buf" invalid! */
1002 
1003 	update_curbuf(NOT_VALID);
1004     }
1005     else
1006     {
1007 	rb_raise(rb_eIndexError, "line number %ld out of range", (long)n);
1008     }
1009     return str;
1010 }
1011 
1012 static VALUE buffer_aset(VALUE self, VALUE num, VALUE str)
1013 {
1014     buf_T *buf = get_buf(self);
1015 
1016     if (buf != NULL)
1017 	return set_buffer_line(buf, (linenr_T)NUM2LONG(num), str);
1018     return str;
1019 }
1020 
1021 static VALUE buffer_delete(VALUE self, VALUE num)
1022 {
1023     buf_T	*buf = get_buf(self);
1024     long	n = NUM2LONG(num);
1025     aco_save_T	aco;
1026 
1027     if (n > 0 && n <= buf->b_ml.ml_line_count)
1028     {
1029 	/* set curwin/curbuf for "buf" and save some things */
1030 	aucmd_prepbuf(&aco, buf);
1031 
1032 	if (u_savedel(n, 1) == OK) {
1033 	    ml_delete(n, 0);
1034 
1035 	    /* Changes to non-active buffers should properly refresh
1036 	     *   SegPhault - 01/09/05 */
1037 	    deleted_lines_mark(n, 1L);
1038 
1039 	    changed();
1040 	}
1041 
1042 	/* restore curwin/curbuf and a few other things */
1043 	aucmd_restbuf(&aco);
1044 	/* Careful: autocommands may have made "buf" invalid! */
1045 
1046 	update_curbuf(NOT_VALID);
1047     }
1048     else
1049     {
1050 	rb_raise(rb_eIndexError, "line number %ld out of range", n);
1051     }
1052     return Qnil;
1053 }
1054 
1055 static VALUE buffer_append(VALUE self, VALUE num, VALUE str)
1056 {
1057     buf_T	*buf = get_buf(self);
1058     char	*line = StringValuePtr(str);
1059     long	n = NUM2LONG(num);
1060     aco_save_T	aco;
1061 
1062     if (line == NULL)
1063     {
1064 	rb_raise(rb_eIndexError, "NULL line");
1065     }
1066     else if (n >= 0 && n <= buf->b_ml.ml_line_count)
1067     {
1068 	/* set curwin/curbuf for "buf" and save some things */
1069 	aucmd_prepbuf(&aco, buf);
1070 
1071 	if (u_inssub(n + 1) == OK) {
1072 	    ml_append(n, (char_u *) line, (colnr_T) 0, FALSE);
1073 
1074 	    /*  Changes to non-active buffers should properly refresh screen
1075 	     *    SegPhault - 12/20/04 */
1076 	    appended_lines_mark(n, 1L);
1077 
1078 	    changed();
1079 	}
1080 
1081 	/* restore curwin/curbuf and a few other things */
1082 	aucmd_restbuf(&aco);
1083 	/* Careful: autocommands may have made "buf" invalid! */
1084 
1085 	update_curbuf(NOT_VALID);
1086     }
1087     else
1088     {
1089 	rb_raise(rb_eIndexError, "line number %ld out of range", n);
1090     }
1091     return str;
1092 }
1093 
1094 static VALUE window_new(win_T *win)
1095 {
1096     if (win->w_ruby_ref)
1097     {
1098 	return (VALUE) win->w_ruby_ref;
1099     }
1100     else
1101     {
1102 	VALUE obj = Data_Wrap_Struct(cVimWindow, 0, 0, win);
1103 	win->w_ruby_ref = (void *) obj;
1104 	rb_hash_aset(objtbl, rb_obj_id(obj), obj);
1105 	return obj;
1106     }
1107 }
1108 
1109 static win_T *get_win(VALUE obj)
1110 {
1111     win_T *win;
1112 
1113     Data_Get_Struct(obj, win_T, win);
1114     if (win == NULL)
1115 	rb_raise(eDeletedWindowError, "attempt to refer to deleted window");
1116     return win;
1117 }
1118 
1119 static VALUE window_s_current()
1120 {
1121     return window_new(curwin);
1122 }
1123 
1124 /*
1125  * Added line manipulation functions
1126  *    SegPhault - 03/07/05
1127  */
1128 static VALUE line_s_current()
1129 {
1130     return get_buffer_line(curbuf, curwin->w_cursor.lnum);
1131 }
1132 
1133 static VALUE set_current_line(VALUE self UNUSED, VALUE str)
1134 {
1135     return set_buffer_line(curbuf, curwin->w_cursor.lnum, str);
1136 }
1137 
1138 static VALUE current_line_number()
1139 {
1140     return INT2FIX((int)curwin->w_cursor.lnum);
1141 }
1142 
1143 
1144 
1145 static VALUE window_s_count()
1146 {
1147 #ifdef FEAT_WINDOWS
1148     win_T	*w;
1149     int n = 0;
1150 
1151     for (w = firstwin; w != NULL; w = w->w_next)
1152 	n++;
1153     return INT2NUM(n);
1154 #else
1155     return INT2NUM(1);
1156 #endif
1157 }
1158 
1159 static VALUE window_s_aref(VALUE self UNUSED, VALUE num)
1160 {
1161     win_T *w;
1162     int n = NUM2INT(num);
1163 
1164 #ifndef FEAT_WINDOWS
1165     w = curwin;
1166 #else
1167     for (w = firstwin; w != NULL; w = w->w_next, --n)
1168 #endif
1169 	if (n == 0)
1170 	    return window_new(w);
1171     return Qnil;
1172 }
1173 
1174 static VALUE window_buffer(VALUE self)
1175 {
1176     win_T *win = get_win(self);
1177 
1178     return buffer_new(win->w_buffer);
1179 }
1180 
1181 static VALUE window_height(VALUE self)
1182 {
1183     win_T *win = get_win(self);
1184 
1185     return INT2NUM(win->w_height);
1186 }
1187 
1188 static VALUE window_set_height(VALUE self, VALUE height)
1189 {
1190     win_T *win = get_win(self);
1191     win_T *savewin = curwin;
1192 
1193     curwin = win;
1194     win_setheight(NUM2INT(height));
1195     curwin = savewin;
1196     return height;
1197 }
1198 
1199 static VALUE window_width(VALUE self)
1200 {
1201     win_T *win = get_win(self);
1202 
1203     return INT2NUM(win->w_width);
1204 }
1205 
1206 static VALUE window_set_width(VALUE self, VALUE width)
1207 {
1208     win_T *win = get_win(self);
1209     win_T *savewin = curwin;
1210 
1211     curwin = win;
1212     win_setwidth(NUM2INT(width));
1213     curwin = savewin;
1214     return width;
1215 }
1216 
1217 static VALUE window_cursor(VALUE self)
1218 {
1219     win_T *win = get_win(self);
1220 
1221     return rb_assoc_new(INT2NUM(win->w_cursor.lnum), INT2NUM(win->w_cursor.col));
1222 }
1223 
1224 static VALUE window_set_cursor(VALUE self, VALUE pos)
1225 {
1226     VALUE lnum, col;
1227     win_T *win = get_win(self);
1228 
1229     Check_Type(pos, T_ARRAY);
1230     if (RARRAY_LEN(pos) != 2)
1231 	rb_raise(rb_eArgError, "array length must be 2");
1232     lnum = RARRAY_PTR(pos)[0];
1233     col = RARRAY_PTR(pos)[1];
1234     win->w_cursor.lnum = NUM2LONG(lnum);
1235     win->w_cursor.col = NUM2UINT(col);
1236     check_cursor();		    /* put cursor on an existing line */
1237     update_screen(NOT_VALID);
1238     return Qnil;
1239 }
1240 
1241 static VALUE f_p(int argc, VALUE *argv, VALUE self UNUSED)
1242 {
1243     int i;
1244     VALUE str = rb_str_new("", 0);
1245 
1246     for (i = 0; i < argc; i++) {
1247 	if (i > 0) rb_str_cat(str, ", ", 2);
1248 	rb_str_concat(str, rb_inspect(argv[i]));
1249     }
1250     MSG(RSTRING_PTR(str));
1251     return Qnil;
1252 }
1253 
1254 static void ruby_io_init(void)
1255 {
1256 #ifndef DYNAMIC_RUBY
1257     RUBYEXTERN VALUE rb_stdout;
1258 #endif
1259 
1260     rb_stdout = rb_obj_alloc(rb_cObject);
1261     rb_define_singleton_method(rb_stdout, "write", vim_message, 1);
1262     rb_define_global_function("p", f_p, -1);
1263 }
1264 
1265 static void ruby_vim_init(void)
1266 {
1267     objtbl = rb_hash_new();
1268     rb_global_variable(&objtbl);
1269 
1270     /* The Vim module used to be called "VIM", but "Vim" is better.  Make an
1271      * alias "VIM" for backwards compatiblity. */
1272     mVIM = rb_define_module("Vim");
1273     rb_define_const(rb_cObject, "VIM", mVIM);
1274     rb_define_const(mVIM, "VERSION_MAJOR", INT2NUM(VIM_VERSION_MAJOR));
1275     rb_define_const(mVIM, "VERSION_MINOR", INT2NUM(VIM_VERSION_MINOR));
1276     rb_define_const(mVIM, "VERSION_BUILD", INT2NUM(VIM_VERSION_BUILD));
1277     rb_define_const(mVIM, "VERSION_PATCHLEVEL", INT2NUM(VIM_VERSION_PATCHLEVEL));
1278     rb_define_const(mVIM, "VERSION_SHORT", rb_str_new2(VIM_VERSION_SHORT));
1279     rb_define_const(mVIM, "VERSION_MEDIUM", rb_str_new2(VIM_VERSION_MEDIUM));
1280     rb_define_const(mVIM, "VERSION_LONG", rb_str_new2(VIM_VERSION_LONG));
1281     rb_define_const(mVIM, "VERSION_LONG_DATE", rb_str_new2(VIM_VERSION_LONG_DATE));
1282     rb_define_module_function(mVIM, "message", vim_message, 1);
1283     rb_define_module_function(mVIM, "set_option", vim_set_option, 1);
1284     rb_define_module_function(mVIM, "command", vim_command, 1);
1285     rb_define_module_function(mVIM, "evaluate", vim_evaluate, 1);
1286 
1287     eDeletedBufferError = rb_define_class_under(mVIM, "DeletedBufferError",
1288 						rb_eStandardError);
1289     eDeletedWindowError = rb_define_class_under(mVIM, "DeletedWindowError",
1290 						rb_eStandardError);
1291 
1292     cBuffer = rb_define_class_under(mVIM, "Buffer", rb_cObject);
1293     rb_define_singleton_method(cBuffer, "current", buffer_s_current, 0);
1294     rb_define_singleton_method(cBuffer, "count", buffer_s_count, 0);
1295     rb_define_singleton_method(cBuffer, "[]", buffer_s_aref, 1);
1296     rb_define_method(cBuffer, "name", buffer_name, 0);
1297     rb_define_method(cBuffer, "number", buffer_number, 0);
1298     rb_define_method(cBuffer, "count", buffer_count, 0);
1299     rb_define_method(cBuffer, "length", buffer_count, 0);
1300     rb_define_method(cBuffer, "[]", buffer_aref, 1);
1301     rb_define_method(cBuffer, "[]=", buffer_aset, 2);
1302     rb_define_method(cBuffer, "delete", buffer_delete, 1);
1303     rb_define_method(cBuffer, "append", buffer_append, 2);
1304 
1305     /* Added line manipulation functions
1306      *   SegPhault - 03/07/05 */
1307     rb_define_method(cBuffer, "line_number", current_line_number, 0);
1308     rb_define_method(cBuffer, "line", line_s_current, 0);
1309     rb_define_method(cBuffer, "line=", set_current_line, 1);
1310 
1311 
1312     cVimWindow = rb_define_class_under(mVIM, "Window", rb_cObject);
1313     rb_define_singleton_method(cVimWindow, "current", window_s_current, 0);
1314     rb_define_singleton_method(cVimWindow, "count", window_s_count, 0);
1315     rb_define_singleton_method(cVimWindow, "[]", window_s_aref, 1);
1316     rb_define_method(cVimWindow, "buffer", window_buffer, 0);
1317     rb_define_method(cVimWindow, "height", window_height, 0);
1318     rb_define_method(cVimWindow, "height=", window_set_height, 1);
1319     rb_define_method(cVimWindow, "width", window_width, 0);
1320     rb_define_method(cVimWindow, "width=", window_set_width, 1);
1321     rb_define_method(cVimWindow, "cursor", window_cursor, 0);
1322     rb_define_method(cVimWindow, "cursor=", window_set_cursor, 1);
1323 
1324     rb_define_virtual_variable("$curbuf", buffer_s_current, 0);
1325     rb_define_virtual_variable("$curwin", window_s_current, 0);
1326 }
1327