Skip to content

Instantly share code, notes, and snippets.

@mattn
Last active December 11, 2015 21:29
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattn/4662845 to your computer and use it in GitHub Desktop.
Save mattn/4662845 to your computer and use it in GitHub Desktop.
mruby interface for vim
diff -r ccbde540a714 runtime/doc/eval.txt
--- a/runtime/doc/eval.txt Wed Apr 03 21:14:29 2013 +0200
+++ b/runtime/doc/eval.txt Fri Apr 05 21:20:11 2013 +0900
@@ -6412,6 +6412,7 @@
mouse_urxvt Compiled with support for urxvt mouse.
mouse_xterm Compiled with support for xterm mouse.
mouseshape Compiled with support for 'mouseshape'.
+mruby Compiled with MRuby interface |mruby|.
multi_byte Compiled with support for 'encoding'
multi_byte_encoding 'encoding' is set to a multi-byte encoding.
multi_byte_ime Compiled with support for IME input method.
diff -r ccbde540a714 runtime/doc/help.txt
--- a/runtime/doc/help.txt Wed Apr 03 21:14:29 2013 +0200
+++ b/runtime/doc/help.txt Fri Apr 05 21:20:11 2013 +0900
@@ -166,6 +166,7 @@
|if_tcl.txt| Tcl interface
|if_ole.txt| OLE automation interface for Win32
|if_ruby.txt| Ruby interface
+|if_mruby.txt| MRuby interface
|debugger.txt| Interface with a debugger
|workshop.txt| Sun Visual Workshop interface
|netbeans.txt| NetBeans External Editor interface
diff -r ccbde540a714 runtime/doc/if_mruby.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/runtime/doc/if_mruby.txt Fri Apr 05 21:20:11 2013 +0900
@@ -0,0 +1,207 @@
+*if_mruby.txt* For Vim version 7.3. Last change: 2013 Jan 30
+
+
+ VIM REFERENCE MANUAL by Yasuhiro Matsumoto
+
+The MRuby Interface to Vim *mruby* *MRuby*
+
+
+1. Commands |mruby-commands|
+2. The VIM module |mruby-vim|
+3. VIM::Buffer objects |mruby-buffer|
+4. VIM::Window objects |mruby-window|
+5. Global variables |mruby-globals|
+6. Using mrbgems |mruby-mrbgems|
+
+{Vi does not have any of these commands}
+
+The MRuby interface only works when Vim was compiled with the |+mruby| feature.
+Most of features in if_mruby are similar to if_ruby.
+
+The home page for mruby is https://github.com/mruby/mruby/. You can find
+links for downloading MRuby there.
+
+==============================================================================
+1. Commands *mruby-commands*
+
+ *:mruby* *:mrub*
+:mrub[y] {cmd} Execute MRuby command {cmd}. A command to try it out: >
+ :mruby print "Hello"
+
+:mrub[y] << {endpattern}
+{script}
+{endpattern}
+ Execute MRuby script {script}.
+ {endpattern} must NOT be preceded by any white space.
+ If {endpattern} is omitted, it defaults to a dot '.'
+ like for the |:append| and |:insert| commands. This
+ form of the |:mruby| command is mainly useful for
+ including mruby code in vim scripts.
+ Note: This command doesn't work when the MRuby feature
+ wasn't compiled in. To avoid errors, see
+ |script-here|.
+
+Example Vim script: >
+
+ function! RedGem()
+ mruby << EOF
+ class Garnet
+ def initialize(s)
+ @buffer = VIM::Buffer.current
+ vimputs(s)
+ end
+ def vimputs(s)
+ @buffer.append(@buffer.count,s)
+ end
+ end
+ gem = Garnet.new("pretty")
+ EOF
+ endfunction
+<
+
+ *:mrubydo* *:mrubyd*
+:[range]mrubyd[o] {cmd} Evaluate MRuby command {cmd} for each line in the
+ [range], with $_ being set to the text of each line in
+ turn, without a trailing <EOL>. Setting $_ will change
+ the text, but note that it is not possible to add or
+ delete lines using this command.
+ The default for [range] is the whole file: "1,$".
+
+ *:mrubyfile* *:mrubyf*
+:mrubyf[ile] {file} Execute the MRuby script in {file}. This is the same
+ as ":mruby load 'file'", but allows file name
+ completion.
+
+Executing MRuby commands is not possible in the |sandbox|.
+
+==============================================================================
+2. The VIM module *mruby-vim*
+
+MRuby code gets all of its access to vim via the "VIM" module.
+
+Overview >
+ print "Hello" # displays a message
+ VIM.command(cmd) # execute an Ex command
+ num = VIM::Window.count # gets the number of windows
+ w = VIM::Window[n] # gets window "n"
+ cw = VIM::Window.current # gets the current window
+ num = VIM::Buffer.count # gets the number of buffers
+ b = VIM::Buffer[n] # gets buffer "n"
+ cb = VIM::Buffer.current # gets the current buffer
+ w.height = lines # sets the window height
+ w.cursor = [row, col] # sets the window cursor position
+ pos = w.cursor # gets an array [row, col]
+ name = b.name # gets the buffer file name
+ line = b[n] # gets a line from the buffer
+ num = b.count # gets the number of lines
+ b[n] = str # sets a line in the buffer
+ b.delete(n) # deletes a line
+ b.append(n, str) # appends a line after n
+ line = VIM::Buffer.current.line # gets the current line
+ num = VIM::Buffer.current.line_number # gets the current line number
+ VIM::Buffer.current.line = "test" # sets the current line number
+<
+
+Module Functions:
+
+ *mruby-message*
+VIM::message({msg})
+ Displays the message {msg}.
+
+ *mruby-set_option*
+VIM::set_option({arg})
+ Sets a vim option. {arg} can be any argument that the ":set" command
+ accepts. Note that this means that no spaces are allowed in the
+ argument! See |:set|.
+
+ *mruby-command*
+VIM::command({cmd})
+ Executes Ex command {cmd}.
+
+ *mruby-evaluate*
+VIM::evaluate({expr})
+ Evaluates {expr} using the vim internal expression evaluator (see
+ |expression|). Returns the expression result as a string.
+ A |List| is turned into a string by joining the items and inserting
+ line breaks.
+
+==============================================================================
+3. VIM::Buffer objects *mruby-buffer*
+
+VIM::Buffer objects represent vim buffers.
+
+Class Methods:
+
+current Returns the current buffer object.
+count Returns the number of buffers.
+self[{n}] Returns the buffer object for the number {n}. The first number
+ is 0.
+
+Methods:
+
+name Returns the name of the buffer.
+number Returns the number of the buffer.
+count Returns the number of lines.
+length Returns the number of lines.
+self[{n}] Returns a line from the buffer. {n} is the line number.
+self[{n}] = {str}
+ Sets a line in the buffer. {n} is the line number.
+delete({n}) Deletes a line from the buffer. {n} is the line number.
+append({n}, {str})
+ Appends a line after the line {n}.
+line Returns the current line of the buffer if the buffer is
+ active.
+line = {str} Sets the current line of the buffer if the buffer is active.
+line_number Returns the number of the current line if the buffer is
+ active.
+
+==============================================================================
+4. VIM::Window objects *mruby-window*
+
+VIM::Window objects represent vim windows.
+
+Class Methods:
+
+current Returns the current window object.
+count Returns the number of windows.
+self[{n}] Returns the window object for the number {n}. The first number
+ is 0.
+
+Methods:
+
+buffer Returns the buffer displayed in the window.
+height Returns the height of the window.
+height = {n} Sets the window height to {n}.
+width Returns the width of the window.
+width = {n} Sets the window width to {n}.
+cursor Returns a [row, col] array for the cursor position.
+cursor = [{row}, {col}]
+ Sets the cursor position to {row} and {col}.
+
+==============================================================================
+5. Global variables *mruby-globals*
+
+There are two global variables.
+
+__curwin The current window object.
+__$curbuf The current buffer object.
+
+==============================================================================
+6. Using mrbgems *mruby-mrbgems*
+
+MRuby support CRuby like package system. But it's not dynamic loading packages.
+The dynamic loading package will not be provided by mruby official.
+
+ https://github.com/mattn/mruby-require
+
+This mrbgem provide dynamic loading packages. If you want to add new feature
+to mruby interface, you should build libmruby.a with this mrbgem. And call
+require in mruby:
+>
+ mruby << EOF
+ require 'mruby-env'
+ puts ENV["HOME"]
+ EOF
+<
+==============================================================================
+ vim:tw=78:ts=8:ft=help:norl:
diff -r ccbde540a714 runtime/doc/if_perl.txt
--- a/runtime/doc/if_perl.txt Wed Apr 03 21:14:29 2013 +0200
+++ b/runtime/doc/if_perl.txt Fri Apr 05 21:20:11 2013 +0900
@@ -253,8 +253,8 @@
this will NOT work!
EOF
endif
-Instead, put the Perl/Python/Ruby/etc. command in a function and call that
-function: >
+Instead, put the Perl/Python/Ruby/MRuby/etc. command in a function and call
+that function: >
if has('perl')
function DefPerl()
perl << EOF
diff -r ccbde540a714 runtime/doc/index.txt
--- a/runtime/doc/index.txt Wed Apr 03 21:14:29 2013 +0200
+++ b/runtime/doc/index.txt Fri Apr 05 21:20:11 2013 +0900
@@ -1339,6 +1339,9 @@
|:mkvimrc| :mkv[imrc] write current mappings and settings to a file
|:mkview| :mkvie[w] write view of current window to a file
|:mode| :mod[e] show or change the screen mode
+|:mruby| :mrub[y] execute MRuby command
+|:mrubydo| :mrubyd[o] execute MRuby command for each line
+|:mrubyfile| :mrubyf[ile] execute MRuby script file
|:mzscheme| :mz[scheme] execute MzScheme command
|:mzfile| :mzf[ile] execute MzScheme script file
|:nbclose| :nbc[lose] close the current Netbeans session
diff -r ccbde540a714 src/Make_ming.mak
--- a/src/Make_ming.mak Wed Apr 03 21:14:29 2013 +0200
+++ b/src/Make_ming.mak Fri Apr 05 21:20:11 2013 +0900
@@ -405,6 +405,12 @@
endif
endif
+ifdef MRUBY
+include $(MRUBY)/build/host/lib/libmruby.flags.mak
+CFLAGS += -DFEAT_MRUBY -I$(MRUBY)/include $(MRUBY_CFLAGS)
+MRUBYLIB = -L$(MRUBY)/build/host/lib -lmruby -lmruby_core $(MRUBY_LD_FLAGS) $(MRUBY_LIBS)
+endif
+
ifdef PYTHON
CFLAGS += -DFEAT_PYTHON
ifeq (yes, $(DYNAMIC_PYTHON))
@@ -575,6 +581,9 @@
ifdef RUBY
OBJ += $(OUTDIR)/if_ruby.o
endif
+ifdef MRUBY
+OBJ += $(OUTDIR)/if_mruby.o
+endif
ifdef TCL
OBJ += $(OUTDIR)/if_tcl.o
endif
@@ -685,7 +694,7 @@
$(CC) $(CFLAGS) -o uninstal.exe uninstal.c $(LIB)
$(TARGET): $(OUTDIR) $(OBJ)
- $(CC) $(CFLAGS) $(LFLAGS) -o $@ $(OBJ) $(LIB) -lole32 -luuid $(LUA_LIB) $(MZSCHEME_LIBDIR) $(MZSCHEME_LIB) $(PYTHONLIB) $(PYTHON3LIB) $(RUBYLIB)
+ $(CC) $(CFLAGS) $(LFLAGS) -o $@ $(OBJ) $(LIB) -lole32 -luuid $(LUA_LIB) $(MZSCHEME_LIBDIR) $(MZSCHEME_LIB) $(PYTHONLIB) $(PYTHON3LIB) $(RUBYLIB) $(MRUBYLIB)
upx: exes
upx gvim.exe
@@ -758,6 +767,9 @@
$(CC) $(CFLAGS) -U_WIN32 -c -o $(OUTDIR)/if_ruby.o if_ruby.c
endif
+$(OUTDIR)/if_mruby.o: if_mruby.c $(INCL)
+ $(CC) -c $(CFLAGS) if_mruby.c -o $(OUTDIR)/if_mruby.o
+
if_perl.c: if_perl.xs typemap
$(XSUBPP) -prototypes -typemap \
$(PERLLIB)/ExtUtils/typemap if_perl.xs > $@
@@ -779,7 +791,7 @@
@echo 'char_u *default_vim_dir = (char_u *)"$(VIMRCLOC)";' >> pathdef.c
@echo 'char_u *default_vimruntime_dir = (char_u *)"$(VIMRUNTIMEDIR)";' >> pathdef.c
@echo 'char_u *all_cflags = (char_u *)"$(CC) $(CFLAGS)";' >> pathdef.c
- @echo 'char_u *all_lflags = (char_u *)"$(CC) $(CFLAGS) $(LFLAGS) -o $(TARGET) $(LIB) -lole32 -luuid $(LUA_LIB) $(MZSCHEME_LIBDIR) $(MZSCHEME_LIB) $(PYTHONLIB) $(PYTHON3LIB) $(RUBYLIB)";' >> pathdef.c
+ @echo 'char_u *all_lflags = (char_u *)"$(CC) $(CFLAGS) $(LFLAGS) -o $(TARGET) $(LIB) -lole32 -luuid $(LUA_LIB) $(MZSCHEME_LIBDIR) $(MZSCHEME_LIB) $(PYTHONLIB) $(PYTHON3LIB) $(RUBYLIB) $(MRUBYLIB)";' >> pathdef.c
@echo 'char_u *compiled_user = (char_u *)"$(USERNAME)";' >> pathdef.c
@echo 'char_u *compiled_sys = (char_u *)"$(USERDOMAIN)";' >> pathdef.c
else
@@ -789,7 +801,7 @@
@echo char_u *default_vim_dir = (char_u *)"$(VIMRCLOC)"; >> pathdef.c
@echo char_u *default_vimruntime_dir = (char_u *)"$(VIMRUNTIMEDIR)"; >> pathdef.c
@echo char_u *all_cflags = (char_u *)"$(CC) $(CFLAGS)"; >> pathdef.c
- @echo char_u *all_lflags = (char_u *)"$(CC) $(CFLAGS) $(LFLAGS) -o $(TARGET) $(LIB) -lole32 -luuid $(LUA_LIB) $(MZSCHEME_LIBDIR) $(MZSCHEME_LIB) $(PYTHONLIB) $(PYTHON3LIB) $(RUBYLIB)"; >> pathdef.c
+ @echo char_u *all_lflags = (char_u *)"$(CC) $(CFLAGS) $(LFLAGS) -o $(TARGET) $(LIB) -lole32 -luuid $(LUA_LIB) $(MZSCHEME_LIBDIR) $(MZSCHEME_LIB) $(PYTHONLIB) $(PYTHON3LIB) $(RUBYLIB) $(MRUBYLIB)"; >> pathdef.c
@echo char_u *compiled_user = (char_u *)"$(USERNAME)"; >> pathdef.c
@echo char_u *compiled_sys = (char_u *)"$(USERDOMAIN)"; >> pathdef.c
endif
diff -r ccbde540a714 src/Make_mvc.mak
--- a/src/Make_mvc.mak Wed Apr 03 21:14:29 2013 +0200
+++ b/src/Make_mvc.mak Fri Apr 05 21:20:11 2013 +0900
@@ -69,6 +69,9 @@
# You must set RUBY_API_VER to RUBY_VER_LONG.
# Don't set ruby API version to RUBY_VER like 191.
#
+# MRuby interface:
+# MRUBY=[Path to Ruby directory]
+#
# Tcl interface:
# TCL=[Path to Tcl directory]
# DYNAMIC_TCL=yes (to load the Tcl DLL dynamically)
@@ -187,6 +190,9 @@
!ifdef RUBY
OBJDIR = $(OBJDIR)R
!endif
+!ifdef MRUBY
+OBJDIR = $(OBJDIR)MR
+!endif
!ifdef MZSCHEME
OBJDIR = $(OBJDIR)Z
!endif
@@ -883,6 +889,18 @@
!endif # RUBY
#
+# Support MRuby interface
+#
+!ifdef MRUBY
+# TODO: libmruby.flags.mak doesn't need on MSVC.
+#!include $(MRUBY)/build/host/lib/libmruby.flags.mak
+CFLAGS = $(CFLAGS) -DFEAT_MRUBY /I $(MRUBY)/include
+MRUBY_OBJ = $(OUTDIR)\if_mruby.obj
+MRUBY_INC = /I "$(MRUBY)\include"
+MRUBY_LIB = /LIBPATH:"$(MRUBY)\build\host\lib" libmruby.lib
+!endif #MRUBY
+
+#
# Support PostScript printing
#
!if "$(POSTSCRIPT)" == "yes"
@@ -926,7 +944,7 @@
LINKARGS1 = $(linkdebug) $(conflags)
LINKARGS2 = $(CON_LIB) $(GUI_LIB) $(LIBC) $(OLE_LIB) user32.lib $(SNIFF_LIB) \
$(LUA_LIB) $(MZSCHEME_LIB) $(PERL_LIB) $(PYTHON_LIB) $(PYTHON3_LIB) $(RUBY_LIB) \
- $(TCL_LIB) $(NETBEANS_LIB) $(XPM_LIB) $(LINK_PDB)
+ $(MRUBY_LIB) $(TCL_LIB) $(NETBEANS_LIB) $(XPM_LIB) $(LINK_PDB)
# Report link time code generation progress if used.
!ifdef NODEBUG
@@ -942,12 +960,12 @@
$(VIM).exe: $(OUTDIR) $(OBJ) $(GUI_OBJ) $(OLE_OBJ) $(OLE_IDL) $(MZSCHEME_OBJ) \
$(LUA_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) $(TCL_OBJ) \
- $(SNIFF_OBJ) $(CSCOPE_OBJ) $(NETBEANS_OBJ) $(XPM_OBJ) \
+ $(MRUBY_OBJ) $(SNIFF_OBJ) $(CSCOPE_OBJ) $(NETBEANS_OBJ) $(XPM_OBJ) \
version.c version.h
$(CC) $(CFLAGS) version.c
$(link) $(LINKARGS1) -out:$(VIM).exe $(OBJ) $(GUI_OBJ) $(OLE_OBJ) \
$(LUA_OBJ) $(MZSCHEME_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) \
- $(TCL_OBJ) $(SNIFF_OBJ) $(CSCOPE_OBJ) $(NETBEANS_OBJ) \
+ $(MRUBY_OBJ) $(TCL_OBJ) $(SNIFF_OBJ) $(CSCOPE_OBJ) $(NETBEANS_OBJ) \
$(XPM_OBJ) $(OUTDIR)\version.obj $(LINKARGS2)
$(VIM): $(VIM).exe
@@ -1114,6 +1132,9 @@
$(OUTDIR)/if_ruby.obj: $(OUTDIR) if_ruby.c $(INCL)
$(CC) $(CFLAGS) $(RUBY_INC) if_ruby.c
+$(OUTDIR)/if_mruby.obj: $(OUTDIR) if_mruby.c $(INCL)
+ $(CC) $(CFLAGS) $(MRUBY_INC) if_mruby.c
+
$(OUTDIR)/if_sniff.obj: $(OUTDIR) if_sniff.c $(INCL)
$(CC) $(CFLAGS) if_sniff.c
diff -r ccbde540a714 src/Makefile
--- a/src/Makefile Wed Apr 03 21:14:29 2013 +0200
+++ b/src/Makefile Fri Apr 05 21:20:11 2013 +0900
@@ -44,6 +44,7 @@
# --enable-python3interp for Python3 interpreter
# --enable-pythoninterp for Python interpreter
# --enable-rubyinterp for Ruby interpreter
+# --enable-mrubyinterp for MRuby interpreter
# --enable-tclinterp for Tcl interpreter
# --enable-cscope for Cscope interface
# - Uncomment one of the lines with --with-features= to enable a set of
@@ -432,6 +433,9 @@
#CONF_OPT_RUBY = --enable-rubyinterp=dynamic
#CONF_OPT_RUBY = --enable-rubyinterp --with-ruby-command=ruby1.9.1
+# MRUBY
+#CONF_OPT_MRUBY = --enable-rubyinterp
+
# TCL
# Uncomment this when you want to include the Tcl interface.
#CONF_OPT_TCL = --enable-tclinterp
@@ -1339,7 +1343,7 @@
# with "-E".
OSDEF_CFLAGS = $(PRE_DEFS) $(POST_DEFS)
-LINT_CFLAGS = -DLINT -I. $(PRE_DEFS) $(POST_DEFS) $(RUBY_CFLAGS) $(LUA_CFLAGS) $(PERL_CFLAGS) $(PYTHON_CFLAGS) $(PYTHON3_CFLAGS) -Dinline= -D__extension__= -Dalloca=alloca
+LINT_CFLAGS = -DLINT -I. $(PRE_DEFS) $(POST_DEFS) $(RUBY_CFLAGS) $(MRUBY_CFLAGS) $(LUA_CFLAGS) $(PERL_CFLAGS) $(PYTHON_CFLAGS) $(PYTHON3_CFLAGS) -Dinline= -D__extension__= -Dalloca=alloca
LINT_EXTRA = -DUSE_SNIFF -DHANGUL_INPUT -D"__attribute__(x)="
@@ -1364,6 +1368,7 @@
$(PYTHON3_LIBS) \
$(TCL_LIBS) \
$(RUBY_LIBS) \
+ $(MRUBY_LIBS) \
$(PROFILE_LIBS) \
$(LEAK_LIBS)
@@ -1477,6 +1482,7 @@
$(PYTHON_SRC) $(PYTHON3_SRC) \
$(TCL_SRC) \
$(RUBY_SRC) \
+ $(MRUBY_SRC) \
$(SNIFF_SRC) \
$(WORKSHOP_SRC) \
$(WSDEBUG_SRC)
@@ -1484,7 +1490,7 @@
TAGS_SRC = *.c *.cpp if_perl.xs
EXTRA_SRC = hangulin.c if_lua.c if_mzsch.c auto/if_perl.c if_perlsfio.c \
- if_python.c if_python3.c if_tcl.c if_ruby.c if_sniff.c \
+ if_python.c if_python3.c if_tcl.c if_ruby.c if_mruby.c if_sniff.c \
gui_beval.c workshop.c wsdebug.c integration.c netbeans.c
# Unittest files
@@ -1563,6 +1569,7 @@
$(PYTHON3_OBJ) \
$(TCL_OBJ) \
$(RUBY_OBJ) \
+ $(MRUBY_OBJ) \
$(OS_EXTRA_OBJ) \
$(WORKSHOP_OBJ) \
$(NETBEANS_OBJ) \
@@ -1599,6 +1606,7 @@
if_python.pro \
if_python3.pro \
if_ruby.pro \
+ if_mruby.pro \
main.pro \
mark.pro \
memfile.pro \
@@ -1661,7 +1669,7 @@
./configure $(CONF_OPT_GUI) $(CONF_OPT_X) $(CONF_OPT_XSMP) \
$(CONF_OPT_DARWIN) $(CONF_OPT_FAIL) \
$(CONF_OPT_PERL) $(CONF_OPT_PYTHON) $(CONF_OPT_PYTHON3) \
- $(CONF_OPT_TCL) $(CONF_OPT_RUBY) $(CONF_OPT_NLS) \
+ $(CONF_OPT_TCL) $(CONF_OPT_RUBY) $(CONF_OPT_MRUBY) $(CONF_OPT_NLS) \
$(CONF_OPT_CSCOPE) $(CONF_OPT_MULTIBYTE) $(CONF_OPT_INPUT) \
$(CONF_OPT_OUTPUT) $(CONF_OPT_GPM) $(CONF_OPT_WORKSHOP) \
$(CONF_OPT_SNIFF) $(CONF_OPT_FEAT) $(CONF_TERM_LIB) \
@@ -2580,6 +2588,9 @@
objects/if_ruby.o: if_ruby.c
$(CCC) $(RUBY_CFLAGS) -o $@ if_ruby.c
+objects/if_mruby.o: if_mruby.c
+ $(CCC) $(MRUBY_CFLAGS) -o $@ if_mruby.c
+
objects/if_sniff.o: if_sniff.c
$(CCC) -o $@ if_sniff.c
@@ -3108,6 +3119,10 @@
ascii.h keymap.h term.h macros.h option.h structs.h regexp.h gui.h \
gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h globals.h farsi.h \
arabic.h version.h
+objects/if_mruby.o: if_mruby.c auto/config.h vim.h feature.h os_unix.h auto/osdef.h \
+ ascii.h keymap.h term.h macros.h option.h structs.h regexp.h gui.h \
+ gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h globals.h farsi.h \
+ arabic.h version.h
objects/if_sniff.o: if_sniff.c vim.h auto/config.h feature.h os_unix.h \
auto/osdef.h ascii.h keymap.h term.h macros.h option.h structs.h \
regexp.h gui.h gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h \
diff -r ccbde540a714 src/buffer.c
--- a/src/buffer.c Wed Apr 03 21:14:29 2013 +0200
+++ b/src/buffer.c Fri Apr 05 21:20:11 2013 +0900
@@ -666,6 +666,9 @@
#ifdef FEAT_RUBY
ruby_buffer_free(buf);
#endif
+#ifdef FEAT_MRUBY
+ mruby_buffer_free(buf);
+#endif
#ifdef FEAT_AUTOCMD
aubuflocal_remove(buf);
#endif
diff -r ccbde540a714 src/config.aap.in
--- a/src/config.aap.in Wed Apr 03 21:14:29 2013 +0200
+++ b/src/config.aap.in Fri Apr 05 21:20:11 2013 +0900
@@ -73,6 +73,12 @@
RUBY_CFLAGS = @RUBY_CFLAGS@
RUBY_LIBS = @RUBY_LIBS@
+MRUBY_SRC = @MRUBY_SRC@
+MRUBY_OBJ = @MRUBY_OBJ@
+MRUBY_PRO = @MRUBY_PRO@
+MRUBY_CFLAGS = @MRUBY_CFLAGS@
+MRUBY_LIBS = @MRUBY_LIBS@
+
SNIFF_SRC = @SNIFF_SRC@
SNIFF_OBJ = @SNIFF_OBJ@
diff -r ccbde540a714 src/config.h.in
--- a/src/config.h.in Wed Apr 03 21:14:29 2013 +0200
+++ b/src/config.h.in Fri Apr 05 21:20:11 2013 +0900
@@ -356,6 +356,9 @@
/* Define for linking via dlopen() or LoadLibrary() */
#undef DYNAMIC_RUBY
+/* Define if you want to include the MRuby interpreter. */
+#undef FEAT_MRUBY
+
/* Define if you want to include the Tcl interpreter. */
#undef FEAT_TCL
diff -r ccbde540a714 src/config.mk.in
--- a/src/config.mk.in Wed Apr 03 21:14:29 2013 +0200
+++ b/src/config.mk.in Fri Apr 05 21:20:11 2013 +0900
@@ -96,6 +96,12 @@
RUBY_CFLAGS = @RUBY_CFLAGS@
RUBY_LIBS = @RUBY_LIBS@
+MRUBY_SRC = @MRUBY_SRC@
+MRUBY_OBJ = @MRUBY_OBJ@
+MRUBY_PRO = @MRUBY_PRO@
+MRUBY_CFLAGS = @MRUBY_CFLAGS@
+MRUBY_LIBS = @MRUBY_LIBS@
+
SNIFF_SRC = @SNIFF_SRC@
SNIFF_OBJ = @SNIFF_OBJ@
diff -r ccbde540a714 src/configure.in
--- a/src/configure.in Wed Apr 03 21:14:29 2013 +0200
+++ b/src/configure.in Fri Apr 05 21:20:11 2013 +0900
@@ -1540,6 +1540,32 @@
AC_SUBST(RUBY_CFLAGS)
AC_SUBST(RUBY_LIBS)
+AC_MSG_CHECKING(--enable-mrubyinterp argument)
+AC_ARG_ENABLE(mrubyinterp,
+ [ --enable-mrubyinterp[=OPTS] Include MRuby interpreter. [default=no] [OPTS=no/yes/dynamic]], ,
+ [enable_mrubyinterp="no"])
+AC_MSG_RESULT($enable_mrubyinterp)
+if test "$enable_mrubyinterp" = "yes"; then
+ if test "x$MRUBY_ROOT" != "x" -a -f "$MRUBY_ROOT/build/host/lib/libmruby.flags.mak"; then
+ MRUBY_CFLAGS=`grep MRUBY_CFLAGS $MRUBY_ROOT/build/host/lib/libmruby.flags.mak | sed 's/MRUBY_CFLAGS\s*=\s*//'`
+ MRUBY_LIBS=`grep MRUBY_LIBS $MRUBY_ROOT/build/host/lib/libmruby.flags.mak | sed 's/MRUBY_LIBS\s*=\s*//'`
+ MRUBY_LIBS="$MRUBY_LIBS $MRUBY_ROOT/build/host/lib/libmruby.a $MRUBY_ROOT/build/host/lib/libmruby_core.a"
+ MRUBY_SRC="if_mruby.c"
+ MRUBY_OBJ="objects/if_mruby.o"
+ MRUBY_PRO="if_mruby.pro"
+ AC_DEFINE(FEAT_MRUBY)
+ else
+ AC_MSG_ERROR(not found; disabling MRuby)
+ fi
+else
+ AC_MSG_ERROR(not found; disabling MRuby)
+fi
+AC_SUBST(MRUBY_SRC)
+AC_SUBST(MRUBY_OBJ)
+AC_SUBST(MRUBY_PRO)
+AC_SUBST(MRUBY_CFLAGS)
+AC_SUBST(MRUBY_LIBS)
+
AC_MSG_CHECKING(--enable-cscope argument)
AC_ARG_ENABLE(cscope,
[ --enable-cscope Include cscope interface.], ,
diff -r ccbde540a714 src/eval.c
--- a/src/eval.c Wed Apr 03 21:14:29 2013 +0200
+++ b/src/eval.c Fri Apr 05 21:20:11 2013 +0900
@@ -6026,8 +6026,9 @@
return item1 == NULL && item2 == NULL;
}
-#if defined(FEAT_RUBY) || defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) \
- || defined(FEAT_MZSCHEME) || defined(FEAT_LUA) || defined(PROTO)
+#if defined(FEAT_RUBY) || defined(FEAT_MRUBY) || defined(FEAT_PYTHON) || \
+ defined(FEAT_PYTHON3) || defined(FEAT_MZSCHEME) || defined(FEAT_LUA) || \
+ defined(PROTO)
/*
* Return the dictitem that an entry in a hashtable points to.
*/
@@ -12377,6 +12378,9 @@
#if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY)
"ruby",
#endif
+#if defined(FEAT_MRUBY)
+ "mruby",
+#endif
#ifdef FEAT_SCROLLBIND
"scrollbind",
#endif
diff -r ccbde540a714 src/ex_cmds.h
--- a/src/ex_cmds.h Wed Apr 03 21:14:29 2013 +0200
+++ b/src/ex_cmds.h Fri Apr 05 21:20:11 2013 +0900
@@ -619,6 +619,12 @@
BANG|FILE1|TRLBAR),
EX(CMD_mode, "mode", ex_mode,
WORD1|TRLBAR|CMDWIN),
+EX(CMD_mruby, "mruby", ex_mruby,
+ RANGE|EXTRA|NEEDARG|CMDWIN),
+EX(CMD_mrubydo, "mrubydo", ex_mrubydo,
+ RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN),
+EX(CMD_mrubyfile, "mrubyfile", ex_mrubyfile,
+ RANGE|FILE1|NEEDARG|CMDWIN),
EX(CMD_mzscheme, "mzscheme", ex_mzscheme,
RANGE|EXTRA|DFLALL|NEEDARG|CMDWIN|SBOXOK),
EX(CMD_mzfile, "mzfile", ex_mzfile,
diff -r ccbde540a714 src/ex_docmd.c
--- a/src/ex_docmd.c Wed Apr 03 21:14:29 2013 +0200
+++ b/src/ex_docmd.c Fri Apr 05 21:20:11 2013 +0900
@@ -134,6 +134,7 @@
|| !defined(FEAT_PYTHON) || !defined(FEAT_PYTHON3) \
|| !defined(FEAT_TCL) \
|| !defined(FEAT_RUBY) \
+ || !defined(FEAT_MRUBY) \
|| !defined(FEAT_LUA) \
|| !defined(FEAT_MZSCHEME)
# define HAVE_EX_SCRIPT_NI
@@ -284,6 +285,11 @@
# define ex_rubydo ex_ni
# define ex_rubyfile ex_ni
#endif
+#ifndef FEAT_MRUBY
+# define ex_mruby ex_script_ni
+# define ex_mrubydo ex_ni
+# define ex_mrubyfile ex_ni
+#endif
#ifndef FEAT_SNIFF
# define ex_sniff ex_ni
#endif
@@ -2593,6 +2599,7 @@
case CMD_return:
case CMD_rightbelow:
case CMD_ruby:
+ case CMD_mruby:
case CMD_silent:
case CMD_smagic:
case CMD_snomagic:
diff -r ccbde540a714 src/if_mruby.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/if_mruby.c Fri Apr 05 21:20:11 2013 +0900
@@ -0,0 +1,812 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved by Bram Moolenaar
+ *
+ * MRuby interface by Yasuhiro Matsumoto
+ *
+ * Do ":help uganda" in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "auto/config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include <mruby.h>
+#include <mruby/compile.h>
+#include <mruby/class.h>
+#include <mruby/proc.h>
+#include <mruby/data.h>
+#include <mruby/array.h>
+#include <mruby/hash.h>
+#include <mruby/string.h>
+#include <mruby/variable.h>
+
+#include "vim.h"
+#include "version.h"
+
+static mrb_state* mrb = NULL;
+static struct mrbc_context* context = NULL;
+static mrb_value objtbl;
+static struct RObject* mrb_stdout;
+
+static struct RClass* mVIM;
+static struct RClass* cBuffer;
+static struct RClass* cVimWindow;
+static struct RClass* eDeletedBufferError;
+static struct RClass* eDeletedWindowError;
+
+static int ensure_mruby_initialized(void);
+static void error_print();
+static void mruby_io_init(void);
+static void mruby_vim_init(void);
+
+static void
+mrb_vim_free(mrb_state *mrb, void *p) {
+}
+
+static const struct mrb_data_type VIM_Window_type = {
+ "VIM::Window", mrb_vim_free,
+};
+
+static const struct mrb_data_type VIM_Buffer_type = {
+ "VIM::Buffer", mrb_vim_free,
+};
+
+void
+mruby_end()
+{
+ if (context) {
+ mrbc_context_free(mrb, context);
+ context = NULL;
+ }
+ if (mrb) {
+ mrb_close(mrb);
+ mrb = NULL;
+ }
+}
+
+static mrb_value
+eval_string(const char *str)
+{
+ mrb_value result;
+ struct mrb_parser_state *parser;
+ int ai = mrb_gc_arena_save(mrb);
+ parser = mrb_parser_new(mrb);
+ parser->s = str;
+ parser->send = str + strlen(str);
+ parser->lineno = 1;
+ mrb_parser_parse(parser, context);
+ result = mrb_nil_value();
+ if (0 < parser->nerr) {
+ MSG(parser->error_buffer[0].message);
+ } else {
+ int n = mrb_generate_code(mrb, parser);
+ result = mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb));
+ }
+ mrb_gc_arena_restore(mrb, ai);
+ mrb_parser_free(parser);
+ return result;
+}
+
+void
+ex_mruby(exarg_T *eap)
+{
+ char *script = NULL;
+
+ script = (char *)script_get(eap, eap->arg);
+ if (!eap->skip && ensure_mruby_initialized()) {
+ eval_string(script ? script : (char *)eap->arg);
+ if (mrb->exc)
+ error_print();
+ }
+ vim_free(script);
+}
+
+void ex_mrubydo(exarg_T *eap)
+{
+ linenr_T i;
+
+ if (ensure_mruby_initialized())
+ {
+ if (u_save(eap->line1 - 1, eap->line2 + 1) != OK)
+ return;
+ for (i = eap->line1; i <= eap->line2; i++) {
+ mrb_value line;
+
+ line = mrb_str_new_cstr(mrb, (char *)ml_get(i));
+ mrb_vm_const_set(mrb, mrb_intern(mrb, "$_"), line);
+ line = eval_string((char *) eap->arg);
+ if (mrb->exc) {
+ error_print();
+ break;
+ }
+ line = mrb_vm_const_get(mrb, mrb_intern(mrb, "$_"));
+ if (!mrb_nil_p(line)) {
+ if (mrb_type(line) != MRB_TT_STRING) {
+ EMSG(_("E265: $_ must be an instance of String"));
+ return;
+ }
+ ml_replace(i, (char_u *) mrb_string_value_ptr(mrb, line), 1);
+ changed();
+#ifdef SYNTAX_HL
+ syn_changed(i); /* recompute syntax hl. for this line */
+#endif
+ }
+ }
+ check_cursor();
+ update_curbuf(NOT_VALID);
+ }
+}
+
+void ex_mrubyfile(exarg_T *eap)
+{
+ if (ensure_mruby_initialized())
+ {
+ FILE* fp = fopen((char *) eap->arg, "rb");
+ if (fp) {
+ mrbc_filename(mrb, context, (char *) eap->arg);
+ mrb_load_file_cxt(mrb, fp, context);
+ fclose(fp);
+ if (mrb->exc)
+ error_print();
+ } else {
+ EMSG("Cannot open file");
+ }
+
+ }
+}
+
+void mruby_buffer_free(buf_T *buf)
+{
+ if (buf->b_mruby_ref)
+ {
+ mrb_funcall(mrb, objtbl, "[]=", 2,
+ mrb_fixnum_value(mrb_obj_id(*(mrb_value*) buf->b_mruby_ref)),
+ mrb_nil_value());
+ ((struct RData*) buf->b_mruby_ref)->data = NULL;
+ }
+}
+
+void mruby_window_free(win_T *win)
+{
+ if (win->w_mruby_ref)
+ {
+ mrb_funcall(mrb, objtbl, "[]=", 2,
+ mrb_fixnum_value(mrb_obj_id(*(mrb_value*) win->w_mruby_ref)),
+ mrb_nil_value());
+ ((struct RData*) win->w_mruby_ref)->data = NULL;
+ }
+}
+
+static int ensure_mruby_initialized(void)
+{
+ if (!mrb)
+ {
+ mrb = mrb_open();
+ if (mrb) {
+ context = mrbc_context_new(mrb);
+ context->capture_errors = 1;
+ mruby_io_init();
+ mruby_vim_init();
+ }
+ }
+ return mrb != NULL;
+}
+
+static void
+error_print()
+{
+ EMSG(mrb_string_value_ptr(mrb, mrb_obj_value(mrb->exc)));
+ mrb->exc = 0;
+}
+
+static mrb_value vim_message(mrb_state *mrb, mrb_value self)
+{
+ char *buff, *p;
+ mrb_value str;
+ int ai = mrb_gc_arena_save(mrb);
+
+ mrb_get_args(mrb, "o", &str);
+
+ str = mrb_obj_as_string(mrb, str);
+ if (RSTRING_LEN(str) > 0) {
+ MSG(RSTRING_PTR(str));
+ } else {
+ MSG("");
+ }
+ mrb_gc_arena_restore(mrb, ai);
+ return mrb_nil_value();
+}
+
+static mrb_value vim_set_option(mrb_state* mrb, mrb_value self)
+{
+ mrb_value str;
+ mrb_get_args(mrb, "S", &str);
+ do_set((char_u *) mrb_string_value_ptr(mrb, str), 0);
+ update_screen(NOT_VALID);
+ return mrb_nil_value();
+}
+
+static mrb_value vim_command(mrb_state* mrb, mrb_value self)
+{
+ mrb_value str;
+ mrb_get_args(mrb, "S", &str);
+ do_cmdline_cmd((char_u *) mrb_string_value_ptr(mrb, str));
+ return mrb_nil_value();
+}
+
+#ifdef FEAT_EVAL
+static mrb_value vim_to_mruby(typval_T *tv)
+{
+ mrb_value result = mrb_nil_value();
+
+ if (tv->v_type == VAR_STRING)
+ {
+ result = mrb_str_new_cstr(mrb, tv->vval.v_string == NULL
+ ? "" : (char *)(tv->vval.v_string));
+ }
+ else if (tv->v_type == VAR_NUMBER)
+ {
+ result = mrb_fixnum_value(tv->vval.v_number);
+ }
+# ifdef FEAT_FLOAT
+ else if (tv->v_type == VAR_FLOAT)
+ {
+ result = mrb_float_value(tv->vval.v_float);
+ }
+# endif
+ else if (tv->v_type == VAR_LIST)
+ {
+ list_T *list = tv->vval.v_list;
+ listitem_T *curr;
+
+ result = mrb_ary_new(mrb);
+
+ if (list != NULL)
+ {
+ for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
+ {
+ mrb_ary_push(mrb, result, vim_to_mruby(&curr->li_tv));
+ }
+ }
+ }
+ else if (tv->v_type == VAR_DICT)
+ {
+ result = mrb_hash_new(mrb);
+
+ if (tv->vval.v_dict != NULL)
+ {
+ hashtab_T *ht = &tv->vval.v_dict->dv_hashtab;
+ long_u todo = ht->ht_used;
+ hashitem_T *hi;
+ dictitem_T *di;
+
+ for (hi = ht->ht_array; todo > 0; ++hi)
+ {
+ if (!HASHITEM_EMPTY(hi))
+ {
+ --todo;
+
+ di = dict_lookup(hi);
+ mrb_funcall(mrb, result, "[]=", 2,
+ mrb_str_new_cstr(mrb, (char *)hi->hi_key),
+ vim_to_mruby(&di->di_tv));
+ }
+ }
+ }
+ } /* else return mrb_nil_value(); */
+
+ return result;
+}
+#endif
+
+static mrb_value vim_evaluate(mrb_state* mrb, mrb_value self)
+{
+#ifdef FEAT_EVAL
+ typval_T *tv;
+ mrb_value result;
+ mrb_value str;
+ mrb_get_args(mrb, "S", &str);
+
+ tv = eval_expr((char_u *) mrb_string_value_ptr(mrb, str), NULL);
+ if (tv == NULL)
+ {
+ return mrb_nil_value();
+ }
+ result = vim_to_mruby(tv);
+
+ free_tv(tv);
+
+ return result;
+#else
+ return mrb_nil_value();
+#endif
+}
+
+static mrb_value buffer_new(buf_T *buf)
+{
+ if (buf->b_mruby_ref)
+ {
+ return mrb_obj_value((struct RData*) buf->b_mruby_ref);
+ }
+ else
+ {
+ struct RData* obj = mrb_data_object_alloc(mrb, cBuffer, buf, &VIM_Buffer_type);
+ buf->b_mruby_ref = (void *) obj;
+ mrb_funcall(mrb, objtbl, "[]=", 2,
+ mrb_fixnum_value(mrb_obj_id(mrb_obj_value(obj))),
+ mrb_obj_value(obj));
+ return mrb_obj_value(obj);
+ }
+}
+
+static buf_T *get_buf(mrb_value obj)
+{
+ buf_T *buf;
+
+ Data_Get_Struct(mrb, obj, &VIM_Buffer_type, buf);
+ if (buf == NULL)
+ mrb_raise(mrb, eDeletedBufferError, "attempt to refer to deleted buffer");
+ return buf;
+}
+
+static mrb_value buffer_s_current(mrb_state* mrb, mrb_value self)
+{
+ return buffer_new(curbuf);
+}
+
+static mrb_value buffer_s_count(mrb_state* mrb, mrb_value self)
+{
+ buf_T *b;
+ int n = 0;
+
+ for (b = firstbuf; b != NULL; b = b->b_next)
+ {
+ /* Deleted buffers should not be counted
+ * SegPhault - 01/07/05 */
+ if (b->b_p_bl)
+ n++;
+ }
+
+ return mrb_fixnum_value(n);
+}
+
+static mrb_value buffer_s_aref(mrb_state* mrb, mrb_value self)
+{
+ mrb_value num;
+ buf_T *b;
+ int n;
+
+ mrb_get_args(mrb, "i", &num);
+ n = mrb_fixnum(num);
+
+ for (b = firstbuf; b != NULL; b = b->b_next)
+ {
+ /* Deleted buffers should not be counted
+ * SegPhault - 01/07/05 */
+ if (!b->b_p_bl)
+ continue;
+
+ if (n == 0)
+ return buffer_new(b);
+
+ n--;
+ }
+ return mrb_nil_value();
+}
+
+static mrb_value buffer_name(mrb_state* mrb, mrb_value self)
+{
+ buf_T *buf = get_buf(self);
+
+ return buf->b_ffname ? mrb_str_new_cstr(mrb, (char *)buf->b_ffname) : mrb_nil_value();
+}
+
+static mrb_value buffer_number(mrb_state* mrb, mrb_value self)
+{
+ buf_T *buf = get_buf(self);
+
+ return mrb_fixnum_value(buf->b_fnum);
+}
+
+static mrb_value buffer_count(mrb_state* mrb, mrb_value self)
+{
+ buf_T *buf = get_buf(self);
+
+ return mrb_fixnum_value(buf->b_ml.ml_line_count);
+}
+
+static mrb_value get_buffer_line(buf_T *buf, linenr_T n)
+{
+ if (n <= 0 || n > buf->b_ml.ml_line_count)
+ mrb_raisef(mrb, E_INDEX_ERROR, "line number %ld out of range", (long)n);
+ return mrb_str_new_cstr(mrb, (char *)ml_get_buf(buf, n, FALSE));
+}
+
+static mrb_value buffer_aref(mrb_state* mrb, mrb_value self)
+{
+ buf_T *buf = get_buf(self);
+
+ if (buf != NULL) {
+ mrb_value num;
+ mrb_get_args(mrb, "i", &num);
+ return get_buffer_line(buf, (linenr_T)mrb_fixnum(num));
+ }
+ return mrb_nil_value(); /* For stop warning */
+}
+
+static mrb_value set_buffer_line(buf_T *buf, linenr_T n, mrb_value str)
+{
+ char *line = mrb_string_value_ptr(mrb, str);
+ aco_save_T aco;
+
+ if (n > 0 && n <= buf->b_ml.ml_line_count && line != NULL)
+ {
+ /* set curwin/curbuf for "buf" and save some things */
+ aucmd_prepbuf(&aco, buf);
+
+ if (u_savesub(n) == OK) {
+ ml_replace(n, (char_u *)line, TRUE);
+ changed();
+#ifdef SYNTAX_HL
+ syn_changed(n); /* recompute syntax hl. for this line */
+#endif
+ }
+
+ /* restore curwin/curbuf and a few other things */
+ aucmd_restbuf(&aco);
+ /* Careful: autocommands may have made "buf" invalid! */
+
+ update_curbuf(NOT_VALID);
+ }
+ else
+ {
+ mrb_raisef(mrb, E_INDEX_ERROR, "line number %ld out of range", (long)n);
+ }
+ return str;
+}
+
+static mrb_value buffer_aset(mrb_state* mrb, mrb_value self)
+{
+ buf_T *buf = get_buf(self);
+ mrb_value num, str;
+
+ mrb_get_args(mrb, "iS", &num, &str);
+ if (buf != NULL) {
+ return set_buffer_line(buf, (linenr_T)mrb_fixnum(num), str);
+ }
+ return str;
+}
+
+static mrb_value buffer_delete(mrb_state* mrb, mrb_value self)
+{
+ buf_T *buf = get_buf(self);
+ mrb_value num;
+ long n;
+ aco_save_T aco;
+
+ mrb_get_args(mrb, "i", &num);
+ n = mrb_fixnum(num);
+ if (n > 0 && n <= buf->b_ml.ml_line_count)
+ {
+ /* set curwin/curbuf for "buf" and save some things */
+ aucmd_prepbuf(&aco, buf);
+
+ if (u_savedel(n, 1) == OK) {
+ ml_delete(n, 0);
+
+ /* Changes to non-active buffers should properly refresh
+ * SegPhault - 01/09/05 */
+ deleted_lines_mark(n, 1L);
+
+ changed();
+ }
+
+ /* restore curwin/curbuf and a few other things */
+ aucmd_restbuf(&aco);
+ /* Careful: autocommands may have made "buf" invalid! */
+
+ update_curbuf(NOT_VALID);
+ }
+ else
+ {
+ mrb_raisef(mrb, E_INDEX_ERROR, "line number %ld out of range", n);
+ }
+ return mrb_nil_value();
+}
+
+static mrb_value buffer_append(mrb_state* mrb, mrb_value self)
+{
+ buf_T *buf = get_buf(self);
+ mrb_value num, str;
+ char *line;
+ long n;
+ aco_save_T aco;
+
+ mrb_get_args(mrb, "iS", &num, &str);
+ line = mrb_string_value_ptr(mrb, str);
+ n = mrb_fixnum(num);
+ if (line == NULL)
+ {
+ mrb_raise(mrb, E_INDEX_ERROR, "NULL line");
+ }
+ else if (n >= 0 && n <= buf->b_ml.ml_line_count)
+ {
+ /* set curwin/curbuf for "buf" and save some things */
+ aucmd_prepbuf(&aco, buf);
+
+ if (u_inssub(n + 1) == OK) {
+ ml_append(n, (char_u *) line, (colnr_T) 0, FALSE);
+
+ /* Changes to non-active buffers should properly refresh screen
+ * SegPhault - 12/20/04 */
+ appended_lines_mark(n, 1L);
+
+ changed();
+ }
+
+ /* restore curwin/curbuf and a few other things */
+ aucmd_restbuf(&aco);
+ /* Careful: autocommands may have made "buf" invalid! */
+
+ update_curbuf(NOT_VALID);
+ }
+ else
+ {
+ mrb_raisef(mrb, E_INDEX_ERROR, "line number %ld out of range", n);
+ }
+ return str;
+}
+
+static mrb_value window_new(win_T *win)
+{
+ if (win->w_mruby_ref)
+ {
+ return mrb_obj_value((struct RData*) win->w_mruby_ref);
+ }
+ else
+ {
+ struct RData* obj = mrb_data_object_alloc(mrb, cVimWindow, win, &VIM_Window_type);
+ win->w_mruby_ref = (void *) obj;
+ mrb_funcall(mrb, objtbl, "[]=", 2,
+ mrb_fixnum_value(mrb_obj_id(mrb_obj_value(obj))),
+ mrb_obj_value(obj));
+ return mrb_obj_value(obj);
+ }
+}
+
+static win_T *get_win(mrb_value obj)
+{
+ win_T *win;
+
+ Data_Get_Struct(mrb, obj, &VIM_Window_type, win);
+ if (win == NULL)
+ mrb_raise(mrb, eDeletedWindowError, "attempt to refer to deleted window");
+ return win;
+}
+
+static mrb_value window_s_current(mrb_state* mrb, mrb_value self)
+{
+ return window_new(curwin);
+}
+
+/*
+ * Added line manipulation functions
+ * SegPhault - 03/07/05
+ */
+static mrb_value line_s_current(mrb_state* mrb, mrb_value self)
+{
+ return get_buffer_line(curbuf, curwin->w_cursor.lnum);
+}
+
+static mrb_value set_current_line(mrb_state* mrb, mrb_value self)
+{
+ mrb_value str;
+ mrb_get_args(mrb, "S", &str);
+ return set_buffer_line(curbuf, curwin->w_cursor.lnum, str);
+}
+
+static mrb_value current_line_number(mrb_state* mrb, mrb_value self)
+{
+ return mrb_fixnum_value((int)curwin->w_cursor.lnum);
+}
+
+
+
+static mrb_value window_s_count(mrb_state* mrb, mrb_value self)
+{
+#ifdef FEAT_WINDOWS
+ win_T *w;
+ int n = 0;
+
+ for (w = firstwin; w != NULL; w = w->w_next)
+ n++;
+ return mrb_fixnum_value(n);
+#else
+ return mrb_fixnum_value(1);
+#endif
+}
+
+static mrb_value window_s_aref(mrb_state* mrb, mrb_value self)
+{
+ win_T *w;
+ int n;
+ mrb_value num;
+
+ mrb_get_args(mrb, "i", &num);
+ n = mrb_fixnum(num);
+#ifndef FEAT_WINDOWS
+ w = curwin;
+#else
+ for (w = firstwin; w != NULL; w = w->w_next, --n)
+#endif
+ if (n == 0)
+ return window_new(w);
+ return mrb_nil_value();
+}
+
+static mrb_value window_buffer(mrb_state* mrb, mrb_value self)
+{
+ win_T *win = get_win(self);
+
+ return buffer_new(win->w_buffer);
+}
+
+static mrb_value window_height(mrb_state* mrb, mrb_value self)
+{
+ win_T *win = get_win(self);
+
+ return mrb_fixnum_value(win->w_height);
+}
+
+static mrb_value window_set_height(mrb_state* mrb, mrb_value self)
+{
+ win_T *win = get_win(self);
+ win_T *savewin = curwin;
+ mrb_value height;
+
+ mrb_get_args(mrb, "i", &height);
+ curwin = win;
+ win_setheight(mrb_fixnum(height));
+ curwin = savewin;
+ return height;
+}
+
+static mrb_value window_width(mrb_state* mrb, mrb_value self)
+{
+ win_T *win = get_win(self);
+
+ return mrb_fixnum_value(win->w_width);
+}
+
+static mrb_value window_set_width(mrb_state* mrb, mrb_value self)
+{
+ win_T *win = get_win(self);
+ win_T *savewin = curwin;
+ mrb_value width;
+
+ mrb_get_args(mrb, "i", &width);
+ curwin = win;
+ win_setwidth(mrb_fixnum(width));
+ curwin = savewin;
+ return width;
+}
+
+static mrb_value window_cursor(mrb_value self)
+{
+ win_T *win = get_win(self);
+
+ return mrb_assoc_new(mrb, mrb_fixnum_value(win->w_cursor.lnum), mrb_fixnum_value(win->w_cursor.col));
+}
+
+static mrb_value window_set_cursor(mrb_state* mrb, mrb_value self)
+{
+ mrb_value lnum, col;
+ win_T *win = get_win(self);
+ mrb_value pos;
+
+ mrb_get_args(mrb, "A", &pos);
+ mrb_check_type(mrb, pos, MRB_TT_ARRAY);
+ if (RARRAY_LEN(pos) != 2)
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "array length must be 2");
+ lnum = RARRAY_PTR(pos)[0];
+ col = RARRAY_PTR(pos)[1];
+ win->w_cursor.lnum = mrb_fixnum(lnum);
+ win->w_cursor.col = mrb_fixnum(col);
+ check_cursor(); /* put cursor on an existing line */
+ update_screen(NOT_VALID);
+ return mrb_nil_value();
+}
+
+static mrb_value f_nop(mrb_state* mrb, mrb_value self)
+{
+ return mrb_nil_value();
+}
+
+static mrb_value f_p(mrb_state* mrb, mrb_value self)
+{
+ int argc;
+ mrb_value *argv;
+ int i;
+ mrb_value str;
+
+ mrb_get_args(mrb, "*", &argv, &argc);
+ str = mrb_str_new(mrb, "", 0);
+
+ for (i = 0; i < argc; i++) {
+ if (i > 0) mrb_str_cat(mrb, str, ", ", 2);
+ mrb_str_concat(mrb, str, mrb_inspect(mrb, argv[i]));
+ }
+ MSG(RSTRING_PTR(str));
+ return mrb_nil_value();
+}
+
+static void mruby_io_init(void)
+{
+ mrb_define_method(mrb, mrb->kernel_module, "p", f_p, ARGS_OPT(1));
+ mrb_define_method(mrb, mrb->kernel_module, "puts", vim_message, ARGS_OPT(1));
+}
+
+static void mruby_vim_init(void)
+{
+ objtbl = mrb_hash_new(mrb);
+ mrb_gv_set(mrb, mrb_intern(mrb, "$VIM_OBJECTS"), objtbl);
+
+ mVIM = mrb_define_module(mrb, "Vim");
+ mrb_define_const(mrb, mrb->object_class, "VIM", mrb_obj_value(mVIM));
+ mrb_define_const(mrb, mVIM, "VERSION_MAJOR", mrb_fixnum_value(VIM_VERSION_MAJOR));
+ mrb_define_const(mrb, mVIM, "VERSION_MINOR", mrb_fixnum_value(VIM_VERSION_MINOR));
+ mrb_define_const(mrb, mVIM, "VERSION_BUILD", mrb_fixnum_value(VIM_VERSION_BUILD));
+ mrb_define_const(mrb, mVIM, "VERSION_PATCHLEVEL", mrb_fixnum_value(VIM_VERSION_PATCHLEVEL));
+ mrb_define_const(mrb, mVIM, "VERSION_SHORT", mrb_str_new_cstr(mrb, VIM_VERSION_SHORT));
+ mrb_define_const(mrb, mVIM, "VERSION_MEDIUM", mrb_str_new_cstr(mrb, VIM_VERSION_MEDIUM));
+ mrb_define_const(mrb, mVIM, "VERSION_LONG", mrb_str_new_cstr(mrb, VIM_VERSION_LONG));
+ mrb_define_const(mrb, mVIM, "VERSION_LONG_DATE", mrb_str_new_cstr(mrb, VIM_VERSION_LONG_DATE));
+ mrb_define_module_function(mrb, mVIM, "message", vim_message, ARGS_REQ(1));
+ mrb_define_module_function(mrb, mVIM, "set_option", vim_set_option, ARGS_REQ(1));
+ mrb_define_module_function(mrb, mVIM, "command", vim_command, ARGS_REQ(1));
+ mrb_define_module_function(mrb, mVIM, "evaluate", vim_evaluate, ARGS_REQ(1));
+
+ eDeletedBufferError = mrb_define_class_under(mrb, mVIM, "DeletedBufferError",
+ mrb->eStandardError_class);
+ eDeletedWindowError = mrb_define_class_under(mrb, mVIM, "DeletedWindowError",
+ mrb->eStandardError_class);
+
+ cBuffer = mrb_define_class_under(mrb, mVIM, "Buffer", mrb->object_class);
+ mrb_define_singleton_method(mrb, cBuffer, "current", buffer_s_current, ARGS_NONE());
+ mrb_define_singleton_method(mrb, cBuffer, "count", buffer_s_count, ARGS_NONE());
+ mrb_define_singleton_method(mrb, cBuffer, "[]", buffer_s_aref, 1);
+ mrb_define_method(mrb, cBuffer, "name", buffer_name, ARGS_NONE());
+ mrb_define_method(mrb, cBuffer, "number", buffer_number, ARGS_NONE());
+ mrb_define_method(mrb, cBuffer, "count", buffer_count, ARGS_NONE());
+ mrb_define_method(mrb, cBuffer, "length", buffer_count, ARGS_NONE());
+ mrb_define_method(mrb, cBuffer, "[]", buffer_aref, ARGS_REQ(1));
+ mrb_define_method(mrb, cBuffer, "[]=", buffer_aset, ARGS_REQ(2));
+ mrb_define_method(mrb, cBuffer, "delete", buffer_delete, ARGS_REQ(1));
+ mrb_define_method(mrb, cBuffer, "append", buffer_append, ARGS_REQ(2));
+
+ mrb_define_method(mrb, cBuffer, "line_number", current_line_number, ARGS_NONE());
+ mrb_define_method(mrb, cBuffer, "line", line_s_current, ARGS_NONE());
+ mrb_define_method(mrb, cBuffer, "line=", set_current_line, ARGS_REQ(1));
+
+
+ cVimWindow = mrb_define_class_under(mrb, mVIM, "Window", mrb->object_class);
+ mrb_define_singleton_method(mrb, cVimWindow, "current", window_s_current, ARGS_NONE());
+ mrb_define_singleton_method(mrb, cVimWindow, "count", window_s_count, ARGS_NONE());
+ mrb_define_singleton_method(mrb, cVimWindow, "[]", window_s_aref, ARGS_REQ(1));
+ mrb_define_method(mrb, cVimWindow, "buffer", window_buffer, ARGS_NONE());
+ mrb_define_method(mrb, cVimWindow, "height", window_height, ARGS_NONE());
+ mrb_define_method(mrb, cVimWindow, "height=", window_set_height, ARGS_REQ(1));
+ mrb_define_method(mrb, cVimWindow, "width", window_width, ARGS_NONE());
+ mrb_define_method(mrb, cVimWindow, "width=", window_set_width, ARGS_REQ(1));
+ mrb_define_method(mrb, cVimWindow, "cursor", window_cursor, ARGS_NONE());
+ mrb_define_method(mrb, cVimWindow, "cursor=", window_set_cursor, ARGS_REQ(1));
+
+ mrb_define_method(mrb, mrb->kernel_module, "__curbuf", buffer_s_current, ARGS_NONE());
+ mrb_define_method(mrb, mrb->kernel_module, "__curwin", window_s_current, ARGS_NONE());
+}
diff -r ccbde540a714 src/main.c
--- a/src/main.c Wed Apr 03 21:14:29 2013 +0200
+++ b/src/main.c Fri Apr 05 21:20:11 2013 +0900
@@ -1471,6 +1471,9 @@
#ifdef FEAT_RUBY
ruby_end();
#endif
+#ifdef FEAT_MRUBY
+ mruby_end();
+#endif
#ifdef FEAT_PYTHON
python_end();
#endif
diff -r ccbde540a714 src/proto.h
--- a/src/proto.h Wed Apr 03 21:14:29 2013 +0200
+++ b/src/proto.h Fri Apr 05 21:20:11 2013 +0900
@@ -197,6 +197,10 @@
# include "if_ruby.pro"
# endif
+# ifdef FEAT_MRUBY
+# include "if_mruby.pro"
+# endif
+
/* Ugly solution for "BalloonEval" not being defined while it's used in some
* .pro files. */
# ifndef FEAT_BEVAL
diff -r ccbde540a714 src/proto/if_mruby.pro
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/proto/if_mruby.pro Fri Apr 05 21:20:11 2013 +0900
@@ -0,0 +1,9 @@
+/* if_ruby.c */
+int mruby_enabled __ARGS((int verbose));
+void mruby_end __ARGS((void));
+void ex_mruby __ARGS((exarg_T *eap));
+void ex_mrubydo __ARGS((exarg_T *eap));
+void ex_mrubyfile __ARGS((exarg_T *eap));
+void mruby_buffer_free __ARGS((buf_T *buf));
+void mruby_window_free __ARGS((win_T *win));
+/* vim: set ft=c : */
diff -r ccbde540a714 src/screen.c
--- a/src/screen.c Wed Apr 03 21:14:29 2013 +0200
+++ b/src/screen.c Fri Apr 05 21:20:11 2013 +0900
@@ -301,8 +301,9 @@
#endif
}
-#if defined(FEAT_RUBY) || defined(FEAT_PERL) || defined(FEAT_VISUAL) || \
- (defined(FEAT_CLIPBOARD) && defined(FEAT_X11)) || defined(PROTO)
+#if defined(FEAT_RUBY) || defined(FEAT_MRUBY) || defined(FEAT_PERL) || \
+ defined(FEAT_VISUAL) || (defined(FEAT_CLIPBOARD) && defined(FEAT_X11)) || \
+ defined(PROTO)
/*
* update all windows that are editing the current buffer
*/
diff -r ccbde540a714 src/structs.h
--- a/src/structs.h Wed Apr 03 21:14:29 2013 +0200
+++ b/src/structs.h Fri Apr 05 21:20:11 2013 +0900
@@ -1671,6 +1671,10 @@
void *b_ruby_ref;
#endif
+#ifdef FEAT_MRUBY
+ void *b_mruby_ref;
+#endif
+
#if defined(FEAT_SYN_HL) || defined(FEAT_SPELL)
synblock_T b_s; /* Info related to syntax highlighting. w_s
* normally points to this, but some windows
@@ -2172,6 +2176,10 @@
#ifdef FEAT_RUBY
void *w_ruby_ref;
#endif
+
+#ifdef FEAT_MRUBY
+ void *w_mruby_ref;
+#endif
};
/*
diff -r ccbde540a714 src/version.c
--- a/src/version.c Wed Apr 03 21:14:29 2013 +0200
+++ b/src/version.c Fri Apr 05 21:20:11 2013 +0900
@@ -521,6 +521,11 @@
#else
"-ruby",
#endif
+#ifdef FEAT_RUBY
+ "+mruby",
+#else
+ "-mruby",
+#endif
#ifdef FEAT_SCROLLBIND
"+scrollbind",
#else
diff -r ccbde540a714 src/window.c
--- a/src/window.c Wed Apr 03 21:14:29 2013 +0200
+++ b/src/window.c Fri Apr 05 21:20:11 2013 +0900
@@ -4484,6 +4484,10 @@
ruby_window_free(wp);
#endif
+#ifdef FEAT_MRUBY
+ mruby_window_free(wp);
+#endif
+
clear_winopt(&wp->w_onebuf_opt);
clear_winopt(&wp->w_allbuf_opt);
@mattn
Copy link
Author

mattn commented Jan 30, 2013

How to apply this patch

$ cd /path/to/vim
$ curl https://gist.github.com/raw/4662845/vim7-if_mruby.diff | patch -p1
$ make autoconf
$ export MRUBY_ROOT=/path/to/mruby
$ ./configure --enable-mrubyinterp=yes
$ make

@k-takata
Copy link

+++ b/src/proto/if_mruby.pro Thu Jan 31 11:31:22 2013 +0900
@@ -0,0 +1,9 @@
+/* if_ruby.c */

if_ruby.c -> if_mruby.c

--- a/src/version.c Wed Jan 30 21:56:21 2013 +0100
+++ b/src/version.c Thu Jan 31 11:31:22 2013 +0900
@@ -518,6 +518,11 @@
 #else
 "-ruby",
 #endif
+#ifdef FEAT_RUBY
+ "+mruby",
+#else
+ "-mruby",
+#endif

FEAT_RUBY -> FEAT_MRUBY

@mattn
Copy link
Author

mattn commented Jan 31, 2013

あざます

@k-takata
Copy link

+# MRUBY
+#CONF_OPT_MRUBY = --enable-rubyinterp
+

--enable-rubyinterp -> --enable-mrubyinterp

@mattn
Copy link
Author

mattn commented Jan 31, 2013

あざます
configureで指定してない時にエラー出てたの直しました。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment