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