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