blob: a45269d6e6f376431ef04f9a40c87036bf9bec4a [file] [log] [blame]
Bram Moolenaar071d4272004-06-13 20:20:40 +00001/* vi:set ts=8 sts=4 sw=4:
2 *
3 * VIM - Vi IMproved by Bram Moolenaar
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00004 *
5 * Ruby interface by Shugo Maeda
6 * with improvements by SegPhault (Ryan Paul)
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +02007 * with improvements by Jon Maken
Bram Moolenaar071d4272004-06-13 20:20:40 +00008 *
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
Bram Moolenaar2d73ff42010-10-27 17:40:59 +020014#ifdef HAVE_CONFIG_H
15# include "auto/config.h"
16#endif
Bram Moolenaar3ca71f12010-10-27 16:49:47 +020017
Bram Moolenaare2793352011-01-17 19:53:27 +010018#include <stdio.h>
19#include <string.h>
20
Bram Moolenaar071d4272004-06-13 20:20:40 +000021#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
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +020034#ifdef DYNAMIC_RUBY
Bram Moolenaar071d4272004-06-13 20:20:40 +000035/*
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 */
Bram Moolenaar071d4272004-06-13 20:20:40 +000040# 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/*
Bram Moolenaar42d57f02010-03-10 12:47:00 +010047 * 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
Bram Moolenaar071d4272004-06-13 20:20:40 +000049 * 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
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +020054
Bram Moolenaar2d73ff42010-10-27 17:40:59 +020055#if !(defined(WIN32) || defined(_WIN64))
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +020056# include <dlfcn.h>
Bram Moolenaar3ca71f12010-10-27 16:49:47 +020057# define HINSTANCE void*
58# define RUBY_PROC void*
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +020059# define load_dll(n) dlopen((n), RTLD_LAZY|RTLD_GLOBAL)
60# define symbol_from_dll dlsym
61# define close_dll dlclose
62#else
Bram Moolenaar3ca71f12010-10-27 16:49:47 +020063# define RUBY_PROC FARPROC
Bram Moolenaarebbcb822010-10-23 14:02:54 +020064# define load_dll vimLoadLib
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +020065# define symbol_from_dll GetProcAddress
66# define close_dll FreeLibrary
Bram Moolenaar071d4272004-06-13 20:20:40 +000067#endif
68
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +020069#endif /* ifdef DYNAMIC_RUBY */
70
Bram Moolenaar0b69c732010-02-17 15:11:50 +010071/* suggested by Ariya Mizutani */
72#if (_MSC_VER == 1200)
73# undef _WIN32_WINNT
74#endif
75
Bram Moolenaar639a2552010-03-17 18:15:23 +010076#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
Bram Moolenaar42d57f02010-03-10 12:47:00 +010081#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
Bram Moolenaar071d4272004-06-13 20:20:40 +000088#include <ruby.h>
Bram Moolenaar639a2552010-03-17 18:15:23 +010089#ifdef RUBY19_OR_LATER
Bram Moolenaar165641d2010-02-17 16:23:09 +010090# include <ruby/encoding.h>
91#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +000092
Bram Moolenaar7a8ef142010-12-24 13:39:35 +010093#undef off_t /* ruby defines off_t as _int64, Mingw uses long */
Bram Moolenaar071d4272004-06-13 20:20:40 +000094#undef EXTERN
95#undef _
96
97/* T_DATA defined both by Ruby and Mac header files, hack around it... */
Bram Moolenaarcb635362007-05-12 13:02:42 +000098#if defined(MACOS_X_UNIX) || defined(macintosh)
Bram Moolenaar071d4272004-06-13 20:20:40 +000099# define __OPENTRANSPORT__
100# define __OPENTRANSPORTPROTOCOL__
101# define __OPENTRANSPORTPROVIDERS__
102#endif
103
Bram Moolenaar165641d2010-02-17 16:23:09 +0100104/*
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
Bram Moolenaar071d4272004-06-13 20:20:40 +0000126#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
135static int ruby_initialized = 0;
136static VALUE objtbl;
137
138static VALUE mVIM;
139static VALUE cBuffer;
140static VALUE cVimWindow;
141static VALUE eDeletedBufferError;
142static VALUE eDeletedWindowError;
143
144static int ensure_ruby_initialized(void);
145static void error_print(int);
146static void ruby_io_init(void);
147static 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
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200184#ifndef RUBY19_OR_LATER
Bram Moolenaar071d4272004-06-13 20:20:40 +0000185#define rb_num2long dll_rb_num2long
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200186#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000187#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
Bram Moolenaar071d4272004-06-13 20:20:40 +0000192#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
Bram Moolenaar1d2beae2010-05-22 21:56:55 +0200195#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
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200198/* 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
Bram Moolenaar1d2beae2010-05-22 21:56:55 +0200201# define rb_str_new_cstr dll_rb_str_new_cstr
202#else
Bram Moolenaar218116c2010-05-20 21:46:00 +0200203# define rb_str_new2 dll_rb_str_new2
204#endif
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100205#if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +0200206# define rb_string_value dll_rb_string_value
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100207# 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
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +0200211#else
212# define rb_str2cstr dll_rb_str2cstr
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100213#endif
Bram Moolenaar639a2552010-03-17 18:15:23 +0100214#ifdef RUBY19_OR_LATER
Bram Moolenaar165641d2010-02-17 16:23:09 +0100215# define rb_errinfo dll_rb_errinfo
216#else
217# define ruby_errinfo (*dll_ruby_errinfo)
218#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000219#define ruby_init dll_ruby_init
220#define ruby_init_loadpath dll_ruby_init_loadpath
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200221#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
Bram Moolenaar071d4272004-06-13 20:20:40 +0000226#endif
227
Bram Moolenaar639a2552010-03-17 18:15:23 +0100228#ifdef RUBY19_OR_LATER
Bram Moolenaar165641d2010-02-17 16:23:09 +0100229# 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
Bram Moolenaar7a8ef142010-12-24 13:39:35 +0100234# define rb_require dll_rb_require
Bram Moolenaar639a2552010-03-17 18:15:23 +0100235# define ruby_init_stack dll_ruby_init_stack
Bram Moolenaar7a8ef142010-12-24 13:39:35 +0100236# define ruby_process_options dll_ruby_process_options
Bram Moolenaar165641d2010-02-17 16:23:09 +0100237#endif
238
Bram Moolenaar071d4272004-06-13 20:20:40 +0000239/*
240 * Pointers for dynamic link
241 */
242static VALUE (*dll_rb_assoc_new) (VALUE, VALUE);
Bram Moolenaarba52cde2010-06-25 04:29:11 +0200243VALUE *dll_rb_cFalseClass;
244VALUE *dll_rb_cFixnum;
245VALUE *dll_rb_cNilClass;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000246static VALUE *dll_rb_cObject;
Bram Moolenaarba52cde2010-06-25 04:29:11 +0200247VALUE *dll_rb_cSymbol;
248VALUE *dll_rb_cTrueClass;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000249static void (*dll_rb_check_type) (VALUE,int);
250static VALUE (*dll_rb_class_path) (VALUE);
251static VALUE (*dll_rb_data_object_alloc) (VALUE, void*, RUBY_DATA_FUNC, RUBY_DATA_FUNC);
252static VALUE (*dll_rb_define_class_under) (VALUE, const char*, VALUE);
253static void (*dll_rb_define_const) (VALUE,const char*,VALUE);
254static void (*dll_rb_define_global_function) (const char*,VALUE(*)(),int);
255static void (*dll_rb_define_method) (VALUE,const char*,VALUE(*)(),int);
256static VALUE (*dll_rb_define_module) (const char*);
257static void (*dll_rb_define_module_function) (VALUE,const char*,VALUE(*)(),int);
258static void (*dll_rb_define_singleton_method) (VALUE,const char*,VALUE(*)(),int);
259static void (*dll_rb_define_virtual_variable) (const char*,VALUE(*)(),void(*)());
260static VALUE *dll_rb_stdout;
261static VALUE *dll_rb_eArgError;
262static VALUE *dll_rb_eIndexError;
263static VALUE *dll_rb_eRuntimeError;
264static VALUE *dll_rb_eStandardError;
265static VALUE (*dll_rb_eval_string_protect) (const char*, int*);
266static void (*dll_rb_global_variable) (VALUE*);
267static VALUE (*dll_rb_hash_aset) (VALUE, VALUE, VALUE);
268static VALUE (*dll_rb_hash_new) (void);
269static VALUE (*dll_rb_inspect) (VALUE);
270static VALUE (*dll_rb_int2inum) (long);
271static VALUE (*dll_rb_int2inum) (long);
272static VALUE (*dll_rb_lastline_get) (void);
273static void (*dll_rb_lastline_set) (VALUE);
274static void (*dll_rb_load_protect) (VALUE, int, int*);
275static long (*dll_rb_num2long) (VALUE);
276static unsigned long (*dll_rb_num2ulong) (VALUE);
277static VALUE (*dll_rb_obj_alloc) (VALUE);
278static VALUE (*dll_rb_obj_as_string) (VALUE);
279static VALUE (*dll_rb_obj_id) (VALUE);
280static void (*dll_rb_raise) (VALUE, const char*, ...);
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +0200281#if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
282static VALUE (*dll_rb_string_value) (volatile VALUE*);
283#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000284static char *(*dll_rb_str2cstr) (VALUE,int*);
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +0200285#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000286static VALUE (*dll_rb_str_cat) (VALUE, const char*, long);
287static VALUE (*dll_rb_str_concat) (VALUE, VALUE);
288static VALUE (*dll_rb_str_new) (const char*, long);
Bram Moolenaar1d2beae2010-05-22 21:56:55 +0200289#ifdef need_rb_str_new_cstr
290/* Ruby may #define rb_str_new2 to use rb_str_new_cstr. */
291static VALUE (*dll_rb_str_new_cstr) (const char*);
292#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000293static VALUE (*dll_rb_str_new2) (const char*);
Bram Moolenaar1d2beae2010-05-22 21:56:55 +0200294#endif
Bram Moolenaar639a2552010-03-17 18:15:23 +0100295#ifdef RUBY19_OR_LATER
Bram Moolenaar165641d2010-02-17 16:23:09 +0100296static VALUE (*dll_rb_errinfo) (void);
297#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000298static VALUE *dll_ruby_errinfo;
Bram Moolenaar165641d2010-02-17 16:23:09 +0100299#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000300static void (*dll_ruby_init) (void);
301static void (*dll_ruby_init_loadpath) (void);
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200302#ifdef WIN3264
Bram Moolenaar0b69c732010-02-17 15:11:50 +0100303static void (*dll_NtInitialize) (int*, char***);
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200304# if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
305static int (*dll_rb_w32_snprintf)(char*, size_t, const char*, ...);
306# endif
307#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000308#if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100309static char * (*dll_rb_string_value_ptr) (volatile VALUE*);
310static VALUE (*dll_rb_float_new) (double);
311static VALUE (*dll_rb_ary_new) (void);
312static VALUE (*dll_rb_ary_push) (VALUE, VALUE);
313#endif
Bram Moolenaar639a2552010-03-17 18:15:23 +0100314#ifdef RUBY19_OR_LATER
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100315static VALUE (*dll_rb_int2big)(SIGNED_VALUE);
316#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000317
Bram Moolenaar639a2552010-03-17 18:15:23 +0100318#ifdef RUBY19_OR_LATER
Bram Moolenaar165641d2010-02-17 16:23:09 +0100319static void (*dll_ruby_script) (const char*);
320static int (*dll_rb_enc_find_index) (const char*);
321static rb_encoding* (*dll_rb_enc_find) (const char*);
322static VALUE (*dll_rb_enc_str_new) (const char*, long, rb_encoding*);
323static VALUE (*dll_rb_sprintf) (const char*, ...);
Bram Moolenaar7a8ef142010-12-24 13:39:35 +0100324static VALUE (*dll_rb_require) (const char*);
Bram Moolenaar639a2552010-03-17 18:15:23 +0100325static void (*ruby_init_stack)(VALUE*);
Bram Moolenaar7a8ef142010-12-24 13:39:35 +0100326static void* (*ruby_process_options)(int, char**);
Bram Moolenaar165641d2010-02-17 16:23:09 +0100327#endif
328
Bram Moolenaar639a2552010-03-17 18:15:23 +0100329#ifdef RUBY19_OR_LATER
Bram Moolenaarba52cde2010-06-25 04:29:11 +0200330SIGNED_VALUE rb_num2long_stub(VALUE x)
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100331{
332 return dll_rb_num2long(x);
333}
Bram Moolenaarba52cde2010-06-25 04:29:11 +0200334VALUE rb_int2big_stub(SIGNED_VALUE x)
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100335{
336 return dll_rb_int2big(x);
337}
338#endif
339
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200340static HINSTANCE hinstRuby = NULL; /* Instance of ruby.dll */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000341
342/*
Bram Moolenaarda2303d2005-08-30 21:55:26 +0000343 * Table of name to function pointer of ruby.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000344 */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000345static 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},
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +0200389#if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
390 {"rb_string_value", (RUBY_PROC*)&dll_rb_string_value},
391#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000392 {"rb_str2cstr", (RUBY_PROC*)&dll_rb_str2cstr},
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +0200393#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000394 {"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},
Bram Moolenaar1d2beae2010-05-22 21:56:55 +0200397#ifdef need_rb_str_new_cstr
398 {"rb_str_new_cstr", (RUBY_PROC*)&dll_rb_str_new_cstr},
399#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000400 {"rb_str_new2", (RUBY_PROC*)&dll_rb_str_new2},
Bram Moolenaar1d2beae2010-05-22 21:56:55 +0200401#endif
Bram Moolenaar639a2552010-03-17 18:15:23 +0100402#ifdef RUBY19_OR_LATER
Bram Moolenaar165641d2010-02-17 16:23:09 +0100403 {"rb_errinfo", (RUBY_PROC*)&dll_rb_errinfo},
404#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000405 {"ruby_errinfo", (RUBY_PROC*)&dll_ruby_errinfo},
Bram Moolenaar165641d2010-02-17 16:23:09 +0100406#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000407 {"ruby_init", (RUBY_PROC*)&dll_ruby_init},
408 {"ruby_init_loadpath", (RUBY_PROC*)&dll_ruby_init_loadpath},
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200409#ifdef WIN3264
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100410 {
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200411# if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER < 19
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100412 "NtInitialize",
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200413# else
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100414 "ruby_sysinit",
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200415# endif
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100416 (RUBY_PROC*)&dll_NtInitialize},
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200417# if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
Bram Moolenaar071d4272004-06-13 20:20:40 +0000418 {"rb_w32_snprintf", (RUBY_PROC*)&dll_rb_w32_snprintf},
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200419# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000420#endif
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100421#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
Bram Moolenaar639a2552010-03-17 18:15:23 +0100427#ifdef RUBY19_OR_LATER
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100428 {"rb_int2big", (RUBY_PROC*)&dll_rb_int2big},
Bram Moolenaar165641d2010-02-17 16:23:09 +0100429 {"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},
Bram Moolenaar7a8ef142010-12-24 13:39:35 +0100434 {"rb_require", (RUBY_PROC*)&dll_rb_require},
Bram Moolenaar639a2552010-03-17 18:15:23 +0100435 {"ruby_init_stack", (RUBY_PROC*)&dll_ruby_init_stack},
Bram Moolenaar7a8ef142010-12-24 13:39:35 +0100436 {"ruby_process_options", (RUBY_PROC*)&dll_ruby_process_options},
Bram Moolenaar165641d2010-02-17 16:23:09 +0100437#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000438 {"", NULL},
439};
440
441/*
442 * Free ruby.dll
443 */
444 static void
445end_dynamic_ruby()
446{
447 if (hinstRuby)
448 {
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +0200449 close_dll(hinstRuby);
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200450 hinstRuby = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000451 }
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
460ruby_runtime_link_init(char *libname, int verbose)
461{
462 int i;
463
464 if (hinstRuby)
465 return OK;
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +0200466 hinstRuby = load_dll(libname);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000467 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 {
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +0200476 if (!(*ruby_funcname_table[i].ptr = symbol_from_dll(hinstRuby,
Bram Moolenaar071d4272004-06-13 20:20:40 +0000477 ruby_funcname_table[i].name)))
478 {
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +0200479 close_dll(hinstRuby);
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200480 hinstRuby = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000481 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
494ruby_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
502ruby_end()
503{
504#ifdef DYNAMIC_RUBY
505 end_dynamic_ruby();
506#endif
507}
508
509void ex_ruby(exarg_T *eap)
510{
511 int state;
512 char *script = NULL;
513
Bram Moolenaar35a2e192006-03-13 22:07:11 +0000514 script = (char *)script_get(eap, eap->arg);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000515 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
Bram Moolenaar165641d2010-02-17 16:23:09 +0100527/*
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
533vim_str2rb_enc_str(const char *s)
534{
Bram Moolenaar639a2552010-03-17 18:15:23 +0100535#ifdef RUBY19_OR_LATER
Bram Moolenaar165641d2010-02-17 16:23:09 +0100536 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
555eval_enc_string_protect(const char *str, int *state)
556{
Bram Moolenaar639a2552010-03-17 18:15:23 +0100557#ifdef RUBY19_OR_LATER
Bram Moolenaar165641d2010-02-17 16:23:09 +0100558 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
Bram Moolenaar071d4272004-06-13 20:20:40 +0000579void 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++) {
Bram Moolenaare980d8a2010-12-08 13:11:21 +0100589 VALUE line;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000590
Bram Moolenaare980d8a2010-12-08 13:11:21 +0100591 line = vim_str2rb_enc_str((char *)ml_get(i));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000592 rb_lastline_set(line);
Bram Moolenaar165641d2010-02-17 16:23:09 +0100593 eval_enc_string_protect((char *) eap->arg, &state);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000594 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) {
Bram Moolenaara93fa7e2006-04-17 22:14:47 +0000601 EMSG(_("E265: $_ must be an instance of String"));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000602 return;
603 }
Bram Moolenaar165641d2010-02-17 16:23:09 +0100604 ml_replace(i, (char_u *) StringValuePtr(line), 1);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000605 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
616void 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
627void ruby_buffer_free(buf_T *buf)
628{
Bram Moolenaare344bea2005-09-01 20:46:49 +0000629 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;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000633 }
634}
635
636void ruby_window_free(win_T *win)
637{
Bram Moolenaare344bea2005-09-01 20:46:49 +0000638 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;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000642 }
643}
644
645static int ensure_ruby_initialized(void)
646{
647 if (!ruby_initialized)
648 {
649#ifdef DYNAMIC_RUBY
650 if (ruby_enabled(TRUE))
651 {
652#endif
Bram Moolenaar0b69c732010-02-17 15:11:50 +0100653#ifdef _WIN32
654 /* suggested by Ariya Mizutani */
655 int argc = 1;
656 char *argv[] = {"gvim.exe"};
657 NtInitialize(&argc, &argv);
658#endif
Bram Moolenaarb2c03502010-07-02 20:20:09 +0200659 {
Bram Moolenaar639a2552010-03-17 18:15:23 +0100660#ifdef RUBY19_OR_LATER
Bram Moolenaarb2c03502010-07-02 20:20:09 +0200661 RUBY_INIT_STACK;
Bram Moolenaar165641d2010-02-17 16:23:09 +0100662#endif
Bram Moolenaarb2c03502010-07-02 20:20:09 +0200663 ruby_init();
664 }
Bram Moolenaar639a2552010-03-17 18:15:23 +0100665#ifdef RUBY19_OR_LATER
Bram Moolenaar7a8ef142010-12-24 13:39:35 +0100666 {
667 int dummy_argc = 2;
668 char *dummy_argv[] = {"vim-ruby", "-e0"};
669 ruby_process_options(dummy_argc, dummy_argv);
670 }
Bram Moolenaar165641d2010-02-17 16:23:09 +0100671 ruby_script("vim-ruby");
Bram Moolenaar7a8ef142010-12-24 13:39:35 +0100672#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000673 ruby_init_loadpath();
Bram Moolenaar165641d2010-02-17 16:23:09 +0100674#endif
Bram Moolenaar7a8ef142010-12-24 13:39:35 +0100675 ruby_io_init();
Bram Moolenaar071d4272004-06-13 20:20:40 +0000676 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
690static void error_print(int state)
691{
692#ifndef DYNAMIC_RUBY
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100693#if !(defined(RUBY_VERSION) && RUBY_VERSION >= 19) \
694 && !(defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 19)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000695 RUBYEXTERN VALUE ruby_errinfo;
696#endif
Bram Moolenaar165641d2010-02-17 16:23:09 +0100697#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000698 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:
Bram Moolenaara93fa7e2006-04-17 22:14:47 +0000714 EMSG(_("E267: unexpected return"));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000715 break;
716 case TAG_NEXT:
Bram Moolenaara93fa7e2006-04-17 22:14:47 +0000717 EMSG(_("E268: unexpected next"));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000718 break;
719 case TAG_BREAK:
Bram Moolenaara93fa7e2006-04-17 22:14:47 +0000720 EMSG(_("E269: unexpected break"));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000721 break;
722 case TAG_REDO:
Bram Moolenaara93fa7e2006-04-17 22:14:47 +0000723 EMSG(_("E270: unexpected redo"));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000724 break;
725 case TAG_RETRY:
Bram Moolenaara93fa7e2006-04-17 22:14:47 +0000726 EMSG(_("E271: retry outside of rescue clause"));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000727 break;
728 case TAG_RAISE:
729 case TAG_FATAL:
Bram Moolenaar639a2552010-03-17 18:15:23 +0100730#ifdef RUBY19_OR_LATER
Bram Moolenaar165641d2010-02-17 16:23:09 +0100731 eclass = CLASS_OF(rb_errinfo());
732 einfo = rb_obj_as_string(rb_errinfo());
733#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000734 eclass = CLASS_OF(ruby_errinfo);
735 einfo = rb_obj_as_string(ruby_errinfo);
Bram Moolenaar165641d2010-02-17 16:23:09 +0100736#endif
737 if (eclass == rb_eRuntimeError && RSTRING_LEN(einfo) == 0) {
Bram Moolenaara93fa7e2006-04-17 22:14:47 +0000738 EMSG(_("E272: unhandled exception"));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000739 }
740 else {
741 VALUE epath;
742 char *p;
743
744 epath = rb_class_path(eclass);
Bram Moolenaar9c13b352005-05-19 20:53:52 +0000745 vim_snprintf(buff, BUFSIZ, "%s: %s",
Bram Moolenaar165641d2010-02-17 16:23:09 +0100746 RSTRING_PTR(epath), RSTRING_PTR(einfo));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000747 p = strchr(buff, '\n');
748 if (p) *p = '\0';
749 EMSG(buff);
750 }
751 break;
752 default:
Bram Moolenaar9c13b352005-05-19 20:53:52 +0000753 vim_snprintf(buff, BUFSIZ, _("E273: unknown longjmp status %d"), state);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000754 EMSG(buff);
755 break;
756 }
757}
758
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +0000759static VALUE vim_message(VALUE self UNUSED, VALUE str)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000760{
761 char *buff, *p;
762
763 str = rb_obj_as_string(str);
Bram Moolenaar165641d2010-02-17 16:23:09 +0100764 buff = ALLOCA_N(char, RSTRING_LEN(str));
765 strcpy(buff, RSTRING_PTR(str));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000766 p = strchr(buff, '\n');
767 if (p) *p = '\0';
768 MSG(buff);
769 return Qnil;
770}
771
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +0000772static VALUE vim_set_option(VALUE self UNUSED, VALUE str)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000773{
Bram Moolenaar165641d2010-02-17 16:23:09 +0100774 do_set((char_u *)StringValuePtr(str), 0);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000775 update_screen(NOT_VALID);
776 return Qnil;
777}
778
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +0000779static VALUE vim_command(VALUE self UNUSED, VALUE str)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000780{
Bram Moolenaar165641d2010-02-17 16:23:09 +0100781 do_cmdline_cmd((char_u *)StringValuePtr(str));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000782 return Qnil;
783}
784
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100785#ifdef FEAT_EVAL
786static VALUE vim_to_ruby(typval_T *tv)
787{
788 VALUE result = Qnil;
789
790 if (tv->v_type == VAR_STRING)
791 {
Bram Moolenaar94127e42010-03-19 23:08:48 +0100792 result = rb_str_new2(tv->vval.v_string == NULL
793 ? "" : (char *)(tv->vval.v_string));
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100794 }
795 else if (tv->v_type == VAR_NUMBER)
796 {
Bram Moolenaar639a2552010-03-17 18:15:23 +0100797 result = INT2NUM(tv->vval.v_number);
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100798 }
799# ifdef FEAT_FLOAT
800 else if (tv->v_type == VAR_FLOAT)
801 {
Bram Moolenaar639a2552010-03-17 18:15:23 +0100802 result = rb_float_new(tv->vval.v_float);
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100803 }
804# endif
805 else if (tv->v_type == VAR_LIST)
806 {
Bram Moolenaar639a2552010-03-17 18:15:23 +0100807 list_T *list = tv->vval.v_list;
808 listitem_T *curr;
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100809
Bram Moolenaar639a2552010-03-17 18:15:23 +0100810 result = rb_ary_new();
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100811
Bram Moolenaar639a2552010-03-17 18:15:23 +0100812 if (list != NULL)
813 {
814 for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
815 {
816 rb_ary_push(result, vim_to_ruby(&curr->li_tv));
817 }
818 }
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100819 }
820 else if (tv->v_type == VAR_DICT)
821 {
Bram Moolenaar639a2552010-03-17 18:15:23 +0100822 result = rb_hash_new();
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100823
Bram Moolenaar639a2552010-03-17 18:15:23 +0100824 if (tv->vval.v_dict != NULL)
825 {
826 hashtab_T *ht = &tv->vval.v_dict->dv_hashtab;
827 long_u todo = ht->ht_used;
828 hashitem_T *hi;
829 dictitem_T *di;
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100830
Bram Moolenaar639a2552010-03-17 18:15:23 +0100831 for (hi = ht->ht_array; todo > 0; ++hi)
832 {
833 if (!HASHITEM_EMPTY(hi))
834 {
835 --todo;
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100836
Bram Moolenaar639a2552010-03-17 18:15:23 +0100837 di = dict_lookup(hi);
838 rb_hash_aset(result, rb_str_new2((char *)hi->hi_key),
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100839 vim_to_ruby(&di->di_tv));
Bram Moolenaar639a2552010-03-17 18:15:23 +0100840 }
841 }
842 }
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100843 } /* else return Qnil; */
844
845 return result;
846}
847#endif
848
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +0000849static VALUE vim_evaluate(VALUE self UNUSED, VALUE str)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000850{
851#ifdef FEAT_EVAL
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100852 typval_T *tv;
853 VALUE result;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000854
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100855 tv = eval_expr((char_u *)StringValuePtr(str), NULL);
856 if (tv == NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000857 {
Bram Moolenaar639a2552010-03-17 18:15:23 +0100858 return Qnil;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000859 }
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100860 result = vim_to_ruby(tv);
861
862 free_tv(tv);
863
864 return result;
865#else
866 return Qnil;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000867#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000868}
869
870static VALUE buffer_new(buf_T *buf)
871{
Bram Moolenaare344bea2005-09-01 20:46:49 +0000872 if (buf->b_ruby_ref)
873 {
874 return (VALUE) buf->b_ruby_ref;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000875 }
Bram Moolenaare344bea2005-09-01 20:46:49 +0000876 else
877 {
Bram Moolenaar071d4272004-06-13 20:20:40 +0000878 VALUE obj = Data_Wrap_Struct(cBuffer, 0, 0, buf);
Bram Moolenaare344bea2005-09-01 20:46:49 +0000879 buf->b_ruby_ref = (void *) obj;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000880 rb_hash_aset(objtbl, rb_obj_id(obj), obj);
881 return obj;
882 }
883}
884
885static buf_T *get_buf(VALUE obj)
886{
887 buf_T *buf;
888
889 Data_Get_Struct(obj, buf_T, buf);
890 if (buf == NULL)
891 rb_raise(eDeletedBufferError, "attempt to refer to deleted buffer");
892 return buf;
893}
894
895static VALUE buffer_s_current()
896{
897 return buffer_new(curbuf);
898}
899
900static VALUE buffer_s_count()
901{
902 buf_T *b;
903 int n = 0;
904
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000905 for (b = firstbuf; b != NULL; b = b->b_next)
906 {
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000907 /* Deleted buffers should not be counted
908 * SegPhault - 01/07/05 */
909 if (b->b_p_bl)
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000910 n++;
911 }
912
Bram Moolenaar071d4272004-06-13 20:20:40 +0000913 return INT2NUM(n);
914}
915
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +0000916static VALUE buffer_s_aref(VALUE self UNUSED, VALUE num)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000917{
918 buf_T *b;
919 int n = NUM2INT(num);
920
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000921 for (b = firstbuf; b != NULL; b = b->b_next)
922 {
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000923 /* Deleted buffers should not be counted
924 * SegPhault - 01/07/05 */
925 if (!b->b_p_bl)
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000926 continue;
927
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000928 if (n == 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000929 return buffer_new(b);
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000930
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000931 n--;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000932 }
933 return Qnil;
934}
935
936static VALUE buffer_name(VALUE self)
937{
938 buf_T *buf = get_buf(self);
939
Bram Moolenaar35a2e192006-03-13 22:07:11 +0000940 return buf->b_ffname ? rb_str_new2((char *)buf->b_ffname) : Qnil;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000941}
942
943static VALUE buffer_number(VALUE self)
944{
945 buf_T *buf = get_buf(self);
946
947 return INT2NUM(buf->b_fnum);
948}
949
950static VALUE buffer_count(VALUE self)
951{
952 buf_T *buf = get_buf(self);
953
954 return INT2NUM(buf->b_ml.ml_line_count);
955}
956
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000957static VALUE get_buffer_line(buf_T *buf, linenr_T n)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000958{
Bram Moolenaar3c531602010-11-16 14:46:19 +0100959 if (n <= 0 || n > buf->b_ml.ml_line_count)
960 rb_raise(rb_eIndexError, "line number %ld out of range", (long)n);
961 return vim_str2rb_enc_str((char *)ml_get_buf(buf, n, FALSE));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000962}
963
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000964static VALUE buffer_aref(VALUE self, VALUE num)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000965{
966 buf_T *buf = get_buf(self);
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000967
968 if (buf != NULL)
969 return get_buffer_line(buf, (linenr_T)NUM2LONG(num));
970 return Qnil; /* For stop warning */
971}
972
973static VALUE set_buffer_line(buf_T *buf, linenr_T n, VALUE str)
974{
Bram Moolenaar165641d2010-02-17 16:23:09 +0100975 char *line = StringValuePtr(str);
Bram Moolenaar20ff7922006-06-20 19:10:43 +0000976 aco_save_T aco;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000977
Bram Moolenaar20ff7922006-06-20 19:10:43 +0000978 if (n > 0 && n <= buf->b_ml.ml_line_count && line != NULL)
979 {
Bram Moolenaar20ff7922006-06-20 19:10:43 +0000980 /* set curwin/curbuf for "buf" and save some things */
981 aucmd_prepbuf(&aco, buf);
Bram Moolenaar20ff7922006-06-20 19:10:43 +0000982
Bram Moolenaar071d4272004-06-13 20:20:40 +0000983 if (u_savesub(n) == OK) {
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000984 ml_replace(n, (char_u *)line, TRUE);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000985 changed();
986#ifdef SYNTAX_HL
987 syn_changed(n); /* recompute syntax hl. for this line */
988#endif
989 }
Bram Moolenaar20ff7922006-06-20 19:10:43 +0000990
Bram Moolenaar20ff7922006-06-20 19:10:43 +0000991 /* restore curwin/curbuf and a few other things */
992 aucmd_restbuf(&aco);
993 /* Careful: autocommands may have made "buf" invalid! */
Bram Moolenaarf30e74c2006-08-16 17:35:00 +0000994
Bram Moolenaar071d4272004-06-13 20:20:40 +0000995 update_curbuf(NOT_VALID);
996 }
Bram Moolenaar20ff7922006-06-20 19:10:43 +0000997 else
998 {
Bram Moolenaar165641d2010-02-17 16:23:09 +0100999 rb_raise(rb_eIndexError, "line number %ld out of range", (long)n);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001000 }
1001 return str;
1002}
1003
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001004static VALUE buffer_aset(VALUE self, VALUE num, VALUE str)
1005{
1006 buf_T *buf = get_buf(self);
1007
1008 if (buf != NULL)
1009 return set_buffer_line(buf, (linenr_T)NUM2LONG(num), str);
1010 return str;
1011}
1012
Bram Moolenaar071d4272004-06-13 20:20:40 +00001013static VALUE buffer_delete(VALUE self, VALUE num)
1014{
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001015 buf_T *buf = get_buf(self);
1016 long n = NUM2LONG(num);
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001017 aco_save_T aco;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001018
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001019 if (n > 0 && n <= buf->b_ml.ml_line_count)
1020 {
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001021 /* set curwin/curbuf for "buf" and save some things */
1022 aucmd_prepbuf(&aco, buf);
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001023
Bram Moolenaar071d4272004-06-13 20:20:40 +00001024 if (u_savedel(n, 1) == OK) {
Bram Moolenaar071d4272004-06-13 20:20:40 +00001025 ml_delete(n, 0);
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001026
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001027 /* Changes to non-active buffers should properly refresh
1028 * SegPhault - 01/09/05 */
1029 deleted_lines_mark(n, 1L);
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001030
Bram Moolenaar071d4272004-06-13 20:20:40 +00001031 changed();
1032 }
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001033
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001034 /* restore curwin/curbuf and a few other things */
1035 aucmd_restbuf(&aco);
1036 /* Careful: autocommands may have made "buf" invalid! */
Bram Moolenaarf30e74c2006-08-16 17:35:00 +00001037
Bram Moolenaar071d4272004-06-13 20:20:40 +00001038 update_curbuf(NOT_VALID);
1039 }
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001040 else
1041 {
Bram Moolenaar165641d2010-02-17 16:23:09 +01001042 rb_raise(rb_eIndexError, "line number %ld out of range", n);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001043 }
1044 return Qnil;
1045}
1046
1047static VALUE buffer_append(VALUE self, VALUE num, VALUE str)
1048{
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001049 buf_T *buf = get_buf(self);
Bram Moolenaar165641d2010-02-17 16:23:09 +01001050 char *line = StringValuePtr(str);
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001051 long n = NUM2LONG(num);
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001052 aco_save_T aco;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001053
Bram Moolenaar3c531602010-11-16 14:46:19 +01001054 if (line == NULL)
1055 {
Bram Moolenaar165641d2010-02-17 16:23:09 +01001056 rb_raise(rb_eIndexError, "NULL line");
1057 }
1058 else if (n >= 0 && n <= buf->b_ml.ml_line_count)
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001059 {
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001060 /* set curwin/curbuf for "buf" and save some things */
1061 aucmd_prepbuf(&aco, buf);
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001062
Bram Moolenaar071d4272004-06-13 20:20:40 +00001063 if (u_inssub(n + 1) == OK) {
Bram Moolenaar071d4272004-06-13 20:20:40 +00001064 ml_append(n, (char_u *) line, (colnr_T) 0, FALSE);
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001065
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001066 /* Changes to non-active buffers should properly refresh screen
1067 * SegPhault - 12/20/04 */
1068 appended_lines_mark(n, 1L);
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001069
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001070 changed();
Bram Moolenaar071d4272004-06-13 20:20:40 +00001071 }
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001072
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001073 /* restore curwin/curbuf and a few other things */
1074 aucmd_restbuf(&aco);
1075 /* Careful: autocommands may have made "buf" invalid! */
Bram Moolenaarf30e74c2006-08-16 17:35:00 +00001076
Bram Moolenaar071d4272004-06-13 20:20:40 +00001077 update_curbuf(NOT_VALID);
1078 }
Bram Moolenaar3c531602010-11-16 14:46:19 +01001079 else
1080 {
Bram Moolenaar165641d2010-02-17 16:23:09 +01001081 rb_raise(rb_eIndexError, "line number %ld out of range", n);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001082 }
1083 return str;
1084}
1085
1086static VALUE window_new(win_T *win)
1087{
Bram Moolenaare344bea2005-09-01 20:46:49 +00001088 if (win->w_ruby_ref)
1089 {
1090 return (VALUE) win->w_ruby_ref;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001091 }
Bram Moolenaare344bea2005-09-01 20:46:49 +00001092 else
1093 {
Bram Moolenaar071d4272004-06-13 20:20:40 +00001094 VALUE obj = Data_Wrap_Struct(cVimWindow, 0, 0, win);
Bram Moolenaare344bea2005-09-01 20:46:49 +00001095 win->w_ruby_ref = (void *) obj;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001096 rb_hash_aset(objtbl, rb_obj_id(obj), obj);
1097 return obj;
1098 }
1099}
1100
1101static win_T *get_win(VALUE obj)
1102{
1103 win_T *win;
1104
1105 Data_Get_Struct(obj, win_T, win);
1106 if (win == NULL)
1107 rb_raise(eDeletedWindowError, "attempt to refer to deleted window");
1108 return win;
1109}
1110
1111static VALUE window_s_current()
1112{
1113 return window_new(curwin);
1114}
1115
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001116/*
1117 * Added line manipulation functions
1118 * SegPhault - 03/07/05
1119 */
1120static VALUE line_s_current()
1121{
1122 return get_buffer_line(curbuf, curwin->w_cursor.lnum);
1123}
1124
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +00001125static VALUE set_current_line(VALUE self UNUSED, VALUE str)
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001126{
1127 return set_buffer_line(curbuf, curwin->w_cursor.lnum, str);
1128}
1129
1130static VALUE current_line_number()
1131{
1132 return INT2FIX((int)curwin->w_cursor.lnum);
1133}
1134
1135
1136
Bram Moolenaar071d4272004-06-13 20:20:40 +00001137static VALUE window_s_count()
1138{
1139#ifdef FEAT_WINDOWS
1140 win_T *w;
1141 int n = 0;
1142
Bram Moolenaarf740b292006-02-16 22:11:02 +00001143 for (w = firstwin; w != NULL; w = w->w_next)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001144 n++;
1145 return INT2NUM(n);
1146#else
1147 return INT2NUM(1);
1148#endif
1149}
1150
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +00001151static VALUE window_s_aref(VALUE self UNUSED, VALUE num)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001152{
1153 win_T *w;
1154 int n = NUM2INT(num);
1155
1156#ifndef FEAT_WINDOWS
1157 w = curwin;
1158#else
1159 for (w = firstwin; w != NULL; w = w->w_next, --n)
1160#endif
1161 if (n == 0)
1162 return window_new(w);
1163 return Qnil;
1164}
1165
1166static VALUE window_buffer(VALUE self)
1167{
1168 win_T *win = get_win(self);
1169
1170 return buffer_new(win->w_buffer);
1171}
1172
1173static VALUE window_height(VALUE self)
1174{
1175 win_T *win = get_win(self);
1176
1177 return INT2NUM(win->w_height);
1178}
1179
1180static VALUE window_set_height(VALUE self, VALUE height)
1181{
1182 win_T *win = get_win(self);
1183 win_T *savewin = curwin;
1184
1185 curwin = win;
1186 win_setheight(NUM2INT(height));
1187 curwin = savewin;
1188 return height;
1189}
1190
Bram Moolenaarda2303d2005-08-30 21:55:26 +00001191static VALUE window_width(VALUE self)
1192{
1193 win_T *win = get_win(self);
1194
1195 return INT2NUM(win->w_width);
1196}
1197
1198static VALUE window_set_width(VALUE self, VALUE width)
1199{
1200 win_T *win = get_win(self);
1201 win_T *savewin = curwin;
1202
1203 curwin = win;
1204 win_setwidth(NUM2INT(width));
1205 curwin = savewin;
1206 return width;
1207}
1208
Bram Moolenaar071d4272004-06-13 20:20:40 +00001209static VALUE window_cursor(VALUE self)
1210{
1211 win_T *win = get_win(self);
1212
1213 return rb_assoc_new(INT2NUM(win->w_cursor.lnum), INT2NUM(win->w_cursor.col));
1214}
1215
1216static VALUE window_set_cursor(VALUE self, VALUE pos)
1217{
1218 VALUE lnum, col;
1219 win_T *win = get_win(self);
1220
1221 Check_Type(pos, T_ARRAY);
Bram Moolenaar165641d2010-02-17 16:23:09 +01001222 if (RARRAY_LEN(pos) != 2)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001223 rb_raise(rb_eArgError, "array length must be 2");
Bram Moolenaar165641d2010-02-17 16:23:09 +01001224 lnum = RARRAY_PTR(pos)[0];
1225 col = RARRAY_PTR(pos)[1];
Bram Moolenaar071d4272004-06-13 20:20:40 +00001226 win->w_cursor.lnum = NUM2LONG(lnum);
1227 win->w_cursor.col = NUM2UINT(col);
1228 check_cursor(); /* put cursor on an existing line */
1229 update_screen(NOT_VALID);
1230 return Qnil;
1231}
1232
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +00001233static VALUE f_p(int argc, VALUE *argv, VALUE self UNUSED)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001234{
1235 int i;
1236 VALUE str = rb_str_new("", 0);
1237
1238 for (i = 0; i < argc; i++) {
1239 if (i > 0) rb_str_cat(str, ", ", 2);
1240 rb_str_concat(str, rb_inspect(argv[i]));
1241 }
Bram Moolenaar165641d2010-02-17 16:23:09 +01001242 MSG(RSTRING_PTR(str));
Bram Moolenaar071d4272004-06-13 20:20:40 +00001243 return Qnil;
1244}
1245
1246static void ruby_io_init(void)
1247{
1248#ifndef DYNAMIC_RUBY
1249 RUBYEXTERN VALUE rb_stdout;
1250#endif
1251
1252 rb_stdout = rb_obj_alloc(rb_cObject);
1253 rb_define_singleton_method(rb_stdout, "write", vim_message, 1);
1254 rb_define_global_function("p", f_p, -1);
1255}
1256
1257static void ruby_vim_init(void)
1258{
1259 objtbl = rb_hash_new();
1260 rb_global_variable(&objtbl);
1261
Bram Moolenaarf711faf2007-05-10 16:48:19 +00001262 /* The Vim module used to be called "VIM", but "Vim" is better. Make an
1263 * alias "VIM" for backwards compatiblity. */
1264 mVIM = rb_define_module("Vim");
1265 rb_define_const(rb_cObject, "VIM", mVIM);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001266 rb_define_const(mVIM, "VERSION_MAJOR", INT2NUM(VIM_VERSION_MAJOR));
1267 rb_define_const(mVIM, "VERSION_MINOR", INT2NUM(VIM_VERSION_MINOR));
1268 rb_define_const(mVIM, "VERSION_BUILD", INT2NUM(VIM_VERSION_BUILD));
1269 rb_define_const(mVIM, "VERSION_PATCHLEVEL", INT2NUM(VIM_VERSION_PATCHLEVEL));
1270 rb_define_const(mVIM, "VERSION_SHORT", rb_str_new2(VIM_VERSION_SHORT));
1271 rb_define_const(mVIM, "VERSION_MEDIUM", rb_str_new2(VIM_VERSION_MEDIUM));
1272 rb_define_const(mVIM, "VERSION_LONG", rb_str_new2(VIM_VERSION_LONG));
1273 rb_define_const(mVIM, "VERSION_LONG_DATE", rb_str_new2(VIM_VERSION_LONG_DATE));
1274 rb_define_module_function(mVIM, "message", vim_message, 1);
1275 rb_define_module_function(mVIM, "set_option", vim_set_option, 1);
1276 rb_define_module_function(mVIM, "command", vim_command, 1);
1277 rb_define_module_function(mVIM, "evaluate", vim_evaluate, 1);
1278
1279 eDeletedBufferError = rb_define_class_under(mVIM, "DeletedBufferError",
1280 rb_eStandardError);
1281 eDeletedWindowError = rb_define_class_under(mVIM, "DeletedWindowError",
1282 rb_eStandardError);
1283
1284 cBuffer = rb_define_class_under(mVIM, "Buffer", rb_cObject);
1285 rb_define_singleton_method(cBuffer, "current", buffer_s_current, 0);
1286 rb_define_singleton_method(cBuffer, "count", buffer_s_count, 0);
1287 rb_define_singleton_method(cBuffer, "[]", buffer_s_aref, 1);
1288 rb_define_method(cBuffer, "name", buffer_name, 0);
1289 rb_define_method(cBuffer, "number", buffer_number, 0);
1290 rb_define_method(cBuffer, "count", buffer_count, 0);
1291 rb_define_method(cBuffer, "length", buffer_count, 0);
1292 rb_define_method(cBuffer, "[]", buffer_aref, 1);
1293 rb_define_method(cBuffer, "[]=", buffer_aset, 2);
1294 rb_define_method(cBuffer, "delete", buffer_delete, 1);
1295 rb_define_method(cBuffer, "append", buffer_append, 2);
1296
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001297 /* Added line manipulation functions
1298 * SegPhault - 03/07/05 */
1299 rb_define_method(cBuffer, "line_number", current_line_number, 0);
1300 rb_define_method(cBuffer, "line", line_s_current, 0);
1301 rb_define_method(cBuffer, "line=", set_current_line, 1);
1302
1303
Bram Moolenaar071d4272004-06-13 20:20:40 +00001304 cVimWindow = rb_define_class_under(mVIM, "Window", rb_cObject);
1305 rb_define_singleton_method(cVimWindow, "current", window_s_current, 0);
1306 rb_define_singleton_method(cVimWindow, "count", window_s_count, 0);
1307 rb_define_singleton_method(cVimWindow, "[]", window_s_aref, 1);
1308 rb_define_method(cVimWindow, "buffer", window_buffer, 0);
1309 rb_define_method(cVimWindow, "height", window_height, 0);
1310 rb_define_method(cVimWindow, "height=", window_set_height, 1);
Bram Moolenaarda2303d2005-08-30 21:55:26 +00001311 rb_define_method(cVimWindow, "width", window_width, 0);
1312 rb_define_method(cVimWindow, "width=", window_set_width, 1);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001313 rb_define_method(cVimWindow, "cursor", window_cursor, 0);
1314 rb_define_method(cVimWindow, "cursor=", window_set_cursor, 1);
1315
1316 rb_define_virtual_variable("$curbuf", buffer_s_current, 0);
1317 rb_define_virtual_variable("$curwin", window_s_current, 0);
1318}