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