blob: 18e43f481ea290c5ceded28d39f4426b9c67baa1 [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
14#include <stdio.h>
15#include <string.h>
16
Bram Moolenaar2d73ff42010-10-27 17:40:59 +020017#ifdef HAVE_CONFIG_H
18# include "auto/config.h"
19#endif
Bram Moolenaar3ca71f12010-10-27 16:49:47 +020020
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
93#undef EXTERN
94#undef _
95
96/* T_DATA defined both by Ruby and Mac header files, hack around it... */
Bram Moolenaarcb635362007-05-12 13:02:42 +000097#if defined(MACOS_X_UNIX) || defined(macintosh)
Bram Moolenaar071d4272004-06-13 20:20:40 +000098# define __OPENTRANSPORT__
99# define __OPENTRANSPORTPROTOCOL__
100# define __OPENTRANSPORTPROVIDERS__
101#endif
102
Bram Moolenaar165641d2010-02-17 16:23:09 +0100103/*
104 * Backward compatiblity for Ruby 1.8 and earlier.
105 * Ruby 1.9 does not provide STR2CSTR, instead StringValuePtr is provided.
106 * Ruby 1.9 does not provide RXXX(s)->len and RXXX(s)->ptr, instead
107 * RXXX_LEN(s) and RXXX_PTR(s) are provided.
108 */
109#ifndef StringValuePtr
110# define StringValuePtr(s) STR2CSTR(s)
111#endif
112#ifndef RARRAY_LEN
113# define RARRAY_LEN(s) RARRAY(s)->len
114#endif
115#ifndef RARRAY_PTR
116# define RARRAY_PTR(s) RARRAY(s)->ptr
117#endif
118#ifndef RSTRING_LEN
119# define RSTRING_LEN(s) RSTRING(s)->len
120#endif
121#ifndef RSTRING_PTR
122# define RSTRING_PTR(s) RSTRING(s)->ptr
123#endif
124
Bram Moolenaar071d4272004-06-13 20:20:40 +0000125#include "vim.h"
126#include "version.h"
127
128#if defined(PROTO) && !defined(FEAT_RUBY)
129/* Define these to be able to generate the function prototypes. */
130# define VALUE int
131# define RUBY_DATA_FUNC int
132#endif
133
134static int ruby_initialized = 0;
135static VALUE objtbl;
136
137static VALUE mVIM;
138static VALUE cBuffer;
139static VALUE cVimWindow;
140static VALUE eDeletedBufferError;
141static VALUE eDeletedWindowError;
142
143static int ensure_ruby_initialized(void);
144static void error_print(int);
145static void ruby_io_init(void);
146static void ruby_vim_init(void);
147
148#if defined(DYNAMIC_RUBY) || defined(PROTO)
149#ifdef PROTO
150# define HINSTANCE int /* for generating prototypes */
151#endif
152
153/*
154 * Wrapper defines
155 */
156#define rb_assoc_new dll_rb_assoc_new
157#define rb_cObject (*dll_rb_cObject)
158#define rb_check_type dll_rb_check_type
159#define rb_class_path dll_rb_class_path
160#define rb_data_object_alloc dll_rb_data_object_alloc
161#define rb_define_class_under dll_rb_define_class_under
162#define rb_define_const dll_rb_define_const
163#define rb_define_global_function dll_rb_define_global_function
164#define rb_define_method dll_rb_define_method
165#define rb_define_module dll_rb_define_module
166#define rb_define_module_function dll_rb_define_module_function
167#define rb_define_singleton_method dll_rb_define_singleton_method
168#define rb_define_virtual_variable dll_rb_define_virtual_variable
169#define rb_stdout (*dll_rb_stdout)
170#define rb_eArgError (*dll_rb_eArgError)
171#define rb_eIndexError (*dll_rb_eIndexError)
172#define rb_eRuntimeError (*dll_rb_eRuntimeError)
173#define rb_eStandardError (*dll_rb_eStandardError)
174#define rb_eval_string_protect dll_rb_eval_string_protect
175#define rb_global_variable dll_rb_global_variable
176#define rb_hash_aset dll_rb_hash_aset
177#define rb_hash_new dll_rb_hash_new
178#define rb_inspect dll_rb_inspect
179#define rb_int2inum dll_rb_int2inum
180#define rb_lastline_get dll_rb_lastline_get
181#define rb_lastline_set dll_rb_lastline_set
182#define rb_load_protect dll_rb_load_protect
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200183#ifndef RUBY19_OR_LATER
Bram Moolenaar071d4272004-06-13 20:20:40 +0000184#define rb_num2long dll_rb_num2long
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200185#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000186#define rb_num2ulong dll_rb_num2ulong
187#define rb_obj_alloc dll_rb_obj_alloc
188#define rb_obj_as_string dll_rb_obj_as_string
189#define rb_obj_id dll_rb_obj_id
190#define rb_raise dll_rb_raise
Bram Moolenaar071d4272004-06-13 20:20:40 +0000191#define rb_str_cat dll_rb_str_cat
192#define rb_str_concat dll_rb_str_concat
193#define rb_str_new dll_rb_str_new
Bram Moolenaar1d2beae2010-05-22 21:56:55 +0200194#ifdef rb_str_new2
195/* Ruby may #define rb_str_new2 to use rb_str_new_cstr. */
196# define need_rb_str_new_cstr 1
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200197/* Ruby's headers #define rb_str_new_cstr to make use of GCC's
198 * __builtin_constant_p extension. */
199# undef rb_str_new_cstr
Bram Moolenaar1d2beae2010-05-22 21:56:55 +0200200# define rb_str_new_cstr dll_rb_str_new_cstr
201#else
Bram Moolenaar218116c2010-05-20 21:46:00 +0200202# define rb_str_new2 dll_rb_str_new2
203#endif
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100204#if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +0200205# define rb_string_value dll_rb_string_value
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100206# define rb_string_value_ptr dll_rb_string_value_ptr
207# define rb_float_new dll_rb_float_new
208# define rb_ary_new dll_rb_ary_new
209# define rb_ary_push dll_rb_ary_push
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +0200210#else
211# define rb_str2cstr dll_rb_str2cstr
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100212#endif
Bram Moolenaar639a2552010-03-17 18:15:23 +0100213#ifdef RUBY19_OR_LATER
Bram Moolenaar165641d2010-02-17 16:23:09 +0100214# define rb_errinfo dll_rb_errinfo
215#else
216# define ruby_errinfo (*dll_ruby_errinfo)
217#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000218#define ruby_init dll_ruby_init
219#define ruby_init_loadpath dll_ruby_init_loadpath
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200220#ifdef WIN3264
221# define NtInitialize dll_NtInitialize
222# if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
223# define rb_w32_snprintf dll_rb_w32_snprintf
224# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000225#endif
226
Bram Moolenaar639a2552010-03-17 18:15:23 +0100227#ifdef RUBY19_OR_LATER
Bram Moolenaar165641d2010-02-17 16:23:09 +0100228# define ruby_script dll_ruby_script
229# define rb_enc_find_index dll_rb_enc_find_index
230# define rb_enc_find dll_rb_enc_find
231# define rb_enc_str_new dll_rb_enc_str_new
Bram Moolenaar3c531602010-11-16 14:46:19 +0100232# define rb_intern2 dll_rb_intern2
233# define rb_const_remove dll_rb_const_remove
Bram Moolenaar165641d2010-02-17 16:23:09 +0100234# define rb_sprintf dll_rb_sprintf
Bram Moolenaar639a2552010-03-17 18:15:23 +0100235# define ruby_init_stack dll_ruby_init_stack
Bram Moolenaar165641d2010-02-17 16:23:09 +0100236#endif
237
Bram Moolenaar071d4272004-06-13 20:20:40 +0000238/*
239 * Pointers for dynamic link
240 */
241static VALUE (*dll_rb_assoc_new) (VALUE, VALUE);
Bram Moolenaarba52cde2010-06-25 04:29:11 +0200242VALUE *dll_rb_cFalseClass;
243VALUE *dll_rb_cFixnum;
244VALUE *dll_rb_cNilClass;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000245static VALUE *dll_rb_cObject;
Bram Moolenaarba52cde2010-06-25 04:29:11 +0200246VALUE *dll_rb_cSymbol;
247VALUE *dll_rb_cTrueClass;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000248static void (*dll_rb_check_type) (VALUE,int);
249static VALUE (*dll_rb_class_path) (VALUE);
250static VALUE (*dll_rb_data_object_alloc) (VALUE, void*, RUBY_DATA_FUNC, RUBY_DATA_FUNC);
251static VALUE (*dll_rb_define_class_under) (VALUE, const char*, VALUE);
252static void (*dll_rb_define_const) (VALUE,const char*,VALUE);
253static void (*dll_rb_define_global_function) (const char*,VALUE(*)(),int);
254static void (*dll_rb_define_method) (VALUE,const char*,VALUE(*)(),int);
255static VALUE (*dll_rb_define_module) (const char*);
256static void (*dll_rb_define_module_function) (VALUE,const char*,VALUE(*)(),int);
257static void (*dll_rb_define_singleton_method) (VALUE,const char*,VALUE(*)(),int);
258static void (*dll_rb_define_virtual_variable) (const char*,VALUE(*)(),void(*)());
259static VALUE *dll_rb_stdout;
260static VALUE *dll_rb_eArgError;
261static VALUE *dll_rb_eIndexError;
262static VALUE *dll_rb_eRuntimeError;
263static VALUE *dll_rb_eStandardError;
264static VALUE (*dll_rb_eval_string_protect) (const char*, int*);
265static void (*dll_rb_global_variable) (VALUE*);
266static VALUE (*dll_rb_hash_aset) (VALUE, VALUE, VALUE);
267static VALUE (*dll_rb_hash_new) (void);
268static VALUE (*dll_rb_inspect) (VALUE);
269static VALUE (*dll_rb_int2inum) (long);
270static VALUE (*dll_rb_int2inum) (long);
271static VALUE (*dll_rb_lastline_get) (void);
272static void (*dll_rb_lastline_set) (VALUE);
273static void (*dll_rb_load_protect) (VALUE, int, int*);
274static long (*dll_rb_num2long) (VALUE);
275static unsigned long (*dll_rb_num2ulong) (VALUE);
276static VALUE (*dll_rb_obj_alloc) (VALUE);
277static VALUE (*dll_rb_obj_as_string) (VALUE);
278static VALUE (*dll_rb_obj_id) (VALUE);
279static void (*dll_rb_raise) (VALUE, const char*, ...);
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +0200280#if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
281static VALUE (*dll_rb_string_value) (volatile VALUE*);
282#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000283static char *(*dll_rb_str2cstr) (VALUE,int*);
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +0200284#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000285static VALUE (*dll_rb_str_cat) (VALUE, const char*, long);
286static VALUE (*dll_rb_str_concat) (VALUE, VALUE);
287static VALUE (*dll_rb_str_new) (const char*, long);
Bram Moolenaar1d2beae2010-05-22 21:56:55 +0200288#ifdef need_rb_str_new_cstr
289/* Ruby may #define rb_str_new2 to use rb_str_new_cstr. */
290static VALUE (*dll_rb_str_new_cstr) (const char*);
291#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000292static VALUE (*dll_rb_str_new2) (const char*);
Bram Moolenaar1d2beae2010-05-22 21:56:55 +0200293#endif
Bram Moolenaar639a2552010-03-17 18:15:23 +0100294#ifdef RUBY19_OR_LATER
Bram Moolenaar165641d2010-02-17 16:23:09 +0100295static VALUE (*dll_rb_errinfo) (void);
296#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000297static VALUE *dll_ruby_errinfo;
Bram Moolenaar165641d2010-02-17 16:23:09 +0100298#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000299static void (*dll_ruby_init) (void);
300static void (*dll_ruby_init_loadpath) (void);
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200301#ifdef WIN3264
Bram Moolenaar0b69c732010-02-17 15:11:50 +0100302static void (*dll_NtInitialize) (int*, char***);
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200303# if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
304static int (*dll_rb_w32_snprintf)(char*, size_t, const char*, ...);
305# endif
306#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000307#if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100308static char * (*dll_rb_string_value_ptr) (volatile VALUE*);
309static VALUE (*dll_rb_float_new) (double);
310static VALUE (*dll_rb_ary_new) (void);
311static VALUE (*dll_rb_ary_push) (VALUE, VALUE);
312#endif
Bram Moolenaar639a2552010-03-17 18:15:23 +0100313#ifdef RUBY19_OR_LATER
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100314static VALUE (*dll_rb_int2big)(SIGNED_VALUE);
315#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000316
Bram Moolenaar639a2552010-03-17 18:15:23 +0100317#ifdef RUBY19_OR_LATER
Bram Moolenaar165641d2010-02-17 16:23:09 +0100318static void (*dll_ruby_script) (const char*);
319static int (*dll_rb_enc_find_index) (const char*);
320static rb_encoding* (*dll_rb_enc_find) (const char*);
321static VALUE (*dll_rb_enc_str_new) (const char*, long, rb_encoding*);
Bram Moolenaar3c531602010-11-16 14:46:19 +0100322static ID (*dll_rb_intern2) (const char*, long);
323static void (*dll_Init_prelude) (void);
324static VALUE (*dll_rb_const_remove) (VALUE, ID);
Bram Moolenaar165641d2010-02-17 16:23:09 +0100325static VALUE (*dll_rb_sprintf) (const char*, ...);
Bram Moolenaar639a2552010-03-17 18:15:23 +0100326static void (*ruby_init_stack)(VALUE*);
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},
Bram Moolenaar3c531602010-11-16 14:46:19 +0100433 {"rb_intern2", (RUBY_PROC*)&dll_rb_intern2},
434 {"rb_const_remove", (RUBY_PROC*)&dll_rb_const_remove},
Bram Moolenaar165641d2010-02-17 16:23:09 +0100435 {"rb_sprintf", (RUBY_PROC*)&dll_rb_sprintf},
Bram Moolenaar639a2552010-03-17 18:15:23 +0100436 {"ruby_init_stack", (RUBY_PROC*)&dll_ruby_init_stack},
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 Moolenaar165641d2010-02-17 16:23:09 +0100666 ruby_script("vim-ruby");
667#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000668 ruby_init_loadpath();
669 ruby_io_init();
Bram Moolenaar639a2552010-03-17 18:15:23 +0100670#ifdef RUBY19_OR_LATER
Bram Moolenaar165641d2010-02-17 16:23:09 +0100671 rb_enc_find_index("encdb");
Bram Moolenaar3c531602010-11-16 14:46:19 +0100672
673 /* This avoids the error "Encoding::ConverterNotFoundError: code
674 * converter not found (UTF-16LE to ASCII-8BIT)". */
675 rb_define_module("Gem");
Bram Moolenaar3c531602010-11-16 14:46:19 +0100676 rb_const_remove(rb_cObject, rb_intern2("TMP_RUBY_PREFIX", 15));
Bram Moolenaar165641d2010-02-17 16:23:09 +0100677#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000678 ruby_vim_init();
679 ruby_initialized = 1;
680#ifdef DYNAMIC_RUBY
681 }
682 else
683 {
684 EMSG(_("E266: Sorry, this command is disabled, the Ruby library could not be loaded."));
685 return 0;
686 }
687#endif
688 }
689 return ruby_initialized;
690}
691
692static void error_print(int state)
693{
694#ifndef DYNAMIC_RUBY
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100695#if !(defined(RUBY_VERSION) && RUBY_VERSION >= 19) \
696 && !(defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 19)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000697 RUBYEXTERN VALUE ruby_errinfo;
698#endif
Bram Moolenaar165641d2010-02-17 16:23:09 +0100699#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000700 VALUE eclass;
701 VALUE einfo;
702 char buff[BUFSIZ];
703
704#define TAG_RETURN 0x1
705#define TAG_BREAK 0x2
706#define TAG_NEXT 0x3
707#define TAG_RETRY 0x4
708#define TAG_REDO 0x5
709#define TAG_RAISE 0x6
710#define TAG_THROW 0x7
711#define TAG_FATAL 0x8
712#define TAG_MASK 0xf
713
714 switch (state) {
715 case TAG_RETURN:
Bram Moolenaara93fa7e2006-04-17 22:14:47 +0000716 EMSG(_("E267: unexpected return"));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000717 break;
718 case TAG_NEXT:
Bram Moolenaara93fa7e2006-04-17 22:14:47 +0000719 EMSG(_("E268: unexpected next"));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000720 break;
721 case TAG_BREAK:
Bram Moolenaara93fa7e2006-04-17 22:14:47 +0000722 EMSG(_("E269: unexpected break"));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000723 break;
724 case TAG_REDO:
Bram Moolenaara93fa7e2006-04-17 22:14:47 +0000725 EMSG(_("E270: unexpected redo"));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000726 break;
727 case TAG_RETRY:
Bram Moolenaara93fa7e2006-04-17 22:14:47 +0000728 EMSG(_("E271: retry outside of rescue clause"));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000729 break;
730 case TAG_RAISE:
731 case TAG_FATAL:
Bram Moolenaar639a2552010-03-17 18:15:23 +0100732#ifdef RUBY19_OR_LATER
Bram Moolenaar165641d2010-02-17 16:23:09 +0100733 eclass = CLASS_OF(rb_errinfo());
734 einfo = rb_obj_as_string(rb_errinfo());
735#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000736 eclass = CLASS_OF(ruby_errinfo);
737 einfo = rb_obj_as_string(ruby_errinfo);
Bram Moolenaar165641d2010-02-17 16:23:09 +0100738#endif
739 if (eclass == rb_eRuntimeError && RSTRING_LEN(einfo) == 0) {
Bram Moolenaara93fa7e2006-04-17 22:14:47 +0000740 EMSG(_("E272: unhandled exception"));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000741 }
742 else {
743 VALUE epath;
744 char *p;
745
746 epath = rb_class_path(eclass);
Bram Moolenaar9c13b352005-05-19 20:53:52 +0000747 vim_snprintf(buff, BUFSIZ, "%s: %s",
Bram Moolenaar165641d2010-02-17 16:23:09 +0100748 RSTRING_PTR(epath), RSTRING_PTR(einfo));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000749 p = strchr(buff, '\n');
750 if (p) *p = '\0';
751 EMSG(buff);
752 }
753 break;
754 default:
Bram Moolenaar9c13b352005-05-19 20:53:52 +0000755 vim_snprintf(buff, BUFSIZ, _("E273: unknown longjmp status %d"), state);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000756 EMSG(buff);
757 break;
758 }
759}
760
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +0000761static VALUE vim_message(VALUE self UNUSED, VALUE str)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000762{
763 char *buff, *p;
764
765 str = rb_obj_as_string(str);
Bram Moolenaar165641d2010-02-17 16:23:09 +0100766 buff = ALLOCA_N(char, RSTRING_LEN(str));
767 strcpy(buff, RSTRING_PTR(str));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000768 p = strchr(buff, '\n');
769 if (p) *p = '\0';
770 MSG(buff);
771 return Qnil;
772}
773
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +0000774static VALUE vim_set_option(VALUE self UNUSED, VALUE str)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000775{
Bram Moolenaar165641d2010-02-17 16:23:09 +0100776 do_set((char_u *)StringValuePtr(str), 0);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000777 update_screen(NOT_VALID);
778 return Qnil;
779}
780
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +0000781static VALUE vim_command(VALUE self UNUSED, VALUE str)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000782{
Bram Moolenaar165641d2010-02-17 16:23:09 +0100783 do_cmdline_cmd((char_u *)StringValuePtr(str));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000784 return Qnil;
785}
786
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100787#ifdef FEAT_EVAL
788static VALUE vim_to_ruby(typval_T *tv)
789{
790 VALUE result = Qnil;
791
792 if (tv->v_type == VAR_STRING)
793 {
Bram Moolenaar94127e42010-03-19 23:08:48 +0100794 result = rb_str_new2(tv->vval.v_string == NULL
795 ? "" : (char *)(tv->vval.v_string));
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100796 }
797 else if (tv->v_type == VAR_NUMBER)
798 {
Bram Moolenaar639a2552010-03-17 18:15:23 +0100799 result = INT2NUM(tv->vval.v_number);
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100800 }
801# ifdef FEAT_FLOAT
802 else if (tv->v_type == VAR_FLOAT)
803 {
Bram Moolenaar639a2552010-03-17 18:15:23 +0100804 result = rb_float_new(tv->vval.v_float);
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100805 }
806# endif
807 else if (tv->v_type == VAR_LIST)
808 {
Bram Moolenaar639a2552010-03-17 18:15:23 +0100809 list_T *list = tv->vval.v_list;
810 listitem_T *curr;
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100811
Bram Moolenaar639a2552010-03-17 18:15:23 +0100812 result = rb_ary_new();
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100813
Bram Moolenaar639a2552010-03-17 18:15:23 +0100814 if (list != NULL)
815 {
816 for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
817 {
818 rb_ary_push(result, vim_to_ruby(&curr->li_tv));
819 }
820 }
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100821 }
822 else if (tv->v_type == VAR_DICT)
823 {
Bram Moolenaar639a2552010-03-17 18:15:23 +0100824 result = rb_hash_new();
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100825
Bram Moolenaar639a2552010-03-17 18:15:23 +0100826 if (tv->vval.v_dict != NULL)
827 {
828 hashtab_T *ht = &tv->vval.v_dict->dv_hashtab;
829 long_u todo = ht->ht_used;
830 hashitem_T *hi;
831 dictitem_T *di;
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100832
Bram Moolenaar639a2552010-03-17 18:15:23 +0100833 for (hi = ht->ht_array; todo > 0; ++hi)
834 {
835 if (!HASHITEM_EMPTY(hi))
836 {
837 --todo;
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100838
Bram Moolenaar639a2552010-03-17 18:15:23 +0100839 di = dict_lookup(hi);
840 rb_hash_aset(result, rb_str_new2((char *)hi->hi_key),
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100841 vim_to_ruby(&di->di_tv));
Bram Moolenaar639a2552010-03-17 18:15:23 +0100842 }
843 }
844 }
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100845 } /* else return Qnil; */
846
847 return result;
848}
849#endif
850
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +0000851static VALUE vim_evaluate(VALUE self UNUSED, VALUE str)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000852{
853#ifdef FEAT_EVAL
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100854 typval_T *tv;
855 VALUE result;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000856
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100857 tv = eval_expr((char_u *)StringValuePtr(str), NULL);
858 if (tv == NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000859 {
Bram Moolenaar639a2552010-03-17 18:15:23 +0100860 return Qnil;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000861 }
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100862 result = vim_to_ruby(tv);
863
864 free_tv(tv);
865
866 return result;
867#else
868 return Qnil;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000869#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000870}
871
872static VALUE buffer_new(buf_T *buf)
873{
Bram Moolenaare344bea2005-09-01 20:46:49 +0000874 if (buf->b_ruby_ref)
875 {
876 return (VALUE) buf->b_ruby_ref;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000877 }
Bram Moolenaare344bea2005-09-01 20:46:49 +0000878 else
879 {
Bram Moolenaar071d4272004-06-13 20:20:40 +0000880 VALUE obj = Data_Wrap_Struct(cBuffer, 0, 0, buf);
Bram Moolenaare344bea2005-09-01 20:46:49 +0000881 buf->b_ruby_ref = (void *) obj;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000882 rb_hash_aset(objtbl, rb_obj_id(obj), obj);
883 return obj;
884 }
885}
886
887static buf_T *get_buf(VALUE obj)
888{
889 buf_T *buf;
890
891 Data_Get_Struct(obj, buf_T, buf);
892 if (buf == NULL)
893 rb_raise(eDeletedBufferError, "attempt to refer to deleted buffer");
894 return buf;
895}
896
897static VALUE buffer_s_current()
898{
899 return buffer_new(curbuf);
900}
901
902static VALUE buffer_s_count()
903{
904 buf_T *b;
905 int n = 0;
906
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000907 for (b = firstbuf; b != NULL; b = b->b_next)
908 {
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000909 /* Deleted buffers should not be counted
910 * SegPhault - 01/07/05 */
911 if (b->b_p_bl)
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000912 n++;
913 }
914
Bram Moolenaar071d4272004-06-13 20:20:40 +0000915 return INT2NUM(n);
916}
917
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +0000918static VALUE buffer_s_aref(VALUE self UNUSED, VALUE num)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000919{
920 buf_T *b;
921 int n = NUM2INT(num);
922
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000923 for (b = firstbuf; b != NULL; b = b->b_next)
924 {
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000925 /* Deleted buffers should not be counted
926 * SegPhault - 01/07/05 */
927 if (!b->b_p_bl)
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000928 continue;
929
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000930 if (n == 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000931 return buffer_new(b);
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000932
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000933 n--;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000934 }
935 return Qnil;
936}
937
938static VALUE buffer_name(VALUE self)
939{
940 buf_T *buf = get_buf(self);
941
Bram Moolenaar35a2e192006-03-13 22:07:11 +0000942 return buf->b_ffname ? rb_str_new2((char *)buf->b_ffname) : Qnil;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000943}
944
945static VALUE buffer_number(VALUE self)
946{
947 buf_T *buf = get_buf(self);
948
949 return INT2NUM(buf->b_fnum);
950}
951
952static VALUE buffer_count(VALUE self)
953{
954 buf_T *buf = get_buf(self);
955
956 return INT2NUM(buf->b_ml.ml_line_count);
957}
958
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000959static VALUE get_buffer_line(buf_T *buf, linenr_T n)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000960{
Bram Moolenaar3c531602010-11-16 14:46:19 +0100961 if (n <= 0 || n > buf->b_ml.ml_line_count)
962 rb_raise(rb_eIndexError, "line number %ld out of range", (long)n);
963 return vim_str2rb_enc_str((char *)ml_get_buf(buf, n, FALSE));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000964}
965
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000966static VALUE buffer_aref(VALUE self, VALUE num)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000967{
968 buf_T *buf = get_buf(self);
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000969
970 if (buf != NULL)
971 return get_buffer_line(buf, (linenr_T)NUM2LONG(num));
972 return Qnil; /* For stop warning */
973}
974
975static VALUE set_buffer_line(buf_T *buf, linenr_T n, VALUE str)
976{
Bram Moolenaar165641d2010-02-17 16:23:09 +0100977 char *line = StringValuePtr(str);
Bram Moolenaar20ff7922006-06-20 19:10:43 +0000978 aco_save_T aco;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000979
Bram Moolenaar20ff7922006-06-20 19:10:43 +0000980 if (n > 0 && n <= buf->b_ml.ml_line_count && line != NULL)
981 {
Bram Moolenaar20ff7922006-06-20 19:10:43 +0000982 /* set curwin/curbuf for "buf" and save some things */
983 aucmd_prepbuf(&aco, buf);
Bram Moolenaar20ff7922006-06-20 19:10:43 +0000984
Bram Moolenaar071d4272004-06-13 20:20:40 +0000985 if (u_savesub(n) == OK) {
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000986 ml_replace(n, (char_u *)line, TRUE);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000987 changed();
988#ifdef SYNTAX_HL
989 syn_changed(n); /* recompute syntax hl. for this line */
990#endif
991 }
Bram Moolenaar20ff7922006-06-20 19:10:43 +0000992
Bram Moolenaar20ff7922006-06-20 19:10:43 +0000993 /* restore curwin/curbuf and a few other things */
994 aucmd_restbuf(&aco);
995 /* Careful: autocommands may have made "buf" invalid! */
Bram Moolenaarf30e74c2006-08-16 17:35:00 +0000996
Bram Moolenaar071d4272004-06-13 20:20:40 +0000997 update_curbuf(NOT_VALID);
998 }
Bram Moolenaar20ff7922006-06-20 19:10:43 +0000999 else
1000 {
Bram Moolenaar165641d2010-02-17 16:23:09 +01001001 rb_raise(rb_eIndexError, "line number %ld out of range", (long)n);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001002 }
1003 return str;
1004}
1005
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001006static VALUE buffer_aset(VALUE self, VALUE num, VALUE str)
1007{
1008 buf_T *buf = get_buf(self);
1009
1010 if (buf != NULL)
1011 return set_buffer_line(buf, (linenr_T)NUM2LONG(num), str);
1012 return str;
1013}
1014
Bram Moolenaar071d4272004-06-13 20:20:40 +00001015static VALUE buffer_delete(VALUE self, VALUE num)
1016{
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001017 buf_T *buf = get_buf(self);
1018 long n = NUM2LONG(num);
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001019 aco_save_T aco;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001020
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001021 if (n > 0 && n <= buf->b_ml.ml_line_count)
1022 {
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001023 /* set curwin/curbuf for "buf" and save some things */
1024 aucmd_prepbuf(&aco, buf);
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001025
Bram Moolenaar071d4272004-06-13 20:20:40 +00001026 if (u_savedel(n, 1) == OK) {
Bram Moolenaar071d4272004-06-13 20:20:40 +00001027 ml_delete(n, 0);
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001028
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001029 /* Changes to non-active buffers should properly refresh
1030 * SegPhault - 01/09/05 */
1031 deleted_lines_mark(n, 1L);
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001032
Bram Moolenaar071d4272004-06-13 20:20:40 +00001033 changed();
1034 }
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001035
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001036 /* restore curwin/curbuf and a few other things */
1037 aucmd_restbuf(&aco);
1038 /* Careful: autocommands may have made "buf" invalid! */
Bram Moolenaarf30e74c2006-08-16 17:35:00 +00001039
Bram Moolenaar071d4272004-06-13 20:20:40 +00001040 update_curbuf(NOT_VALID);
1041 }
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001042 else
1043 {
Bram Moolenaar165641d2010-02-17 16:23:09 +01001044 rb_raise(rb_eIndexError, "line number %ld out of range", n);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001045 }
1046 return Qnil;
1047}
1048
1049static VALUE buffer_append(VALUE self, VALUE num, VALUE str)
1050{
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001051 buf_T *buf = get_buf(self);
Bram Moolenaar165641d2010-02-17 16:23:09 +01001052 char *line = StringValuePtr(str);
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001053 long n = NUM2LONG(num);
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001054 aco_save_T aco;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001055
Bram Moolenaar3c531602010-11-16 14:46:19 +01001056 if (line == NULL)
1057 {
Bram Moolenaar165641d2010-02-17 16:23:09 +01001058 rb_raise(rb_eIndexError, "NULL line");
1059 }
1060 else if (n >= 0 && n <= buf->b_ml.ml_line_count)
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001061 {
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001062 /* set curwin/curbuf for "buf" and save some things */
1063 aucmd_prepbuf(&aco, buf);
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001064
Bram Moolenaar071d4272004-06-13 20:20:40 +00001065 if (u_inssub(n + 1) == OK) {
Bram Moolenaar071d4272004-06-13 20:20:40 +00001066 ml_append(n, (char_u *) line, (colnr_T) 0, FALSE);
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001067
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001068 /* Changes to non-active buffers should properly refresh screen
1069 * SegPhault - 12/20/04 */
1070 appended_lines_mark(n, 1L);
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001071
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001072 changed();
Bram Moolenaar071d4272004-06-13 20:20:40 +00001073 }
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001074
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001075 /* restore curwin/curbuf and a few other things */
1076 aucmd_restbuf(&aco);
1077 /* Careful: autocommands may have made "buf" invalid! */
Bram Moolenaarf30e74c2006-08-16 17:35:00 +00001078
Bram Moolenaar071d4272004-06-13 20:20:40 +00001079 update_curbuf(NOT_VALID);
1080 }
Bram Moolenaar3c531602010-11-16 14:46:19 +01001081 else
1082 {
Bram Moolenaar165641d2010-02-17 16:23:09 +01001083 rb_raise(rb_eIndexError, "line number %ld out of range", n);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001084 }
1085 return str;
1086}
1087
1088static VALUE window_new(win_T *win)
1089{
Bram Moolenaare344bea2005-09-01 20:46:49 +00001090 if (win->w_ruby_ref)
1091 {
1092 return (VALUE) win->w_ruby_ref;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001093 }
Bram Moolenaare344bea2005-09-01 20:46:49 +00001094 else
1095 {
Bram Moolenaar071d4272004-06-13 20:20:40 +00001096 VALUE obj = Data_Wrap_Struct(cVimWindow, 0, 0, win);
Bram Moolenaare344bea2005-09-01 20:46:49 +00001097 win->w_ruby_ref = (void *) obj;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001098 rb_hash_aset(objtbl, rb_obj_id(obj), obj);
1099 return obj;
1100 }
1101}
1102
1103static win_T *get_win(VALUE obj)
1104{
1105 win_T *win;
1106
1107 Data_Get_Struct(obj, win_T, win);
1108 if (win == NULL)
1109 rb_raise(eDeletedWindowError, "attempt to refer to deleted window");
1110 return win;
1111}
1112
1113static VALUE window_s_current()
1114{
1115 return window_new(curwin);
1116}
1117
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001118/*
1119 * Added line manipulation functions
1120 * SegPhault - 03/07/05
1121 */
1122static VALUE line_s_current()
1123{
1124 return get_buffer_line(curbuf, curwin->w_cursor.lnum);
1125}
1126
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +00001127static VALUE set_current_line(VALUE self UNUSED, VALUE str)
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001128{
1129 return set_buffer_line(curbuf, curwin->w_cursor.lnum, str);
1130}
1131
1132static VALUE current_line_number()
1133{
1134 return INT2FIX((int)curwin->w_cursor.lnum);
1135}
1136
1137
1138
Bram Moolenaar071d4272004-06-13 20:20:40 +00001139static VALUE window_s_count()
1140{
1141#ifdef FEAT_WINDOWS
1142 win_T *w;
1143 int n = 0;
1144
Bram Moolenaarf740b292006-02-16 22:11:02 +00001145 for (w = firstwin; w != NULL; w = w->w_next)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001146 n++;
1147 return INT2NUM(n);
1148#else
1149 return INT2NUM(1);
1150#endif
1151}
1152
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +00001153static VALUE window_s_aref(VALUE self UNUSED, VALUE num)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001154{
1155 win_T *w;
1156 int n = NUM2INT(num);
1157
1158#ifndef FEAT_WINDOWS
1159 w = curwin;
1160#else
1161 for (w = firstwin; w != NULL; w = w->w_next, --n)
1162#endif
1163 if (n == 0)
1164 return window_new(w);
1165 return Qnil;
1166}
1167
1168static VALUE window_buffer(VALUE self)
1169{
1170 win_T *win = get_win(self);
1171
1172 return buffer_new(win->w_buffer);
1173}
1174
1175static VALUE window_height(VALUE self)
1176{
1177 win_T *win = get_win(self);
1178
1179 return INT2NUM(win->w_height);
1180}
1181
1182static VALUE window_set_height(VALUE self, VALUE height)
1183{
1184 win_T *win = get_win(self);
1185 win_T *savewin = curwin;
1186
1187 curwin = win;
1188 win_setheight(NUM2INT(height));
1189 curwin = savewin;
1190 return height;
1191}
1192
Bram Moolenaarda2303d2005-08-30 21:55:26 +00001193static VALUE window_width(VALUE self)
1194{
1195 win_T *win = get_win(self);
1196
1197 return INT2NUM(win->w_width);
1198}
1199
1200static VALUE window_set_width(VALUE self, VALUE width)
1201{
1202 win_T *win = get_win(self);
1203 win_T *savewin = curwin;
1204
1205 curwin = win;
1206 win_setwidth(NUM2INT(width));
1207 curwin = savewin;
1208 return width;
1209}
1210
Bram Moolenaar071d4272004-06-13 20:20:40 +00001211static VALUE window_cursor(VALUE self)
1212{
1213 win_T *win = get_win(self);
1214
1215 return rb_assoc_new(INT2NUM(win->w_cursor.lnum), INT2NUM(win->w_cursor.col));
1216}
1217
1218static VALUE window_set_cursor(VALUE self, VALUE pos)
1219{
1220 VALUE lnum, col;
1221 win_T *win = get_win(self);
1222
1223 Check_Type(pos, T_ARRAY);
Bram Moolenaar165641d2010-02-17 16:23:09 +01001224 if (RARRAY_LEN(pos) != 2)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001225 rb_raise(rb_eArgError, "array length must be 2");
Bram Moolenaar165641d2010-02-17 16:23:09 +01001226 lnum = RARRAY_PTR(pos)[0];
1227 col = RARRAY_PTR(pos)[1];
Bram Moolenaar071d4272004-06-13 20:20:40 +00001228 win->w_cursor.lnum = NUM2LONG(lnum);
1229 win->w_cursor.col = NUM2UINT(col);
1230 check_cursor(); /* put cursor on an existing line */
1231 update_screen(NOT_VALID);
1232 return Qnil;
1233}
1234
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +00001235static VALUE f_p(int argc, VALUE *argv, VALUE self UNUSED)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001236{
1237 int i;
1238 VALUE str = rb_str_new("", 0);
1239
1240 for (i = 0; i < argc; i++) {
1241 if (i > 0) rb_str_cat(str, ", ", 2);
1242 rb_str_concat(str, rb_inspect(argv[i]));
1243 }
Bram Moolenaar165641d2010-02-17 16:23:09 +01001244 MSG(RSTRING_PTR(str));
Bram Moolenaar071d4272004-06-13 20:20:40 +00001245 return Qnil;
1246}
1247
1248static void ruby_io_init(void)
1249{
1250#ifndef DYNAMIC_RUBY
1251 RUBYEXTERN VALUE rb_stdout;
1252#endif
1253
1254 rb_stdout = rb_obj_alloc(rb_cObject);
1255 rb_define_singleton_method(rb_stdout, "write", vim_message, 1);
1256 rb_define_global_function("p", f_p, -1);
1257}
1258
1259static void ruby_vim_init(void)
1260{
1261 objtbl = rb_hash_new();
1262 rb_global_variable(&objtbl);
1263
Bram Moolenaarf711faf2007-05-10 16:48:19 +00001264 /* The Vim module used to be called "VIM", but "Vim" is better. Make an
1265 * alias "VIM" for backwards compatiblity. */
1266 mVIM = rb_define_module("Vim");
1267 rb_define_const(rb_cObject, "VIM", mVIM);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001268 rb_define_const(mVIM, "VERSION_MAJOR", INT2NUM(VIM_VERSION_MAJOR));
1269 rb_define_const(mVIM, "VERSION_MINOR", INT2NUM(VIM_VERSION_MINOR));
1270 rb_define_const(mVIM, "VERSION_BUILD", INT2NUM(VIM_VERSION_BUILD));
1271 rb_define_const(mVIM, "VERSION_PATCHLEVEL", INT2NUM(VIM_VERSION_PATCHLEVEL));
1272 rb_define_const(mVIM, "VERSION_SHORT", rb_str_new2(VIM_VERSION_SHORT));
1273 rb_define_const(mVIM, "VERSION_MEDIUM", rb_str_new2(VIM_VERSION_MEDIUM));
1274 rb_define_const(mVIM, "VERSION_LONG", rb_str_new2(VIM_VERSION_LONG));
1275 rb_define_const(mVIM, "VERSION_LONG_DATE", rb_str_new2(VIM_VERSION_LONG_DATE));
1276 rb_define_module_function(mVIM, "message", vim_message, 1);
1277 rb_define_module_function(mVIM, "set_option", vim_set_option, 1);
1278 rb_define_module_function(mVIM, "command", vim_command, 1);
1279 rb_define_module_function(mVIM, "evaluate", vim_evaluate, 1);
1280
1281 eDeletedBufferError = rb_define_class_under(mVIM, "DeletedBufferError",
1282 rb_eStandardError);
1283 eDeletedWindowError = rb_define_class_under(mVIM, "DeletedWindowError",
1284 rb_eStandardError);
1285
1286 cBuffer = rb_define_class_under(mVIM, "Buffer", rb_cObject);
1287 rb_define_singleton_method(cBuffer, "current", buffer_s_current, 0);
1288 rb_define_singleton_method(cBuffer, "count", buffer_s_count, 0);
1289 rb_define_singleton_method(cBuffer, "[]", buffer_s_aref, 1);
1290 rb_define_method(cBuffer, "name", buffer_name, 0);
1291 rb_define_method(cBuffer, "number", buffer_number, 0);
1292 rb_define_method(cBuffer, "count", buffer_count, 0);
1293 rb_define_method(cBuffer, "length", buffer_count, 0);
1294 rb_define_method(cBuffer, "[]", buffer_aref, 1);
1295 rb_define_method(cBuffer, "[]=", buffer_aset, 2);
1296 rb_define_method(cBuffer, "delete", buffer_delete, 1);
1297 rb_define_method(cBuffer, "append", buffer_append, 2);
1298
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001299 /* Added line manipulation functions
1300 * SegPhault - 03/07/05 */
1301 rb_define_method(cBuffer, "line_number", current_line_number, 0);
1302 rb_define_method(cBuffer, "line", line_s_current, 0);
1303 rb_define_method(cBuffer, "line=", set_current_line, 1);
1304
1305
Bram Moolenaar071d4272004-06-13 20:20:40 +00001306 cVimWindow = rb_define_class_under(mVIM, "Window", rb_cObject);
1307 rb_define_singleton_method(cVimWindow, "current", window_s_current, 0);
1308 rb_define_singleton_method(cVimWindow, "count", window_s_count, 0);
1309 rb_define_singleton_method(cVimWindow, "[]", window_s_aref, 1);
1310 rb_define_method(cVimWindow, "buffer", window_buffer, 0);
1311 rb_define_method(cVimWindow, "height", window_height, 0);
1312 rb_define_method(cVimWindow, "height=", window_set_height, 1);
Bram Moolenaarda2303d2005-08-30 21:55:26 +00001313 rb_define_method(cVimWindow, "width", window_width, 0);
1314 rb_define_method(cVimWindow, "width=", window_set_width, 1);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001315 rb_define_method(cVimWindow, "cursor", window_cursor, 0);
1316 rb_define_method(cVimWindow, "cursor=", window_set_cursor, 1);
1317
1318 rb_define_virtual_variable("$curbuf", buffer_s_current, 0);
1319 rb_define_virtual_variable("$curwin", window_s_current, 0);
1320}