1 /* vi:set ts=8 sts=4 sw=4:
3 * VIM - Vi IMproved by Bram Moolenaar
5 * Ruby interface by Shugo Maeda
6 * with improvements by SegPhault (Ryan Paul)
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.
17 # if !defined(DYNAMIC_RUBY_VER) || (DYNAMIC_RUBY_VER < 18)
21 # define IMPORT /* For static dll usage __declspec(dllimport) */
22 # define RUBYEXTERN __declspec(dllimport)
26 # define RUBYEXTERN extern
29 #if defined(DYNAMIC_RUBY) && !defined(_WIN32)
30 typedef void *HINSTANCE
;
31 typedef void *FARPROC
;
33 # define LoadLibrary(a) dlopen(a,RTLD_NOW|RTLD_GLOBAL)
34 # define FreeLibrary(a) dlclose(a)
35 # define GetProcAddress dlsym
36 # if defined(MACOS_X_UNIX)
37 # define DYNAMIC_RUBY_DLL "/System/Library/Frameworks/Ruby.framework/Versions/Current/Ruby"
39 # define DYNAMIC_RUBY_DLL "libruby.so"
44 * This is tricky. In ruby.h there is (inline) function rb_class_of()
45 * definition. This function use these variables. But we want function to
46 * use dll_* variables.
49 # define rb_cFalseClass (*dll_rb_cFalseClass)
50 # define rb_cFixnum (*dll_rb_cFixnum)
51 # define rb_cNilClass (*dll_rb_cNilClass)
52 # define rb_cSymbol (*dll_rb_cSymbol)
53 # define rb_cTrueClass (*dll_rb_cTrueClass)
54 # if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
56 * On ver 1.8, all Ruby functions are exported with "__declspec(dllimport)"
57 * in ruby.h. But it causes trouble for these variables, because it is
58 * defined in this file. When defined this RUBY_EXPORT it modified to
59 * "extern" and be able to avoid this problem.
65 /* suggested by Ariya Mizutani */
66 #if (_MSC_VER == 1200)
70 #if (defined(RUBY_VERSION) && RUBY_VERSION >= 19) \
71 || (defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 19)
72 # define RUBY19_OR_LATER 1
75 #if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 19
76 /* Ruby 1.9 defines a number of static functions which use rb_num2long and
78 # define rb_num2long rb_num2long_stub
79 # define rb_int2big rb_int2big_stub
82 #ifdef FEAT_GUI_MACVIM
83 # include <Ruby/ruby.h>
88 #ifdef RUBY19_OR_LATER
89 # include <ruby/encoding.h>
95 /* T_DATA defined both by Ruby and Mac header files, hack around it... */
96 #if defined(MACOS_X_UNIX) || defined(macintosh)
97 # define __OPENTRANSPORT__
98 # define __OPENTRANSPORTPROTOCOL__
99 # define __OPENTRANSPORTPROVIDERS__
103 * Backward compatiblity for Ruby 1.8 and earlier.
104 * Ruby 1.9 does not provide STR2CSTR, instead StringValuePtr is provided.
105 * Ruby 1.9 does not provide RXXX(s)->len and RXXX(s)->ptr, instead
106 * RXXX_LEN(s) and RXXX_PTR(s) are provided.
108 #ifndef StringValuePtr
109 # define StringValuePtr(s) STR2CSTR(s)
112 # define RARRAY_LEN(s) RARRAY(s)->len
115 # define RARRAY_PTR(s) RARRAY(s)->ptr
118 # define RSTRING_LEN(s) RSTRING(s)->len
121 # define RSTRING_PTR(s) RSTRING(s)->ptr
127 #if defined(PROTO) && !defined(FEAT_RUBY)
128 /* Define these to be able to generate the function prototypes. */
130 # define RUBY_DATA_FUNC int
133 static int ruby_initialized
= 0;
137 static VALUE cBuffer
;
138 static VALUE cVimWindow
;
139 static VALUE eDeletedBufferError
;
140 static VALUE eDeletedWindowError
;
142 static int ensure_ruby_initialized(void);
143 static void error_print(int);
144 static void ruby_io_init(void);
145 static void ruby_vim_init(void);
147 #if defined(DYNAMIC_RUBY) || defined(PROTO)
149 # define HINSTANCE int /* for generating prototypes */
155 #define rb_assoc_new dll_rb_assoc_new
156 #define rb_cObject (*dll_rb_cObject)
157 #define rb_check_type dll_rb_check_type
158 #define rb_class_path dll_rb_class_path
159 #define rb_data_object_alloc dll_rb_data_object_alloc
160 #define rb_define_class_under dll_rb_define_class_under
161 #define rb_define_const dll_rb_define_const
162 #define rb_define_global_function dll_rb_define_global_function
163 #define rb_define_method dll_rb_define_method
164 #define rb_define_module dll_rb_define_module
165 #define rb_define_module_function dll_rb_define_module_function
166 #define rb_define_singleton_method dll_rb_define_singleton_method
167 #define rb_define_virtual_variable dll_rb_define_virtual_variable
168 #define rb_stdout (*dll_rb_stdout)
169 #define rb_eArgError (*dll_rb_eArgError)
170 #define rb_eIndexError (*dll_rb_eIndexError)
171 #define rb_eRuntimeError (*dll_rb_eRuntimeError)
172 #define rb_eStandardError (*dll_rb_eStandardError)
173 #define rb_eval_string_protect dll_rb_eval_string_protect
174 #define rb_global_variable dll_rb_global_variable
175 #define rb_hash_aset dll_rb_hash_aset
176 #define rb_hash_new dll_rb_hash_new
177 #define rb_inspect dll_rb_inspect
178 #define rb_int2inum dll_rb_int2inum
179 #define rb_lastline_get dll_rb_lastline_get
180 #define rb_lastline_set dll_rb_lastline_set
181 #define rb_load_protect dll_rb_load_protect
182 #if defined(__LP64__)
183 #define rb_fix2int dll_rb_fix2int
184 #define rb_num2int dll_rb_num2int
185 #define rb_num2uint dll_rb_num2uint
187 #define rb_num2long dll_rb_num2long
188 #define rb_num2ulong dll_rb_num2ulong
189 #define rb_obj_alloc dll_rb_obj_alloc
190 #define rb_obj_as_string dll_rb_obj_as_string
191 #define rb_obj_id dll_rb_obj_id
192 #define rb_raise dll_rb_raise
193 #define rb_str2cstr dll_rb_str2cstr
194 #define rb_str_cat dll_rb_str_cat
195 #define rb_str_concat dll_rb_str_concat
196 #define rb_str_new dll_rb_str_new
197 #define rb_str_new2 dll_rb_str_new2
198 #if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
199 # define rb_string_value_ptr dll_rb_string_value_ptr
200 # define rb_float_new dll_rb_float_new
201 # define rb_ary_new dll_rb_ary_new
202 # define rb_ary_push dll_rb_ary_push
204 #ifdef RUBY19_OR_LATER
205 # define rb_errinfo dll_rb_errinfo
207 # define ruby_errinfo (*dll_ruby_errinfo)
209 #define ruby_init dll_ruby_init
210 #define ruby_init_loadpath dll_ruby_init_loadpath
211 #define NtInitialize dll_NtInitialize
212 #if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
213 # define rb_w32_snprintf dll_rb_w32_snprintf
216 #ifdef RUBY19_OR_LATER
217 # define ruby_script dll_ruby_script
218 # define rb_enc_find_index dll_rb_enc_find_index
219 # define rb_enc_find dll_rb_enc_find
220 # define rb_enc_str_new dll_rb_enc_str_new
221 # define rb_sprintf dll_rb_sprintf
222 # define ruby_init_stack dll_ruby_init_stack
226 # define rb_ary_new dll_rb_ary_new
227 # define rb_float_new dll_rb_float_new
228 # define rb_string_value_ptr dll_rb_string_value_ptr
229 # define rb_ary_push dll_rb_ary_push
233 * Pointers for dynamic link
235 static VALUE (*dll_rb_assoc_new
) (VALUE
, VALUE
);
236 VALUE (*dll_rb_cFalseClass
);
237 VALUE (*dll_rb_cFixnum
);
238 VALUE (*dll_rb_cNilClass
);
239 static VALUE (*dll_rb_cObject
);
240 VALUE (*dll_rb_cSymbol
);
241 VALUE (*dll_rb_cTrueClass
);
242 static void (*dll_rb_check_type
) (VALUE
,int);
243 static VALUE (*dll_rb_class_path
) (VALUE
);
244 static VALUE (*dll_rb_data_object_alloc
) (VALUE
, void*, RUBY_DATA_FUNC
, RUBY_DATA_FUNC
);
245 static VALUE (*dll_rb_define_class_under
) (VALUE
, const char*, VALUE
);
246 static void (*dll_rb_define_const
) (VALUE
,const char*,VALUE
);
247 static void (*dll_rb_define_global_function
) (const char*,VALUE(*)(),int);
248 static void (*dll_rb_define_method
) (VALUE
,const char*,VALUE(*)(),int);
249 static VALUE (*dll_rb_define_module
) (const char*);
250 static void (*dll_rb_define_module_function
) (VALUE
,const char*,VALUE(*)(),int);
251 static void (*dll_rb_define_singleton_method
) (VALUE
,const char*,VALUE(*)(),int);
252 static void (*dll_rb_define_virtual_variable
) (const char*,VALUE(*)(),void(*)());
253 static VALUE
*dll_rb_stdout
;
254 static VALUE
*dll_rb_eArgError
;
255 static VALUE
*dll_rb_eIndexError
;
256 static VALUE
*dll_rb_eRuntimeError
;
257 static VALUE
*dll_rb_eStandardError
;
258 static VALUE (*dll_rb_eval_string_protect
) (const char*, int*);
259 static void (*dll_rb_global_variable
) (VALUE
*);
260 static VALUE (*dll_rb_hash_aset
) (VALUE
, VALUE
, VALUE
);
261 static VALUE (*dll_rb_hash_new
) (void);
262 static VALUE (*dll_rb_inspect
) (VALUE
);
263 static VALUE (*dll_rb_int2inum
) (long);
264 static VALUE (*dll_rb_int2inum
) (long);
265 static VALUE (*dll_rb_lastline_get
) (void);
266 static void (*dll_rb_lastline_set
) (VALUE
);
267 static void (*dll_rb_load_protect
) (VALUE
, int, int*);
268 #if defined(__LP64__)
269 static long (*dll_rb_fix2int
) (VALUE
);
270 static long (*dll_rb_num2int
) (VALUE
);
271 static unsigned long (*dll_rb_num2uint
) (VALUE
);
273 static long (*dll_rb_num2long
) (VALUE
);
274 static unsigned long (*dll_rb_num2ulong
) (VALUE
);
275 static VALUE (*dll_rb_obj_alloc
) (VALUE
);
276 static VALUE (*dll_rb_obj_as_string
) (VALUE
);
277 static VALUE (*dll_rb_obj_id
) (VALUE
);
278 static void (*dll_rb_raise
) (VALUE
, const char*, ...);
279 static char *(*dll_rb_str2cstr
) (VALUE
,int*);
280 static VALUE (*dll_rb_str_cat
) (VALUE
, const char*, long);
281 static VALUE (*dll_rb_str_concat
) (VALUE
, VALUE
);
282 static VALUE (*dll_rb_str_new
) (const char*, long);
283 static VALUE (*dll_rb_str_new2
) (const char*);
284 #ifdef RUBY19_OR_LATER
285 static VALUE (*dll_rb_errinfo
) (void);
287 static VALUE
*dll_ruby_errinfo
;
289 static void (*dll_ruby_init
) (void);
290 static void (*dll_ruby_init_loadpath
) (void);
292 static void (*dll_NtInitialize
) (int*, char***);
294 #if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
295 static char * (*dll_rb_string_value_ptr
) (volatile VALUE
*);
296 static VALUE (*dll_rb_float_new
) (double);
297 static VALUE (*dll_rb_ary_new
) (void);
298 static VALUE (*dll_rb_ary_push
) (VALUE
, VALUE
);
300 #ifdef RUBY19_OR_LATER
301 static VALUE (*dll_rb_int2big
)(SIGNED_VALUE
);
303 #if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
304 static int (*dll_rb_w32_snprintf
)(char*, size_t, const char*, ...);
307 #ifdef RUBY19_OR_LATER
308 static void (*dll_ruby_script
) (const char*);
309 static int (*dll_rb_enc_find_index
) (const char*);
310 static rb_encoding
* (*dll_rb_enc_find
) (const char*);
311 static VALUE (*dll_rb_enc_str_new
) (const char*, long, rb_encoding
*);
312 static VALUE (*dll_rb_sprintf
) (const char*, ...);
313 static void (*ruby_init_stack
)(VALUE
*);
316 #ifdef RUBY19_OR_LATER
317 static SIGNED_VALUE
rb_num2long_stub(VALUE x
)
319 return dll_rb_num2long(x
);
321 static VALUE
rb_int2big_stub(SIGNED_VALUE x
)
323 return dll_rb_int2big(x
);
328 static VALUE (*dll_rb_ary_new
) (void);
329 static VALUE (*dll_rb_float_new
) (double);
330 static char *(*dll_rb_string_value_ptr
) (volatile VALUE
*);
331 static VALUE (*dll_rb_ary_push
) (VALUE
, VALUE
);
334 static HINSTANCE hinstRuby
= 0; /* Instance of ruby.dll */
337 * Table of name to function pointer of ruby.
339 #define RUBY_PROC FARPROC
344 } ruby_funcname_table
[] =
346 {"rb_assoc_new", (RUBY_PROC
*)&dll_rb_assoc_new
},
347 {"rb_cFalseClass", (RUBY_PROC
*)&dll_rb_cFalseClass
},
348 {"rb_cFixnum", (RUBY_PROC
*)&dll_rb_cFixnum
},
349 {"rb_cNilClass", (RUBY_PROC
*)&dll_rb_cNilClass
},
350 {"rb_cObject", (RUBY_PROC
*)&dll_rb_cObject
},
351 {"rb_cSymbol", (RUBY_PROC
*)&dll_rb_cSymbol
},
352 {"rb_cTrueClass", (RUBY_PROC
*)&dll_rb_cTrueClass
},
353 {"rb_check_type", (RUBY_PROC
*)&dll_rb_check_type
},
354 {"rb_class_path", (RUBY_PROC
*)&dll_rb_class_path
},
355 {"rb_data_object_alloc", (RUBY_PROC
*)&dll_rb_data_object_alloc
},
356 {"rb_define_class_under", (RUBY_PROC
*)&dll_rb_define_class_under
},
357 {"rb_define_const", (RUBY_PROC
*)&dll_rb_define_const
},
358 {"rb_define_global_function", (RUBY_PROC
*)&dll_rb_define_global_function
},
359 {"rb_define_method", (RUBY_PROC
*)&dll_rb_define_method
},
360 {"rb_define_module", (RUBY_PROC
*)&dll_rb_define_module
},
361 {"rb_define_module_function", (RUBY_PROC
*)&dll_rb_define_module_function
},
362 {"rb_define_singleton_method", (RUBY_PROC
*)&dll_rb_define_singleton_method
},
363 {"rb_define_virtual_variable", (RUBY_PROC
*)&dll_rb_define_virtual_variable
},
364 {"rb_stdout", (RUBY_PROC
*)&dll_rb_stdout
},
365 {"rb_eArgError", (RUBY_PROC
*)&dll_rb_eArgError
},
366 {"rb_eIndexError", (RUBY_PROC
*)&dll_rb_eIndexError
},
367 {"rb_eRuntimeError", (RUBY_PROC
*)&dll_rb_eRuntimeError
},
368 {"rb_eStandardError", (RUBY_PROC
*)&dll_rb_eStandardError
},
369 {"rb_eval_string_protect", (RUBY_PROC
*)&dll_rb_eval_string_protect
},
370 {"rb_global_variable", (RUBY_PROC
*)&dll_rb_global_variable
},
371 {"rb_hash_aset", (RUBY_PROC
*)&dll_rb_hash_aset
},
372 {"rb_hash_new", (RUBY_PROC
*)&dll_rb_hash_new
},
373 {"rb_inspect", (RUBY_PROC
*)&dll_rb_inspect
},
374 {"rb_int2inum", (RUBY_PROC
*)&dll_rb_int2inum
},
375 {"rb_lastline_get", (RUBY_PROC
*)&dll_rb_lastline_get
},
376 {"rb_lastline_set", (RUBY_PROC
*)&dll_rb_lastline_set
},
377 {"rb_load_protect", (RUBY_PROC
*)&dll_rb_load_protect
},
378 #if defined(__LP64__)
379 {"rb_fix2int", (RUBY_PROC
*)&dll_rb_fix2int
},
380 {"rb_num2int", (RUBY_PROC
*)&dll_rb_num2int
},
381 {"rb_num2uint", (RUBY_PROC
*)&dll_rb_num2uint
},
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 {"rb_str2cstr", (RUBY_PROC
*)&dll_rb_str2cstr
},
390 {"rb_str_cat", (RUBY_PROC
*)&dll_rb_str_cat
},
391 {"rb_str_concat", (RUBY_PROC
*)&dll_rb_str_concat
},
392 {"rb_str_new", (RUBY_PROC
*)&dll_rb_str_new
},
393 {"rb_str_new2", (RUBY_PROC
*)&dll_rb_str_new2
},
394 #ifdef RUBY19_OR_LATER
395 {"rb_errinfo", (RUBY_PROC
*)&dll_rb_errinfo
},
397 {"ruby_errinfo", (RUBY_PROC
*)&dll_ruby_errinfo
},
399 {"ruby_init", (RUBY_PROC
*)&dll_ruby_init
},
400 {"ruby_init_loadpath", (RUBY_PROC
*)&dll_ruby_init_loadpath
},
401 #if defined(_WIN32) && defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER < 19
402 {"NtInitialize", (RUBY_PROC
*)&dll_NtInitialize
},
404 //{"ruby_sysinit", (RUBY_PROC*)&dll_ruby_sysinit},
406 #if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
407 {"rb_w32_snprintf", (RUBY_PROC
*)&dll_rb_w32_snprintf
},
409 #if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
410 {"rb_string_value_ptr", (RUBY_PROC
*)&dll_rb_string_value_ptr
},
411 {"rb_float_new", (RUBY_PROC
*)&dll_rb_float_new
},
412 {"rb_ary_new", (RUBY_PROC
*)&dll_rb_ary_new
},
413 {"rb_ary_push", (RUBY_PROC
*)&dll_rb_ary_push
},
415 #ifdef RUBY19_OR_LATER
416 {"rb_int2big", (RUBY_PROC
*)&dll_rb_int2big
},
417 {"ruby_script", (RUBY_PROC
*)&dll_ruby_script
},
418 {"rb_enc_find_index", (RUBY_PROC
*)&dll_rb_enc_find_index
},
419 {"rb_enc_find", (RUBY_PROC
*)&dll_rb_enc_find
},
420 {"rb_enc_str_new", (RUBY_PROC
*)&dll_rb_enc_str_new
},
421 {"rb_sprintf", (RUBY_PROC
*)&dll_rb_sprintf
},
422 {"ruby_init_stack", (RUBY_PROC
*)&dll_ruby_init_stack
},
425 {"rb_ary_new", (RUBY_PROC
*)&dll_rb_ary_new
},
426 {"rb_float_new", (RUBY_PROC
*)&dll_rb_float_new
},
427 {"rb_string_value_ptr", (RUBY_PROC
*)&dll_rb_string_value_ptr
},
428 {"rb_ary_push", (RUBY_PROC
*)&dll_rb_ary_push
},
441 FreeLibrary(hinstRuby
);
447 * Load library and get all pointers.
448 * Parameter 'libname' provides name of DLL.
452 ruby_runtime_link_init(char *libname
, int verbose
)
458 hinstRuby
= LoadLibrary(libname
);
462 EMSG2(_(e_loadlib
), libname
);
466 for (i
= 0; ruby_funcname_table
[i
].ptr
; ++i
)
468 if (!(*ruby_funcname_table
[i
].ptr
= GetProcAddress(hinstRuby
,
469 ruby_funcname_table
[i
].name
)))
471 FreeLibrary(hinstRuby
);
474 EMSG2(_(e_loadfunc
), ruby_funcname_table
[i
].name
);
482 * If ruby is enabled (there is installed ruby on Windows system) return TRUE,
486 ruby_enabled(verbose
)
490 int mustfree
= FALSE
;
491 char *s
= (char *)vim_getenv((char_u
*)"RUBY_DLL", &mustfree
);
493 ret
= ruby_runtime_link_init(s
, verbose
);
497 ret
= ruby_runtime_link_init(DYNAMIC_RUBY_DLL
, verbose
);
500 #endif /* defined(DYNAMIC_RUBY) || defined(PROTO) */
510 void ex_ruby(exarg_T
*eap
)
515 script
= (char *)script_get(eap
, eap
->arg
);
516 if (!eap
->skip
&& ensure_ruby_initialized())
519 rb_eval_string_protect((char *)eap
->arg
, &state
);
521 rb_eval_string_protect(script
, &state
);
529 * In Ruby 1.9 or later, ruby String object has encoding.
530 * conversion buffer string of vim to ruby String object using
531 * VIM encoding option.
534 vim_str2rb_enc_str(const char *s
)
536 #ifdef RUBY19_OR_LATER
542 isnum
= get_option_value((char_u
*)"enc", &lval
, &sval
, 0);
545 enc
= rb_enc_find((char *)sval
);
548 return rb_enc_str_new(s
, strlen(s
), enc
);
552 return rb_str_new2(s
);
556 eval_enc_string_protect(const char *str
, int *state
)
558 #ifdef RUBY19_OR_LATER
565 isnum
= get_option_value((char_u
*)"enc", &lval
, &sval
, 0);
568 enc
= rb_enc_find((char *)sval
);
572 v
= rb_sprintf("#-*- coding:%s -*-\n%s", rb_enc_name(enc
), str
);
573 return rb_eval_string_protect(StringValuePtr(v
), state
);
577 return rb_eval_string_protect(str
, state
);
580 void ex_rubydo(exarg_T
*eap
)
585 if (ensure_ruby_initialized())
587 if (u_save(eap
->line1
- 1, eap
->line2
+ 1) != OK
)
589 for (i
= eap
->line1
; i
<= eap
->line2
; i
++) {
592 line
= oldline
= vim_str2rb_enc_str((char *)ml_get(i
));
593 rb_lastline_set(line
);
594 eval_enc_string_protect((char *) eap
->arg
, &state
);
599 line
= rb_lastline_get();
601 if (TYPE(line
) != T_STRING
) {
602 EMSG(_("E265: $_ must be an instance of String"));
605 ml_replace(i
, (char_u
*) StringValuePtr(line
), 1);
608 syn_changed(i
); /* recompute syntax hl. for this line */
613 update_curbuf(NOT_VALID
);
617 void ex_rubyfile(exarg_T
*eap
)
621 if (ensure_ruby_initialized())
623 rb_load_protect(rb_str_new2((char *) eap
->arg
), 0, &state
);
624 if (state
) error_print(state
);
628 void ruby_buffer_free(buf_T
*buf
)
632 rb_hash_aset(objtbl
, rb_obj_id((VALUE
) buf
->b_ruby_ref
), Qnil
);
633 RDATA(buf
->b_ruby_ref
)->data
= NULL
;
637 void ruby_window_free(win_T
*win
)
641 rb_hash_aset(objtbl
, rb_obj_id((VALUE
) win
->w_ruby_ref
), Qnil
);
642 RDATA(win
->w_ruby_ref
)->data
= NULL
;
646 static int ensure_ruby_initialized(void)
648 if (!ruby_initialized
)
651 if (ruby_enabled(TRUE
))
655 /* suggested by Ariya Mizutani */
657 char *argv
[] = {"gvim.exe"};
658 NtInitialize(&argc
, &argv
);
660 #ifdef RUBY19_OR_LATER
664 #ifdef RUBY19_OR_LATER
665 ruby_script("vim-ruby");
667 ruby_init_loadpath();
669 #ifdef RUBY19_OR_LATER
670 rb_enc_find_index("encdb");
673 ruby_initialized
= 1;
678 EMSG(_("E266: Sorry, this command is disabled, the Ruby library could not be loaded."));
683 return ruby_initialized
;
686 static void error_print(int state
)
689 #if !(defined(RUBY_VERSION) && RUBY_VERSION >= 19) \
690 && !(defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 19)
691 RUBYEXTERN VALUE ruby_errinfo
;
698 #define TAG_RETURN 0x1
699 #define TAG_BREAK 0x2
701 #define TAG_RETRY 0x4
703 #define TAG_RAISE 0x6
704 #define TAG_THROW 0x7
705 #define TAG_FATAL 0x8
710 EMSG(_("E267: unexpected return"));
713 EMSG(_("E268: unexpected next"));
716 EMSG(_("E269: unexpected break"));
719 EMSG(_("E270: unexpected redo"));
722 EMSG(_("E271: retry outside of rescue clause"));
726 #ifdef RUBY19_OR_LATER
727 eclass
= CLASS_OF(rb_errinfo());
728 einfo
= rb_obj_as_string(rb_errinfo());
730 eclass
= CLASS_OF(ruby_errinfo
);
731 einfo
= rb_obj_as_string(ruby_errinfo
);
733 if (eclass
== rb_eRuntimeError
&& RSTRING_LEN(einfo
) == 0) {
734 EMSG(_("E272: unhandled exception"));
740 epath
= rb_class_path(eclass
);
741 vim_snprintf(buff
, BUFSIZ
, "%s: %s",
742 RSTRING_PTR(epath
), RSTRING_PTR(einfo
));
743 p
= strchr(buff
, '\n');
749 vim_snprintf(buff
, BUFSIZ
, _("E273: unknown longjmp status %d"), state
);
755 static VALUE
vim_message(VALUE self UNUSED
, VALUE str
)
759 str
= rb_obj_as_string(str
);
760 buff
= ALLOCA_N(char, RSTRING_LEN(str
));
761 strcpy(buff
, RSTRING_PTR(str
));
762 p
= strchr(buff
, '\n');
768 static VALUE
vim_set_option(VALUE self UNUSED
, VALUE str
)
770 do_set((char_u
*)StringValuePtr(str
), 0);
771 update_screen(NOT_VALID
);
775 static VALUE
vim_command(VALUE self UNUSED
, VALUE str
)
777 do_cmdline_cmd((char_u
*)StringValuePtr(str
));
782 static VALUE
vim_to_ruby(typval_T
*tv
)
786 if (tv
->v_type
== VAR_STRING
)
788 result
= rb_str_new2(tv
->vval
.v_string
== NULL
789 ? "" : (char *)(tv
->vval
.v_string
));
791 else if (tv
->v_type
== VAR_NUMBER
)
793 result
= INT2NUM(tv
->vval
.v_number
);
796 else if (tv
->v_type
== VAR_FLOAT
)
798 result
= rb_float_new(tv
->vval
.v_float
);
801 else if (tv
->v_type
== VAR_LIST
)
803 list_T
*list
= tv
->vval
.v_list
;
806 result
= rb_ary_new();
810 for (curr
= list
->lv_first
; curr
!= NULL
; curr
= curr
->li_next
)
812 rb_ary_push(result
, vim_to_ruby(&curr
->li_tv
));
816 else if (tv
->v_type
== VAR_DICT
)
818 result
= rb_hash_new();
820 if (tv
->vval
.v_dict
!= NULL
)
822 hashtab_T
*ht
= &tv
->vval
.v_dict
->dv_hashtab
;
823 long_u todo
= ht
->ht_used
;
827 for (hi
= ht
->ht_array
; todo
> 0; ++hi
)
829 if (!HASHITEM_EMPTY(hi
))
833 di
= dict_lookup(hi
);
834 rb_hash_aset(result
, rb_str_new2((char *)hi
->hi_key
),
835 vim_to_ruby(&di
->di_tv
));
839 } /* else return Qnil; */
845 static VALUE
vim_evaluate(VALUE self UNUSED
, VALUE str
)
851 tv
= eval_expr((char_u
*)StringValuePtr(str
), NULL
);
856 result
= vim_to_ruby(tv
);
866 static VALUE
buffer_new(buf_T
*buf
)
870 return (VALUE
) buf
->b_ruby_ref
;
874 VALUE obj
= Data_Wrap_Struct(cBuffer
, 0, 0, buf
);
875 buf
->b_ruby_ref
= (void *) obj
;
876 rb_hash_aset(objtbl
, rb_obj_id(obj
), obj
);
881 static buf_T
*get_buf(VALUE obj
)
885 Data_Get_Struct(obj
, buf_T
, buf
);
887 rb_raise(eDeletedBufferError
, "attempt to refer to deleted buffer");
891 static VALUE
buffer_s_current()
893 return buffer_new(curbuf
);
896 static VALUE
buffer_s_count()
901 for (b
= firstbuf
; b
!= NULL
; b
= b
->b_next
)
903 /* Deleted buffers should not be counted
904 * SegPhault - 01/07/05 */
912 static VALUE
buffer_s_aref(VALUE self UNUSED
, VALUE num
)
915 int n
= NUM2INT(num
);
917 for (b
= firstbuf
; b
!= NULL
; b
= b
->b_next
)
919 /* Deleted buffers should not be counted
920 * SegPhault - 01/07/05 */
925 return buffer_new(b
);
932 static VALUE
buffer_name(VALUE self
)
934 buf_T
*buf
= get_buf(self
);
936 return buf
->b_ffname
? rb_str_new2((char *)buf
->b_ffname
) : Qnil
;
939 static VALUE
buffer_number(VALUE self
)
941 buf_T
*buf
= get_buf(self
);
943 return INT2NUM(buf
->b_fnum
);
946 static VALUE
buffer_count(VALUE self
)
948 buf_T
*buf
= get_buf(self
);
950 return INT2NUM(buf
->b_ml
.ml_line_count
);
953 static VALUE
get_buffer_line(buf_T
*buf
, linenr_T n
)
955 if (n
> 0 && n
<= buf
->b_ml
.ml_line_count
)
957 char *line
= (char *)ml_get_buf(buf
, n
, FALSE
);
958 return line
? vim_str2rb_enc_str(line
) : Qnil
;
960 rb_raise(rb_eIndexError
, "line number %ld out of range", (long)n
);
962 return Qnil
; /* For stop warning */
966 static VALUE
buffer_aref(VALUE self
, VALUE num
)
968 buf_T
*buf
= get_buf(self
);
971 return get_buffer_line(buf
, (linenr_T
)NUM2LONG(num
));
972 return Qnil
; /* For stop warning */
975 static VALUE
set_buffer_line(buf_T
*buf
, linenr_T n
, VALUE str
)
977 char *line
= StringValuePtr(str
);
980 if (n
> 0 && n
<= buf
->b_ml
.ml_line_count
&& line
!= NULL
)
982 /* set curwin/curbuf for "buf" and save some things */
983 aucmd_prepbuf(&aco
, buf
);
985 if (u_savesub(n
) == OK
) {
986 ml_replace(n
, (char_u
*)line
, TRUE
);
989 syn_changed(n
); /* recompute syntax hl. for this line */
993 /* restore curwin/curbuf and a few other things */
995 /* Careful: autocommands may have made "buf" invalid! */
997 update_curbuf(NOT_VALID
);
1001 rb_raise(rb_eIndexError
, "line number %ld out of range", (long)n
);
1003 return Qnil
; /* For stop warning */
1009 static VALUE
buffer_aset(VALUE self
, VALUE num
, VALUE str
)
1011 buf_T
*buf
= get_buf(self
);
1014 return set_buffer_line(buf
, (linenr_T
)NUM2LONG(num
), str
);
1018 static VALUE
buffer_delete(VALUE self
, VALUE num
)
1020 buf_T
*buf
= get_buf(self
);
1021 long n
= NUM2LONG(num
);
1024 if (n
> 0 && n
<= buf
->b_ml
.ml_line_count
)
1026 /* set curwin/curbuf for "buf" and save some things */
1027 aucmd_prepbuf(&aco
, buf
);
1029 if (u_savedel(n
, 1) == OK
) {
1032 /* Changes to non-active buffers should properly refresh
1033 * SegPhault - 01/09/05 */
1034 deleted_lines_mark(n
, 1L);
1039 /* restore curwin/curbuf and a few other things */
1040 aucmd_restbuf(&aco
);
1041 /* Careful: autocommands may have made "buf" invalid! */
1043 update_curbuf(NOT_VALID
);
1047 rb_raise(rb_eIndexError
, "line number %ld out of range", n
);
1052 static VALUE
buffer_append(VALUE self
, VALUE num
, VALUE str
)
1054 buf_T
*buf
= get_buf(self
);
1055 char *line
= StringValuePtr(str
);
1056 long n
= NUM2LONG(num
);
1060 rb_raise(rb_eIndexError
, "NULL line");
1062 else if (n
>= 0 && n
<= buf
->b_ml
.ml_line_count
)
1064 /* set curwin/curbuf for "buf" and save some things */
1065 aucmd_prepbuf(&aco
, buf
);
1067 if (u_inssub(n
+ 1) == OK
) {
1068 ml_append(n
, (char_u
*) line
, (colnr_T
) 0, FALSE
);
1070 /* Changes to non-active buffers should properly refresh screen
1071 * SegPhault - 12/20/04 */
1072 appended_lines_mark(n
, 1L);
1077 /* restore curwin/curbuf and a few other things */
1078 aucmd_restbuf(&aco
);
1079 /* Careful: autocommands may have made "buf" invalid! */
1081 update_curbuf(NOT_VALID
);
1084 rb_raise(rb_eIndexError
, "line number %ld out of range", n
);
1089 static VALUE
window_new(win_T
*win
)
1091 if (win
->w_ruby_ref
)
1093 return (VALUE
) win
->w_ruby_ref
;
1097 VALUE obj
= Data_Wrap_Struct(cVimWindow
, 0, 0, win
);
1098 win
->w_ruby_ref
= (void *) obj
;
1099 rb_hash_aset(objtbl
, rb_obj_id(obj
), obj
);
1104 static win_T
*get_win(VALUE obj
)
1108 Data_Get_Struct(obj
, win_T
, win
);
1110 rb_raise(eDeletedWindowError
, "attempt to refer to deleted window");
1114 static VALUE
window_s_current()
1116 return window_new(curwin
);
1120 * Added line manipulation functions
1121 * SegPhault - 03/07/05
1123 static VALUE
line_s_current()
1125 return get_buffer_line(curbuf
, curwin
->w_cursor
.lnum
);
1128 static VALUE
set_current_line(VALUE self UNUSED
, VALUE str
)
1130 return set_buffer_line(curbuf
, curwin
->w_cursor
.lnum
, str
);
1133 static VALUE
current_line_number()
1135 return INT2FIX((int)curwin
->w_cursor
.lnum
);
1140 static VALUE
window_s_count()
1146 for (w
= firstwin
; w
!= NULL
; w
= w
->w_next
)
1154 static VALUE
window_s_aref(VALUE self UNUSED
, VALUE num
)
1157 int n
= NUM2INT(num
);
1159 #ifndef FEAT_WINDOWS
1162 for (w
= firstwin
; w
!= NULL
; w
= w
->w_next
, --n
)
1165 return window_new(w
);
1169 static VALUE
window_buffer(VALUE self
)
1171 win_T
*win
= get_win(self
);
1173 return buffer_new(win
->w_buffer
);
1176 static VALUE
window_height(VALUE self
)
1178 win_T
*win
= get_win(self
);
1180 return INT2NUM(win
->w_height
);
1183 static VALUE
window_set_height(VALUE self
, VALUE height
)
1185 win_T
*win
= get_win(self
);
1186 win_T
*savewin
= curwin
;
1189 win_setheight(NUM2INT(height
));
1194 static VALUE
window_width(VALUE self
)
1196 win_T
*win
= get_win(self
);
1198 return INT2NUM(win
->w_width
);
1201 static VALUE
window_set_width(VALUE self
, VALUE width
)
1203 win_T
*win
= get_win(self
);
1204 win_T
*savewin
= curwin
;
1207 win_setwidth(NUM2INT(width
));
1212 static VALUE
window_cursor(VALUE self
)
1214 win_T
*win
= get_win(self
);
1216 return rb_assoc_new(INT2NUM(win
->w_cursor
.lnum
), INT2NUM(win
->w_cursor
.col
));
1219 static VALUE
window_set_cursor(VALUE self
, VALUE pos
)
1222 win_T
*win
= get_win(self
);
1224 Check_Type(pos
, T_ARRAY
);
1225 if (RARRAY_LEN(pos
) != 2)
1226 rb_raise(rb_eArgError
, "array length must be 2");
1227 lnum
= RARRAY_PTR(pos
)[0];
1228 col
= RARRAY_PTR(pos
)[1];
1229 win
->w_cursor
.lnum
= NUM2LONG(lnum
);
1230 win
->w_cursor
.col
= NUM2UINT(col
);
1231 check_cursor(); /* put cursor on an existing line */
1232 update_screen(NOT_VALID
);
1236 static VALUE
f_p(int argc
, VALUE
*argv
, VALUE self UNUSED
)
1239 VALUE str
= rb_str_new("", 0);
1241 for (i
= 0; i
< argc
; i
++) {
1242 if (i
> 0) rb_str_cat(str
, ", ", 2);
1243 rb_str_concat(str
, rb_inspect(argv
[i
]));
1245 MSG(RSTRING_PTR(str
));
1249 static void ruby_io_init(void)
1251 #ifndef DYNAMIC_RUBY
1252 RUBYEXTERN VALUE rb_stdout
;
1255 rb_stdout
= rb_obj_alloc(rb_cObject
);
1256 rb_define_singleton_method(rb_stdout
, "write", vim_message
, 1);
1257 rb_define_global_function("p", f_p
, -1);
1260 static void ruby_vim_init(void)
1262 objtbl
= rb_hash_new();
1263 rb_global_variable(&objtbl
);
1265 /* The Vim module used to be called "VIM", but "Vim" is better. Make an
1266 * alias "VIM" for backwards compatiblity. */
1267 mVIM
= rb_define_module("Vim");
1268 rb_define_const(rb_cObject
, "VIM", mVIM
);
1269 rb_define_const(mVIM
, "VERSION_MAJOR", INT2NUM(VIM_VERSION_MAJOR
));
1270 rb_define_const(mVIM
, "VERSION_MINOR", INT2NUM(VIM_VERSION_MINOR
));
1271 rb_define_const(mVIM
, "VERSION_BUILD", INT2NUM(VIM_VERSION_BUILD
));
1272 rb_define_const(mVIM
, "VERSION_PATCHLEVEL", INT2NUM(VIM_VERSION_PATCHLEVEL
));
1273 rb_define_const(mVIM
, "VERSION_SHORT", rb_str_new2(VIM_VERSION_SHORT
));
1274 rb_define_const(mVIM
, "VERSION_MEDIUM", rb_str_new2(VIM_VERSION_MEDIUM
));
1275 rb_define_const(mVIM
, "VERSION_LONG", rb_str_new2(VIM_VERSION_LONG
));
1276 rb_define_const(mVIM
, "VERSION_LONG_DATE", rb_str_new2(VIM_VERSION_LONG_DATE
));
1277 rb_define_module_function(mVIM
, "message", vim_message
, 1);
1278 rb_define_module_function(mVIM
, "set_option", vim_set_option
, 1);
1279 rb_define_module_function(mVIM
, "command", vim_command
, 1);
1280 rb_define_module_function(mVIM
, "evaluate", vim_evaluate
, 1);
1282 eDeletedBufferError
= rb_define_class_under(mVIM
, "DeletedBufferError",
1284 eDeletedWindowError
= rb_define_class_under(mVIM
, "DeletedWindowError",
1287 cBuffer
= rb_define_class_under(mVIM
, "Buffer", rb_cObject
);
1288 rb_define_singleton_method(cBuffer
, "current", buffer_s_current
, 0);
1289 rb_define_singleton_method(cBuffer
, "count", buffer_s_count
, 0);
1290 rb_define_singleton_method(cBuffer
, "[]", buffer_s_aref
, 1);
1291 rb_define_method(cBuffer
, "name", buffer_name
, 0);
1292 rb_define_method(cBuffer
, "number", buffer_number
, 0);
1293 rb_define_method(cBuffer
, "count", buffer_count
, 0);
1294 rb_define_method(cBuffer
, "length", buffer_count
, 0);
1295 rb_define_method(cBuffer
, "[]", buffer_aref
, 1);
1296 rb_define_method(cBuffer
, "[]=", buffer_aset
, 2);
1297 rb_define_method(cBuffer
, "delete", buffer_delete
, 1);
1298 rb_define_method(cBuffer
, "append", buffer_append
, 2);
1300 /* Added line manipulation functions
1301 * SegPhault - 03/07/05 */
1302 rb_define_method(cBuffer
, "line_number", current_line_number
, 0);
1303 rb_define_method(cBuffer
, "line", line_s_current
, 0);
1304 rb_define_method(cBuffer
, "line=", set_current_line
, 1);
1307 cVimWindow
= rb_define_class_under(mVIM
, "Window", rb_cObject
);
1308 rb_define_singleton_method(cVimWindow
, "current", window_s_current
, 0);
1309 rb_define_singleton_method(cVimWindow
, "count", window_s_count
, 0);
1310 rb_define_singleton_method(cVimWindow
, "[]", window_s_aref
, 1);
1311 rb_define_method(cVimWindow
, "buffer", window_buffer
, 0);
1312 rb_define_method(cVimWindow
, "height", window_height
, 0);
1313 rb_define_method(cVimWindow
, "height=", window_set_height
, 1);
1314 rb_define_method(cVimWindow
, "width", window_width
, 0);
1315 rb_define_method(cVimWindow
, "width=", window_set_width
, 1);
1316 rb_define_method(cVimWindow
, "cursor", window_cursor
, 0);
1317 rb_define_method(cVimWindow
, "cursor=", window_set_cursor
, 1);
1319 rb_define_virtual_variable("$curbuf", buffer_s_current
, 0);
1320 rb_define_virtual_variable("$curwin", window_s_current
, 0);