blob: 5dc32858be4798cc5b95c4448e2d2f0107af2d4e [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 Moolenaar3f5f7952011-08-04 19:34:59 +0200764 if (RSTRING_LEN(str) > 0)
765 {
766 /* Only do this when the string isn't empty, alloc(0) causes trouble. */
767 buff = ALLOCA_N(char, RSTRING_LEN(str));
768 strcpy(buff, RSTRING_PTR(str));
769 p = strchr(buff, '\n');
770 if (p) *p = '\0';
771 MSG(buff);
772 }
773 else
774 {
775 MSG("");
776 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000777 return Qnil;
778}
779
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +0000780static VALUE vim_set_option(VALUE self UNUSED, VALUE str)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000781{
Bram Moolenaar165641d2010-02-17 16:23:09 +0100782 do_set((char_u *)StringValuePtr(str), 0);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000783 update_screen(NOT_VALID);
784 return Qnil;
785}
786
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +0000787static VALUE vim_command(VALUE self UNUSED, VALUE str)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000788{
Bram Moolenaar165641d2010-02-17 16:23:09 +0100789 do_cmdline_cmd((char_u *)StringValuePtr(str));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000790 return Qnil;
791}
792
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100793#ifdef FEAT_EVAL
794static VALUE vim_to_ruby(typval_T *tv)
795{
796 VALUE result = Qnil;
797
798 if (tv->v_type == VAR_STRING)
799 {
Bram Moolenaar94127e42010-03-19 23:08:48 +0100800 result = rb_str_new2(tv->vval.v_string == NULL
801 ? "" : (char *)(tv->vval.v_string));
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100802 }
803 else if (tv->v_type == VAR_NUMBER)
804 {
Bram Moolenaar639a2552010-03-17 18:15:23 +0100805 result = INT2NUM(tv->vval.v_number);
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100806 }
807# ifdef FEAT_FLOAT
808 else if (tv->v_type == VAR_FLOAT)
809 {
Bram Moolenaar639a2552010-03-17 18:15:23 +0100810 result = rb_float_new(tv->vval.v_float);
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100811 }
812# endif
813 else if (tv->v_type == VAR_LIST)
814 {
Bram Moolenaar639a2552010-03-17 18:15:23 +0100815 list_T *list = tv->vval.v_list;
816 listitem_T *curr;
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100817
Bram Moolenaar639a2552010-03-17 18:15:23 +0100818 result = rb_ary_new();
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100819
Bram Moolenaar639a2552010-03-17 18:15:23 +0100820 if (list != NULL)
821 {
822 for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
823 {
824 rb_ary_push(result, vim_to_ruby(&curr->li_tv));
825 }
826 }
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100827 }
828 else if (tv->v_type == VAR_DICT)
829 {
Bram Moolenaar639a2552010-03-17 18:15:23 +0100830 result = rb_hash_new();
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100831
Bram Moolenaar639a2552010-03-17 18:15:23 +0100832 if (tv->vval.v_dict != NULL)
833 {
834 hashtab_T *ht = &tv->vval.v_dict->dv_hashtab;
835 long_u todo = ht->ht_used;
836 hashitem_T *hi;
837 dictitem_T *di;
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100838
Bram Moolenaar639a2552010-03-17 18:15:23 +0100839 for (hi = ht->ht_array; todo > 0; ++hi)
840 {
841 if (!HASHITEM_EMPTY(hi))
842 {
843 --todo;
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100844
Bram Moolenaar639a2552010-03-17 18:15:23 +0100845 di = dict_lookup(hi);
846 rb_hash_aset(result, rb_str_new2((char *)hi->hi_key),
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100847 vim_to_ruby(&di->di_tv));
Bram Moolenaar639a2552010-03-17 18:15:23 +0100848 }
849 }
850 }
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100851 } /* else return Qnil; */
852
853 return result;
854}
855#endif
856
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +0000857static VALUE vim_evaluate(VALUE self UNUSED, VALUE str)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000858{
859#ifdef FEAT_EVAL
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100860 typval_T *tv;
861 VALUE result;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000862
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100863 tv = eval_expr((char_u *)StringValuePtr(str), NULL);
864 if (tv == NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000865 {
Bram Moolenaar639a2552010-03-17 18:15:23 +0100866 return Qnil;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000867 }
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100868 result = vim_to_ruby(tv);
869
870 free_tv(tv);
871
872 return result;
873#else
874 return Qnil;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000875#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000876}
877
878static VALUE buffer_new(buf_T *buf)
879{
Bram Moolenaare344bea2005-09-01 20:46:49 +0000880 if (buf->b_ruby_ref)
881 {
882 return (VALUE) buf->b_ruby_ref;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000883 }
Bram Moolenaare344bea2005-09-01 20:46:49 +0000884 else
885 {
Bram Moolenaar071d4272004-06-13 20:20:40 +0000886 VALUE obj = Data_Wrap_Struct(cBuffer, 0, 0, buf);
Bram Moolenaare344bea2005-09-01 20:46:49 +0000887 buf->b_ruby_ref = (void *) obj;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000888 rb_hash_aset(objtbl, rb_obj_id(obj), obj);
889 return obj;
890 }
891}
892
893static buf_T *get_buf(VALUE obj)
894{
895 buf_T *buf;
896
897 Data_Get_Struct(obj, buf_T, buf);
898 if (buf == NULL)
899 rb_raise(eDeletedBufferError, "attempt to refer to deleted buffer");
900 return buf;
901}
902
903static VALUE buffer_s_current()
904{
905 return buffer_new(curbuf);
906}
907
908static VALUE buffer_s_count()
909{
910 buf_T *b;
911 int n = 0;
912
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000913 for (b = firstbuf; b != NULL; b = b->b_next)
914 {
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000915 /* Deleted buffers should not be counted
916 * SegPhault - 01/07/05 */
917 if (b->b_p_bl)
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000918 n++;
919 }
920
Bram Moolenaar071d4272004-06-13 20:20:40 +0000921 return INT2NUM(n);
922}
923
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +0000924static VALUE buffer_s_aref(VALUE self UNUSED, VALUE num)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000925{
926 buf_T *b;
927 int n = NUM2INT(num);
928
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000929 for (b = firstbuf; b != NULL; b = b->b_next)
930 {
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000931 /* Deleted buffers should not be counted
932 * SegPhault - 01/07/05 */
933 if (!b->b_p_bl)
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000934 continue;
935
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000936 if (n == 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000937 return buffer_new(b);
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000938
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000939 n--;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000940 }
941 return Qnil;
942}
943
944static VALUE buffer_name(VALUE self)
945{
946 buf_T *buf = get_buf(self);
947
Bram Moolenaar35a2e192006-03-13 22:07:11 +0000948 return buf->b_ffname ? rb_str_new2((char *)buf->b_ffname) : Qnil;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000949}
950
951static VALUE buffer_number(VALUE self)
952{
953 buf_T *buf = get_buf(self);
954
955 return INT2NUM(buf->b_fnum);
956}
957
958static VALUE buffer_count(VALUE self)
959{
960 buf_T *buf = get_buf(self);
961
962 return INT2NUM(buf->b_ml.ml_line_count);
963}
964
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000965static VALUE get_buffer_line(buf_T *buf, linenr_T n)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000966{
Bram Moolenaar3c531602010-11-16 14:46:19 +0100967 if (n <= 0 || n > buf->b_ml.ml_line_count)
968 rb_raise(rb_eIndexError, "line number %ld out of range", (long)n);
969 return vim_str2rb_enc_str((char *)ml_get_buf(buf, n, FALSE));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000970}
971
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000972static VALUE buffer_aref(VALUE self, VALUE num)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000973{
974 buf_T *buf = get_buf(self);
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000975
976 if (buf != NULL)
977 return get_buffer_line(buf, (linenr_T)NUM2LONG(num));
978 return Qnil; /* For stop warning */
979}
980
981static VALUE set_buffer_line(buf_T *buf, linenr_T n, VALUE str)
982{
Bram Moolenaar165641d2010-02-17 16:23:09 +0100983 char *line = StringValuePtr(str);
Bram Moolenaar20ff7922006-06-20 19:10:43 +0000984 aco_save_T aco;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000985
Bram Moolenaar20ff7922006-06-20 19:10:43 +0000986 if (n > 0 && n <= buf->b_ml.ml_line_count && line != NULL)
987 {
Bram Moolenaar20ff7922006-06-20 19:10:43 +0000988 /* set curwin/curbuf for "buf" and save some things */
989 aucmd_prepbuf(&aco, buf);
Bram Moolenaar20ff7922006-06-20 19:10:43 +0000990
Bram Moolenaar071d4272004-06-13 20:20:40 +0000991 if (u_savesub(n) == OK) {
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000992 ml_replace(n, (char_u *)line, TRUE);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000993 changed();
994#ifdef SYNTAX_HL
995 syn_changed(n); /* recompute syntax hl. for this line */
996#endif
997 }
Bram Moolenaar20ff7922006-06-20 19:10:43 +0000998
Bram Moolenaar20ff7922006-06-20 19:10:43 +0000999 /* restore curwin/curbuf and a few other things */
1000 aucmd_restbuf(&aco);
1001 /* Careful: autocommands may have made "buf" invalid! */
Bram Moolenaarf30e74c2006-08-16 17:35:00 +00001002
Bram Moolenaar071d4272004-06-13 20:20:40 +00001003 update_curbuf(NOT_VALID);
1004 }
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001005 else
1006 {
Bram Moolenaar165641d2010-02-17 16:23:09 +01001007 rb_raise(rb_eIndexError, "line number %ld out of range", (long)n);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001008 }
1009 return str;
1010}
1011
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001012static VALUE buffer_aset(VALUE self, VALUE num, VALUE str)
1013{
1014 buf_T *buf = get_buf(self);
1015
1016 if (buf != NULL)
1017 return set_buffer_line(buf, (linenr_T)NUM2LONG(num), str);
1018 return str;
1019}
1020
Bram Moolenaar071d4272004-06-13 20:20:40 +00001021static VALUE buffer_delete(VALUE self, VALUE num)
1022{
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001023 buf_T *buf = get_buf(self);
1024 long n = NUM2LONG(num);
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001025 aco_save_T aco;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001026
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001027 if (n > 0 && n <= buf->b_ml.ml_line_count)
1028 {
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001029 /* set curwin/curbuf for "buf" and save some things */
1030 aucmd_prepbuf(&aco, buf);
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001031
Bram Moolenaar071d4272004-06-13 20:20:40 +00001032 if (u_savedel(n, 1) == OK) {
Bram Moolenaar071d4272004-06-13 20:20:40 +00001033 ml_delete(n, 0);
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001034
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001035 /* Changes to non-active buffers should properly refresh
1036 * SegPhault - 01/09/05 */
1037 deleted_lines_mark(n, 1L);
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001038
Bram Moolenaar071d4272004-06-13 20:20:40 +00001039 changed();
1040 }
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001041
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001042 /* restore curwin/curbuf and a few other things */
1043 aucmd_restbuf(&aco);
1044 /* Careful: autocommands may have made "buf" invalid! */
Bram Moolenaarf30e74c2006-08-16 17:35:00 +00001045
Bram Moolenaar071d4272004-06-13 20:20:40 +00001046 update_curbuf(NOT_VALID);
1047 }
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001048 else
1049 {
Bram Moolenaar165641d2010-02-17 16:23:09 +01001050 rb_raise(rb_eIndexError, "line number %ld out of range", n);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001051 }
1052 return Qnil;
1053}
1054
1055static VALUE buffer_append(VALUE self, VALUE num, VALUE str)
1056{
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001057 buf_T *buf = get_buf(self);
Bram Moolenaar165641d2010-02-17 16:23:09 +01001058 char *line = StringValuePtr(str);
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001059 long n = NUM2LONG(num);
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001060 aco_save_T aco;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001061
Bram Moolenaar3c531602010-11-16 14:46:19 +01001062 if (line == NULL)
1063 {
Bram Moolenaar165641d2010-02-17 16:23:09 +01001064 rb_raise(rb_eIndexError, "NULL line");
1065 }
1066 else if (n >= 0 && n <= buf->b_ml.ml_line_count)
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001067 {
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001068 /* set curwin/curbuf for "buf" and save some things */
1069 aucmd_prepbuf(&aco, buf);
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001070
Bram Moolenaar071d4272004-06-13 20:20:40 +00001071 if (u_inssub(n + 1) == OK) {
Bram Moolenaar071d4272004-06-13 20:20:40 +00001072 ml_append(n, (char_u *) line, (colnr_T) 0, FALSE);
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001073
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001074 /* Changes to non-active buffers should properly refresh screen
1075 * SegPhault - 12/20/04 */
1076 appended_lines_mark(n, 1L);
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001077
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001078 changed();
Bram Moolenaar071d4272004-06-13 20:20:40 +00001079 }
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001080
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001081 /* restore curwin/curbuf and a few other things */
1082 aucmd_restbuf(&aco);
1083 /* Careful: autocommands may have made "buf" invalid! */
Bram Moolenaarf30e74c2006-08-16 17:35:00 +00001084
Bram Moolenaar071d4272004-06-13 20:20:40 +00001085 update_curbuf(NOT_VALID);
1086 }
Bram Moolenaar3c531602010-11-16 14:46:19 +01001087 else
1088 {
Bram Moolenaar165641d2010-02-17 16:23:09 +01001089 rb_raise(rb_eIndexError, "line number %ld out of range", n);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001090 }
1091 return str;
1092}
1093
1094static VALUE window_new(win_T *win)
1095{
Bram Moolenaare344bea2005-09-01 20:46:49 +00001096 if (win->w_ruby_ref)
1097 {
1098 return (VALUE) win->w_ruby_ref;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001099 }
Bram Moolenaare344bea2005-09-01 20:46:49 +00001100 else
1101 {
Bram Moolenaar071d4272004-06-13 20:20:40 +00001102 VALUE obj = Data_Wrap_Struct(cVimWindow, 0, 0, win);
Bram Moolenaare344bea2005-09-01 20:46:49 +00001103 win->w_ruby_ref = (void *) obj;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001104 rb_hash_aset(objtbl, rb_obj_id(obj), obj);
1105 return obj;
1106 }
1107}
1108
1109static win_T *get_win(VALUE obj)
1110{
1111 win_T *win;
1112
1113 Data_Get_Struct(obj, win_T, win);
1114 if (win == NULL)
1115 rb_raise(eDeletedWindowError, "attempt to refer to deleted window");
1116 return win;
1117}
1118
1119static VALUE window_s_current()
1120{
1121 return window_new(curwin);
1122}
1123
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001124/*
1125 * Added line manipulation functions
1126 * SegPhault - 03/07/05
1127 */
1128static VALUE line_s_current()
1129{
1130 return get_buffer_line(curbuf, curwin->w_cursor.lnum);
1131}
1132
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +00001133static VALUE set_current_line(VALUE self UNUSED, VALUE str)
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001134{
1135 return set_buffer_line(curbuf, curwin->w_cursor.lnum, str);
1136}
1137
1138static VALUE current_line_number()
1139{
1140 return INT2FIX((int)curwin->w_cursor.lnum);
1141}
1142
1143
1144
Bram Moolenaar071d4272004-06-13 20:20:40 +00001145static VALUE window_s_count()
1146{
1147#ifdef FEAT_WINDOWS
1148 win_T *w;
1149 int n = 0;
1150
Bram Moolenaarf740b292006-02-16 22:11:02 +00001151 for (w = firstwin; w != NULL; w = w->w_next)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001152 n++;
1153 return INT2NUM(n);
1154#else
1155 return INT2NUM(1);
1156#endif
1157}
1158
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +00001159static VALUE window_s_aref(VALUE self UNUSED, VALUE num)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001160{
1161 win_T *w;
1162 int n = NUM2INT(num);
1163
1164#ifndef FEAT_WINDOWS
1165 w = curwin;
1166#else
1167 for (w = firstwin; w != NULL; w = w->w_next, --n)
1168#endif
1169 if (n == 0)
1170 return window_new(w);
1171 return Qnil;
1172}
1173
1174static VALUE window_buffer(VALUE self)
1175{
1176 win_T *win = get_win(self);
1177
1178 return buffer_new(win->w_buffer);
1179}
1180
1181static VALUE window_height(VALUE self)
1182{
1183 win_T *win = get_win(self);
1184
1185 return INT2NUM(win->w_height);
1186}
1187
1188static VALUE window_set_height(VALUE self, VALUE height)
1189{
1190 win_T *win = get_win(self);
1191 win_T *savewin = curwin;
1192
1193 curwin = win;
1194 win_setheight(NUM2INT(height));
1195 curwin = savewin;
1196 return height;
1197}
1198
Bram Moolenaarda2303d2005-08-30 21:55:26 +00001199static VALUE window_width(VALUE self)
1200{
1201 win_T *win = get_win(self);
1202
1203 return INT2NUM(win->w_width);
1204}
1205
1206static VALUE window_set_width(VALUE self, VALUE width)
1207{
1208 win_T *win = get_win(self);
1209 win_T *savewin = curwin;
1210
1211 curwin = win;
1212 win_setwidth(NUM2INT(width));
1213 curwin = savewin;
1214 return width;
1215}
1216
Bram Moolenaar071d4272004-06-13 20:20:40 +00001217static VALUE window_cursor(VALUE self)
1218{
1219 win_T *win = get_win(self);
1220
1221 return rb_assoc_new(INT2NUM(win->w_cursor.lnum), INT2NUM(win->w_cursor.col));
1222}
1223
1224static VALUE window_set_cursor(VALUE self, VALUE pos)
1225{
1226 VALUE lnum, col;
1227 win_T *win = get_win(self);
1228
1229 Check_Type(pos, T_ARRAY);
Bram Moolenaar165641d2010-02-17 16:23:09 +01001230 if (RARRAY_LEN(pos) != 2)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001231 rb_raise(rb_eArgError, "array length must be 2");
Bram Moolenaar165641d2010-02-17 16:23:09 +01001232 lnum = RARRAY_PTR(pos)[0];
1233 col = RARRAY_PTR(pos)[1];
Bram Moolenaar071d4272004-06-13 20:20:40 +00001234 win->w_cursor.lnum = NUM2LONG(lnum);
1235 win->w_cursor.col = NUM2UINT(col);
1236 check_cursor(); /* put cursor on an existing line */
1237 update_screen(NOT_VALID);
1238 return Qnil;
1239}
1240
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +00001241static VALUE f_p(int argc, VALUE *argv, VALUE self UNUSED)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001242{
1243 int i;
1244 VALUE str = rb_str_new("", 0);
1245
1246 for (i = 0; i < argc; i++) {
1247 if (i > 0) rb_str_cat(str, ", ", 2);
1248 rb_str_concat(str, rb_inspect(argv[i]));
1249 }
Bram Moolenaar165641d2010-02-17 16:23:09 +01001250 MSG(RSTRING_PTR(str));
Bram Moolenaar071d4272004-06-13 20:20:40 +00001251 return Qnil;
1252}
1253
1254static void ruby_io_init(void)
1255{
1256#ifndef DYNAMIC_RUBY
1257 RUBYEXTERN VALUE rb_stdout;
1258#endif
1259
1260 rb_stdout = rb_obj_alloc(rb_cObject);
1261 rb_define_singleton_method(rb_stdout, "write", vim_message, 1);
1262 rb_define_global_function("p", f_p, -1);
1263}
1264
1265static void ruby_vim_init(void)
1266{
1267 objtbl = rb_hash_new();
1268 rb_global_variable(&objtbl);
1269
Bram Moolenaarf711faf2007-05-10 16:48:19 +00001270 /* The Vim module used to be called "VIM", but "Vim" is better. Make an
1271 * alias "VIM" for backwards compatiblity. */
1272 mVIM = rb_define_module("Vim");
1273 rb_define_const(rb_cObject, "VIM", mVIM);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001274 rb_define_const(mVIM, "VERSION_MAJOR", INT2NUM(VIM_VERSION_MAJOR));
1275 rb_define_const(mVIM, "VERSION_MINOR", INT2NUM(VIM_VERSION_MINOR));
1276 rb_define_const(mVIM, "VERSION_BUILD", INT2NUM(VIM_VERSION_BUILD));
1277 rb_define_const(mVIM, "VERSION_PATCHLEVEL", INT2NUM(VIM_VERSION_PATCHLEVEL));
1278 rb_define_const(mVIM, "VERSION_SHORT", rb_str_new2(VIM_VERSION_SHORT));
1279 rb_define_const(mVIM, "VERSION_MEDIUM", rb_str_new2(VIM_VERSION_MEDIUM));
1280 rb_define_const(mVIM, "VERSION_LONG", rb_str_new2(VIM_VERSION_LONG));
1281 rb_define_const(mVIM, "VERSION_LONG_DATE", rb_str_new2(VIM_VERSION_LONG_DATE));
1282 rb_define_module_function(mVIM, "message", vim_message, 1);
1283 rb_define_module_function(mVIM, "set_option", vim_set_option, 1);
1284 rb_define_module_function(mVIM, "command", vim_command, 1);
1285 rb_define_module_function(mVIM, "evaluate", vim_evaluate, 1);
1286
1287 eDeletedBufferError = rb_define_class_under(mVIM, "DeletedBufferError",
1288 rb_eStandardError);
1289 eDeletedWindowError = rb_define_class_under(mVIM, "DeletedWindowError",
1290 rb_eStandardError);
1291
1292 cBuffer = rb_define_class_under(mVIM, "Buffer", rb_cObject);
1293 rb_define_singleton_method(cBuffer, "current", buffer_s_current, 0);
1294 rb_define_singleton_method(cBuffer, "count", buffer_s_count, 0);
1295 rb_define_singleton_method(cBuffer, "[]", buffer_s_aref, 1);
1296 rb_define_method(cBuffer, "name", buffer_name, 0);
1297 rb_define_method(cBuffer, "number", buffer_number, 0);
1298 rb_define_method(cBuffer, "count", buffer_count, 0);
1299 rb_define_method(cBuffer, "length", buffer_count, 0);
1300 rb_define_method(cBuffer, "[]", buffer_aref, 1);
1301 rb_define_method(cBuffer, "[]=", buffer_aset, 2);
1302 rb_define_method(cBuffer, "delete", buffer_delete, 1);
1303 rb_define_method(cBuffer, "append", buffer_append, 2);
1304
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001305 /* Added line manipulation functions
1306 * SegPhault - 03/07/05 */
1307 rb_define_method(cBuffer, "line_number", current_line_number, 0);
1308 rb_define_method(cBuffer, "line", line_s_current, 0);
1309 rb_define_method(cBuffer, "line=", set_current_line, 1);
1310
1311
Bram Moolenaar071d4272004-06-13 20:20:40 +00001312 cVimWindow = rb_define_class_under(mVIM, "Window", rb_cObject);
1313 rb_define_singleton_method(cVimWindow, "current", window_s_current, 0);
1314 rb_define_singleton_method(cVimWindow, "count", window_s_count, 0);
1315 rb_define_singleton_method(cVimWindow, "[]", window_s_aref, 1);
1316 rb_define_method(cVimWindow, "buffer", window_buffer, 0);
1317 rb_define_method(cVimWindow, "height", window_height, 0);
1318 rb_define_method(cVimWindow, "height=", window_set_height, 1);
Bram Moolenaarda2303d2005-08-30 21:55:26 +00001319 rb_define_method(cVimWindow, "width", window_width, 0);
1320 rb_define_method(cVimWindow, "width=", window_set_width, 1);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001321 rb_define_method(cVimWindow, "cursor", window_cursor, 0);
1322 rb_define_method(cVimWindow, "cursor=", window_set_cursor, 1);
1323
1324 rb_define_virtual_variable("$curbuf", buffer_s_current, 0);
1325 rb_define_virtual_variable("$curwin", window_s_current, 0);
1326}