blob: d79d0eeb7ba78e648b394b7f96c9883e4f5223de [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)
Bram Moolenaardb3fbe52013-03-07 15:16:21 +010042# if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 20
43# define rb_cFloat (*dll_rb_cFloat)
44# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +000045# define rb_cNilClass (*dll_rb_cNilClass)
46# define rb_cSymbol (*dll_rb_cSymbol)
47# define rb_cTrueClass (*dll_rb_cTrueClass)
48# if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
49/*
Bram Moolenaar42d57f02010-03-10 12:47:00 +010050 * On ver 1.8, all Ruby functions are exported with "__declspec(dllimport)"
51 * in ruby.h. But it causes trouble for these variables, because it is
Bram Moolenaar071d4272004-06-13 20:20:40 +000052 * defined in this file. When defined this RUBY_EXPORT it modified to
53 * "extern" and be able to avoid this problem.
54 */
55# define RUBY_EXPORT
56# endif
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +020057
Bram Moolenaar2d73ff42010-10-27 17:40:59 +020058#if !(defined(WIN32) || defined(_WIN64))
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +020059# include <dlfcn.h>
Bram Moolenaar3ca71f12010-10-27 16:49:47 +020060# define HINSTANCE void*
61# define RUBY_PROC void*
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +020062# define load_dll(n) dlopen((n), RTLD_LAZY|RTLD_GLOBAL)
63# define symbol_from_dll dlsym
64# define close_dll dlclose
65#else
Bram Moolenaar3ca71f12010-10-27 16:49:47 +020066# define RUBY_PROC FARPROC
Bram Moolenaarebbcb822010-10-23 14:02:54 +020067# define load_dll vimLoadLib
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +020068# define symbol_from_dll GetProcAddress
69# define close_dll FreeLibrary
Bram Moolenaar071d4272004-06-13 20:20:40 +000070#endif
71
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +020072#endif /* ifdef DYNAMIC_RUBY */
73
Bram Moolenaar0b69c732010-02-17 15:11:50 +010074/* suggested by Ariya Mizutani */
75#if (_MSC_VER == 1200)
76# undef _WIN32_WINNT
77#endif
78
Bram Moolenaar639a2552010-03-17 18:15:23 +010079#if (defined(RUBY_VERSION) && RUBY_VERSION >= 19) \
80 || (defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 19)
81# define RUBY19_OR_LATER 1
82#endif
83
Bram Moolenaar42d57f02010-03-10 12:47:00 +010084#if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 19
85/* Ruby 1.9 defines a number of static functions which use rb_num2long and
86 * rb_int2big */
87# define rb_num2long rb_num2long_stub
88# define rb_int2big rb_int2big_stub
89#endif
90
Bram Moolenaar0bcdd6e2013-04-14 16:19:03 +020091#if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 20 \
92 && SIZEOF_INT < SIZEOF_LONG
93/* Ruby 2.0 defines a number of static functions which use rb_fix2int and
94 * rb_num2int if SIZEOF_INT < SIZEOF_LONG (64bit) */
95# define rb_fix2int rb_fix2int_stub
96# define rb_num2int rb_num2int_stub
97#endif
98
Bram Moolenaar071d4272004-06-13 20:20:40 +000099#include <ruby.h>
Bram Moolenaar639a2552010-03-17 18:15:23 +0100100#ifdef RUBY19_OR_LATER
Bram Moolenaar165641d2010-02-17 16:23:09 +0100101# include <ruby/encoding.h>
102#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000103
Bram Moolenaar7a8ef142010-12-24 13:39:35 +0100104#undef off_t /* ruby defines off_t as _int64, Mingw uses long */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000105#undef EXTERN
106#undef _
107
108/* T_DATA defined both by Ruby and Mac header files, hack around it... */
Bram Moolenaarcb635362007-05-12 13:02:42 +0000109#if defined(MACOS_X_UNIX) || defined(macintosh)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000110# define __OPENTRANSPORT__
111# define __OPENTRANSPORTPROTOCOL__
112# define __OPENTRANSPORTPROVIDERS__
113#endif
114
Bram Moolenaar165641d2010-02-17 16:23:09 +0100115/*
Bram Moolenaar84a05ac2013-05-06 04:24:17 +0200116 * Backward compatibility for Ruby 1.8 and earlier.
Bram Moolenaar165641d2010-02-17 16:23:09 +0100117 * Ruby 1.9 does not provide STR2CSTR, instead StringValuePtr is provided.
118 * Ruby 1.9 does not provide RXXX(s)->len and RXXX(s)->ptr, instead
119 * RXXX_LEN(s) and RXXX_PTR(s) are provided.
120 */
121#ifndef StringValuePtr
122# define StringValuePtr(s) STR2CSTR(s)
123#endif
124#ifndef RARRAY_LEN
125# define RARRAY_LEN(s) RARRAY(s)->len
126#endif
127#ifndef RARRAY_PTR
128# define RARRAY_PTR(s) RARRAY(s)->ptr
129#endif
130#ifndef RSTRING_LEN
131# define RSTRING_LEN(s) RSTRING(s)->len
132#endif
133#ifndef RSTRING_PTR
134# define RSTRING_PTR(s) RSTRING(s)->ptr
135#endif
136
Bram Moolenaar071d4272004-06-13 20:20:40 +0000137#include "vim.h"
138#include "version.h"
139
140#if defined(PROTO) && !defined(FEAT_RUBY)
141/* Define these to be able to generate the function prototypes. */
142# define VALUE int
143# define RUBY_DATA_FUNC int
144#endif
145
146static int ruby_initialized = 0;
147static VALUE objtbl;
148
149static VALUE mVIM;
150static VALUE cBuffer;
151static VALUE cVimWindow;
152static VALUE eDeletedBufferError;
153static VALUE eDeletedWindowError;
154
155static int ensure_ruby_initialized(void);
156static void error_print(int);
157static void ruby_io_init(void);
158static void ruby_vim_init(void);
159
160#if defined(DYNAMIC_RUBY) || defined(PROTO)
161#ifdef PROTO
162# define HINSTANCE int /* for generating prototypes */
163#endif
164
165/*
166 * Wrapper defines
167 */
168#define rb_assoc_new dll_rb_assoc_new
169#define rb_cObject (*dll_rb_cObject)
170#define rb_check_type dll_rb_check_type
171#define rb_class_path dll_rb_class_path
172#define rb_data_object_alloc dll_rb_data_object_alloc
173#define rb_define_class_under dll_rb_define_class_under
174#define rb_define_const dll_rb_define_const
175#define rb_define_global_function dll_rb_define_global_function
176#define rb_define_method dll_rb_define_method
177#define rb_define_module dll_rb_define_module
178#define rb_define_module_function dll_rb_define_module_function
179#define rb_define_singleton_method dll_rb_define_singleton_method
180#define rb_define_virtual_variable dll_rb_define_virtual_variable
181#define rb_stdout (*dll_rb_stdout)
182#define rb_eArgError (*dll_rb_eArgError)
183#define rb_eIndexError (*dll_rb_eIndexError)
184#define rb_eRuntimeError (*dll_rb_eRuntimeError)
185#define rb_eStandardError (*dll_rb_eStandardError)
186#define rb_eval_string_protect dll_rb_eval_string_protect
187#define rb_global_variable dll_rb_global_variable
188#define rb_hash_aset dll_rb_hash_aset
189#define rb_hash_new dll_rb_hash_new
190#define rb_inspect dll_rb_inspect
191#define rb_int2inum dll_rb_int2inum
Bram Moolenaarb213da02012-10-03 18:06:59 +0200192#if SIZEOF_INT < SIZEOF_LONG /* 64 bits only */
Bram Moolenaar2623b4f2012-09-18 16:36:32 +0200193#define rb_fix2int dll_rb_fix2int
194#define rb_num2int dll_rb_num2int
195#define rb_num2uint dll_rb_num2uint
Bram Moolenaarb213da02012-10-03 18:06:59 +0200196#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000197#define rb_lastline_get dll_rb_lastline_get
198#define rb_lastline_set dll_rb_lastline_set
199#define rb_load_protect dll_rb_load_protect
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200200#ifndef RUBY19_OR_LATER
Bram Moolenaar071d4272004-06-13 20:20:40 +0000201#define rb_num2long dll_rb_num2long
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200202#endif
Bram Moolenaar886ed692013-02-26 13:41:35 +0100203#if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER <= 19
Bram Moolenaar071d4272004-06-13 20:20:40 +0000204#define rb_num2ulong dll_rb_num2ulong
Bram Moolenaar886ed692013-02-26 13:41:35 +0100205#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000206#define rb_obj_alloc dll_rb_obj_alloc
207#define rb_obj_as_string dll_rb_obj_as_string
208#define rb_obj_id dll_rb_obj_id
209#define rb_raise dll_rb_raise
Bram Moolenaar071d4272004-06-13 20:20:40 +0000210#define rb_str_cat dll_rb_str_cat
211#define rb_str_concat dll_rb_str_concat
212#define rb_str_new dll_rb_str_new
Bram Moolenaar1d2beae2010-05-22 21:56:55 +0200213#ifdef rb_str_new2
214/* Ruby may #define rb_str_new2 to use rb_str_new_cstr. */
215# define need_rb_str_new_cstr 1
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200216/* Ruby's headers #define rb_str_new_cstr to make use of GCC's
217 * __builtin_constant_p extension. */
218# undef rb_str_new_cstr
Bram Moolenaar1d2beae2010-05-22 21:56:55 +0200219# define rb_str_new_cstr dll_rb_str_new_cstr
220#else
Bram Moolenaar218116c2010-05-20 21:46:00 +0200221# define rb_str_new2 dll_rb_str_new2
222#endif
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100223#if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +0200224# define rb_string_value dll_rb_string_value
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100225# define rb_string_value_ptr dll_rb_string_value_ptr
226# define rb_float_new dll_rb_float_new
227# define rb_ary_new dll_rb_ary_new
228# define rb_ary_push dll_rb_ary_push
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +0200229#else
230# define rb_str2cstr dll_rb_str2cstr
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100231#endif
Bram Moolenaar639a2552010-03-17 18:15:23 +0100232#ifdef RUBY19_OR_LATER
Bram Moolenaar165641d2010-02-17 16:23:09 +0100233# define rb_errinfo dll_rb_errinfo
234#else
235# define ruby_errinfo (*dll_ruby_errinfo)
236#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000237#define ruby_init dll_ruby_init
238#define ruby_init_loadpath dll_ruby_init_loadpath
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200239#ifdef WIN3264
240# define NtInitialize dll_NtInitialize
241# if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
242# define rb_w32_snprintf dll_rb_w32_snprintf
243# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000244#endif
245
Bram Moolenaar639a2552010-03-17 18:15:23 +0100246#ifdef RUBY19_OR_LATER
Bram Moolenaar165641d2010-02-17 16:23:09 +0100247# define ruby_script dll_ruby_script
248# define rb_enc_find_index dll_rb_enc_find_index
249# define rb_enc_find dll_rb_enc_find
250# define rb_enc_str_new dll_rb_enc_str_new
251# define rb_sprintf dll_rb_sprintf
Bram Moolenaar7a8ef142010-12-24 13:39:35 +0100252# define rb_require dll_rb_require
Bram Moolenaar639a2552010-03-17 18:15:23 +0100253# define ruby_init_stack dll_ruby_init_stack
Bram Moolenaar7a8ef142010-12-24 13:39:35 +0100254# define ruby_process_options dll_ruby_process_options
Bram Moolenaar165641d2010-02-17 16:23:09 +0100255#endif
256
Bram Moolenaar071d4272004-06-13 20:20:40 +0000257/*
258 * Pointers for dynamic link
259 */
260static VALUE (*dll_rb_assoc_new) (VALUE, VALUE);
Bram Moolenaarba52cde2010-06-25 04:29:11 +0200261VALUE *dll_rb_cFalseClass;
262VALUE *dll_rb_cFixnum;
Bram Moolenaardb3fbe52013-03-07 15:16:21 +0100263#if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 20
264VALUE *dll_rb_cFloat;
265#endif
Bram Moolenaarba52cde2010-06-25 04:29:11 +0200266VALUE *dll_rb_cNilClass;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000267static VALUE *dll_rb_cObject;
Bram Moolenaarba52cde2010-06-25 04:29:11 +0200268VALUE *dll_rb_cSymbol;
269VALUE *dll_rb_cTrueClass;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000270static void (*dll_rb_check_type) (VALUE,int);
271static VALUE (*dll_rb_class_path) (VALUE);
272static VALUE (*dll_rb_data_object_alloc) (VALUE, void*, RUBY_DATA_FUNC, RUBY_DATA_FUNC);
273static VALUE (*dll_rb_define_class_under) (VALUE, const char*, VALUE);
274static void (*dll_rb_define_const) (VALUE,const char*,VALUE);
275static void (*dll_rb_define_global_function) (const char*,VALUE(*)(),int);
276static void (*dll_rb_define_method) (VALUE,const char*,VALUE(*)(),int);
277static VALUE (*dll_rb_define_module) (const char*);
278static void (*dll_rb_define_module_function) (VALUE,const char*,VALUE(*)(),int);
279static void (*dll_rb_define_singleton_method) (VALUE,const char*,VALUE(*)(),int);
280static void (*dll_rb_define_virtual_variable) (const char*,VALUE(*)(),void(*)());
281static VALUE *dll_rb_stdout;
282static VALUE *dll_rb_eArgError;
283static VALUE *dll_rb_eIndexError;
284static VALUE *dll_rb_eRuntimeError;
285static VALUE *dll_rb_eStandardError;
286static VALUE (*dll_rb_eval_string_protect) (const char*, int*);
287static void (*dll_rb_global_variable) (VALUE*);
288static VALUE (*dll_rb_hash_aset) (VALUE, VALUE, VALUE);
289static VALUE (*dll_rb_hash_new) (void);
290static VALUE (*dll_rb_inspect) (VALUE);
291static VALUE (*dll_rb_int2inum) (long);
Bram Moolenaarb213da02012-10-03 18:06:59 +0200292#if SIZEOF_INT < SIZEOF_LONG /* 64 bits only */
Bram Moolenaar2623b4f2012-09-18 16:36:32 +0200293static long (*dll_rb_fix2int) (VALUE);
294static long (*dll_rb_num2int) (VALUE);
295static unsigned long (*dll_rb_num2uint) (VALUE);
Bram Moolenaarb213da02012-10-03 18:06:59 +0200296#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000297static VALUE (*dll_rb_lastline_get) (void);
298static void (*dll_rb_lastline_set) (VALUE);
299static void (*dll_rb_load_protect) (VALUE, int, int*);
300static long (*dll_rb_num2long) (VALUE);
301static unsigned long (*dll_rb_num2ulong) (VALUE);
302static VALUE (*dll_rb_obj_alloc) (VALUE);
303static VALUE (*dll_rb_obj_as_string) (VALUE);
304static VALUE (*dll_rb_obj_id) (VALUE);
305static void (*dll_rb_raise) (VALUE, const char*, ...);
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +0200306#if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
307static VALUE (*dll_rb_string_value) (volatile VALUE*);
308#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000309static char *(*dll_rb_str2cstr) (VALUE,int*);
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +0200310#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000311static VALUE (*dll_rb_str_cat) (VALUE, const char*, long);
312static VALUE (*dll_rb_str_concat) (VALUE, VALUE);
313static VALUE (*dll_rb_str_new) (const char*, long);
Bram Moolenaar1d2beae2010-05-22 21:56:55 +0200314#ifdef need_rb_str_new_cstr
315/* Ruby may #define rb_str_new2 to use rb_str_new_cstr. */
316static VALUE (*dll_rb_str_new_cstr) (const char*);
317#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000318static VALUE (*dll_rb_str_new2) (const char*);
Bram Moolenaar1d2beae2010-05-22 21:56:55 +0200319#endif
Bram Moolenaar639a2552010-03-17 18:15:23 +0100320#ifdef RUBY19_OR_LATER
Bram Moolenaar165641d2010-02-17 16:23:09 +0100321static VALUE (*dll_rb_errinfo) (void);
322#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000323static VALUE *dll_ruby_errinfo;
Bram Moolenaar165641d2010-02-17 16:23:09 +0100324#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000325static void (*dll_ruby_init) (void);
326static void (*dll_ruby_init_loadpath) (void);
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200327#ifdef WIN3264
Bram Moolenaar0b69c732010-02-17 15:11:50 +0100328static void (*dll_NtInitialize) (int*, char***);
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200329# if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
330static int (*dll_rb_w32_snprintf)(char*, size_t, const char*, ...);
331# endif
332#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000333#if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100334static char * (*dll_rb_string_value_ptr) (volatile VALUE*);
335static VALUE (*dll_rb_float_new) (double);
336static VALUE (*dll_rb_ary_new) (void);
337static VALUE (*dll_rb_ary_push) (VALUE, VALUE);
338#endif
Bram Moolenaar639a2552010-03-17 18:15:23 +0100339#ifdef RUBY19_OR_LATER
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100340static VALUE (*dll_rb_int2big)(SIGNED_VALUE);
341#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000342
Bram Moolenaar639a2552010-03-17 18:15:23 +0100343#ifdef RUBY19_OR_LATER
Bram Moolenaar165641d2010-02-17 16:23:09 +0100344static void (*dll_ruby_script) (const char*);
345static int (*dll_rb_enc_find_index) (const char*);
346static rb_encoding* (*dll_rb_enc_find) (const char*);
347static VALUE (*dll_rb_enc_str_new) (const char*, long, rb_encoding*);
348static VALUE (*dll_rb_sprintf) (const char*, ...);
Bram Moolenaar7a8ef142010-12-24 13:39:35 +0100349static VALUE (*dll_rb_require) (const char*);
Bram Moolenaar639a2552010-03-17 18:15:23 +0100350static void (*ruby_init_stack)(VALUE*);
Bram Moolenaar7a8ef142010-12-24 13:39:35 +0100351static void* (*ruby_process_options)(int, char**);
Bram Moolenaar165641d2010-02-17 16:23:09 +0100352#endif
353
Bram Moolenaarff8cf2b2012-11-24 13:39:00 +0100354#if defined(RUBY19_OR_LATER) && !defined(PROTO)
355SIGNED_VALUE rb_num2long_stub(VALUE x)
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100356{
357 return dll_rb_num2long(x);
358}
Bram Moolenaarff8cf2b2012-11-24 13:39:00 +0100359VALUE rb_int2big_stub(SIGNED_VALUE x)
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100360{
361 return dll_rb_int2big(x);
362}
Bram Moolenaar0bcdd6e2013-04-14 16:19:03 +0200363#if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 20 \
364 && SIZEOF_INT < SIZEOF_LONG
365long rb_fix2int_stub(VALUE x)
366{
367 return dll_rb_fix2int(x);
368}
369long rb_num2int_stub(VALUE x)
370{
371 return dll_rb_num2int(x);
372}
373#endif
Bram Moolenaar886ed692013-02-26 13:41:35 +0100374#if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 20
375VALUE
376rb_float_new_in_heap(double d)
377{
378 return dll_rb_float_new(d);
379}
Bram Moolenaardb3fbe52013-03-07 15:16:21 +0100380VALUE rb_num2ulong(VALUE x)
Bram Moolenaar886ed692013-02-26 13:41:35 +0100381{
382 return (long)RSHIFT((SIGNED_VALUE)(x),1);
383}
384#endif
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100385#endif
386
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200387static HINSTANCE hinstRuby = NULL; /* Instance of ruby.dll */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000388
389/*
Bram Moolenaarda2303d2005-08-30 21:55:26 +0000390 * Table of name to function pointer of ruby.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000391 */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000392static struct
393{
394 char *name;
395 RUBY_PROC *ptr;
396} ruby_funcname_table[] =
397{
398 {"rb_assoc_new", (RUBY_PROC*)&dll_rb_assoc_new},
399 {"rb_cFalseClass", (RUBY_PROC*)&dll_rb_cFalseClass},
400 {"rb_cFixnum", (RUBY_PROC*)&dll_rb_cFixnum},
Bram Moolenaardb3fbe52013-03-07 15:16:21 +0100401#if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 20
402 {"rb_cFloat", (RUBY_PROC*)&dll_rb_cFloat},
403#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000404 {"rb_cNilClass", (RUBY_PROC*)&dll_rb_cNilClass},
405 {"rb_cObject", (RUBY_PROC*)&dll_rb_cObject},
406 {"rb_cSymbol", (RUBY_PROC*)&dll_rb_cSymbol},
407 {"rb_cTrueClass", (RUBY_PROC*)&dll_rb_cTrueClass},
408 {"rb_check_type", (RUBY_PROC*)&dll_rb_check_type},
409 {"rb_class_path", (RUBY_PROC*)&dll_rb_class_path},
410 {"rb_data_object_alloc", (RUBY_PROC*)&dll_rb_data_object_alloc},
411 {"rb_define_class_under", (RUBY_PROC*)&dll_rb_define_class_under},
412 {"rb_define_const", (RUBY_PROC*)&dll_rb_define_const},
413 {"rb_define_global_function", (RUBY_PROC*)&dll_rb_define_global_function},
414 {"rb_define_method", (RUBY_PROC*)&dll_rb_define_method},
415 {"rb_define_module", (RUBY_PROC*)&dll_rb_define_module},
416 {"rb_define_module_function", (RUBY_PROC*)&dll_rb_define_module_function},
417 {"rb_define_singleton_method", (RUBY_PROC*)&dll_rb_define_singleton_method},
418 {"rb_define_virtual_variable", (RUBY_PROC*)&dll_rb_define_virtual_variable},
419 {"rb_stdout", (RUBY_PROC*)&dll_rb_stdout},
420 {"rb_eArgError", (RUBY_PROC*)&dll_rb_eArgError},
421 {"rb_eIndexError", (RUBY_PROC*)&dll_rb_eIndexError},
422 {"rb_eRuntimeError", (RUBY_PROC*)&dll_rb_eRuntimeError},
423 {"rb_eStandardError", (RUBY_PROC*)&dll_rb_eStandardError},
424 {"rb_eval_string_protect", (RUBY_PROC*)&dll_rb_eval_string_protect},
425 {"rb_global_variable", (RUBY_PROC*)&dll_rb_global_variable},
426 {"rb_hash_aset", (RUBY_PROC*)&dll_rb_hash_aset},
427 {"rb_hash_new", (RUBY_PROC*)&dll_rb_hash_new},
428 {"rb_inspect", (RUBY_PROC*)&dll_rb_inspect},
429 {"rb_int2inum", (RUBY_PROC*)&dll_rb_int2inum},
Bram Moolenaarb213da02012-10-03 18:06:59 +0200430#if SIZEOF_INT < SIZEOF_LONG /* 64 bits only */
Bram Moolenaar2623b4f2012-09-18 16:36:32 +0200431 {"rb_fix2int", (RUBY_PROC*)&dll_rb_fix2int},
432 {"rb_num2int", (RUBY_PROC*)&dll_rb_num2int},
433 {"rb_num2uint", (RUBY_PROC*)&dll_rb_num2uint},
Bram Moolenaarb213da02012-10-03 18:06:59 +0200434#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000435 {"rb_lastline_get", (RUBY_PROC*)&dll_rb_lastline_get},
436 {"rb_lastline_set", (RUBY_PROC*)&dll_rb_lastline_set},
437 {"rb_load_protect", (RUBY_PROC*)&dll_rb_load_protect},
438 {"rb_num2long", (RUBY_PROC*)&dll_rb_num2long},
439 {"rb_num2ulong", (RUBY_PROC*)&dll_rb_num2ulong},
440 {"rb_obj_alloc", (RUBY_PROC*)&dll_rb_obj_alloc},
441 {"rb_obj_as_string", (RUBY_PROC*)&dll_rb_obj_as_string},
442 {"rb_obj_id", (RUBY_PROC*)&dll_rb_obj_id},
443 {"rb_raise", (RUBY_PROC*)&dll_rb_raise},
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +0200444#if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
445 {"rb_string_value", (RUBY_PROC*)&dll_rb_string_value},
446#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000447 {"rb_str2cstr", (RUBY_PROC*)&dll_rb_str2cstr},
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +0200448#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000449 {"rb_str_cat", (RUBY_PROC*)&dll_rb_str_cat},
450 {"rb_str_concat", (RUBY_PROC*)&dll_rb_str_concat},
451 {"rb_str_new", (RUBY_PROC*)&dll_rb_str_new},
Bram Moolenaar1d2beae2010-05-22 21:56:55 +0200452#ifdef need_rb_str_new_cstr
453 {"rb_str_new_cstr", (RUBY_PROC*)&dll_rb_str_new_cstr},
454#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000455 {"rb_str_new2", (RUBY_PROC*)&dll_rb_str_new2},
Bram Moolenaar1d2beae2010-05-22 21:56:55 +0200456#endif
Bram Moolenaar639a2552010-03-17 18:15:23 +0100457#ifdef RUBY19_OR_LATER
Bram Moolenaar165641d2010-02-17 16:23:09 +0100458 {"rb_errinfo", (RUBY_PROC*)&dll_rb_errinfo},
459#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000460 {"ruby_errinfo", (RUBY_PROC*)&dll_ruby_errinfo},
Bram Moolenaar165641d2010-02-17 16:23:09 +0100461#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000462 {"ruby_init", (RUBY_PROC*)&dll_ruby_init},
463 {"ruby_init_loadpath", (RUBY_PROC*)&dll_ruby_init_loadpath},
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200464#ifdef WIN3264
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100465 {
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200466# if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER < 19
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100467 "NtInitialize",
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200468# else
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100469 "ruby_sysinit",
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200470# endif
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100471 (RUBY_PROC*)&dll_NtInitialize},
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200472# if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
Bram Moolenaar071d4272004-06-13 20:20:40 +0000473 {"rb_w32_snprintf", (RUBY_PROC*)&dll_rb_w32_snprintf},
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200474# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000475#endif
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100476#if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
477 {"rb_string_value_ptr", (RUBY_PROC*)&dll_rb_string_value_ptr},
Bram Moolenaar886ed692013-02-26 13:41:35 +0100478# if DYNAMIC_RUBY_VER <= 19
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100479 {"rb_float_new", (RUBY_PROC*)&dll_rb_float_new},
Bram Moolenaar886ed692013-02-26 13:41:35 +0100480# else
481 {"rb_float_new_in_heap", (RUBY_PROC*)&dll_rb_float_new},
482# endif
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100483 {"rb_ary_new", (RUBY_PROC*)&dll_rb_ary_new},
484 {"rb_ary_push", (RUBY_PROC*)&dll_rb_ary_push},
485#endif
Bram Moolenaar639a2552010-03-17 18:15:23 +0100486#ifdef RUBY19_OR_LATER
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100487 {"rb_int2big", (RUBY_PROC*)&dll_rb_int2big},
Bram Moolenaar165641d2010-02-17 16:23:09 +0100488 {"ruby_script", (RUBY_PROC*)&dll_ruby_script},
489 {"rb_enc_find_index", (RUBY_PROC*)&dll_rb_enc_find_index},
490 {"rb_enc_find", (RUBY_PROC*)&dll_rb_enc_find},
491 {"rb_enc_str_new", (RUBY_PROC*)&dll_rb_enc_str_new},
492 {"rb_sprintf", (RUBY_PROC*)&dll_rb_sprintf},
Bram Moolenaar7a8ef142010-12-24 13:39:35 +0100493 {"rb_require", (RUBY_PROC*)&dll_rb_require},
Bram Moolenaar639a2552010-03-17 18:15:23 +0100494 {"ruby_init_stack", (RUBY_PROC*)&dll_ruby_init_stack},
Bram Moolenaar7a8ef142010-12-24 13:39:35 +0100495 {"ruby_process_options", (RUBY_PROC*)&dll_ruby_process_options},
Bram Moolenaar165641d2010-02-17 16:23:09 +0100496#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000497 {"", NULL},
498};
499
500/*
501 * Free ruby.dll
502 */
503 static void
504end_dynamic_ruby()
505{
506 if (hinstRuby)
507 {
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +0200508 close_dll(hinstRuby);
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200509 hinstRuby = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000510 }
511}
512
513/*
514 * Load library and get all pointers.
515 * Parameter 'libname' provides name of DLL.
516 * Return OK or FAIL.
517 */
518 static int
519ruby_runtime_link_init(char *libname, int verbose)
520{
521 int i;
522
523 if (hinstRuby)
524 return OK;
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +0200525 hinstRuby = load_dll(libname);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000526 if (!hinstRuby)
527 {
528 if (verbose)
529 EMSG2(_(e_loadlib), libname);
530 return FAIL;
531 }
532
533 for (i = 0; ruby_funcname_table[i].ptr; ++i)
534 {
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +0200535 if (!(*ruby_funcname_table[i].ptr = symbol_from_dll(hinstRuby,
Bram Moolenaar071d4272004-06-13 20:20:40 +0000536 ruby_funcname_table[i].name)))
537 {
Bram Moolenaarf9b5ef82010-09-29 13:02:53 +0200538 close_dll(hinstRuby);
Bram Moolenaar3ca71f12010-10-27 16:49:47 +0200539 hinstRuby = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000540 if (verbose)
541 EMSG2(_(e_loadfunc), ruby_funcname_table[i].name);
542 return FAIL;
543 }
544 }
545 return OK;
546}
547
548/*
549 * If ruby is enabled (there is installed ruby on Windows system) return TRUE,
550 * else FALSE.
551 */
552 int
553ruby_enabled(verbose)
554 int verbose;
555{
556 return ruby_runtime_link_init(DYNAMIC_RUBY_DLL, verbose) == OK;
557}
558#endif /* defined(DYNAMIC_RUBY) || defined(PROTO) */
559
560 void
561ruby_end()
562{
563#ifdef DYNAMIC_RUBY
564 end_dynamic_ruby();
565#endif
566}
567
568void ex_ruby(exarg_T *eap)
569{
570 int state;
571 char *script = NULL;
572
Bram Moolenaar35a2e192006-03-13 22:07:11 +0000573 script = (char *)script_get(eap, eap->arg);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000574 if (!eap->skip && ensure_ruby_initialized())
575 {
576 if (script == NULL)
577 rb_eval_string_protect((char *)eap->arg, &state);
578 else
579 rb_eval_string_protect(script, &state);
580 if (state)
581 error_print(state);
582 }
583 vim_free(script);
584}
585
Bram Moolenaar165641d2010-02-17 16:23:09 +0100586/*
587 * In Ruby 1.9 or later, ruby String object has encoding.
588 * conversion buffer string of vim to ruby String object using
589 * VIM encoding option.
590 */
591 static VALUE
592vim_str2rb_enc_str(const char *s)
593{
Bram Moolenaar639a2552010-03-17 18:15:23 +0100594#ifdef RUBY19_OR_LATER
Bram Moolenaar165641d2010-02-17 16:23:09 +0100595 int isnum;
596 long lval;
597 char_u *sval;
598 rb_encoding *enc;
599
600 isnum = get_option_value((char_u *)"enc", &lval, &sval, 0);
601 if (isnum == 0)
602 {
603 enc = rb_enc_find((char *)sval);
604 vim_free(sval);
605 if (enc) {
606 return rb_enc_str_new(s, strlen(s), enc);
607 }
608 }
609#endif
610 return rb_str_new2(s);
611}
612
613 static VALUE
614eval_enc_string_protect(const char *str, int *state)
615{
Bram Moolenaar639a2552010-03-17 18:15:23 +0100616#ifdef RUBY19_OR_LATER
Bram Moolenaar165641d2010-02-17 16:23:09 +0100617 int isnum;
618 long lval;
619 char_u *sval;
620 rb_encoding *enc;
621 VALUE v;
622
623 isnum = get_option_value((char_u *)"enc", &lval, &sval, 0);
624 if (isnum == 0)
625 {
626 enc = rb_enc_find((char *)sval);
627 vim_free(sval);
628 if (enc)
629 {
630 v = rb_sprintf("#-*- coding:%s -*-\n%s", rb_enc_name(enc), str);
631 return rb_eval_string_protect(StringValuePtr(v), state);
632 }
633 }
634#endif
635 return rb_eval_string_protect(str, state);
636}
637
Bram Moolenaar071d4272004-06-13 20:20:40 +0000638void ex_rubydo(exarg_T *eap)
639{
640 int state;
641 linenr_T i;
642
643 if (ensure_ruby_initialized())
644 {
645 if (u_save(eap->line1 - 1, eap->line2 + 1) != OK)
646 return;
647 for (i = eap->line1; i <= eap->line2; i++) {
Bram Moolenaare980d8a2010-12-08 13:11:21 +0100648 VALUE line;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000649
Bram Moolenaare980d8a2010-12-08 13:11:21 +0100650 line = vim_str2rb_enc_str((char *)ml_get(i));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000651 rb_lastline_set(line);
Bram Moolenaar165641d2010-02-17 16:23:09 +0100652 eval_enc_string_protect((char *) eap->arg, &state);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000653 if (state) {
654 error_print(state);
655 break;
656 }
657 line = rb_lastline_get();
658 if (!NIL_P(line)) {
659 if (TYPE(line) != T_STRING) {
Bram Moolenaara93fa7e2006-04-17 22:14:47 +0000660 EMSG(_("E265: $_ must be an instance of String"));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000661 return;
662 }
Bram Moolenaar165641d2010-02-17 16:23:09 +0100663 ml_replace(i, (char_u *) StringValuePtr(line), 1);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000664 changed();
665#ifdef SYNTAX_HL
666 syn_changed(i); /* recompute syntax hl. for this line */
667#endif
668 }
669 }
670 check_cursor();
671 update_curbuf(NOT_VALID);
672 }
673}
674
675void ex_rubyfile(exarg_T *eap)
676{
677 int state;
678
679 if (ensure_ruby_initialized())
680 {
681 rb_load_protect(rb_str_new2((char *) eap->arg), 0, &state);
682 if (state) error_print(state);
683 }
684}
685
686void ruby_buffer_free(buf_T *buf)
687{
Bram Moolenaare344bea2005-09-01 20:46:49 +0000688 if (buf->b_ruby_ref)
689 {
690 rb_hash_aset(objtbl, rb_obj_id((VALUE) buf->b_ruby_ref), Qnil);
691 RDATA(buf->b_ruby_ref)->data = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000692 }
693}
694
695void ruby_window_free(win_T *win)
696{
Bram Moolenaare344bea2005-09-01 20:46:49 +0000697 if (win->w_ruby_ref)
698 {
699 rb_hash_aset(objtbl, rb_obj_id((VALUE) win->w_ruby_ref), Qnil);
700 RDATA(win->w_ruby_ref)->data = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000701 }
702}
703
704static int ensure_ruby_initialized(void)
705{
706 if (!ruby_initialized)
707 {
708#ifdef DYNAMIC_RUBY
709 if (ruby_enabled(TRUE))
710 {
711#endif
Bram Moolenaar0b69c732010-02-17 15:11:50 +0100712#ifdef _WIN32
713 /* suggested by Ariya Mizutani */
714 int argc = 1;
715 char *argv[] = {"gvim.exe"};
716 NtInitialize(&argc, &argv);
717#endif
Bram Moolenaarb2c03502010-07-02 20:20:09 +0200718 {
Bram Moolenaar639a2552010-03-17 18:15:23 +0100719#ifdef RUBY19_OR_LATER
Bram Moolenaarb2c03502010-07-02 20:20:09 +0200720 RUBY_INIT_STACK;
Bram Moolenaar165641d2010-02-17 16:23:09 +0100721#endif
Bram Moolenaarb2c03502010-07-02 20:20:09 +0200722 ruby_init();
723 }
Bram Moolenaar639a2552010-03-17 18:15:23 +0100724#ifdef RUBY19_OR_LATER
Bram Moolenaar7a8ef142010-12-24 13:39:35 +0100725 {
726 int dummy_argc = 2;
727 char *dummy_argv[] = {"vim-ruby", "-e0"};
728 ruby_process_options(dummy_argc, dummy_argv);
729 }
Bram Moolenaar165641d2010-02-17 16:23:09 +0100730 ruby_script("vim-ruby");
Bram Moolenaar7a8ef142010-12-24 13:39:35 +0100731#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000732 ruby_init_loadpath();
Bram Moolenaar165641d2010-02-17 16:23:09 +0100733#endif
Bram Moolenaar7a8ef142010-12-24 13:39:35 +0100734 ruby_io_init();
Bram Moolenaar071d4272004-06-13 20:20:40 +0000735 ruby_vim_init();
736 ruby_initialized = 1;
737#ifdef DYNAMIC_RUBY
738 }
739 else
740 {
741 EMSG(_("E266: Sorry, this command is disabled, the Ruby library could not be loaded."));
742 return 0;
743 }
744#endif
745 }
746 return ruby_initialized;
747}
748
749static void error_print(int state)
750{
751#ifndef DYNAMIC_RUBY
Bram Moolenaar42d57f02010-03-10 12:47:00 +0100752#if !(defined(RUBY_VERSION) && RUBY_VERSION >= 19) \
753 && !(defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 19)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000754 RUBYEXTERN VALUE ruby_errinfo;
755#endif
Bram Moolenaar165641d2010-02-17 16:23:09 +0100756#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000757 VALUE eclass;
758 VALUE einfo;
759 char buff[BUFSIZ];
760
761#define TAG_RETURN 0x1
762#define TAG_BREAK 0x2
763#define TAG_NEXT 0x3
764#define TAG_RETRY 0x4
765#define TAG_REDO 0x5
766#define TAG_RAISE 0x6
767#define TAG_THROW 0x7
768#define TAG_FATAL 0x8
769#define TAG_MASK 0xf
770
771 switch (state) {
772 case TAG_RETURN:
Bram Moolenaara93fa7e2006-04-17 22:14:47 +0000773 EMSG(_("E267: unexpected return"));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000774 break;
775 case TAG_NEXT:
Bram Moolenaara93fa7e2006-04-17 22:14:47 +0000776 EMSG(_("E268: unexpected next"));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000777 break;
778 case TAG_BREAK:
Bram Moolenaara93fa7e2006-04-17 22:14:47 +0000779 EMSG(_("E269: unexpected break"));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000780 break;
781 case TAG_REDO:
Bram Moolenaara93fa7e2006-04-17 22:14:47 +0000782 EMSG(_("E270: unexpected redo"));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000783 break;
784 case TAG_RETRY:
Bram Moolenaara93fa7e2006-04-17 22:14:47 +0000785 EMSG(_("E271: retry outside of rescue clause"));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000786 break;
787 case TAG_RAISE:
788 case TAG_FATAL:
Bram Moolenaar639a2552010-03-17 18:15:23 +0100789#ifdef RUBY19_OR_LATER
Bram Moolenaar165641d2010-02-17 16:23:09 +0100790 eclass = CLASS_OF(rb_errinfo());
791 einfo = rb_obj_as_string(rb_errinfo());
792#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000793 eclass = CLASS_OF(ruby_errinfo);
794 einfo = rb_obj_as_string(ruby_errinfo);
Bram Moolenaar165641d2010-02-17 16:23:09 +0100795#endif
796 if (eclass == rb_eRuntimeError && RSTRING_LEN(einfo) == 0) {
Bram Moolenaara93fa7e2006-04-17 22:14:47 +0000797 EMSG(_("E272: unhandled exception"));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000798 }
799 else {
800 VALUE epath;
801 char *p;
802
803 epath = rb_class_path(eclass);
Bram Moolenaar9c13b352005-05-19 20:53:52 +0000804 vim_snprintf(buff, BUFSIZ, "%s: %s",
Bram Moolenaar165641d2010-02-17 16:23:09 +0100805 RSTRING_PTR(epath), RSTRING_PTR(einfo));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000806 p = strchr(buff, '\n');
807 if (p) *p = '\0';
808 EMSG(buff);
809 }
810 break;
811 default:
Bram Moolenaar9c13b352005-05-19 20:53:52 +0000812 vim_snprintf(buff, BUFSIZ, _("E273: unknown longjmp status %d"), state);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000813 EMSG(buff);
814 break;
815 }
816}
817
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +0000818static VALUE vim_message(VALUE self UNUSED, VALUE str)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000819{
820 char *buff, *p;
821
822 str = rb_obj_as_string(str);
Bram Moolenaar3f5f7952011-08-04 19:34:59 +0200823 if (RSTRING_LEN(str) > 0)
824 {
825 /* Only do this when the string isn't empty, alloc(0) causes trouble. */
826 buff = ALLOCA_N(char, RSTRING_LEN(str));
827 strcpy(buff, RSTRING_PTR(str));
828 p = strchr(buff, '\n');
829 if (p) *p = '\0';
830 MSG(buff);
831 }
832 else
833 {
834 MSG("");
835 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000836 return Qnil;
837}
838
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +0000839static VALUE vim_set_option(VALUE self UNUSED, VALUE str)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000840{
Bram Moolenaar165641d2010-02-17 16:23:09 +0100841 do_set((char_u *)StringValuePtr(str), 0);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000842 update_screen(NOT_VALID);
843 return Qnil;
844}
845
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +0000846static VALUE vim_command(VALUE self UNUSED, VALUE str)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000847{
Bram Moolenaar165641d2010-02-17 16:23:09 +0100848 do_cmdline_cmd((char_u *)StringValuePtr(str));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000849 return Qnil;
850}
851
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100852#ifdef FEAT_EVAL
853static VALUE vim_to_ruby(typval_T *tv)
854{
855 VALUE result = Qnil;
856
857 if (tv->v_type == VAR_STRING)
858 {
Bram Moolenaar94127e42010-03-19 23:08:48 +0100859 result = rb_str_new2(tv->vval.v_string == NULL
860 ? "" : (char *)(tv->vval.v_string));
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100861 }
862 else if (tv->v_type == VAR_NUMBER)
863 {
Bram Moolenaar639a2552010-03-17 18:15:23 +0100864 result = INT2NUM(tv->vval.v_number);
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100865 }
866# ifdef FEAT_FLOAT
867 else if (tv->v_type == VAR_FLOAT)
868 {
Bram Moolenaar639a2552010-03-17 18:15:23 +0100869 result = rb_float_new(tv->vval.v_float);
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100870 }
871# endif
872 else if (tv->v_type == VAR_LIST)
873 {
Bram Moolenaar639a2552010-03-17 18:15:23 +0100874 list_T *list = tv->vval.v_list;
875 listitem_T *curr;
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100876
Bram Moolenaar639a2552010-03-17 18:15:23 +0100877 result = rb_ary_new();
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100878
Bram Moolenaar639a2552010-03-17 18:15:23 +0100879 if (list != NULL)
880 {
881 for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
882 {
883 rb_ary_push(result, vim_to_ruby(&curr->li_tv));
884 }
885 }
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100886 }
887 else if (tv->v_type == VAR_DICT)
888 {
Bram Moolenaar639a2552010-03-17 18:15:23 +0100889 result = rb_hash_new();
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100890
Bram Moolenaar639a2552010-03-17 18:15:23 +0100891 if (tv->vval.v_dict != NULL)
892 {
893 hashtab_T *ht = &tv->vval.v_dict->dv_hashtab;
894 long_u todo = ht->ht_used;
895 hashitem_T *hi;
896 dictitem_T *di;
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100897
Bram Moolenaar639a2552010-03-17 18:15:23 +0100898 for (hi = ht->ht_array; todo > 0; ++hi)
899 {
900 if (!HASHITEM_EMPTY(hi))
901 {
902 --todo;
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100903
Bram Moolenaar639a2552010-03-17 18:15:23 +0100904 di = dict_lookup(hi);
905 rb_hash_aset(result, rb_str_new2((char *)hi->hi_key),
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100906 vim_to_ruby(&di->di_tv));
Bram Moolenaar639a2552010-03-17 18:15:23 +0100907 }
908 }
909 }
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100910 } /* else return Qnil; */
911
912 return result;
913}
914#endif
915
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +0000916static VALUE vim_evaluate(VALUE self UNUSED, VALUE str)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000917{
918#ifdef FEAT_EVAL
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100919 typval_T *tv;
920 VALUE result;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000921
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100922 tv = eval_expr((char_u *)StringValuePtr(str), NULL);
923 if (tv == NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000924 {
Bram Moolenaar639a2552010-03-17 18:15:23 +0100925 return Qnil;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000926 }
Bram Moolenaar3fac56e2010-02-24 15:48:04 +0100927 result = vim_to_ruby(tv);
928
929 free_tv(tv);
930
931 return result;
932#else
933 return Qnil;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000934#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000935}
936
937static VALUE buffer_new(buf_T *buf)
938{
Bram Moolenaare344bea2005-09-01 20:46:49 +0000939 if (buf->b_ruby_ref)
940 {
941 return (VALUE) buf->b_ruby_ref;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000942 }
Bram Moolenaare344bea2005-09-01 20:46:49 +0000943 else
944 {
Bram Moolenaar071d4272004-06-13 20:20:40 +0000945 VALUE obj = Data_Wrap_Struct(cBuffer, 0, 0, buf);
Bram Moolenaare344bea2005-09-01 20:46:49 +0000946 buf->b_ruby_ref = (void *) obj;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000947 rb_hash_aset(objtbl, rb_obj_id(obj), obj);
948 return obj;
949 }
950}
951
952static buf_T *get_buf(VALUE obj)
953{
954 buf_T *buf;
955
956 Data_Get_Struct(obj, buf_T, buf);
957 if (buf == NULL)
958 rb_raise(eDeletedBufferError, "attempt to refer to deleted buffer");
959 return buf;
960}
961
962static VALUE buffer_s_current()
963{
964 return buffer_new(curbuf);
965}
966
967static VALUE buffer_s_count()
968{
969 buf_T *b;
970 int n = 0;
971
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000972 for (b = firstbuf; b != NULL; b = b->b_next)
973 {
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000974 /* Deleted buffers should not be counted
975 * SegPhault - 01/07/05 */
976 if (b->b_p_bl)
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000977 n++;
978 }
979
Bram Moolenaar071d4272004-06-13 20:20:40 +0000980 return INT2NUM(n);
981}
982
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +0000983static VALUE buffer_s_aref(VALUE self UNUSED, VALUE num)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000984{
985 buf_T *b;
986 int n = NUM2INT(num);
987
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000988 for (b = firstbuf; b != NULL; b = b->b_next)
989 {
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000990 /* Deleted buffers should not be counted
991 * SegPhault - 01/07/05 */
992 if (!b->b_p_bl)
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000993 continue;
994
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000995 if (n == 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000996 return buffer_new(b);
Bram Moolenaarbe4d5062006-03-18 21:30:13 +0000997
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000998 n--;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000999 }
1000 return Qnil;
1001}
1002
1003static VALUE buffer_name(VALUE self)
1004{
1005 buf_T *buf = get_buf(self);
1006
Bram Moolenaar35a2e192006-03-13 22:07:11 +00001007 return buf->b_ffname ? rb_str_new2((char *)buf->b_ffname) : Qnil;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001008}
1009
1010static VALUE buffer_number(VALUE self)
1011{
1012 buf_T *buf = get_buf(self);
1013
1014 return INT2NUM(buf->b_fnum);
1015}
1016
1017static VALUE buffer_count(VALUE self)
1018{
1019 buf_T *buf = get_buf(self);
1020
1021 return INT2NUM(buf->b_ml.ml_line_count);
1022}
1023
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001024static VALUE get_buffer_line(buf_T *buf, linenr_T n)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001025{
Bram Moolenaar3c531602010-11-16 14:46:19 +01001026 if (n <= 0 || n > buf->b_ml.ml_line_count)
1027 rb_raise(rb_eIndexError, "line number %ld out of range", (long)n);
1028 return vim_str2rb_enc_str((char *)ml_get_buf(buf, n, FALSE));
Bram Moolenaar071d4272004-06-13 20:20:40 +00001029}
1030
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001031static VALUE buffer_aref(VALUE self, VALUE num)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001032{
1033 buf_T *buf = get_buf(self);
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001034
1035 if (buf != NULL)
1036 return get_buffer_line(buf, (linenr_T)NUM2LONG(num));
1037 return Qnil; /* For stop warning */
1038}
1039
1040static VALUE set_buffer_line(buf_T *buf, linenr_T n, VALUE str)
1041{
Bram Moolenaar165641d2010-02-17 16:23:09 +01001042 char *line = StringValuePtr(str);
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001043 aco_save_T aco;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001044
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001045 if (n > 0 && n <= buf->b_ml.ml_line_count && line != NULL)
1046 {
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001047 /* set curwin/curbuf for "buf" and save some things */
1048 aucmd_prepbuf(&aco, buf);
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001049
Bram Moolenaar071d4272004-06-13 20:20:40 +00001050 if (u_savesub(n) == OK) {
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001051 ml_replace(n, (char_u *)line, TRUE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001052 changed();
1053#ifdef SYNTAX_HL
1054 syn_changed(n); /* recompute syntax hl. for this line */
1055#endif
1056 }
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001057
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001058 /* restore curwin/curbuf and a few other things */
1059 aucmd_restbuf(&aco);
1060 /* Careful: autocommands may have made "buf" invalid! */
Bram Moolenaarf30e74c2006-08-16 17:35:00 +00001061
Bram Moolenaar071d4272004-06-13 20:20:40 +00001062 update_curbuf(NOT_VALID);
1063 }
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001064 else
1065 {
Bram Moolenaar165641d2010-02-17 16:23:09 +01001066 rb_raise(rb_eIndexError, "line number %ld out of range", (long)n);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001067 }
1068 return str;
1069}
1070
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001071static VALUE buffer_aset(VALUE self, VALUE num, VALUE str)
1072{
1073 buf_T *buf = get_buf(self);
1074
1075 if (buf != NULL)
1076 return set_buffer_line(buf, (linenr_T)NUM2LONG(num), str);
1077 return str;
1078}
1079
Bram Moolenaar071d4272004-06-13 20:20:40 +00001080static VALUE buffer_delete(VALUE self, VALUE num)
1081{
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001082 buf_T *buf = get_buf(self);
1083 long n = NUM2LONG(num);
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001084 aco_save_T aco;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001085
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001086 if (n > 0 && n <= buf->b_ml.ml_line_count)
1087 {
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001088 /* set curwin/curbuf for "buf" and save some things */
1089 aucmd_prepbuf(&aco, buf);
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001090
Bram Moolenaar071d4272004-06-13 20:20:40 +00001091 if (u_savedel(n, 1) == OK) {
Bram Moolenaar071d4272004-06-13 20:20:40 +00001092 ml_delete(n, 0);
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001093
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001094 /* Changes to non-active buffers should properly refresh
1095 * SegPhault - 01/09/05 */
1096 deleted_lines_mark(n, 1L);
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001097
Bram Moolenaar071d4272004-06-13 20:20:40 +00001098 changed();
1099 }
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001100
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001101 /* restore curwin/curbuf and a few other things */
1102 aucmd_restbuf(&aco);
1103 /* Careful: autocommands may have made "buf" invalid! */
Bram Moolenaarf30e74c2006-08-16 17:35:00 +00001104
Bram Moolenaar071d4272004-06-13 20:20:40 +00001105 update_curbuf(NOT_VALID);
1106 }
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001107 else
1108 {
Bram Moolenaar165641d2010-02-17 16:23:09 +01001109 rb_raise(rb_eIndexError, "line number %ld out of range", n);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001110 }
1111 return Qnil;
1112}
1113
1114static VALUE buffer_append(VALUE self, VALUE num, VALUE str)
1115{
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001116 buf_T *buf = get_buf(self);
Bram Moolenaar165641d2010-02-17 16:23:09 +01001117 char *line = StringValuePtr(str);
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001118 long n = NUM2LONG(num);
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001119 aco_save_T aco;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001120
Bram Moolenaar3c531602010-11-16 14:46:19 +01001121 if (line == NULL)
1122 {
Bram Moolenaar165641d2010-02-17 16:23:09 +01001123 rb_raise(rb_eIndexError, "NULL line");
1124 }
1125 else if (n >= 0 && n <= buf->b_ml.ml_line_count)
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001126 {
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001127 /* set curwin/curbuf for "buf" and save some things */
1128 aucmd_prepbuf(&aco, buf);
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001129
Bram Moolenaar071d4272004-06-13 20:20:40 +00001130 if (u_inssub(n + 1) == OK) {
Bram Moolenaar071d4272004-06-13 20:20:40 +00001131 ml_append(n, (char_u *) line, (colnr_T) 0, FALSE);
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001132
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001133 /* Changes to non-active buffers should properly refresh screen
1134 * SegPhault - 12/20/04 */
1135 appended_lines_mark(n, 1L);
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001136
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001137 changed();
Bram Moolenaar071d4272004-06-13 20:20:40 +00001138 }
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001139
Bram Moolenaar20ff7922006-06-20 19:10:43 +00001140 /* restore curwin/curbuf and a few other things */
1141 aucmd_restbuf(&aco);
1142 /* Careful: autocommands may have made "buf" invalid! */
Bram Moolenaarf30e74c2006-08-16 17:35:00 +00001143
Bram Moolenaar071d4272004-06-13 20:20:40 +00001144 update_curbuf(NOT_VALID);
1145 }
Bram Moolenaar3c531602010-11-16 14:46:19 +01001146 else
1147 {
Bram Moolenaar165641d2010-02-17 16:23:09 +01001148 rb_raise(rb_eIndexError, "line number %ld out of range", n);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001149 }
1150 return str;
1151}
1152
1153static VALUE window_new(win_T *win)
1154{
Bram Moolenaare344bea2005-09-01 20:46:49 +00001155 if (win->w_ruby_ref)
1156 {
1157 return (VALUE) win->w_ruby_ref;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001158 }
Bram Moolenaare344bea2005-09-01 20:46:49 +00001159 else
1160 {
Bram Moolenaar071d4272004-06-13 20:20:40 +00001161 VALUE obj = Data_Wrap_Struct(cVimWindow, 0, 0, win);
Bram Moolenaare344bea2005-09-01 20:46:49 +00001162 win->w_ruby_ref = (void *) obj;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001163 rb_hash_aset(objtbl, rb_obj_id(obj), obj);
1164 return obj;
1165 }
1166}
1167
1168static win_T *get_win(VALUE obj)
1169{
1170 win_T *win;
1171
1172 Data_Get_Struct(obj, win_T, win);
1173 if (win == NULL)
1174 rb_raise(eDeletedWindowError, "attempt to refer to deleted window");
1175 return win;
1176}
1177
1178static VALUE window_s_current()
1179{
1180 return window_new(curwin);
1181}
1182
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001183/*
1184 * Added line manipulation functions
1185 * SegPhault - 03/07/05
1186 */
1187static VALUE line_s_current()
1188{
1189 return get_buffer_line(curbuf, curwin->w_cursor.lnum);
1190}
1191
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +00001192static VALUE set_current_line(VALUE self UNUSED, VALUE str)
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001193{
1194 return set_buffer_line(curbuf, curwin->w_cursor.lnum, str);
1195}
1196
1197static VALUE current_line_number()
1198{
1199 return INT2FIX((int)curwin->w_cursor.lnum);
1200}
1201
1202
1203
Bram Moolenaar071d4272004-06-13 20:20:40 +00001204static VALUE window_s_count()
1205{
1206#ifdef FEAT_WINDOWS
1207 win_T *w;
1208 int n = 0;
1209
Bram Moolenaarf740b292006-02-16 22:11:02 +00001210 for (w = firstwin; w != NULL; w = w->w_next)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001211 n++;
1212 return INT2NUM(n);
1213#else
1214 return INT2NUM(1);
1215#endif
1216}
1217
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +00001218static VALUE window_s_aref(VALUE self UNUSED, VALUE num)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001219{
1220 win_T *w;
1221 int n = NUM2INT(num);
1222
1223#ifndef FEAT_WINDOWS
1224 w = curwin;
1225#else
1226 for (w = firstwin; w != NULL; w = w->w_next, --n)
1227#endif
1228 if (n == 0)
1229 return window_new(w);
1230 return Qnil;
1231}
1232
1233static VALUE window_buffer(VALUE self)
1234{
1235 win_T *win = get_win(self);
1236
1237 return buffer_new(win->w_buffer);
1238}
1239
1240static VALUE window_height(VALUE self)
1241{
1242 win_T *win = get_win(self);
1243
1244 return INT2NUM(win->w_height);
1245}
1246
1247static VALUE window_set_height(VALUE self, VALUE height)
1248{
1249 win_T *win = get_win(self);
1250 win_T *savewin = curwin;
1251
1252 curwin = win;
1253 win_setheight(NUM2INT(height));
1254 curwin = savewin;
1255 return height;
1256}
1257
Bram Moolenaarfeeaa682013-02-14 22:19:51 +01001258static VALUE window_width(VALUE self UNUSED)
Bram Moolenaarda2303d2005-08-30 21:55:26 +00001259{
Bram Moolenaarfeeaa682013-02-14 22:19:51 +01001260 return INT2NUM(W_WIDTH(get_win(self)));
Bram Moolenaarda2303d2005-08-30 21:55:26 +00001261}
1262
Bram Moolenaarfeeaa682013-02-14 22:19:51 +01001263static VALUE window_set_width(VALUE self UNUSED, VALUE width)
Bram Moolenaarda2303d2005-08-30 21:55:26 +00001264{
Bram Moolenaarfeeaa682013-02-14 22:19:51 +01001265#ifdef FEAT_VERTSPLIT
Bram Moolenaarda2303d2005-08-30 21:55:26 +00001266 win_T *win = get_win(self);
1267 win_T *savewin = curwin;
1268
1269 curwin = win;
1270 win_setwidth(NUM2INT(width));
1271 curwin = savewin;
Bram Moolenaarfeeaa682013-02-14 22:19:51 +01001272#endif
Bram Moolenaarda2303d2005-08-30 21:55:26 +00001273 return width;
1274}
1275
Bram Moolenaar071d4272004-06-13 20:20:40 +00001276static VALUE window_cursor(VALUE self)
1277{
1278 win_T *win = get_win(self);
1279
1280 return rb_assoc_new(INT2NUM(win->w_cursor.lnum), INT2NUM(win->w_cursor.col));
1281}
1282
1283static VALUE window_set_cursor(VALUE self, VALUE pos)
1284{
1285 VALUE lnum, col;
1286 win_T *win = get_win(self);
1287
1288 Check_Type(pos, T_ARRAY);
Bram Moolenaar165641d2010-02-17 16:23:09 +01001289 if (RARRAY_LEN(pos) != 2)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001290 rb_raise(rb_eArgError, "array length must be 2");
Bram Moolenaar165641d2010-02-17 16:23:09 +01001291 lnum = RARRAY_PTR(pos)[0];
1292 col = RARRAY_PTR(pos)[1];
Bram Moolenaar071d4272004-06-13 20:20:40 +00001293 win->w_cursor.lnum = NUM2LONG(lnum);
1294 win->w_cursor.col = NUM2UINT(col);
1295 check_cursor(); /* put cursor on an existing line */
1296 update_screen(NOT_VALID);
1297 return Qnil;
1298}
1299
Bram Moolenaar6217cdc2012-04-25 12:28:09 +02001300static VALUE f_nop(VALUE self UNUSED)
Bram Moolenaar35df7d22012-04-20 18:05:47 +02001301{
1302 return Qnil;
1303}
1304
Bram Moolenaarcd8b20a2009-05-22 16:20:57 +00001305static VALUE f_p(int argc, VALUE *argv, VALUE self UNUSED)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001306{
1307 int i;
1308 VALUE str = rb_str_new("", 0);
1309
1310 for (i = 0; i < argc; i++) {
1311 if (i > 0) rb_str_cat(str, ", ", 2);
1312 rb_str_concat(str, rb_inspect(argv[i]));
1313 }
Bram Moolenaar165641d2010-02-17 16:23:09 +01001314 MSG(RSTRING_PTR(str));
Bram Moolenaar071d4272004-06-13 20:20:40 +00001315 return Qnil;
1316}
1317
1318static void ruby_io_init(void)
1319{
1320#ifndef DYNAMIC_RUBY
1321 RUBYEXTERN VALUE rb_stdout;
1322#endif
1323
1324 rb_stdout = rb_obj_alloc(rb_cObject);
1325 rb_define_singleton_method(rb_stdout, "write", vim_message, 1);
Bram Moolenaar35df7d22012-04-20 18:05:47 +02001326 rb_define_singleton_method(rb_stdout, "flush", f_nop, 0);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001327 rb_define_global_function("p", f_p, -1);
1328}
1329
1330static void ruby_vim_init(void)
1331{
1332 objtbl = rb_hash_new();
1333 rb_global_variable(&objtbl);
1334
Bram Moolenaarf711faf2007-05-10 16:48:19 +00001335 /* The Vim module used to be called "VIM", but "Vim" is better. Make an
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02001336 * alias "VIM" for backwards compatibility. */
Bram Moolenaarf711faf2007-05-10 16:48:19 +00001337 mVIM = rb_define_module("Vim");
1338 rb_define_const(rb_cObject, "VIM", mVIM);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001339 rb_define_const(mVIM, "VERSION_MAJOR", INT2NUM(VIM_VERSION_MAJOR));
1340 rb_define_const(mVIM, "VERSION_MINOR", INT2NUM(VIM_VERSION_MINOR));
1341 rb_define_const(mVIM, "VERSION_BUILD", INT2NUM(VIM_VERSION_BUILD));
1342 rb_define_const(mVIM, "VERSION_PATCHLEVEL", INT2NUM(VIM_VERSION_PATCHLEVEL));
1343 rb_define_const(mVIM, "VERSION_SHORT", rb_str_new2(VIM_VERSION_SHORT));
1344 rb_define_const(mVIM, "VERSION_MEDIUM", rb_str_new2(VIM_VERSION_MEDIUM));
1345 rb_define_const(mVIM, "VERSION_LONG", rb_str_new2(VIM_VERSION_LONG));
1346 rb_define_const(mVIM, "VERSION_LONG_DATE", rb_str_new2(VIM_VERSION_LONG_DATE));
1347 rb_define_module_function(mVIM, "message", vim_message, 1);
1348 rb_define_module_function(mVIM, "set_option", vim_set_option, 1);
1349 rb_define_module_function(mVIM, "command", vim_command, 1);
1350 rb_define_module_function(mVIM, "evaluate", vim_evaluate, 1);
1351
1352 eDeletedBufferError = rb_define_class_under(mVIM, "DeletedBufferError",
1353 rb_eStandardError);
1354 eDeletedWindowError = rb_define_class_under(mVIM, "DeletedWindowError",
1355 rb_eStandardError);
1356
1357 cBuffer = rb_define_class_under(mVIM, "Buffer", rb_cObject);
1358 rb_define_singleton_method(cBuffer, "current", buffer_s_current, 0);
1359 rb_define_singleton_method(cBuffer, "count", buffer_s_count, 0);
1360 rb_define_singleton_method(cBuffer, "[]", buffer_s_aref, 1);
1361 rb_define_method(cBuffer, "name", buffer_name, 0);
1362 rb_define_method(cBuffer, "number", buffer_number, 0);
1363 rb_define_method(cBuffer, "count", buffer_count, 0);
1364 rb_define_method(cBuffer, "length", buffer_count, 0);
1365 rb_define_method(cBuffer, "[]", buffer_aref, 1);
1366 rb_define_method(cBuffer, "[]=", buffer_aset, 2);
1367 rb_define_method(cBuffer, "delete", buffer_delete, 1);
1368 rb_define_method(cBuffer, "append", buffer_append, 2);
1369
Bram Moolenaarbe4d5062006-03-18 21:30:13 +00001370 /* Added line manipulation functions
1371 * SegPhault - 03/07/05 */
1372 rb_define_method(cBuffer, "line_number", current_line_number, 0);
1373 rb_define_method(cBuffer, "line", line_s_current, 0);
1374 rb_define_method(cBuffer, "line=", set_current_line, 1);
1375
1376
Bram Moolenaar071d4272004-06-13 20:20:40 +00001377 cVimWindow = rb_define_class_under(mVIM, "Window", rb_cObject);
1378 rb_define_singleton_method(cVimWindow, "current", window_s_current, 0);
1379 rb_define_singleton_method(cVimWindow, "count", window_s_count, 0);
1380 rb_define_singleton_method(cVimWindow, "[]", window_s_aref, 1);
1381 rb_define_method(cVimWindow, "buffer", window_buffer, 0);
1382 rb_define_method(cVimWindow, "height", window_height, 0);
1383 rb_define_method(cVimWindow, "height=", window_set_height, 1);
Bram Moolenaarda2303d2005-08-30 21:55:26 +00001384 rb_define_method(cVimWindow, "width", window_width, 0);
1385 rb_define_method(cVimWindow, "width=", window_set_width, 1);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001386 rb_define_method(cVimWindow, "cursor", window_cursor, 0);
1387 rb_define_method(cVimWindow, "cursor=", window_set_cursor, 1);
1388
1389 rb_define_virtual_variable("$curbuf", buffer_s_current, 0);
1390 rb_define_virtual_variable("$curwin", window_s_current, 0);
1391}