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