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