Skip to content

Instantly share code, notes, and snippets.

@mattn
Created November 1, 2010 17:02
Show Gist options
  • Select an option

  • Save mattn/658505 to your computer and use it in GitHub Desktop.

Select an option

Save mattn/658505 to your computer and use it in GitHub Desktop.
diff -Nru src.org/Make_bc5.mak src/Make_bc5.mak
--- src.org/Make_bc5.mak 2004-05-19 00:55:41.000000000 +0900
+++ src/Make_bc5.mak 2005-02-08 10:56:09.000000000 +0900
@@ -403,6 +403,12 @@
DEFINES = $(DEFINES) -DNBDEBUG
NBDEBUG_DEP = nbdebug.h nbdebug.c
!endif
+
+!if ("$(IMC)"=="yes")
+DEFINES = $(DEFINES) -DFEAT_IM_CUSTOM -DFEAT_SKK -DFEAT_POBOX
+IMC_OBJ = $(OUTDIR)\skk.obj $(OUTDIR)\pobox.obj
+IMC_PRO = proto/skk.pro proto/pobox.pro
+!endif
!endif
!ifdef XPM
@@ -599,6 +605,11 @@
$(OBJDIR)\netbeans.obj $(OBJDIR)\gui_beval.obj
!endif
+!if ("$(IMC)"=="yes")
+vimobj = $(vimobj) \
+ $(OBJDIR)\skk.obj $(OBJDIR)\pobox.obj
+!endif
+
!ifdef XPM
vimobj = $(vimobj) \
$(OBJDIR)\xpm_w32.obj
@@ -918,6 +929,12 @@
$(OBJDIR)\netbeans.obj: netbeans.c $(NBDEBUG_DEP)
$(CC) $(CCARG) $(CC1) $(CC2)$@ netbeans.c
+$(OBJDIR)\skk.obj: skk.c skklib.c skklib.h
+ $(CC) $(CCARG) $(CC1) $(CC2)$@ skk.c
+
+$(OBJDIR)\pobox.obj: pobox.
+ $(CC) $(CCARG) $(CC1) $(CC2)$@ pobox.c
+
$(OBJDIR)\vim.res: vim.rc version.h tools.bmp tearoff.bmp \
vim.ico vim_error.ico vim_alert.ico vim_info.ico vim_quest.ico
$(BRC) -fo$(OBJDIR)\vim.res -i $(BOR)\include -w32 -r vim.rc @&&|
diff -Nru src.org/Make_mvc.mak src/Make_mvc.mak
--- src.org/Make_mvc.mak 2004-05-17 03:34:17.000000000 +0900
+++ src/Make_mvc.mak 2005-02-08 10:56:09.000000000 +0900
@@ -394,6 +394,12 @@
CFLAGS = $(CFLAGS) -DFEAT_MBYTE
!endif
+!if "$(IMC)" == "yes"
+CFLAGS = $(CFLAGS) -DFEAT_IM_CUSTOM -DFEAT_SKK -DFEAT_POBOX
+IMC_OBJ = $(OUTDIR)\skk.obj $(OUTDIR)\pobox.obj
+IMC_PRO = proto/skk.pro proto/pobox.pro
+!endif
+
!if "$(GUI)" == "yes"
SUBSYSTEM = windows
CFLAGS = $(CFLAGS) -DFEAT_GUI_W32
@@ -611,7 +617,7 @@
$(CC) $(CFLAGS) version.c /Fo$(OUTDIR)/version.obj $(PDB)
$(link) $(LINKARGS1) -out:$*.exe $(OBJ) $(GUI_OBJ) $(OLE_OBJ) \
$(PERL_OBJ) $(PYTHON_OBJ) $(RUBY_OBJ) $(TCL_OBJ) $(SNIFF_OBJ) \
- $(CSCOPE_OBJ) $(NETBEANS_OBJ) $(XPM_OBJ) \
+ $(CSCOPE_OBJ) $(NETBEANS_OBJ) $(XPM_OBJ) $(IMC_OBJ) \
$(OUTDIR)\version.obj $(LINKARGS2)
$(VIM).exe: $(VIM)
@@ -816,6 +822,10 @@
$(OUTDIR)/xpm_w32.obj: $(OUTDIR) xpm_w32.c
$(CC) $(CFLAGS) $(XPM_INC) xpm_w32.c /Fo$(OUTDIR)/xpm_w32.obj $(PDB)
+$(OUTDIR)/skk.obj: $(OUTDIR) skk.c $(INCL)
+
+$(OUTDIR)/pobox.obj: $(OUTDIR) pobox.c $(INCL)
+
$(OUTDIR)/vim.res: $(OUTDIR) vim.rc version.h tools.bmp tearoff.bmp vim.ico vim_error.ico vim_alert.ico vim_info.ico vim_quest.ico
$(RC) /l 0x409 /Fo$(OUTDIR)/vim.res $(RCFLAGS) vim.rc
@@ -882,6 +892,7 @@
proto/term.pro \
proto/ui.pro \
proto/undo.pro \
+ $(IMC_PRO) \
proto/window.pro \
$(NETBEANS_PRO)
diff -Nru src.org/Makefile src/Makefile
--- src.org/Makefile 2004-06-08 02:15:04.000000000 +0900
+++ src/Makefile 2005-02-08 10:56:09.000000000 +0900
@@ -1174,6 +1174,11 @@
ALL_GUI_PRO = gui.pro gui_gtk.pro gui_motif.pro gui_athena.pro gui_gtk_x11.pro gui_x11.pro gui_w16.pro gui_w32.pro gui_amiga.pro gui_photon.pro
# }}}
+### IM_CUSTOM {{{1
+IM_CUSTOM_SRC = canna.c skk.c pobox.c
+IM_CUSTOM_OBJ = objects/canna.o objects/skk.o objects/pobox.o
+IM_CUSTOM_PRO = canna.pro skk.pro pobox.pro
+# }}}
### Command to create dependencies based on #include "..."
### prototype headers are ignored due to -DPROTO, system
@@ -1314,7 +1319,7 @@
workshop.c wsdebug.c integration.c netbeans.c
# All sources, also the ones that are not configured
-ALL_SRC = $(BASIC_SRC) $(ALL_GUI_SRC) $(EXTRA_SRC)
+ALL_SRC = $(BASIC_SRC) $(ALL_GUI_SRC) $(EXTRA_SRC) $(IM_CUSTOM_SRC)
# Which files to check with lint. Select one of these three lines. ALL_SRC
# checks more, but may not work well for checking a GUI that wasn't configured.
@@ -1376,7 +1381,8 @@
$(OS_EXTRA_OBJ) \
$(WORKSHOP_OBJ) \
$(NETBEANS_OBJ) \
- $(WSDEBUG_OBJ)
+ $(WSDEBUG_OBJ) \
+ $(IM_CUSTOM_OBJ)
PRO_AUTO = \
buffer.pro \
@@ -1818,6 +1824,14 @@
$(INSTALL_DATA) $(SCRIPTSOURCE)/vim16x16.png $(ICON16PATH)/gvim.png; \
fi
+objects/canna.o: canna.c
+ $(CCC) -o $@ canna.c
+
+objects/skk.o: skk.c
+ $(CCC) -o $@ skk.c
+
+objects/pobox.o: pobox.c
+ $(CCC) -o $@ pobox.c
$(HELPSOURCE)/vim.1 $(MACROSOURCE) $(TOOLSSOURCE):
@echo Runtime files not found.
diff -Nru src.org/auto/configure src/auto/configure
--- src.org/auto/configure 2004-05-08 09:03:13.000000000 +0900
+++ src/auto/configure 2005-02-08 10:56:09.000000000 +0900
@@ -99,6 +99,12 @@
--disable-gpm Don't use gpm (Linux mouse daemon)."
ac_help="$ac_help
--disable-nls Don't support NLS (gettext())."
+ac_help="$ac_help
+ --enable-canna Include canna support. [default=yes]"
+ac_help="$ac_help
+ --enable-skk Include skk support. [default=yes]"
+ac_help="$ac_help
+ --enable-pobox Include pobox support. [default=yes]"
# Initialize some variables set by options.
# The variables have the same names as the options, with
@@ -7785,6 +7791,100 @@
enable_nls="yes"
fi
+# Check whether --enable-canna or --disable-canna was given.
+if test "${enable_canna+set}" = set; then
+ enableval="$enable_canna"
+ :
+else
+ enable_canna="yes"
+fi
+
+ if test "$enable_canna" = "yes"; then
+ echo $ac_n "checking for jrKanjiControl in -lcanna""... $ac_c" 1>&6
+echo "configure:7194: checking for jrKanjiControl in -lcanna" >&5
+ac_lib_var=`echo canna'_'jrKanjiControl | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lcanna $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 7202 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char jrKanjiControl();
+
+int main() {
+jrKanjiControl()
+; return 0; }
+EOF
+if { (eval echo configure:7213: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ libcanna="yes"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test "$libcanna" = "yes"; then
+ imcustom=yes
+ cat >> confdefs.h <<\EOF
+#define FEAT_CANNA 1
+EOF
+
+ LIBS="$LIBS -lcanna"
+ fi
+ fi
+# Check whether --enable-skk or --disable-skk was given.
+if test "${enable_skk+set}" = set; then
+ enableval="$enable_skk"
+ :
+else
+ enable_skk="yes"
+fi
+
+ if test "$enable_skk" = "yes"; then
+ imcustom=yes
+ cat >> confdefs.h <<\EOF
+#define FEAT_SKK 1
+EOF
+
+ fi
+# Check whether --enable-pobox or --disable-pobox was given.
+if test "${enable_pobox+set}" = set; then
+ enableval="$enable_pobox"
+ :
+else
+ enable_pobox="yes"
+fi
+
+ if test "$enable_pobox" = "yes"; then
+ imcustom=yes
+ cat >> confdefs.h <<\EOF
+#define FEAT_POBOX 1
+EOF
+
+ fi
+if test "$imcustom" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define FEAT_IM_CUSTOM 1
+EOF
+
+fi
if test "$enable_nls" = "yes"; then
echo "$ac_t""no" 1>&6
diff -Nru src.org/canna.c src/canna.c
--- src.org/canna.c 1970-01-01 09:00:00.000000000 +0900
+++ src/canna.c 2005-02-08 10:56:09.000000000 +0900
@@ -0,0 +1,603 @@
+/* vim: set sw=4 ts=4 sts=4: */
+#include "vim.h"
+
+#ifdef FEAT_CANNA
+#include <canna/jrkanji.h>
+
+typedef struct {
+ char_u *echoStr;
+ int length;
+ int revPos;
+ int revLen;
+} echoback_T;
+
+static jrKanjiStatus ks;
+static jrKanjiStatusWithValue ksv;
+static char_u curMode[BUFSIZ];
+static char_u curBuff[BUFSIZ];
+static char_u *server = NULL;
+static char_u *initfile = NULL;
+static char_u *old_enc = NULL;
+static echoback_T curEcho;
+static echoback_T curGLine;
+static int canna_enable = FALSE;
+static int nbytes = 0;
+static int orig_x, orig_y;
+static void canna_save_echoback();
+
+#ifdef USE_ICONV
+static vimconv_T canna_convt;
+#endif
+
+static struct {
+ int vimkey;
+ int cannakey;
+} canna_keytable[] = {
+ {K_UP, CANNA_KEY_Up},
+ {K_DOWN, CANNA_KEY_Down},
+ {K_LEFT, CANNA_KEY_Left},
+ {K_RIGHT, CANNA_KEY_Right},
+ {K_F1, CANNA_KEY_F1},
+ {K_F2, CANNA_KEY_F2},
+ {K_F3, CANNA_KEY_F3},
+ {K_F4, CANNA_KEY_F4},
+ {K_F5, CANNA_KEY_F5},
+ {K_F6, CANNA_KEY_F6},
+ {K_F7, CANNA_KEY_F7},
+ {K_F8, CANNA_KEY_F8},
+ {K_F9, CANNA_KEY_F9},
+ {K_F10, CANNA_KEY_F10},
+ {K_HOME, CANNA_KEY_Home},
+#ifdef CANNA_KEY_End
+ {K_END, CANNA_KEY_End},
+#endif
+#ifdef CANNA_KEY_PageUp
+ {K_PAGEUP, CANNA_KEY_PageUp},
+#endif
+#ifdef CANNA_KEY_PageDown
+ {K_PAGEDOWN, CANNA_KEY_PageDown},
+#endif
+ {K_BS, '\b'},
+ {K_DEL, '\177'},
+ {NUL, NUL}
+};
+
+static int
+canna_getmode(void)
+{
+ char buf[2];
+ jrKanjiControl(0, KC_SETMODEINFOSTYLE, (char *)1);
+ jrKanjiControl(0, KC_QUERYMODE, buf);
+ jrKanjiControl(0, KC_SETMODEINFOSTYLE, (char *)0);
+ return buf[0] - '@';
+}
+
+int
+canna_set_active(int act)
+{
+ int mode;
+ if (act)
+ canna_enabled(TRUE);
+ if (!canna_enable)
+ return FALSE;
+ ksv.ks = &ks;
+ ksv.buffer = curBuff;
+ ksv.bytes_buffer = BUFSIZ;
+ mode = canna_getmode();
+ if (act && mode == CANNA_MODE_AlphaMode)
+ {
+ ksv.val = CANNA_MODE_HenkanNyuryokuMode;
+ jrKanjiControl(0, KC_CHANGEMODE, (char *)&ksv);
+ canna_save_echoback();
+ /*
+ * When we get into CANNA_MODE_HenkanNyuryokuMode,
+ * ks.info may not set.
+ */
+ jrKanjiControl(0, KC_QUERYMODE, (char *)curMode);
+ }
+ else if (!act && mode != CANNA_MODE_AlphaMode)
+ {
+ ksv.val = CANNA_MODE_AlphaMode;
+ jrKanjiControl(0, KC_CHANGEMODE, (char *)&ksv);
+ canna_save_echoback();
+ }
+ return TRUE;
+}
+
+int
+canna_get_active()
+{
+ if (!canna_enabled)
+ return FALSE;
+ return (canna_getmode() == CANNA_MODE_AlphaMode) ? FALSE : TRUE;
+}
+
+static int
+canna_puts(char *src, int *x, int *y, int attr)
+{
+ int len = 1;
+ int all_cells = 0;
+ char_u *ptr;
+#ifdef FEAT_MBYTE
+ char_u cell[MB_MAXBYTES];
+#else
+ char_u cell[2];
+#endif
+
+ for(ptr = src; *ptr; ptr+=len)
+ {
+ int cells = 0;
+ int diffs = 0;
+#ifdef FEAT_MBYTE
+ cells = mb_ptr2cells(ptr);
+#else
+ cells = ptr2cells(ptr);
+#endif
+
+#ifdef FEAT_MBYTE
+ len = mb_ptr2len_check(ptr);
+#else
+ len = 1;
+#endif
+ strncpy(cell, ptr, len);
+ cell[len] = 0;
+ if (State & CMDLINE || *y == Rows - 1)
+ {
+ diffs = *x + cells - Columns;
+ if (diffs > 0)
+ {
+ if (diffs < cells)
+ screen_putchar('>', *y, *x, hl_attr(HLF_AT));
+ *x = 0;
+ }
+ }
+ else
+ {
+ diffs = *x + cells - W_WINCOL(curwin) - W_WIDTH(curwin);
+ if (diffs > 0)
+ {
+ if (diffs < cells)
+ screen_putchar('>', *y, *x, hl_attr(HLF_AT));
+ *x = W_WINCOL(curwin);
+ if (*y < W_WINROW(curwin) + curwin->w_height - 1)
+ *y += 1;
+ }
+ }
+ screen_puts(cell, *y, *x, attr);
+ *x += cells;
+ all_cells += cells;
+ }
+ if ((State & CMDLINE) == 0)
+ {
+ if (*x == W_WINCOL(curwin) + W_WIDTH(curwin))
+ {
+ *x = W_WINCOL(curwin);
+ if (*y < W_WINROW(curwin) + curwin->w_height - 1)
+ *y += 1;
+ windgoto(*y, *x);
+ }
+ }
+ return all_cells;
+}
+
+static void
+canna_getxy(int *x, int *y)
+{
+ if (State & CMDLINE)
+ {
+ *x = msg_col;
+ *y = msg_row;
+ }
+ else
+ {
+ *x = W_WINCOL(curwin) + curwin->w_wcol;
+ *y = W_WINROW(curwin) + curwin->w_wrow;
+ }
+
+}
+
+static void
+canna_conv_free(char_u* src)
+{
+#ifdef FEAT_MBYTE
+#ifdef USE_ICONV
+ vim_free(src);
+#else
+ if (enc_dbcs == DBCS_JPNU)
+ return;
+ vim_free(src);
+#endif
+#else
+ return;
+#endif
+}
+
+static char_u*
+canna_conv_alloc(char_u* src)
+{
+#ifdef FEAT_MBYTE
+ char_u *ret;
+
+#ifdef USE_ICONV
+ ret = string_convert(&canna_convt, (char_u*)src, NULL);
+ if (!ret)
+ ret = strdup(src);
+#else
+ char_u c1, c2;
+ char_u *dst;
+ ret = dst = strdup(src);
+ switch(enc_dbcs)
+ {
+ case DBCS_JPNU:
+ break;
+ case DBCS_JPN:
+ while(*src)
+ {
+ c1 = *src;
+ c2 = *(src+1);
+ if (c2 == 0x00 || (c1 & 0x80) == 0)
+ *dst++ = c1;
+ else
+ if (c1 == 0x8e)
+ {
+ *dst++ = c2;
+ src++;
+ }
+ else
+ {
+ if (c1 % 2 == 0)
+ c2 -= 0x02;
+ else
+ c2 -= (c2 > 0xdf) ? 0x60 : 0x61;
+ if (c1 < 0xdf)
+ c1 = (c1 + 1) / 2 + 0x30;
+ else
+ c1 = (c1 + 1) / 2 + 0x70;
+ *dst++ = c1;
+ *dst++ = c2;
+ src++;
+ }
+ src++;
+ }
+ *dst = 0;
+ break;
+ default:
+ break;
+ }
+#endif
+ return ret;
+#else
+ return src;
+#endif
+}
+
+/* must free using vim_free(), not canna_conv_free()! */
+static char_u *
+canna_conv_alloc_n(char_u *p, int len)
+{
+ char_u *tmp;
+ char_u *dst;
+ tmp = vim_strnsave(p, len);
+ dst = canna_conv_alloc(tmp);
+ canna_conv_free(tmp); /* ugly! */
+ return dst;
+}
+
+static void
+canna_save_echoback()
+{
+ if (ks.length != -1)
+ {
+ vim_free(curEcho.echoStr);
+ curEcho.echoStr = vim_strnsave(ks.echoStr, ks.length);
+ curEcho.length = ks.length;
+ curEcho.revPos = ks.revPos;
+ curEcho.revLen = ks.revLen;
+ }
+
+ if (ks.info & KanjiModeInfo)
+ STRCPY(curMode, ks.mode);
+
+ vim_free(curGLine.echoStr);
+ curGLine.echoStr = NULL;
+ if (ks.info & KanjiGLineInfo && ks.gline.length != 0) {
+ curGLine.echoStr = vim_strnsave(ks.gline.line, ks.gline.length);
+ curGLine.length = ks.gline.length;
+ curGLine.revPos = ks.gline.revPos;
+ curGLine.revLen = ks.gline.revLen;
+ }
+}
+
+static int
+canna_echoback(echoback_T *pecho, int *px, int *py, int attr)
+{
+ int off;
+ int cells;
+ char_u *msg;
+ if (!pecho || !pecho->echoStr)
+ return 0;
+ off = pecho->revPos;
+ msg = canna_conv_alloc_n(pecho->echoStr, off);
+ cells = canna_puts(msg, px, py, attr);
+ vim_free(msg);
+
+ msg = canna_conv_alloc_n(pecho->echoStr + off, pecho->revLen);
+ cells += canna_puts(msg, px, py, HL_STANDOUT);
+ vim_free(msg);
+
+ off += pecho->revLen;
+ msg = canna_conv_alloc_n(pecho->echoStr + off, pecho->length - off);
+ cells += canna_puts(msg, px, py, attr);
+ vim_free(msg);
+ return cells;
+}
+
+static int
+canna_beep(void)
+{
+ vim_beep();
+ return 0;
+}
+
+extern int (*jrBeepFunc)(void);
+int
+canna_enabled(int verbose)
+{
+ if (!canna_enable)
+ {
+ char_u **ptr = NULL;
+ int r;
+ if (server)
+ jrKanjiControl(0, KC_SETSERVERNAME, server);
+ if (initfile)
+ jrKanjiControl(0, KC_SETINITFILENAME, initfile);
+ r = jrKanjiControl(0, KC_INITIALIZE, (char*)&ptr);
+ if (ptr)
+ {
+ if (verbose)
+ {
+ while(*ptr)
+ {
+ char *dst = canna_conv_alloc(*ptr++);
+ EMSG(dst);
+ canna_conv_free(dst);
+ }
+ }
+ }
+ else
+ {
+ jrKanjiControl(0, KC_SETAPPNAME, "vim");
+#if 0
+ if (!initfile)
+ jrKanjiControl(0, KC_SETBUNSETSUKUGIRI, (char*) &ksv);
+#endif
+ jrKanjiControl(0, KC_SETUNDEFKEYFUNCTION, kc_normal);
+ jrKanjiControl(0, KC_SETWIDTH, (char*) Columns-8);
+ curBuff[0] = '\0';
+ nbytes = 0;
+ canna_enable = TRUE;
+ }
+ jrBeepFunc = &canna_beep;
+ ksv.ks = &ks;
+ ksv.buffer = curBuff;
+ ksv.bytes_buffer = BUFSIZ;
+ ksv.val = CANNA_MODE_AlphaMode;
+ jrKanjiControl(0, KC_CHANGEMODE, (char*) &ksv);
+ curBuff[0] = '\0';
+ nbytes = 0;
+ curEcho.echoStr = NULL;
+ canna_save_echoback();
+ canna_enable = TRUE;
+ }
+#ifdef USE_ICONV
+ if (canna_enabled && old_enc != p_enc)
+ {
+ canna_convt.vc_fd = (iconv_t)-1;
+ convert_setup(&canna_convt, "euc-jp", p_enc);
+ }
+#endif
+ return canna_enable;
+
+}
+
+int
+canna_end()
+{
+ if (canna_enable)
+ jrKanjiControl(0, KC_FINALIZE, 0);
+ canna_enable = FALSE;
+ return TRUE;
+}
+
+static void
+canna_kakutei(char_u* p)
+{
+ char_u *dst;
+ dst = canna_conv_alloc(p);
+ strcpy(curBuff, dst);
+ canna_conv_free(dst);
+}
+
+static int
+canna_fetch()
+{
+ int c;
+#ifdef FEAT_MBYTE
+ c = mb_ptr2char(curBuff+nbytes);
+ if (c)
+ nbytes += mb_ptr2len_check(curBuff+nbytes);
+#else
+ c = curBuff[nbytes];
+ if (c)
+ nbytes++;
+#endif
+ return c;
+}
+
+int
+canna_vgetc()
+{
+ int c, c2, length;
+
+ if (canna_enable == FALSE)
+ return 0;
+
+ c = canna_fetch();
+ if (c)
+ return c;
+
+ canna_getxy(&orig_x, &orig_y);
+
+ curBuff[0] = '\0';
+ nbytes = 0;
+ length = 0;
+ ksv.ks = &ks;
+ ksv.buffer = curBuff;
+ ksv.bytes_buffer = BUFSIZ;
+
+ while (1)
+ {
+ int idx;
+ c = c2 = vgetc();
+ if (ex_normal_busy || KeyStuffed)
+ return c;
+ if (c == 0)
+ continue;
+
+ for (idx = 0; canna_keytable[idx].vimkey; idx++)
+ {
+ if (canna_keytable[idx].vimkey == c)
+ {
+ c = canna_keytable[idx].cannakey;
+ break;
+ }
+ }
+
+ nbytes = jrKanjiString(0, c, (char*)curBuff, BUFSIZ, &ks);
+ canna_save_echoback();
+ if (!(State & CMDLINE))
+ redraw_cmdline = TRUE;
+
+ if (ks.info & KanjiThroughInfo)
+ {
+ curBuff[0] = '\0';
+ nbytes = 0;
+ return c2;
+ }
+
+ got_int = FALSE;
+
+ if (nbytes > 0)
+ {
+ curBuff[nbytes] = '\0';
+ canna_kakutei(curBuff);
+ nbytes = 0;
+ length = 0;
+ redraw_later(NOT_VALID);
+ break;
+ }
+
+ if (nbytes < 0)
+ {
+ jrKanjiControl(0, KC_KILL, (char*) &ksv);
+ canna_save_echoback();
+ curBuff[0] = '\0';
+ length = 0;
+ redraw_later(NOT_VALID);
+ continue;
+ }
+
+ if (ks.length == 0)
+ {
+ update_screen(NOT_VALID);
+ if (State & CMDLINE)
+ redrawcmd();
+ windgoto(orig_y, orig_x);
+ length = 0;
+ }
+ else
+ {
+ int newlen;
+ int x, y, xx, yy;
+ int i;
+ showmode();
+ x = orig_x;
+ y = orig_y;
+ newlen = canna_echoback(&curEcho, &x, &y, HL_UNDERLINE);
+ xx = x;
+ yy = y;
+ for (i = newlen; i < length; i++)
+ canna_puts(" ", &xx, &yy, HL_NORMAL);
+ length = newlen;
+ windgoto(y, x);
+ }
+ }
+ return canna_fetch();
+}
+
+int
+canna_redraw(void)
+{
+ jrKanjiControl(0, KC_SETWIDTH, (char*) Columns-8);
+ jrKanjiControl(0, KC_KILL, (char*) &ksv);
+ canna_save_echoback();
+ return TRUE;
+}
+
+char_u*
+canna_imopts(char_u *opts)
+{
+ char_u *errmsg = NULL;
+ char_u *org, *ptr;
+ char_u *name, *val = NULL; /* for gcc */
+ vim_free(server);
+ vim_free(initfile);
+ server = NULL;
+ initfile = NULL;
+ org = ptr = strdup(opts);
+ while(*ptr)
+ {
+ name = ptr;
+ while(*ptr != ':' && *ptr != ',' && *ptr != '\0')
+ ptr++;
+ switch(*ptr)
+ {
+ case ',':
+ *ptr++ = 0;
+ name = NULL;
+ val = NULL;
+ continue;
+ break;
+ case ':':
+ *ptr++ = 0;
+ val = ptr;
+ while(*ptr != ',' && *ptr != '\0')
+ ptr++;
+ if (*ptr != '\0')
+ *ptr++ = 0;
+ }
+ if (!STRICMP(name, "serv"))
+ server = vim_strsave(val);
+ else if (!STRICMP(name, "ini"))
+ initfile = vim_strsave(val);
+ else
+ errmsg = (char_u *)_("illegal imoptions");
+ }
+ vim_free(org);
+ return errmsg;
+}
+
+int
+canna_showmode(void)
+{
+ char_u *p;
+ if (!canna_get_active())
+ return FALSE;
+ p = canna_conv_alloc(curMode);
+ canna_puts(p, &msg_col, &msg_row, HL_NORMAL);
+ canna_conv_free(p);
+ if (curGLine.echoStr)
+ canna_echoback(&curGLine, &msg_col, &msg_row, HL_NORMAL);
+ return TRUE;
+}
+#endif /* FEAT_CANNA */
diff -Nru src.org/config.h.in src/config.h.in
--- src.org/config.h.in 2004-04-26 01:59:51.000000000 +0900
+++ src/config.h.in 2005-02-08 10:56:09.000000000 +0900
@@ -359,3 +359,15 @@
/* Define if vsnprintf() works */
#undef HAVE_VSNPRINTF
+
+/* Define if use im_custom */
+# undef FEAT_IM_CUSTOM
+
+/* Define if use canna */
+#undef FEAT_CANNA
+
+/* Define if use skk */
+# undef FEAT_SKK
+
+/* Define if use pobox */
+# undef FEAT_POBOX
diff -Nru src.org/configure.in src/configure.in
--- src.org/configure.in 2004-05-08 09:02:49.000000000 +0900
+++ src/configure.in 2005-02-08 10:56:09.000000000 +0900
@@ -2654,6 +2654,35 @@
fi
+AC_ARG_ENABLE(canna,
+ [ --enable-canna Include canna support. [default=yes]], ,
+ [enable_canna="yes"])
+ if test "$enable_canna" = "yes"; then
+ AC_CHECK_LIB(canna, jrKanjiControl, libcanna="yes")
+ if test "$libcanna" = "yes"; then
+ imcustom=yes
+ AC_DEFINE(FEAT_CANNA)
+ LIBS="$LIBS -lcanna"
+ fi
+ fi
+AC_ARG_ENABLE(skk,
+ [ --enable-skk Include skk support. [default=yes]], ,
+ [enable_skk="yes"])
+ if test "$enable_skk" = "yes"; then
+ imcustom=yes
+ AC_DEFINE(FEAT_SKK)
+ fi
+AC_ARG_ENABLE(pobox,
+ [ --enable-pobox Include pobox support. [default=yes]], ,
+ [enable_pobox="yes"])
+ if test "$enable_pobox" = "yes"; then
+ imcustom=yes
+ AC_DEFINE(FEAT_POBOX)
+ fi
+if test "$imcustom" = "yes"; then
+ AC_DEFINE(FEAT_IM_CUSTOM)
+fi
+
dnl write output files
AC_OUTPUT(auto/config.mk:config.mk.in)
diff -Nru src.org/eval.c src/eval.c
--- src.org/eval.c 2004-07-29 23:41:31.000000000 +0900
+++ src/eval.c 2005-02-08 10:56:09.000000000 +0900
@@ -4874,6 +4874,18 @@
#if defined(HAVE_ICONV_H) && defined(USE_ICONV)
"iconv",
#endif
+#if defined(FEAT_IM_CUSTOM)
+ "im_custom",
+# if defined(FEAT_CANNA)
+ "im_custom/canna",
+# endif
+# if defined(FEAT_SKK)
+ "im_custom/skk",
+# endif
+# if defined(FEAT_POBOX)
+ "im_custom/pobox",
+# endif
+#endif
#ifdef FEAT_INS_EXPAND
"insert_expand",
#endif
diff -Nru src.org/getchar.c src/getchar.c
--- src.org/getchar.c 2004-09-05 03:16:42.000000000 +0900
+++ src/getchar.c 2005-02-08 10:56:09.000000000 +0900
@@ -1600,7 +1600,16 @@
{
int c;
- c = vgetc();
+#ifdef FEAT_IM_CUSTOM
+ if (im_custom_enabled && im_custom_enabled(FALSE)
+#ifdef FEAT_EX_EXTRA
+ && !ex_normal_busy
+#endif
+ )
+ c = im_custom_vgetc();
+ else
+#endif
+ c = vgetc();
if (c == NUL)
c = get_keystroke();
return c;
diff -Nru src.org/globals.h src/globals.h
--- src.org/globals.h 2004-06-29 00:50:24.000000000 +0900
+++ src/globals.h 2005-02-08 10:56:09.000000000 +0900
@@ -1379,3 +1379,15 @@
#ifdef FEAT_ARABIC
# include "arabic.h"
#endif
+
+#ifdef FEAT_IM_CUSTOM
+EXTERN int (*im_custom_vgetc)(void) INIT(=NULL);
+EXTERN int (*im_custom_enabled)(int) INIT(=NULL);
+EXTERN int (*im_custom_end)(void) INIT(=NULL);
+EXTERN char_u* (*im_custom_imopts)(char_u *) INIT(=NULL);
+EXTERN int (*im_custom_get_active)(void) INIT(=NULL);
+EXTERN int (*im_custom_set_active)(int) INIT(=NULL);
+EXTERN int (*im_custom_redraw)(void) INIT(=NULL);
+EXTERN int (*im_custom_showmode)(void) INIT(=NULL);
+#endif
+
diff -Nru src.org/gui_w32.c src/gui_w32.c
--- src.org/gui_w32.c 2004-05-29 15:23:32.000000000 +0900
+++ src/gui_w32.c 2005-02-08 10:56:09.000000000 +0900
@@ -1624,6 +1624,13 @@
HIMC hImc;
static HIMC hImcOld = (HIMC)0;
+#ifdef FEAT_IM_CUSTOM
+ if (im_custom_set_active)
+ {
+ im_custom_set_active(active);
+ return;
+ }
+#endif
if (pImmGetContext) /* if NULL imm32.dll wasn't loaded (yet) */
{
if (p_imdisable)
@@ -1660,6 +1667,11 @@
int status = 0;
HIMC hImc;
+#ifdef FEAT_IM_CUSTOM
+ if (im_custom_get_active)
+ return im_custom_get_active();
+#endif
+
if (pImmGetContext && (hImc = pImmGetContext(s_hwnd)) != (HIMC)0)
{
status = pImmGetOpenStatus(hImc) ? 1 : 0;
diff -Nru src.org/main.c src/main.c
--- src.org/main.c 2004-12-24 01:20:24.000000000 +0900
+++ src/main.c 2005-02-08 10:56:09.000000000 +0900
@@ -2298,6 +2298,10 @@
#ifdef FEAT_PERL
perl_end();
#endif
+#if defined(FEAT_IM_CUSTOM)
+ if (im_custom_end)
+ im_custom_end();
+#endif
#if defined(USE_ICONV) && defined(DYNAMIC_ICONV)
iconv_end();
#endif
diff -Nru src.org/mbyte.c src/mbyte.c
--- src.org/mbyte.c 2004-10-08 12:28:34.000000000 +0900
+++ src/mbyte.c 2005-02-08 10:56:09.000000000 +0900
@@ -603,7 +603,10 @@
/* enc_dbcs is set by setting 'fileencoding'. It becomes a Windows
* CodePage identifier, which we can pass directly in to Windows
* API */
- n = IsDBCSLeadByteEx(enc_dbcs, (BYTE)i) ? 2 : 1;
+ if (enc_dbcs == DBCS_JPNU)
+ n = (i & 0x80) ? 2 : 1;
+ else
+ n = IsDBCSLeadByteEx(enc_dbcs, (BYTE)i) ? 2 : 1;
#else
# ifdef MACOS
/*
@@ -3172,6 +3175,13 @@
{
int was_active;
+#ifdef FEAT_IM_CUSTOM
+ if (im_custom_set_active)
+ {
+ im_custom_set_active(active);
+ return;
+ }
+#endif
was_active = !!im_is_active;
im_is_active = (active && !p_imdisable);
@@ -3975,6 +3985,10 @@
int
im_get_status(void)
{
+#ifdef FEAT_IM_CUSTOM
+ if (im_custom_get_active)
+ return im_custom_get_active();
+#endif
return im_is_active;
}
@@ -4136,6 +4150,13 @@
im_set_active(active)
int active;
{
+#ifdef FEAT_IM_CUSTOM
+ if (im_custom_set_active)
+ {
+ im_custom_set_active(active);
+ return;
+ }
+#endif
if (xic == NULL)
return;
@@ -4995,6 +5016,7 @@
str[2] = 'b';
while (n-- > 0)
add_to_input_buf(str, 3);
+
}
static GSList *key_press_event_queue = NULL;
@@ -5385,7 +5407,7 @@
return gui.char_height;
#endif
return 0;
-}
+}
/*
* Get IM status. When IM is on, return TRUE. Else return FALSE.
@@ -5396,6 +5418,10 @@
int
im_get_status()
{
+#ifdef FEAT_IM_CUSTOM
+ if (im_custom_get_active)
+ return im_custom_get_active();
+#endif
# ifdef FEAT_GUI_GTK
if (xim_input_style & (int)GDK_IM_PREEDIT_CALLBACKS)
return xim_can_preediting;
@@ -5414,6 +5440,24 @@
# endif
#endif /* FEAT_XIM */
+#if !defined(FEAT_XIM) && defined(FEAT_IM_CUSTOM)
+ int
+im_get_status(void)
+{
+ if (im_custom_get_active)
+ return im_custom_get_active();
+ return FALSE;
+}
+
+ void
+im_set_active(int active)
+{
+ if (im_custom_set_active)
+ im_custom_set_active(active);
+ return;
+}
+#endif
+
#if defined(FEAT_MBYTE) || defined(PROTO)
/*
diff -Nru src.org/option.c src/option.c
--- src.org/option.c 2004-12-17 11:28:19.000000000 +0900
+++ src/option.c 2005-02-08 10:56:09.000000000 +0900
@@ -1146,6 +1146,12 @@
{(char_u *)B_IMODE_NONE, (char_u *)0L}
#endif
},
+#ifdef FEAT_IM_CUSTOM
+ {"imoptions", "imo", P_STRING|P_VI_DEF|P_RALL|P_COMMA|P_NODUP,
+ (char_u *)&p_imoptions, PV_NONE,
+ {(char_u *)"none", (char_u *)0L}
+ },
+#endif
{"imsearch", "ims", P_NUM|P_VI_DEF,
(char_u *)&p_imsearch, PV_IMS,
#ifdef B_IMODE_IM
@@ -2447,6 +2453,9 @@
static void set_string_option __ARGS((int opt_idx, char_u *value, int opt_flags));
static char_u *did_set_string_option __ARGS((int opt_idx, char_u **varp, int new_value_alloced, char_u *oldval, char_u *errbuf, int opt_flags));
static char_u *set_chars_option __ARGS((char_u **varp));
+#ifdef FEAT_IM_CUSTOM
+static char_u *set_imoptions __ARGS((char_u **varp));
+#endif
#ifdef FEAT_CLIPBOARD
static char_u *check_clipboard_option __ARGS((void));
#endif
@@ -2748,6 +2757,10 @@
set_option_value((char_u *)"tbidi", 1L, NULL, 0);
#endif
+#ifdef FEAT_IM_CUSTOM
+ (void)set_imoptions(&p_imoptions);
+#endif
+
#if defined(FEAT_WINDOWS) || defined(FEAT_FOLDING)
/* Parse default for 'fillchars'. */
(void)set_chars_option(&p_fcs);
@@ -5049,6 +5062,14 @@
}
#endif
+#ifdef FEAT_IM_CUSTOM
+ /* 'imoptions' */
+ else if (varp == &p_imoptions)
+ {
+ errmsg = set_imoptions(&p_imoptions);
+ }
+#endif
+
/* 'listchars' */
else if (varp == &p_lcs)
{
@@ -5785,6 +5806,92 @@
return errmsg;
}
+#ifdef FEAT_IM_CUSTOM
+static char_u *
+set_imoptions(varp)
+ char_u **varp;
+{
+ char_u *p, *errmsg = NULL, *settings = NULL;
+ p = *varp;
+
+ if (im_custom_end)
+ im_custom_end();
+
+ if (!p || !STRICMP(p, "none"))
+ {
+ im_custom_vgetc = NULL;
+ im_custom_enabled = NULL;
+ im_custom_end = NULL;
+ im_custom_imopts = NULL;
+ im_custom_set_active = NULL;
+ im_custom_get_active = NULL;
+ im_custom_redraw = NULL;
+ im_custom_showmode = NULL;
+ errmsg = NULL;
+ }
+#ifdef FEAT_CANNA
+ else
+ if (!STRNICMP(p, "canna",5) && (*(p+5) == ',' || *(p+5) == NUL))
+ {
+ im_custom_vgetc = canna_vgetc;
+ im_custom_enabled = canna_enabled;
+ im_custom_end = canna_end;
+ im_custom_imopts = canna_imopts;
+ im_custom_set_active = canna_set_active;
+ im_custom_get_active = canna_get_active;
+ im_custom_redraw = canna_redraw;
+ im_custom_showmode = canna_showmode;
+ settings = p+5;
+ }
+#endif
+#ifdef FEAT_SKK
+ else
+ if (!STRNICMP(p, "skk",3) && (*(p+3) == ',' || *(p+3) == NUL))
+ {
+ im_custom_vgetc = skk_vgetc;
+ im_custom_enabled = skk_enabled;
+ im_custom_end = skk_end;
+ im_custom_imopts = skk_imopts;
+ im_custom_set_active = skk_set_active;
+ im_custom_get_active = skk_get_active;
+ im_custom_redraw = skk_redraw;
+ im_custom_showmode = skk_showmode;
+ settings = p+3;
+ }
+#endif
+#ifdef FEAT_POBOX
+ else
+ if (!STRNICMP(p, "pobox",5) && (*(p+5) == ',' || *(p+5) == NUL))
+ {
+ im_custom_vgetc = pobox_vgetc;
+ im_custom_enabled = pobox_enabled;
+ im_custom_end = pobox_end;
+ im_custom_imopts = pobox_imopts;
+ im_custom_set_active = pobox_set_active;
+ im_custom_get_active = pobox_get_active;
+ im_custom_redraw = pobox_redraw;
+ im_custom_showmode = pobox_showmode;
+ settings = p+5;
+ }
+#endif
+ else
+ {
+ errmsg = (char_u *)_("illegal imoptions");
+ }
+
+ if (!errmsg && im_custom_enabled)
+ {
+ errmsg = (char_u *)im_custom_imopts(settings);
+ if (!errmsg)
+ {
+ if (im_custom_enabled(TRUE) == FALSE)
+ errmsg = (char_u *)_("can't load custom im");
+ }
+ }
+ return errmsg;
+}
+#endif
+
/*
* Handle setting 'listchars' or 'fillchars'.
* Returns error message, NULL if it's OK.
diff -Nru src.org/option.h src/option.h
--- src.org/option.h 2004-04-20 00:30:09.000000000 +0900
+++ src/option.h 2005-02-08 10:56:09.000000000 +0900
@@ -518,6 +518,9 @@
EXTERN int p_imcmdline; /* 'imcmdline' */
EXTERN int p_imdisable; /* 'imdisable' */
#endif
+#ifdef FEAT_IM_CUSTOM
+EXTERN char_u *p_imoptions; /* 'imoptions' */
+#endif
EXTERN int p_is; /* 'incsearch' */
EXTERN int p_im; /* 'insertmode' */
EXTERN char_u *p_isf; /* 'isfname' */
diff -Nru src.org/pobox.c src/pobox.c
--- src.org/pobox.c 1970-01-01 09:00:00.000000000 +0900
+++ src/pobox.c 2005-02-08 10:56:09.000000000 +0900
@@ -0,0 +1,731 @@
+#include "vim.h"
+
+#ifdef FEAT_POBOX
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#ifdef WIN32
+#include <winsock.h>
+#include <io.h>
+#else
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#define closesocket(s) close(s)
+#endif
+
+#ifdef BCOPY
+#define bincopy(a,b,n) bcopy(a,b,n)
+#define fillzero(a,n) bzero(a,n)
+#else
+#define bincopy(a,b,n) memcpy(b,a,n)
+#define fillzero(a,n) memset(a,0,n)
+#endif
+
+#define iseuckanji(c) (0xa1 <= c && c <= 0xfe)
+
+static char_u *svr_name = NULL;
+static unsigned short svr_port = 1178;
+static char_u *old_enc = NULL;
+
+#define MAXCANDS 50
+#ifdef WIN32
+static int win32poboxfd = -1;
+#endif
+static int poboxfd = -1;
+static char_u curBuff[50];
+static char_u inpBuff[50];
+static char_u cands[MAXCANDS][100];
+static int ncands = 0;
+static int candindex = 0;
+static int exact = 0;
+
+static int maybe_skk = FALSE;
+static int nbytes = 0;
+static int pobox_enable = FALSE;
+static int pobox_active = FALSE;
+static int orig_x, orig_y;
+static int activate_key = 28;
+
+static int length = 0;
+int pobox_enabled(int verborse);
+
+#ifdef USE_ICONV
+static vimconv_T pobox_convt;
+#endif
+
+int
+pobox_set_active(int act)
+{
+ if (act)
+ pobox_enabled(TRUE);
+ if (pobox_enable)
+ pobox_active = act;
+ return TRUE;
+}
+
+int
+pobox_get_active()
+{
+ return pobox_active;
+}
+
+static int
+pobox_puts(char *src, int *x, int *y, int attr)
+{
+ int len = 1;
+ int all_cells = 0;
+ char_u *ptr;
+#ifdef FEAT_MBYTE
+ char_u cell[MB_MAXBYTES];
+#else
+ char_u cell[2];
+#endif
+
+ for(ptr = src; *ptr; ptr+=len)
+ {
+ int cells = 0;
+ int diffs = 0;
+#ifdef FEAT_MBYTE
+ cells = mb_ptr2cells(ptr);
+#else
+ cells = ptr2cells(ptr);
+#endif
+
+#ifdef FEAT_MBYTE
+ len = mb_ptr2len_check(ptr);
+#else
+ len = 1;
+#endif
+ STRNCPY(cell, ptr, len);
+ cell[len] = 0;
+ if (State & CMDLINE) {
+ diffs = *x + cells - Columns;
+ if (diffs > 0) {
+ if (diffs < cells)
+ screen_putchar('>', *y, *x, hl_attr(HLF_AT));
+ *x = 0;
+ }
+ } else {
+ diffs = *x + cells - W_WINCOL(curwin) - W_WIDTH(curwin);
+ if (diffs > 0) {
+ if (diffs < cells)
+ screen_putchar('>', *y, *x, hl_attr(HLF_AT));
+ *x = W_WINCOL(curwin);
+ if (*y < W_WINROW(curwin) + curwin->w_height - 1)
+ *y += 1;
+ }
+ }
+ screen_puts(cell, *y, *x, attr);
+ *x += cells;
+ all_cells += cells;
+ }
+ if ((State & CMDLINE) == 0) {
+ if (*x == W_WINCOL(curwin) + W_WIDTH(curwin)) {
+ *x = W_WINCOL(curwin);
+ if (*y < W_WINROW(curwin) + curwin->w_height - 1)
+ *y += 1;
+ windgoto(*y, *x);
+ }
+ }
+ return all_cells;
+}
+
+static void
+pobox_getxy(int *x, int *y)
+{
+ if (State & CMDLINE) {
+ *x = msg_col;
+ *y = msg_row;
+ } else {
+ *x = W_WINCOL(curwin) + curwin->w_wcol;
+ *y = W_WINROW(curwin) + curwin->w_wrow;
+ }
+
+}
+
+static void
+pobox_conv_free(char_u* src)
+{
+#ifdef FEAT_MBYTE
+#ifdef USE_ICONV
+ vim_free(src);
+#else
+ if (enc_dbcs == DBCS_JPNU)
+ return;
+ vim_free(src);
+#endif
+#else
+ return;
+#endif
+}
+
+static char_u*
+pobox_conv_alloc(char_u* src)
+{
+ char_u *ret;
+#ifdef FEAT_MBYTE
+
+#ifdef USE_ICONV
+ ret = string_convert(&pobox_convt, (char_u*)src, NULL);
+ if (!ret)
+ ret = strdup(src);
+#else
+ char_u c1, c2;
+ char_u *dst;
+ ret = dst = strdup(src);
+ switch(enc_dbcs)
+ {
+ case DBCS_JPNU:
+ break;
+ case DBCS_JPN:
+ while(*src)
+ {
+ c1 = *src;
+ c2 = *(src+1);
+ if (c2 == 0x00 || !iseuckanji(c1))
+ *dst++ = c1;
+ else if (c1 == 0x8e) {
+ *dst++ = c2;
+ src++;
+ } else {
+ if (c1 % 2 == 0)
+ c2 -= 0x02;
+ else
+ c2 -= (c2 > 0xdf) ? 0x60 : 0x61;
+ if (c1 < 0xdf)
+ c1 = (c1 + 1) / 2 + 0x30;
+ else
+ c1 = (c1 + 1) / 2 + 0x70;
+ *dst++ = c1;
+ *dst++ = c2;
+ src++;
+ }
+ src++;
+ }
+ *dst = 0;
+ break;
+ default:
+ break;
+ }
+#endif
+#endif
+ return ret;
+}
+
+int init_socket(char *server, int port)
+{
+ int sd;
+ struct sockaddr_in sin;
+ struct hostent *hp;
+ struct in_addr hp_addr;
+
+#ifdef WIN32
+ {
+ WORD wVersionRequested;
+ WSADATA wsaData;
+ int sockopt = SO_SYNCHRONOUS_NONALERT;
+ wVersionRequested = MAKEWORD(1, 1);
+ if (WSAStartup(wVersionRequested, &wsaData) != 0) {
+ return -1;
+ }
+ /* Enable the use of sockets as filehandles */
+ setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
+ (char *)&sockopt, sizeof(sockopt));
+ }
+#endif
+ if ((hp=gethostbyname(server))==0) {
+ EMSG("Unknown host");
+ return -1;
+ }
+
+ fillzero((char *)&sin,sizeof(sin));
+ bincopy(hp->h_addr, (char *)&hp_addr, hp->h_length);
+
+ sin.sin_family = AF_INET;
+ sin.sin_addr = hp_addr;
+ sin.sin_port = htons((u_short)port);
+
+ if ((sd = socket(AF_INET,SOCK_STREAM,0)) < 0) {
+ EMSG("Invalid socket");
+ return -1;
+ }
+ if (connect(sd, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
+ EMSG("Can't connect server");
+ return -1;
+ }
+#ifdef WIN321
+ if ((poboxfd = _open_osfhandle(sd, 0)) < 0) {
+ EMSG("Can't connect server");
+ closesocket(sd);
+ return -1;
+ }
+ win32poboxfd = sd;
+#endif
+ return sd;
+}
+
+int
+pobox_enabled(int verbose)
+{
+ if (!pobox_enable) {
+ char_u **ptr = NULL;
+ if (svr_name) {
+ poboxfd = init_socket(svr_name, svr_port);
+ if (poboxfd != -1)
+ {
+ curBuff[0] = '\0';
+ inpBuff[0] = '\0';
+ nbytes = 0;
+ pobox_enable = TRUE;
+ }
+ else
+ {
+ pobox_enable = FALSE;
+ free(svr_name);
+ svr_name = NULL;
+ }
+ }
+ }
+#ifdef USE_ICONV
+ if (pobox_enable && old_enc != p_enc)
+ {
+ pobox_convt.vc_fd = (iconv_t)-1;
+ convert_setup(&pobox_convt, "euc-jp", p_enc);
+ }
+#endif
+ return pobox_enable;
+}
+
+int
+pobox_end()
+{
+ if (pobox_enable) {
+ closesocket(poboxfd);
+ poboxfd = -1;
+#ifdef WIN32
+ closesocket(win32poboxfd);
+ win32poboxfd = -1;
+ WSACleanup();
+#endif
+ if (svr_name)
+ vim_free(svr_name);
+ svr_name = NULL;
+ }
+ pobox_enable = FALSE;
+ return TRUE;
+}
+
+static void
+pobox_kakutei(char_u* p)
+{
+ char_u *dst;
+ dst = pobox_conv_alloc(p);
+ strcpy(curBuff, dst);
+ pobox_conv_free(dst);
+}
+
+static int
+pobox_henkan(char_u* p, int len)
+{
+ char_u *dst, *cpy;
+ int x, y, cells = 0;
+ static char_u *mark_list[] = {
+ "\xa2\xa6", "\xa2\xa7",
+ };
+
+ pobox_getxy(&x, &y);
+
+ cpy = strdup(p);
+ cpy[len] = 0;
+ dst = pobox_conv_alloc(cpy);
+ cells += pobox_puts(dst, &x, &y, HL_UNDERLINE);
+ pobox_conv_free(dst);
+ vim_free(cpy);
+
+ return cells;
+}
+
+static void
+pobox_delhenkan(int len)
+{
+ if (len > 0) {
+ int x, y;
+ char_u *ptr;
+
+ x = orig_x;
+ y = orig_y;
+ ptr = malloc(len+1);
+ memset(ptr, ' ', len);
+ ptr[len] = 0;
+ pobox_puts(ptr, &x, &y, HL_NORMAL);
+ vim_free(ptr);
+ }
+ windgoto(orig_y, orig_x);
+}
+
+static void
+pobox_gline(int pos)
+{
+ char_u *dst;
+ int n, lastn;
+ int x, y;
+ char_u *ptr;
+ int len;
+
+ if (State & CMDLINE || State & NORMAL)
+ return;
+
+ x = 0;
+ y = Rows - 1;
+
+ dst = malloc(Columns+1);
+ memset(dst, ' ', Columns);
+ dst[Columns] = 0;
+ pobox_puts(dst, &x, &y, HL_NORMAL);
+ vim_free(dst);
+ if (pos == -2)
+ return;
+
+ len = 0;
+ lastn = 0;
+ if (pos >= 0) {
+ for(n = 0; n < ncands; n++) {
+ if (n == pos)
+ break;
+ dst = pobox_conv_alloc(cands[n]);
+ for(ptr = dst; *ptr; ptr += (*mb_ptr2len_check)(ptr))
+ len += (*mb_ptr2cells)(ptr);
+ pobox_conv_free(dst);
+ len++;
+ if (len >= Columns) {
+ lastn = n;
+ len = 0;
+ }
+ }
+ }
+
+ x = 0;
+ y = Rows - 1;
+
+ len = 0;
+ for(n = lastn; n < ncands; n++) {
+ dst = pobox_conv_alloc(cands[n]);
+ for(ptr = dst; *ptr; ptr += (*mb_ptr2len_check)(ptr))
+ len += (*mb_ptr2cells)(ptr);
+ len++;
+ if (len >= Columns) {
+ pobox_conv_free(dst);
+ break;
+ }
+ if (n == pos)
+ pobox_puts(dst, &x, &y, HL_INVERSE);
+ else
+ pobox_puts(dst, &x, &y, HL_NORMAL);
+ pobox_conv_free(dst);
+ pobox_puts(" ", &x, &y, HL_NORMAL);
+ }
+
+ windgoto(orig_y, orig_x);
+}
+
+static int
+pobox_fetch()
+{
+ int c;
+#ifdef FEAT_MBYTE
+ c = mb_ptr2char(curBuff+nbytes);
+ if (c)
+ nbytes += mb_ptr2len_check(curBuff+nbytes);
+#else
+ c = curBuff[nbytes];
+ if (c)
+ nbytes++;
+#endif
+ return c;
+}
+
+void Insert(char_u *s)
+{
+ STRCAT(inpBuff, s);
+}
+
+void SelCand()
+{
+ char buf[100];
+
+ if (maybe_skk == TRUE)
+ return;
+ if (candindex == 0)
+ return;
+ sprintf(buf,"8%d\n",candindex-1);
+ send(poboxfd,buf,STRLEN(buf),0);
+ recv(poboxfd,buf,10,0);
+}
+
+void Search()
+{
+ char_u buf[2000];
+ char_u buf2[100];
+ char_u *s,*se;
+ int bytes;
+ int len;
+
+ sprintf(buf,"1%s",inpBuff);
+ if (!exact) strcat(buf," ");
+ strcat(buf,"\n");
+ send(poboxfd,buf,strlen(buf),0);
+
+ len = 0;
+ while(bytes = recv(poboxfd,buf+len,sizeof(buf)-len,0)) {
+ if (bytes < 0) {
+ EMSG("Can't read from POBox server");
+ return;
+ }
+ if (buf[0] == '0')
+ return;
+ len += bytes;
+ if (buf[len-1] == '\n')
+ break;
+ }
+ buf[len] = '\0';
+ for(bytes = 0; nbytes < len; bytes++)
+ {
+ if (buf[bytes] == '/')
+ {
+ buf[bytes] = '\t';
+ maybe_skk = TRUE;
+ }
+ else
+ if (buf[bytes] == '\n')
+ {
+ buf[bytes] = '\0';
+ break;
+ }
+ }
+
+ if (buf[1] == '\t')
+ s = buf + 2;
+ else
+ s = buf + 1;
+ for(ncands=0; *s && *s != '\n' && ncands < MAXCANDS; ncands++) {
+ for(se = s; *se && *se != '\t'; se++);
+ if (se-s > sizeof(buf2))
+ se = s + sizeof(buf2) - 1;
+ STRNCPY(buf2,s,se-s);
+ buf2[se-s] = '\0';
+ STRCPY(cands[ncands], buf2);
+ if (*se == '\t')
+ s = se+1;
+ else
+ s = se;
+ }
+}
+
+int
+pobox_vgetc()
+{
+ int c;
+ int candindex = 0;
+ int prevpos = 0;
+
+ if (pobox_enable == FALSE)
+ return 0;
+
+ c = pobox_fetch();
+ if (c)
+ return c;
+
+ pobox_getxy(&orig_x, &orig_y);
+
+ curBuff[0] = '\0';
+ inpBuff[0] = '\0';
+ length = 0;
+ nbytes = 0;
+
+ while (1)
+ {
+ c = vgetc();
+ if (ex_normal_busy || KeyStuffed)
+ return c;
+ if (c == 0)
+ continue;
+
+ if (pobox_active)
+ {
+ if (c == activate_key || c == ESC)
+ {
+ memset(inpBuff, 0, sizeof(inpBuff));
+ curBuff[0] = '\0';
+ inpBuff[0] = '\0';
+ nbytes = 0;
+ redraw_later(NOT_VALID);
+ windgoto(orig_y, orig_x);
+ pobox_active = FALSE;
+ if (c == ESC)
+ return c;
+ else
+ return '\0';
+ }
+ }
+ else
+ {
+ if (c == activate_key)
+ {
+ pobox_active = TRUE;
+ continue;
+ }
+ else
+ return c;
+ }
+ got_int = FALSE;
+
+ pobox_delhenkan(length);
+
+ if (c == activate_key || c == ESC) {
+ }
+
+ switch(c)
+ {
+ case '\b':
+ case K_BS:
+ case K_DEL:
+ if (candindex > 0)
+ candindex--;
+ else if (nbytes == 0)
+ return c;
+ else if (nbytes > 0) {
+ inpBuff[--nbytes] = '\0';
+ if (nbytes > 0)
+ Search();
+ }
+ break;
+ case '\t':
+ case ' ':
+ if (nbytes > 0)
+ candindex = (candindex % ncands) + 1;
+ else {
+ nbytes = 0;
+ ncands = 0;
+ candindex = 0;
+ exact = 0;
+ return ' ';
+ }
+ break;
+ case '\n':
+ case '\r':
+ if (candindex > 0) {
+ pobox_kakutei(cands[candindex-1]);
+ SelCand();
+ nbytes = 0;
+ ncands = 0;
+ candindex = 0;
+ exact = 0;
+ } else if (nbytes == 0) {
+ inpBuff[0] = '\0';
+ nbytes = 0;
+ ncands = 0;
+ candindex = 0;
+ exact = 0;
+ return c;
+ } else {
+ candindex = 1;
+ pobox_kakutei(cands[candindex-1]);
+ SelCand();
+ nbytes = 0;
+ ncands = 0;
+ candindex = 0;
+ exact = 0;
+ }
+ nbytes = 0;
+ pobox_gline(-2);
+ return pobox_fetch();
+ break;
+ default:
+ if (isupper(c))
+ c = tolower(c);
+ if (nbytes < sizeof(inpBuff)-1)
+ {
+ inpBuff[nbytes++] = c;
+ inpBuff[nbytes] = '\0';
+ }
+ candindex = 0;
+ exact = 1;
+ Search();
+ break;
+ }
+ pobox_gline(candindex-1);
+ if (candindex > 0)
+ length = pobox_henkan(cands[candindex-1], STRLEN(cands[candindex-1]));
+ else
+ length = pobox_henkan(inpBuff, STRLEN(inpBuff));
+ }
+
+ return pobox_fetch();
+}
+
+int
+pobox_redraw(void)
+{
+ if (pobox_get_active()) {
+ }
+ return TRUE;
+}
+
+int
+pobox_showmode()
+{
+ return FALSE;
+}
+
+char_u*
+pobox_imopts(char_u *opts)
+{
+ char_u *errmsg = NULL;
+ char_u *org, *ptr;
+ char_u *name, *val;
+ org = ptr = strdup(opts);
+ svr_name = NULL;
+ while(*ptr)
+ {
+ name = ptr;
+ while(*ptr != ':' && *ptr != ',' && *ptr != '\0')
+ ptr++;
+ switch(*ptr)
+ {
+ case ',':
+ *ptr++ = 0;
+ name = NULL;
+ val = NULL;
+ continue;
+ break;
+ case ':':
+ *ptr++ = 0;
+ val = ptr;
+ while(*ptr != ',' && *ptr != '\0')
+ ptr++;
+ if (*ptr != '\0')
+ *ptr++ = 0;
+ break;
+ }
+ if (!STRICMP(name, "serv")) {
+ if (svr_name)
+ vim_free(svr_name);
+ svr_name = strdup(val);
+ }
+ else if (!STRICMP(name, "port")) {
+ svr_port = (unsigned short)atoi((char*)val);
+ }
+ else if (!STRICMP(name, "key"))
+ activate_key = atol(val);
+ else
+ errmsg = (char_u *)_("illegal imoptions");
+ }
+ if (!svr_name)
+ errmsg = (char_u *)_("Didn't set server name");
+ vim_free(org);
+ return errmsg;
+}
+#endif /* FEAT_POBOX */
diff -Nru src.org/proto/canna.pro src/proto/canna.pro
--- src.org/proto/canna.pro 1970-01-01 09:00:00.000000000 +0900
+++ src/proto/canna.pro 2005-02-08 10:56:09.000000000 +0900
@@ -0,0 +1,10 @@
+/* canna.c */
+int canna_enabled __ARGS((int verbose));
+int canna_end __ARGS((void));
+int canna_set_active __ARGS((int act));
+int canna_get_active __ARGS((void));
+int canna_vgetc __ARGS((void));
+char_u* canna_imopts __ARGS((char_u* opts));
+int canna_redraw __ARGS((void));
+int canna_showmode __ARGS((void));
+/* vim: set ft=c : */
diff -Nru src.org/proto/pobox.pro src/proto/pobox.pro
--- src.org/proto/pobox.pro 1970-01-01 09:00:00.000000000 +0900
+++ src/proto/pobox.pro 2005-02-08 10:56:09.000000000 +0900
@@ -0,0 +1,10 @@
+/* pobox.c */
+int pobox_enabled __ARGS((int verbose));
+int pobox_end __ARGS((void));
+int pobox_set_active __ARGS((int act));
+int pobox_get_active __ARGS((void));
+int pobox_vgetc __ARGS((void));
+char_u* pobox_imopts __ARGS((char_u* opts));
+int pobox_redraw __ARGS((void));
+int pobox_showmode __ARGS((void));
+/* vim: set ft=c : */
diff -Nru src.org/proto/skk.pro src/proto/skk.pro
--- src.org/proto/skk.pro 1970-01-01 09:00:00.000000000 +0900
+++ src/proto/skk.pro 2005-02-08 10:56:09.000000000 +0900
@@ -0,0 +1,10 @@
+/* skk.c */
+int skk_enabled __ARGS((int verbose));
+int skk_end __ARGS((void));
+int skk_set_active __ARGS((int act));
+int skk_get_active __ARGS((void));
+int skk_vgetc __ARGS((void));
+char_u* skk_imopts __ARGS((char_u* opts));
+int skk_redraw __ARGS((void));
+int skk_showmode __ARGS((void));
+/* vim: set ft=c : */
diff -Nru src.org/proto.h src/proto.h
--- src.org/proto.h 2004-05-08 09:03:11.000000000 +0900
+++ src/proto.h 2005-02-08 10:56:09.000000000 +0900
@@ -244,6 +244,15 @@
# endif
# include "if_perlsfio.pro"
#endif
+#if defined(FEAT_CANNA)
+# include "canna.pro"
+#endif
+#if defined(FEAT_SKK)
+# include "skk.pro"
+#endif
+#if defined(FEAT_POBOX)
+# include "pobox.pro"
+#endif
#ifdef __BORLANDC__
# define _PROTO_H
diff -Nru src.org/screen.c src/screen.c
--- src.org/screen.c 2005-01-30 00:59:21.000000000 +0900
+++ src/screen.c 2005-02-08 10:56:09.000000000 +0900
@@ -7919,6 +7919,9 @@
#ifdef FEAT_INS_EXPAND
int sub_attr;
#endif
+#ifdef FEAT_IM_CUSTOM
+ int nomore = FALSE;
+#endif
do_mode = (p_smd && ((State & INSERT) || restart_edit
#ifdef FEAT_VISUAL
@@ -7951,8 +7954,22 @@
/* Position on the last line in the window, column 0 */
msg_pos_mode();
cursor_off();
+#ifdef FEAT_IM_CUSTOM
+ if (do_mode && im_custom_showmode)
+ {
+ if (im_custom_showmode())
+ {
+ nomore = TRUE;
+ need_clear = TRUE;
+ }
+ }
+#endif
attr = hl_attr(HLF_CM); /* Highlight mode */
- if (do_mode)
+ if (do_mode
+#ifdef FEAT_IM_CUSTOM
+ && !nomore
+#endif
+ )
{
MSG_PUTS_ATTR("--", attr);
#if defined(FEAT_XIM)
@@ -8076,6 +8093,9 @@
#ifdef FEAT_INS_EXPAND
&& edit_submode == NULL /* otherwise it gets too long */
#endif
+#ifdef FEAT_IM_CUSTOM
+ && !nomore
+#endif
)
{
MSG_PUTS_ATTR(_("recording"), attr);
@@ -8106,7 +8126,10 @@
&& lastwin->w_status_height == 0
# endif
)
- win_redr_ruler(lastwin, TRUE);
+# ifdef FEAT_IM_CUSTOM
+ if (!nomore)
+# endif
+ win_redr_ruler(lastwin, TRUE);
#endif
redraw_cmdline = FALSE;
clear_cmdline = FALSE;
diff -Nru src.org/skk.c src/skk.c
--- src.org/skk.c 1970-01-01 09:00:00.000000000 +0900
+++ src/skk.c 2005-02-09 18:54:49.082908528 +0900
@@ -0,0 +1,1875 @@
+#include "vim.h"
+
+#ifdef FEAT_SKK
+#define USE_SERVER
+#include "skklib.c"
+
+#define SKK_INPUT_HALP 0
+#define SKK_INPUT_HIRA 1
+#define SKK_INPUT_KATA 2
+#define SKK_INPUT_ZALP 3
+#define SKK_RET_UNK 0
+#define SKK_RET_FND 1
+#define SKK_RET_OKR 2
+#define SKK_DIC_USR 0
+#define SKK_DIC_MST 1
+#define SKK_DIC_SVR 2
+#define iseuckanji(c) (0xa1 <= c && c <= 0xfe)
+
+static Dictionary dic_usr = NULL;
+static Dictionary dic_mst = NULL;
+static char_u *usr_dic_path = NULL;
+static char_u *mst_dic_path = NULL;
+static char_u *svr_dic_host = NULL;
+static unsigned short svr_dic_port = SKK_PORT_NUMBER;
+static char_u *old_enc = NULL;
+static char_u curBuff[256];
+static char_u inpBuff[128];
+static int input_mode = SKK_INPUT_HALP;
+static char_u *regs_key = NULL;
+static char_u *regs_str = NULL;
+static int nfetch = 0;
+static int preedit = 0;
+static int skk_enable = FALSE;
+static int skk_active = FALSE;
+static int orig_x, orig_y;
+static int dic_from = SKK_DIC_USR;
+int skk_enabled(int verborse);
+#ifdef USE_SERVER
+static int has_server = FALSE;
+#endif
+
+#ifdef USE_ICONV
+static vimconv_T skk_convt;
+#endif
+
+struct iroha_struct {
+ char *key;
+ char *str;
+} iroha_table[] = {
+ /* ん行 */
+ {"n","\xa4\xf3"}, /* ん */
+ /* あ行 */
+ {"a","\xa4\xa2"}, /* あ */
+ {"i","\xa4\xa4"}, /* い */
+ {"u","\xa4\xa6"}, /* う */
+ {"e","\xa4\xa8"}, /* え */
+ {"o","\xa4\xaa"}, /* お */
+ {"xa","\xa4\xa1"}, /* ぁ */
+ {"xi","\xa4\xa3"}, /* ぃ */
+ {"xu","\xa4\xa5"}, /* ぅ */
+ {"xe","\xa4\xa7"}, /* ぇ */
+ {"xo","\xa4\xa9"}, /* ぉ */
+ /* か行 */
+ {"ka","\xa4\xab"}, /* か */
+ {"ki","\xa4\xad"}, /* き */
+ {"ku","\xa4\xaf"}, /* く */
+ {"ke","\xa4\xb1"}, /* け */
+ {"ko","\xa4\xb3"}, /* こ */
+ {"ca","\xa4\xab"}, /* か */
+ {"cu","\xa4\xaf"}, /* く */
+ {"co","\xa4\xb3"}, /* こ */
+ {"kya","\xa4\xad\xa4\xe3"}, /* きゃ */
+ {"kyi","\xa4\xad\xa4\xa3"}, /* きぃ */
+ {"kyu","\xa4\xad\xa4\xe5"}, /* きゅ */
+ {"kye","\xa4\xad\xa4\xa7"}, /* きぇ */
+ {"kyo","\xa4\xad\xa4\xe7"}, /* きょ */
+ {"ga","\xa4\xac"}, /* が */
+ {"gi","\xa4\xae"}, /* ぎ */
+ {"gu","\xa4\xb0"}, /* ぐ */
+ {"ge","\xa4\xb2"}, /* げ */
+ {"go","\xa4\xb4"}, /* ご */
+ {"gya","\xa4\xae\xa4\xe3"}, /* ぎゃ */
+ {"gyi","\xa4\xae\xa4\xa3"}, /* ぎぃ */
+ {"gyu","\xa4\xae\xa4\xe5"}, /* ぎゅ */
+ {"gye","\xa4\xae\xa4\xa7"}, /* ぎぇ */
+ {"gyo","\xa4\xae\xa4\xe7"}, /* ぎょ */
+ /* さ行 */
+ {"sa","\xa4\xb5"}, /* さ */
+ {"si","\xa4\xb7"}, /* し */
+ {"su","\xa4\xb9"}, /* す */
+ {"se","\xa4\xbb"}, /* せ */
+ {"so","\xa4\xbd"}, /* そ */
+ {"ci","\xa4\xb7"}, /* し */
+ {"ce","\xa4\xbb"}, /* せ */
+ {"sha","\xa4\xb7\xa4\xe3"}, /* しゃ */
+ {"shi","\xa4\xb7"}, /* し */
+ {"shu","\xa4\xb7\xa4\xe5"}, /* しゅ */
+ {"she","\xa4\xb7\xa4\xa7"}, /* しぇ */
+ {"sho","\xa4\xb7\xa4\xe7"}, /* しょ */
+ {"sya","\xa4\xb7\xa4\xe3"}, /* しゃ */
+ {"syi","\xa4\xb7\xa4\xa3"}, /* しぃ */
+ {"syu","\xa4\xb7\xa4\xe5"}, /* しゅ */
+ {"sye","\xa4\xb7\xa4\xa7"}, /* しぇ */
+ {"syo","\xa4\xb7\xa4\xe7"}, /* しょ */
+ {"za","\xa4\xb6"}, /* ざ */
+ {"zi","\xa4\xb8"}, /* じ */
+ {"zu","\xa4\xba"}, /* ず */
+ {"ze","\xa4\xbc"}, /* ぜ */
+ {"zo","\xa4\xbe"}, /* ぞ */
+ {"ja","\xa4\xb8\xa4\xe3"}, /* じゃ */
+ {"ji","\xa4\xb8"}, /* じ */
+ {"ju","\xa4\xb8\xa4\xe5"}, /* じゅ */
+ {"je","\xa4\xb8\xa4\xa7"}, /* じぇ */
+ {"jo","\xa4\xb8\xa4\xe7"}, /* じょ */
+ {"zya","\xa4\xb8\xa4\xe3"}, /* じゃ */
+ {"zyi","\xa4\xb8\xa4\xa3"}, /* じぃ */
+ {"zyu","\xa4\xb8\xa4\xe5"}, /* じゅ */
+ {"zye","\xa4\xb8\xa4\xa7"}, /* じぇ */
+ {"zyo","\xa4\xb8\xa4\xe7"}, /* じょ */
+ {"jya","\xa4\xb8\xa4\xe3"}, /* じゃ */
+ {"jyi","\xa4\xb8\xa4\xa3"}, /* じぃ */
+ {"jyu","\xa4\xb8\xa4\xe5"}, /* じゅ */
+ {"jye","\xa4\xb8\xa4\xa7"}, /* じぇ */
+ {"jyo","\xa4\xb8\xa4\xe7"}, /* じょ */
+ /* た行 */
+ {"ta","\xa4\xbf"}, /* た */
+ {"ti","\xa4\xc1"}, /* ち */
+ {"tu","\xa4\xc4"}, /* つ */
+ {"te","\xa4\xc6"}, /* て */
+ {"to","\xa4\xc8"}, /* と */
+ {"cha","\xa4\xc1\xa4\xe3"}, /* ちゃ */
+ {"chi","\xa4\xc1"}, /* ち */
+ {"chu","\xa4\xc1\xa4\xe5"}, /* ちゅ */
+ {"che","\xa4\xc1\xa4\xa7"}, /* ちぇ */
+ {"cho","\xa4\xc1\xa4\xe7"}, /* ちょ */
+ {"tya","\xa4\xc1\xa4\xe3"}, /* ちゃ */
+ {"tyi","\xa4\xc1\xa4\xa3"}, /* ちぃ */
+ {"tyu","\xa4\xc1\xa4\xe5"}, /* ちゅ */
+ {"tye","\xa4\xc1\xa4\xa7"}, /* ちぇ */
+ {"tyo","\xa4\xc1\xa4\xe7"}, /* ちょ */
+ {"tsa","\xa4\xc4\xa4\xa1"}, /* つぁ */
+ {"tsi","\xa4\xc4\xa4\xa3"}, /* つぃ */
+ {"tsu","\xa4\xc4"}, /* つ */
+ {"tse","\xa4\xc4\xa4\xa7"}, /* つぇ */
+ {"tso","\xa4\xc4\xa4\xa9"}, /* つぉ */
+ {"tha","\xa4\xc6\xa4\xe3"}, /* てゃ */
+ {"thi","\xa4\xc6\xa4\xa3"}, /* てぃ */
+ {"thu","\xa4\xc6\xa4\xe5"}, /* てゅ */
+ {"the","\xa4\xc6\xa4\xa7"}, /* てぇ */
+ {"tho","\xa4\xc6\xa4\xe7"}, /* てょ */
+ {"da","\xa4\xc0"}, /* だ */
+ {"di","\xa4\xc2"}, /* ぢ */
+ {"du","\xa4\xc5"}, /* づ */
+ {"de","\xa4\xc7"}, /* で */
+ {"do","\xa4\xc9"}, /* ど */
+ {"dya","\xa4\xc2\xa4\xe3"}, /* ぢゃ */
+ {"dyi","\xa4\xc2\xa4\xa3"}, /* ぢぃ */
+ {"dyu","\xa4\xc2\xa4\xe5"}, /* ぢゅ */
+ {"dye","\xa4\xc2\xa4\xa7"}, /* ぢぇ */
+ {"dyo","\xa4\xc2\xa4\xe7"}, /* ぢょ */
+ {"dha","\xa4\xc7\xa4\xe3"}, /* でゃ */
+ {"dhi","\xa4\xc7\xa4\xa3"}, /* でぃ */
+ {"dhu","\xa4\xc7\xa4\xe5"}, /* でゅ */
+ {"dhe","\xa4\xc7\xa4\xa7"}, /* でぇ */
+ {"dho","\xa4\xc7\xa4\xe7"}, /* でょ */
+ {"xtu","\xa4\xc3"}, /* っ */
+ {"xtsu","\xa4\xc3"}, /* っ */
+ /* な行 */
+ {"na","\xa4\xca"}, /* な */
+ {"ni","\xa4\xcb"}, /* に */
+ {"nu","\xa4\xcc"}, /* ぬ */
+ {"ne","\xa4\xcd"}, /* ね */
+ {"no","\xa4\xce"}, /* の */
+ {"nya","\xa4\xcb\xa4\xe3"}, /* にゃ */
+ {"nyi","\xa4\xcb\xa4\xa3"}, /* にぃ */
+ {"nyu","\xa4\xcb\xa4\xe5"}, /* にゅ */
+ {"nye","\xa4\xcb\xa4\xa7"}, /* にぇ */
+ {"nyo","\xa4\xcb\xa4\xe7"}, /* にょ */
+ /* は行 */
+ {"fa","\xa4\xd5\xa4\xa1"}, /* ふぁ */
+ {"fi","\xa4\xd5\xa4\xa3"}, /* ふぃ */
+ {"fu","\xa4\xd5"}, /* ふ */
+ {"fe","\xa4\xd5\xa4\xa7"}, /* ふぇ */
+ {"fo","\xa4\xd5\xa4\xa9"}, /* ふぉ */
+ {"ha","\xa4\xcf"}, /* は */
+ {"hi","\xa4\xd2"}, /* ひ */
+ {"hu","\xa4\xd5"}, /* ふ */
+ {"he","\xa4\xd8"}, /* へ */
+ {"ho","\xa4\xdb"}, /* ほ */
+ {"hya","\xa4\xd2\xa4\xe3"}, /* ひゃ */
+ {"hyi","\xa4\xd2\xa4\xa3"}, /* ひぃ */
+ {"hyu","\xa4\xd2\xa4\xe5"}, /* ひゅ */
+ {"hye","\xa4\xd2\xa4\xa7"}, /* ひぇ */
+ {"hyo","\xa4\xd2\xa4\xe7"}, /* ひょ */
+ {"ba","\xa4\xd0"}, /* ば */
+ {"bi","\xa4\xd3"}, /* び */
+ {"bu","\xa4\xd6"}, /* ぶ */
+ {"be","\xa4\xd9"}, /* べ */
+ {"bo","\xa4\xdc"}, /* ぼ */
+ {"bya","\xa4\xd3\xa4\xe3"}, /* びゃ */
+ {"byi","\xa4\xd3\xa4\xa3"}, /* びぃ */
+ {"byu","\xa4\xd3\xa4\xe5"}, /* びゅ */
+ {"bye","\xa4\xd3\xa4\xa7"}, /* びぇ */
+ {"byo","\xa4\xd3\xa4\xe7"}, /* びょ */
+ {"pa","\xa4\xd1"}, /* ぱ */
+ {"pi","\xa4\xd4"}, /* ぴ */
+ {"pu","\xa4\xd7"}, /* ぷ */
+ {"pe","\xa4\xda"}, /* ぺ */
+ {"po","\xa4\xdd"}, /* ぽ */
+ {"pya","\xa4\xd4\xa4\xe3"}, /* ぴゃ */
+ {"pyi","\xa4\xd4\xa4\xa3"}, /* ぴぃ */
+ {"pyu","\xa4\xd4\xa4\xe5"}, /* ぴゅ */
+ {"pye","\xa4\xd4\xa4\xa7"}, /* ぴぇ */
+ {"pyo","\xa4\xd4\xa4\xe7"}, /* ぴょ */
+ /* ま行 */
+ {"ma","\xa4\xde"}, /* ま */
+ {"mi","\xa4\xdf"}, /* み */
+ {"mu","\xa4\xe0"}, /* む */
+ {"me","\xa4\xe1"}, /* め */
+ {"mo","\xa4\xe2"}, /* も */
+ {"mya","\xa4\xdf\xa4\xe3"}, /* みゃ */
+ {"myi","\xa4\xdf\xa4\xa3"}, /* みぃ */
+ {"myu","\xa4\xdf\xa4\xe5"}, /* みゅ */
+ {"mye","\xa4\xdf\xa4\xa7"}, /* みぇ */
+ {"myo","\xa4\xdf\xa4\xe7"}, /* みょ */
+ /* や行 */
+ {"ya","\xa4\xe4"}, /* や */
+ {"yu","\xa4\xe6"}, /* ゆ */
+ {"yo","\xa4\xe8"}, /* よ */
+ {"xya","\xa4\xe3"}, /* ゃ */
+ {"xyu","\xa4\xe5"}, /* ゅ */
+ {"xyo","\xa4\xe7"}, /* ょ */
+ /* ら行 */
+ {"ra","\xa4\xe9"}, /* ら */
+ {"ri","\xa4\xea"}, /* り */
+ {"ru","\xa4\xeb"}, /* る */
+ {"re","\xa4\xec"}, /* れ */
+ {"ro","\xa4\xed"}, /* ろ */
+ {"rya","\xa4\xea\xa4\xe3"}, /* りゃ */
+ {"ryi","\xa4\xea\xa4\xa3"}, /* りぃ */
+ {"ryu","\xa4\xea\xa4\xe5"}, /* りゅ */
+ {"rye","\xa4\xea\xa4\xa7"}, /* りぇ */
+ {"ryo","\xa4\xea\xa4\xe7"}, /* りょ */
+ /* わ行 */
+ {"wa","\xa4\xef"}, /* わ */
+ {"wi","\xa4\xf0"}, /* ゐ */
+ {"wu","\xa4\xa6"}, /* う */
+ {"we","\xa4\xf1"}, /* ゑ */
+ {"wo","\xa4\xf2"}, /* を */
+ /* ヴ行 */
+ {"va","\xa5\xf4\xa4\xa1"}, /* ヴぁ */
+ {"vi","\xa5\xf4\xa4\xa3"}, /* ヴぃ */
+ {"vu","\xa5\xf4"}, /* ヴ */
+ {"ve","\xa5\xf4\xa4\xa7"}, /* ヴぇ */
+ {"vo","\xa5\xf4\xa4\xa9"}, /* ヴぉ */
+ /* ん */
+ {"nn","\xa4\xf3"}, /* ん */
+ /* 記号 */
+ {"!", "\xa1\xaa"}, /* ! */
+ {"\"","\xa1\xc9"}, /* ” */
+ {"#", "\xa1\xf4"}, /* # */
+ {"$", "\xa1\xf0"}, /* $ */
+ {"%", "\xa1\xf3"}, /* % */
+ {"&", "\xa1\xf5"}, /* & */
+ {"'", "\xa1\xc7"}, /* ’ */
+ {"(", "\xa1\xca"}, /* ( */
+ {")", "\xa1\xcb"}, /* ) */
+ {"=", "\xa1\xe1"}, /* = */
+ {"^", "\xa1\xb0"}, /* ^ */
+ {"~", "\xa1\xc1"}, /*  ̄ */
+ {"\\","\xa1\xef"}, /* ¥ */
+ {"|", "\xa1\xc3"}, /* | */
+ {"@", "\xa1\xf7"}, /* @ */
+ {"`", "\xa1\xae"}, /* ` */
+ {"{", "\xa1\xd0"}, /* { */
+ {"}", "\xa1\xd1"}, /* } */
+ {"+", "\xa1\xdc"}, /* + */
+ {"*", "\xa1\xf6"}, /* * */
+ {"/", "\xa1\xbf"}, /* / */
+ {"<", "\xa1\xe3"}, /* < */
+ {">", "\xa1\xe4"}, /* > */
+ {"?", "\xa1\xa9"}, /* ? */
+ {"_", "\xa1\xb2"}, /* _ */
+ {",", "\xa1\xa2"}, /* 、 */
+ {".", "\xa1\xa3"}, /* 。 */
+ {"-", "\xa1\xbc"}, /* ー */
+ {":", "\xa1\xa7"}, /* : */
+ {";", "\xa1\xa8"}, /* ; */
+ {"[", "\xa1\xd6"}, /* 「 */
+ {"]", "\xa1\xd7"}, /* 」 */
+ {NULL, NULL}
+};
+
+#define is_kuten(c) ((\
+ (c == ',') || (c == '.') || (c == '-') || \
+ (c == '-') || (c == ':') || (c == ';') || \
+ (c == '[') || (c == ']') || (c == '{') || (c == '}') || \
+ (c == '=') || (c == '~') || (c == '|')) ? 1 : 0)
+
+int
+skk_set_active(int act)
+{
+ if (act)
+ skk_enabled(TRUE);
+ if (skk_enable)
+ skk_active = act;
+ return TRUE;
+}
+
+int
+skk_get_active()
+{
+ return skk_active;
+}
+
+int
+skk_dicload()
+{
+ if (skk_enable)
+ {
+ static int at_first = 0;
+ if (!at_first && mst_dic_path)
+ {
+ if ((State & CMDLINE) == 0)
+ MSG("Loading Master dictionary...");
+ dic_mst = openSKK(mst_dic_path);
+ if (!dic_mst)
+ {
+ vim_free(mst_dic_path);
+ mst_dic_path = NULL;
+ }
+ at_first = 1;
+ }
+ if (!dic_usr)
+ {
+ if ((State & CMDLINE) == 0)
+ MSG("Loading User dictionary...");
+ dic_usr = openSKK(usr_dic_path);
+ at_first = 1;
+ }
+#ifdef USE_SERVER
+ if (dic_usr)
+ {
+ if (has_server == FALSE && svr_dic_host)
+ {
+ if (openSKKserv(svr_dic_host, svr_dic_port) != 0)
+ {
+ vim_free(svr_dic_host);
+ svr_dic_host = NULL;
+ if ((State & CMDLINE) == 0)
+ EMSG("Can't connect server");
+ }
+ else
+ has_server = TRUE;
+ at_first = 1;
+ }
+ }
+#endif
+ else
+ skk_enable = FALSE;
+ if (skk_enable && at_first && (State & CMDLINE) == 0)
+ MSG("Loading Done...");
+ }
+ return 0;
+}
+
+static char_u*
+skk_iroha2alpha(char_u *src)
+{
+ int idx, hit;
+ char_u *ptr;
+ char_u *str1;
+ char_u *back_pos = 0;
+ char_u buffer[256];
+ memset(buffer, 0x00, sizeof(buffer));
+ ptr = src;
+ while(*ptr)
+ {
+ hit = -1;
+ for (idx = 0; iroha_table[idx].str; idx++)
+ {
+ str1 = iroha_table[idx].str;
+ if (!STRNICMP(str1, ptr, strlen(str1)))
+ hit = idx;
+ }
+ str1 = iroha_table[hit].str;
+ if (hit >= 0)
+ {
+ strcat(buffer, iroha_table[hit].key);
+ ptr += strlen(iroha_table[hit].str);
+ }
+ else
+ {
+ char_u ch = tolower(*ptr);
+ strncat(buffer, &ch, 1);
+ ptr++;
+ }
+ }
+ if (ptr == src)
+ strcpy(buffer, ptr);
+ return strdup(buffer);
+}
+
+static char_u*
+skk_alpha2iroha(char_u *src, int flg)
+{
+ int idx, hit, dup;
+ char_u *ptr;
+ char_u *key1, *key2;
+ char_u *back_pos = 0;
+ char_u buffer[256];
+ memset(buffer, 0x00, sizeof(buffer));
+ ptr = src;
+ while(*ptr)
+ {
+ hit = -1;
+ dup = 0;
+ for (idx = 0; iroha_table[idx].key; idx++)
+ {
+ key1 = iroha_table[idx].key;
+ if (!STRNICMP(key1, ptr, strlen(key1)))
+ hit = idx;
+ }
+ key1 = iroha_table[hit].key;
+ if (hit >= 0)
+ {
+ if (!flg)
+ {
+ for (idx = 0; iroha_table[idx].key; idx++)
+ {
+ key2 = iroha_table[idx].key;
+ if (!STRNICMP(key2, ptr, strlen(ptr)))
+ {
+ dup++;
+ if (hit != idx)
+ hit = -1;
+ }
+ }
+ if (dup == 0)
+ dup = 1;
+ }
+ else
+ dup = 1;
+ }
+ //if (*ptr == '.' && input_mode == SKK_INPUT_ZALP)
+ //{
+ //strcat(buffer, "\x1a\xa5");
+ //ptr++;
+ //}
+ //else
+ if (hit >= 0 && dup == 1)
+ {
+ char_u ch = tolower(*ptr);
+ if (flg == SKK_RET_OKR
+ && !*(ptr + strlen(iroha_table[hit].key)))
+ {
+ strncat(buffer, &ch, 1);
+ break;
+ }
+ if (strlen(buffer) && buffer[strlen(buffer)-1] == *ptr)
+ {
+ buffer[strlen(buffer)-1] = 0;
+ strcat(buffer, "\xa4\xc3");
+ }
+ strcat(buffer, iroha_table[hit].str);
+ ptr += strlen(iroha_table[hit].key);
+ }
+ else
+ {
+ char_u ch = tolower(*ptr);
+ int buflen = strlen(buffer);
+ if (buflen && buffer[buflen-1] == *ptr)
+ {
+ buffer[buflen-1] = 0;
+ strcat(buffer, "\xa4\xc3");
+ }
+ strncat(buffer, &ch, 1);
+ ptr++;
+ }
+ }
+ if (ptr == src)
+ strcpy(buffer, ptr);
+ return strdup(buffer);
+}
+
+static void
+skk_regist(char_u *key, char_u *str)
+{
+ CandList fcand = (CandList)NULL;
+ CandList ncand = (CandList)NULL;
+ CandList tcand = (CandList)NULL;
+ DicList dlist;
+
+ skk_dicload();
+ if (skk_enable)
+ tcand = getCand(dic_usr,key);
+ if (tcand)
+ {
+ fcand = tcand;
+ while(tcand)
+ {
+ if (!STRICMP(str, tcand->candword))
+ {
+ selectCand(&fcand, tcand);
+ tcand->dicitem->cand = fcand;
+ MSG("Updated");
+ break;
+ }
+ tcand = tcand->nextcand;
+ }
+ if (!tcand) {
+ ncand = _NEW2(CandList,STRLEN(str));
+ ncand->okuri = NULL;
+ ncand->nextcand = fcand;
+ ncand->prevcand = NULL;
+ STRCPY(ncand->candword, str);
+ ncand->dicitem = fcand->dicitem;
+ fcand->prevcand = ncand;
+ fcand->dicitem->cand = ncand;
+ MSG("Inserted");
+ }
+ }
+ else
+ {
+ dlist = _NEW2(DicList,strlen(key));
+ dlist->nextitem = NULL;
+ STRCPY(dlist->kanaword, key);
+
+ ncand = _NEW2(CandList,STRLEN(str));
+ ncand->okuri = NULL;
+ ncand->prevcand = NULL;
+ ncand->nextcand = NULL;
+ STRCPY(ncand->candword, str);
+ dlist->cand = ncand;
+
+ addHash(dic_usr->dhash, dlist);
+ if (dic_usr->dlist)
+ dic_usr->dlist->nextitem = dlist;
+ else
+ dic_usr->dlist = dlist;
+ if (isConjugate(str, strlen(str))) {
+ if (!dic_usr->okuriAriFirst)
+ dic_usr->okuriAriFirst = dlist;
+ } else {
+ if (!dic_usr->okuriNasiFirst)
+ dic_usr->okuriNasiFirst = dlist;
+ }
+ MSG("Created New");
+ }
+}
+
+static CandList
+skk_commitcand(char_u *inp, int okuri_pos, CandList scand)
+{
+ CandList fcand = (CandList)NULL;
+ CandList ncand = (CandList)NULL;
+ CandList tcand = (CandList)NULL;
+ DicList dlist;
+ char_u *yomi;
+ char_u *iroha;
+
+ if (okuri_pos == 0)
+ yomi = iroha = skk_alpha2iroha(inp, SKK_RET_FND);
+ else
+ {
+ size_t len;
+ char_u *ptr = strdup(inp);
+ ptr[okuri_pos] = 0;
+ iroha = skk_alpha2iroha(ptr, SKK_RET_FND);
+ len = STRLEN(iroha);
+ yomi = alloc(len + 2);
+ STRCPY(yomi, iroha);
+ yomi[len] = (char_u)tolower(inp[okuri_pos]);
+ yomi[len + 1] = NUL;
+ vim_free(iroha);
+ vim_free(ptr);
+ }
+ tcand = getCand(dic_usr,yomi);
+ if (tcand)
+ {
+ fcand = tcand;
+ while(tcand)
+ {
+ if (!STRICMP(scand->candword, tcand->candword))
+ {
+ selectCand(&fcand, tcand);
+ tcand->dicitem->cand = fcand;
+ MSG("Updated");
+ break;
+ }
+ tcand = tcand->nextcand;
+ }
+ if (!tcand) {
+ ncand = _NEW2(CandList,STRLEN(scand->candword));
+ ncand->okuri = NULL;
+ ncand->nextcand = fcand;
+ ncand->prevcand = NULL;
+ STRCPY(ncand->candword, scand->candword);
+ ncand->dicitem = fcand->dicitem;
+ fcand->prevcand = ncand;
+ fcand->dicitem->cand = ncand;
+ MSG("Inserted");
+ }
+ }
+ else
+ {
+ dlist = _NEW2(DicList,strlen(yomi));
+ dlist->nextitem = NULL;
+ STRCPY(dlist->kanaword, yomi);
+
+ ncand = _NEW2(CandList,STRLEN(scand->candword));
+ ncand->okuri = NULL;
+ ncand->prevcand = NULL;
+ ncand->nextcand = NULL;
+ STRCPY(ncand->candword, scand->candword);
+ dlist->cand = ncand;
+
+ addHash(dic_usr->dhash, dlist);
+ if (dic_usr->dlist)
+ dic_usr->dlist->nextitem = dlist;
+ else
+ dic_usr->dlist = dlist;
+ if (okuri_pos) {
+ if (!dic_usr->okuriAriFirst)
+ dic_usr->okuriAriFirst = dlist;
+ } else {
+ if (!dic_usr->okuriNasiFirst)
+ dic_usr->okuriNasiFirst = dlist;
+ }
+ MSG("Created New");
+ }
+ return scand;
+}
+
+static CandList
+skk_alpha2cand(char_u *alpha, char_u ch, int *from)
+{
+ char_u *iroha;
+ char_u *yomi;
+ CandList scand = NULL;
+
+ if (ch == NUL)
+ yomi = iroha = skk_alpha2iroha(alpha, SKK_RET_FND);
+ else
+ {
+ size_t len;
+ iroha = skk_alpha2iroha(alpha, SKK_RET_FND);
+ len = STRLEN(iroha);
+ yomi = alloc(len + 2);
+ STRCPY(yomi, iroha);
+ yomi[len] = (char_u)tolower(ch);
+ yomi[len + 1] = NUL;
+ vim_free(iroha);
+ }
+
+ if (strlen(yomi) > 1)
+ {
+ skk_dicload();
+ if (skk_enable)
+ {
+ CandList ncand = NULL;
+ if (*from == SKK_DIC_USR && !scand) {
+ scand = getCand(dic_usr, yomi);
+ if (!scand) (*from)++;
+ }
+
+ if (*from == SKK_DIC_MST && !scand && dic_mst) {
+ scand = getCand(dic_mst, yomi);
+ if (!scand) (*from)++;
+ }
+#ifdef USE_SERVER
+ if (*from == SKK_DIC_SVR && !scand && svr_dic_host) {
+ scand = getCandFromServer(yomi);
+ if (!scand) (*from)++;
+ }
+#endif
+ }
+ }
+ vim_free(yomi);
+ return scand;
+}
+
+static void
+skk_hira2kata(char_u *src)
+{
+ char_u *ptr;
+ for (ptr = src; *ptr; ptr++)
+ {
+ if (*ptr == 0xa4 && *(ptr+1) >= 0xa1 &&
+ *(ptr+1) <= 0xf3)
+ *(ptr++) = 0xa5;
+ else if (*ptr & 0x80)
+ ptr++;
+ }
+}
+
+static int
+skk_puts(char *src, int *x, int *y, int attr)
+{
+ int len = 1;
+ int all_cells = 0;
+ char_u *ptr;
+#ifdef FEAT_MBYTE
+ char_u cell[MB_MAXBYTES];
+#else
+ char_u cell[2];
+#endif
+
+ for(ptr = src; *ptr; ptr+=len)
+ {
+ int cells = 0;
+ int diffs = 0;
+#ifdef FEAT_MBYTE
+ cells = mb_ptr2cells(ptr);
+#else
+ cells = ptr2cells(ptr);
+#endif
+
+#ifdef FEAT_MBYTE
+ len = mb_ptr2len_check(ptr);
+#else
+ len = 1;
+#endif
+ STRNCPY(cell, ptr, len);
+ cell[len] = 0;
+ if (State & CMDLINE)
+ {
+ diffs = *x + cells - Columns;
+ if (diffs > 0)
+ {
+ if (diffs < cells)
+ screen_putchar('>', *y, *x, hl_attr(HLF_AT));
+ *x = 0;
+ }
+ }
+ else
+ {
+ diffs = *x + cells - W_WINCOL(curwin) - W_WIDTH(curwin);
+ if (diffs > 0)
+ {
+ if (diffs < cells)
+ screen_putchar('>', *y, *x, hl_attr(HLF_AT));
+ *x = W_WINCOL(curwin);
+ if (*y < W_WINROW(curwin) + curwin->w_height - 1)
+ *y += 1;
+ }
+ }
+ screen_puts(cell, *y, *x, attr);
+ *x += cells;
+ all_cells += cells;
+ }
+ if ((State & CMDLINE) == 0)
+ {
+ if (*x == W_WINCOL(curwin) + W_WIDTH(curwin))
+ {
+ *x = W_WINCOL(curwin);
+ if (*y < W_WINROW(curwin) + curwin->w_height - 1)
+ *y += 1;
+ windgoto(*y, *x);
+ }
+ }
+ return all_cells;
+}
+
+static void
+skk_getxy(int *x, int *y)
+{
+ if (State & CMDLINE)
+ {
+ *x = msg_col;
+ *y = msg_row;
+ }
+ else
+ {
+ *x = W_WINCOL(curwin) + curwin->w_wcol;
+ *y = W_WINROW(curwin) + curwin->w_wrow;
+ }
+}
+
+static void
+skk_conv_free(char_u* src)
+{
+#ifdef FEAT_MBYTE
+#ifdef USE_ICONV
+ vim_free(src);
+#else
+ if (enc_dbcs == DBCS_JPNU)
+ return;
+ vim_free(src);
+#endif
+#else
+ return;
+#endif
+}
+
+static char_u*
+skk_conv_alloc(char_u* src)
+{
+ char_u *ret;
+#ifdef FEAT_MBYTE
+
+#ifdef USE_ICONV
+ ret = string_convert(&skk_convt, (char_u*)src, NULL);
+ if (!ret)
+ ret = strdup(src);
+#else
+ char_u c1, c2;
+ char_u *dst;
+ ret = dst = strdup(src);
+ switch(enc_dbcs)
+ {
+ case DBCS_JPNU:
+ break;
+ case DBCS_JPN:
+ while(*src)
+ {
+ c1 = *src;
+ c2 = *(src+1);
+ if (c2 == 0x00 || !iseuckanji(c1))
+ *dst++ = c1;
+ else
+ if (c1 == 0x8e)
+ {
+ *dst++ = c2;
+ src++;
+ }
+ else
+ {
+ if (c1 % 2 == 0)
+ c2 -= 0x02;
+ else
+ c2 -= (c2 > 0xdf) ? 0x60 : 0x61;
+ if (c1 < 0xdf)
+ c1 = (c1 + 1) / 2 + 0x30;
+ else
+ c1 = (c1 + 1) / 2 + 0x70;
+ *dst++ = c1;
+ *dst++ = c2;
+ src++;
+ }
+ src++;
+ }
+ *dst = 0;
+ break;
+ default:
+ break;
+ }
+#endif
+#endif
+ return ret;
+}
+
+int
+skk_showmode()
+{
+ char_u *dst;
+ static char_u *mode_table[] = {
+ "[\xc8\xbe\xb3\xd1]", /* [半角] */
+ "[\xa4\xab\xa4\xca]", /* [かな] */
+ "[\xa5\xab\xa5\xca]", /* [カナ] */
+ "[\xc1\xb4\xb1\xd1]", /* [全英] */
+ NULL
+ };
+
+ dst = skk_conv_alloc(mode_table[input_mode]);
+ msg_puts(dst);
+ skk_conv_free(dst);
+ return TRUE;
+}
+
+static void
+skk_mode(int mode)
+{
+ char_u *dst;
+ int x, y;
+ static char_u *mode_table[] = {
+ "[\xc8\xbe\xb3\xd1]", /* [半角] */
+ "[\xa4\xab\xa4\xca]", /* [かな] */
+ "[\xa5\xab\xa5\xca]", /* [カナ] */
+ "[\xc1\xb4\xb1\xd1]", /* [全英] */
+ NULL
+ };
+
+ if (State & CMDLINE || State & NORMAL)
+ return;
+ x = 0;
+ y = Rows - 1;
+
+ dst = malloc(Columns+1);
+ memset(dst, ' ', Columns);
+ dst[Columns] = 0;
+ skk_puts(dst, &x, &y, HL_NORMAL);
+ vim_free(dst);
+
+ x = 0;
+ dst = skk_conv_alloc(mode_table[mode]);
+ skk_puts(dst, &x, &y, HL_NORMAL);
+ skk_conv_free(dst);
+
+ windgoto(orig_y, orig_x);
+}
+
+int
+skk_enabled(int verbose)
+{
+ if (!skk_enable)
+ {
+ char_u **ptr = NULL;
+ curBuff[0] = '\0';
+ inpBuff[0] = '\0';
+ nfetch = 0;
+ skk_enable = TRUE;
+ }
+#ifdef USE_ICONV
+ if (skk_enable && old_enc != p_enc)
+ {
+ skk_convt.vc_fd = (iconv_t)-1;
+ convert_setup(&skk_convt, "euc-jp", p_enc);
+ }
+#endif
+ return skk_enable;
+}
+
+int
+skk_end()
+{
+ if (skk_enable)
+ {
+ if (dic_usr)
+ closeSKK(dic_usr,usr_dic_path);
+ dic_usr = NULL;
+ if (usr_dic_path)
+ vim_free(usr_dic_path);
+ usr_dic_path = NULL;
+
+ if (dic_mst)
+ closeSKK(dic_mst,NULL);
+ dic_mst = NULL;
+ if (mst_dic_path)
+ vim_free(mst_dic_path);
+ mst_dic_path = NULL;
+
+#ifdef USE_SERVER
+ if (has_server && getSKKservStatus())
+ closeSKKserv();
+ has_server = FALSE;
+ if (svr_dic_host)
+ vim_free(svr_dic_host);
+ svr_dic_host = NULL;
+#endif
+ }
+ skk_enable = FALSE;
+ return TRUE;
+}
+
+static void
+skk_kakutei(char_u* p)
+{
+ char_u *dst;
+ if (p)
+ {
+ dst = skk_conv_alloc(p);
+ strcpy(curBuff, dst);
+ skk_conv_free(dst);
+ nfetch = 0;
+ }
+ else
+ {
+ curBuff[0] = 0;
+ nfetch = 0;
+ }
+}
+
+static int
+skk_henkan(char_u* p, int pos, int len, int flg)
+{
+ char_u *dst, *cpy;
+ int x, y, cells = 0;
+ static char_u *mark_list[] = {
+ "\xa2\xa6", "\xa2\xa7",
+ };
+
+ skk_getxy(&x, &y);
+
+ if (flg)
+ {
+ cpy = strdup(mark_list[flg-1]);
+ dst = skk_conv_alloc(cpy);
+ cells += skk_puts(dst, &x, &y, HL_INVERSE);
+ skk_conv_free(dst);
+ vim_free(cpy);
+ }
+
+ cpy = strdup(p);
+ cpy[pos] = 0;
+ dst = skk_conv_alloc(cpy);
+ cells += skk_puts(dst, &x, &y, HL_UNDERLINE);
+ skk_conv_free(dst);
+ vim_free(cpy);
+
+ cpy = strdup(p+pos);
+ cpy[len] = 0;
+ dst = skk_conv_alloc(cpy);
+ if (flg)
+ cells += skk_puts(dst, &x, &y, HL_INVERSE);
+ else
+ cells += skk_puts(dst, &x, &y, HL_UNDERLINE);
+ skk_conv_free(dst);
+ vim_free(cpy);
+
+ cpy = strdup(p+pos+len);
+ dst = skk_conv_alloc(cpy);
+ cells += skk_puts(dst, &x, &y, HL_UNDERLINE);
+ vim_free(cpy);
+
+ return cells;
+}
+
+static void
+skk_delhenkan(int len)
+{
+ int x, y;
+ if (len > 0)
+ {
+ char_u *ptr;
+
+ skk_getxy(&x, &y);
+ ptr = malloc(len+1);
+ memset(ptr, ' ', len);
+ ptr[len] = 0;
+ skk_puts(ptr, &x, &y, HL_NORMAL);
+ vim_free(ptr);
+ }
+ skk_getxy(&x, &y);
+ windgoto(y, x);
+}
+
+static void
+skk_gline(char_u* p, char_u* l, int pos, int len)
+{
+ char_u *dst, *cpy;
+ int x, y;
+
+ if (State & CMDLINE || State & NORMAL)
+ return;
+ x = 0;
+ y = Rows - 1;
+
+ dst = skk_conv_alloc(p);
+ skk_puts(dst, &x, &y, HL_NORMAL);
+ skk_conv_free(dst);
+
+ skk_puts(" ", &x, &y, HL_NORMAL);
+
+ cpy = strdup(l);
+ cpy[pos] = 0;
+ dst = skk_conv_alloc(cpy);
+ skk_puts(dst, &x, &y, HL_NORMAL);
+ skk_conv_free(dst);
+ vim_free(cpy);
+
+ cpy = strdup(l+pos);
+ cpy[len] = 0;
+ dst = skk_conv_alloc(cpy);
+ skk_puts(dst, &x, &y, HL_INVERSE);
+ skk_conv_free(dst);
+ vim_free(cpy);
+
+ cpy = strdup(l+pos+len);
+ dst = skk_conv_alloc(cpy);
+ skk_puts(dst, &x, &y, HL_NORMAL);
+ skk_conv_free(dst);
+ vim_free(cpy);
+
+ windgoto(orig_y, orig_x);
+}
+
+static int
+skk_fetch()
+{
+ int c;
+#ifdef FEAT_MBYTE
+ c = mb_ptr2char(curBuff+nfetch);
+ if (c)
+ nfetch += mb_ptr2len_check(curBuff+nfetch);
+#else
+ c = curBuff[nfetch];
+ if (c)
+ nfetch++;
+#endif
+ return c;
+}
+
+int
+skk_vgetc()
+{
+ unsigned int c, length;
+ CandList scand = (CandList)NULL;
+ CandList fcand = (CandList)NULL;
+ int okuri_pos = 0;
+ int old_mode;
+
+ if (skk_enable == FALSE)
+ return 0;
+
+ c = skk_fetch();
+ if (c)
+ return c;
+
+ skk_getxy(&orig_x, &orig_y);
+
+ skk_kakutei(NULL);
+ length = 0;
+ if (strlen(inpBuff))
+ {
+ char_u *iroha;
+ iroha = skk_alpha2iroha(inpBuff, SKK_RET_UNK);
+ if (preedit)
+ length = skk_henkan(iroha, 0, strlen(iroha), 1);
+ else
+ length = skk_henkan(iroha, 0, strlen(iroha), 0);
+ vim_free(iroha);
+ }
+
+ while (1)
+ {
+ c = vgetc();
+ if (ex_normal_busy || KeyStuffed)
+ return c;
+ if (c == 0)
+ continue;
+ got_int = FALSE;
+
+ if (c == '\t')
+ {
+ if (strlen(inpBuff) == 0)
+ return c;
+ else
+ continue;
+ }
+
+ skk_delhenkan(length);
+
+ if (c == ESC)
+ {
+ okuri_pos = 0;
+ length = 0;
+ preedit = 0;
+ inpBuff[0] = 0;
+ skk_kakutei(NULL);
+ input_mode = SKK_INPUT_HALP;
+ showmode();
+ return c;
+ }
+
+ old_mode = input_mode;
+
+ if (preedit != 2)
+ {
+ switch(c)
+ {
+ case 'l':
+ if (input_mode != SKK_INPUT_ZALP &&
+ input_mode != SKK_INPUT_HALP)
+ input_mode = SKK_INPUT_HALP;
+ break;
+ case 'L':
+ if (input_mode != SKK_INPUT_ZALP &&
+ input_mode != SKK_INPUT_HALP)
+ input_mode = SKK_INPUT_ZALP;
+ break;
+ case 'q':
+ if (input_mode == SKK_INPUT_KATA ||
+ input_mode == SKK_INPUT_HIRA)
+ input_mode = (input_mode == SKK_INPUT_KATA ) ?
+ SKK_INPUT_HIRA : SKK_INPUT_KATA;
+ break;
+ case Ctrl_J:
+ input_mode = SKK_INPUT_HIRA;
+ break;
+ }
+ }
+ if (old_mode != input_mode)
+ {
+ if (!(State & CMDLINE))
+ {
+ showmode();
+ windgoto(orig_y, orig_x);
+ }
+ if (scand)
+ {
+ scand = skk_commitcand(inpBuff, okuri_pos, scand);
+ if (okuri_pos)
+ {
+ char_u *ptr;
+ char_u *iroha;
+
+ iroha = skk_alpha2iroha(&inpBuff[okuri_pos], SKK_RET_UNK);
+ if (old_mode == SKK_INPUT_KATA)
+ skk_hira2kata(iroha);
+ ptr = malloc(strlen(scand->candword) + strlen(iroha) + 1);
+ strcpy(ptr, scand->candword);
+ strcat(ptr, iroha);
+ vim_free(iroha);
+ skk_kakutei(ptr);
+ vim_free(ptr);
+ }
+ else
+ skk_kakutei(scand->candword);
+ okuri_pos = 0;
+ length = 0;
+ preedit = 0;
+ }
+ else
+ if (strlen(inpBuff))
+ {
+ char_u *ptr;
+ char_u *iroha;
+
+ iroha = skk_alpha2iroha(inpBuff, SKK_RET_FND);
+ switch(old_mode)
+ {
+ case SKK_INPUT_HIRA:
+ if (preedit)
+ {
+ skk_hira2kata(iroha);
+ input_mode = SKK_INPUT_HIRA;
+ }
+ break;
+ case SKK_INPUT_KATA:
+ if (!preedit)
+ input_mode = SKK_INPUT_KATA;
+ else
+ skk_hira2kata(iroha);
+ break;
+ }
+ showmode();
+ skk_kakutei(iroha);
+ vim_free(iroha);
+ okuri_pos = 0;
+ length = 0;
+ preedit = 0;
+ }
+ if (strlen(inpBuff) == 0)
+ continue;
+ inpBuff[0] = 0;
+ break;
+ }
+
+ if (c == Ctrl_G)
+ {
+ if (scand)
+ {
+ scand = NULL;
+ c = 0;
+ }
+ else
+ {
+ if (preedit)
+ c = 0;
+ inpBuff[0] = 0;
+ skk_kakutei(NULL);
+ length = 0;
+ preedit = 0;
+ okuri_pos = 0;
+ if (c)
+ return c;
+ }
+ }
+ else
+ if (c == 'x' && scand)
+ scand = scand->prevcand;
+ else
+ if (!regs_key && strlen(inpBuff) > 0 && c == Ctrl_R)
+ {
+ char_u *ptr, *dst;
+ char_u *old_inpBuff;
+ CandList scand = NULL;
+ CandList ncand = NULL;
+ DicList dlist;
+
+ regs_key = skk_alpha2iroha(inpBuff, SKK_RET_FND);
+ if (!regs_key)
+ continue;
+ dst = skk_conv_alloc(regs_key);
+ ptr = malloc(strlen(dst) + 2);
+ strcpy(ptr, dst);
+ skk_conv_free(dst);
+ strcat(ptr, ":");
+
+ old_inpBuff = strdup(inpBuff);
+ inpBuff[0] = 0;
+
+ regs_str = getcmdline_prompt('@', ptr, HL_NORMAL);
+
+ vim_free(ptr);
+ strcpy(inpBuff, old_inpBuff);
+ vim_free(old_inpBuff);
+
+ if (!regs_str || strlen(regs_str) == 0)
+ {
+ if (regs_str)
+ vim_free(regs_str);
+ regs_str = NULL;
+ vim_free(regs_key);
+ regs_key = NULL;
+ continue;
+ }
+
+ skk_regist(regs_key, regs_str);
+
+ skk_kakutei(regs_str);
+ okuri_pos = 0;
+ inpBuff[0] = 0;
+ length = 0;
+ scand = NULL;
+ preedit = 0;
+
+ skk_active = TRUE;
+ vim_free(regs_str);
+ regs_str = NULL;
+ vim_free(regs_key);
+ regs_key = NULL;
+ break;
+ }
+ else
+ if (c == '\n' || c == '\r')
+ {
+ if (scand)
+ {
+ scand = skk_commitcand(inpBuff, okuri_pos, scand);
+ if (okuri_pos)
+ {
+ char_u *ptr;
+ char_u *iroha;
+
+ iroha = skk_alpha2iroha(&inpBuff[okuri_pos], SKK_RET_FND);
+ ptr = malloc(strlen(scand->candword) + strlen(iroha) + 1);
+ strcpy(ptr, scand->candword);
+ strcat(ptr, iroha);
+ vim_free(iroha);
+ skk_kakutei(ptr);
+ vim_free(ptr);
+ }
+ else
+ skk_kakutei(scand->candword);
+ }
+ else
+ {
+ if (strlen(inpBuff))
+ {
+ if (preedit == 1)
+ {
+ char_u *ptr;
+ char_u *iroha;
+ iroha = skk_alpha2iroha(inpBuff, SKK_RET_FND);
+ if (input_mode == SKK_INPUT_KATA)
+ skk_hira2kata(iroha);
+ skk_kakutei(iroha);
+ vim_free(iroha);
+ }
+ else
+ skk_kakutei(inpBuff);
+ }
+ else
+ skk_kakutei("\n");
+
+ if (State & CMDLINE)
+ input_mode = SKK_INPUT_HALP;
+ }
+
+ okuri_pos = 0;
+ inpBuff[0] = 0;
+ length = 0;
+ scand = NULL;
+ preedit = 0;
+ break;
+ }
+ else
+ if (c == ' ' && strlen(inpBuff))
+ {
+ char_u *old_candword = NULL;
+
+ if (!preedit)
+ {
+ char_u *iroha;
+ iroha = skk_alpha2iroha(inpBuff, SKK_RET_FND);
+ length = skk_henkan(iroha,
+ 0, strlen(iroha), 0);
+ vim_free(iroha);
+ continue;
+ }
+
+ if (scand) {
+ old_candword = strdup(scand->candword);
+ scand = scand->nextcand;
+ if (!scand) dic_from++;
+ }
+ else
+ dic_from = SKK_DIC_USR;
+
+ if (!scand)
+ {
+ if (okuri_pos)
+ {
+ char_u *ptr = strdup(inpBuff);
+ ptr[okuri_pos] = 0;
+ scand = skk_alpha2cand(ptr, inpBuff[okuri_pos], &dic_from);
+ vim_free(ptr);
+
+ if (scand)
+ {
+ CandList *ocand;
+ CandList old_cand = (CandList)scand;
+
+ ptr = skk_alpha2iroha(&inpBuff[okuri_pos], SKK_RET_UNK);
+ scand = searchOkuri(scand, ptr, &ocand);
+ if (!scand)
+ scand = old_cand;
+ vim_free(ptr);
+ }
+ }
+ else
+ {
+ scand = skk_alpha2cand(inpBuff, 0, &dic_from);
+ }
+ }
+ if (scand && scand->okuri)
+ scand = scand->okuri->nextcand;
+ if (old_candword) {
+ while(scand) {
+ if (strcmp(old_candword, scand->candword))
+ break;
+ scand = scand->nextcand;
+ }
+ vim_free(old_candword);
+ }
+ }
+ else
+ if (c == K_BS || c == K_DEL || c == Ctrl_H)
+ {
+ char_u *ptr, *old;
+ if (regs_str && STRLEN(regs_str))
+ {
+ for (ptr = regs_str, old = regs_str; *ptr; ptr++)
+ {
+ old = ptr;
+ if (*ptr & 0x80)
+ ptr++;
+ }
+ *old = '\0';
+ }
+ else
+ if (!scand)
+ {
+ if (strlen(inpBuff) > 0)
+ {
+ if (preedit == 2)
+ {
+ int nbytes = strlen(inpBuff);
+ if (nbytes)
+ inpBuff[nbytes-1] = 0;
+ }
+ else
+ {
+ char_u *iroha;
+ char_u *alpha;
+
+ iroha = skk_alpha2iroha(inpBuff, SKK_RET_FND);
+ for (ptr = iroha, old = iroha; *ptr; ptr++)
+ {
+ old = ptr;
+ if (*ptr & 0x80)
+ ptr++;
+ }
+ *old = '\0';
+ alpha = skk_iroha2alpha(iroha);
+ vim_free(iroha);
+ strcpy(inpBuff, alpha);
+ vim_free(alpha);
+ }
+ }
+ else
+ {
+ if (preedit)
+ {
+ preedit = 0;
+ c = 0;
+ }
+ else
+ return c;
+ }
+ }
+ else
+ {
+ scand = NULL;
+ }
+ c = 0;
+ okuri_pos = 0;
+ } else
+ if (IS_SPECIAL(c))
+ {
+ if (regs_key)
+ return c;
+ }
+ else
+ if (isprint((char)c))
+ {
+ if (scand)
+ {
+ char_u *ptr;
+ char_u *iroha;
+
+ scand = skk_commitcand(inpBuff, okuri_pos, scand);
+ if (okuri_pos)
+ {
+ iroha = skk_alpha2iroha(&inpBuff[okuri_pos], SKK_RET_UNK);
+ if (input_mode == SKK_INPUT_KATA)
+ skk_hira2kata(iroha);
+ ptr = malloc(strlen(scand->candword) + strlen(iroha) + 1);
+ strcpy(ptr, scand->candword);
+ strcat(ptr, iroha);
+ vim_free(iroha);
+ }
+ else
+ ptr = strdup(scand->candword);
+
+ inpBuff[0] = tolower(c);
+ inpBuff[1] = 0;
+ if (isupper(c))
+ preedit = 1;
+ else
+ {
+ preedit = 0;
+ iroha = skk_alpha2iroha(inpBuff, SKK_RET_UNK);
+ if (STRICMP(inpBuff, iroha))
+ {
+ ptr = realloc(ptr, strlen(ptr) + strlen(iroha) + 1);
+ strcat(ptr, iroha);
+ vim_free(iroha);
+ inpBuff[0] = 0;
+ }
+ }
+ skk_kakutei(ptr);
+ vim_free(ptr);
+ okuri_pos = 0;
+ nfetch = 0;
+ length = 0;
+ break;
+ }
+
+ switch(input_mode)
+ {
+ case SKK_INPUT_HALP:
+ return c;
+ break;
+ case SKK_INPUT_HIRA:
+ case SKK_INPUT_KATA:
+ if (preedit == 0 && strlen(inpBuff) == 0 && c == '/')
+ preedit = 2;
+ else
+ if (c)
+ {
+ if (preedit != 2 && isupper(c))
+ {
+ if (preedit && c > 0 && okuri_pos == 0)
+ okuri_pos = strlen(inpBuff);
+ preedit = 1;
+ }
+ inpBuff[strlen(inpBuff)+1] = 0;
+ inpBuff[strlen(inpBuff)] = c;
+ }
+ break;
+ case SKK_INPUT_ZALP:
+ if (isalnum(c))
+ {
+ int nbytes = strlen(inpBuff);
+ inpBuff[nbytes++] = 0xa3;
+ inpBuff[nbytes++] = c + 0x880;
+ inpBuff[nbytes] = 0;
+ }
+ else
+ {
+ int nbytes = strlen(inpBuff);
+ char_u *iroha;
+ inpBuff[nbytes++] = c;
+ inpBuff[nbytes] = 0;
+ iroha = skk_alpha2iroha(inpBuff, SKK_RET_UNK);
+ strcpy(inpBuff, iroha);
+ vim_free(iroha);
+ }
+ break;
+ }
+ if (scand)
+ {
+ scand = NULL;
+ break;
+ }
+ }
+ else
+ return c;
+
+ if (scand)
+ {
+ if (okuri_pos)
+ {
+ char_u *ptr;
+ char_u *iroha;
+
+ iroha = skk_alpha2iroha(&inpBuff[okuri_pos], SKK_RET_UNK);
+ if (input_mode == SKK_INPUT_KATA)
+ skk_hira2kata(iroha);
+ ptr = malloc(strlen(scand->candword) + strlen(iroha) + 1);
+ strcpy(ptr, scand->candword);
+ strcat(ptr, iroha);
+ vim_free(iroha);
+ length = skk_henkan(ptr, 0, strlen(scand->candword), 2);
+ vim_free(ptr);
+ }
+ else {
+ length = skk_henkan(scand->candword, 0, strlen(scand->candword), 2);
+ }
+ }
+ else
+ if (!preedit)
+ {
+ if (c == ' ')
+ {
+ skk_kakutei(" ");
+ inpBuff[0] = 0;
+ okuri_pos = 0;
+ length = 0;
+ scand = NULL;
+ preedit = 0;
+ break;
+ }
+ else
+ {
+ char_u *iroha;
+ iroha = skk_alpha2iroha(inpBuff, SKK_RET_UNK);
+ if (STRICMP(inpBuff,iroha) ||
+ (input_mode != SKK_INPUT_HIRA &&
+ input_mode != SKK_INPUT_KATA))
+ {
+ char_u *ptr;
+ unsigned int n;
+
+ if (input_mode == SKK_INPUT_ZALP)
+ {
+ for (ptr = iroha; *ptr; ptr++)
+ {
+ if (*ptr == 0xa1 && *(ptr+1) == 0xa2)
+ *(ptr+1) = 0xa4;
+ else
+ if (*ptr == 0xa1 && *(ptr+1) == 0xa3)
+ *(ptr+1) = 0xa5;
+ else
+ if (*ptr & 0x80)
+ ptr++;
+ }
+ }
+ if (input_mode == SKK_INPUT_KATA)
+ skk_hira2kata(iroha);
+
+ for(n = 0; n < strlen(iroha);)
+ if (!iseuckanji(*(iroha+n)))
+ n ++;
+ else
+ break;
+ for(; n < strlen(iroha);)
+ if (iseuckanji(*(iroha+n)))
+ n += 2;
+ else
+ break;
+ ptr = strdup(iroha);
+ iroha[n] = 0;
+ skk_kakutei(iroha);
+ STRCPY(inpBuff, ptr+n);
+ vim_free(iroha);
+ vim_free(ptr);
+
+ okuri_pos = 0;
+ length = 0;
+ scand = NULL;
+ preedit = 0;
+ break;
+ }
+ else
+ length = skk_henkan(iroha, 0, strlen(iroha), 0);
+ vim_free(iroha);
+ }
+ }
+ else
+ {
+ if (okuri_pos && c)
+ {
+ char_u *iroha;
+ char_u *iroha1, *iroha2;
+ char_u *ptr1 = strdup(inpBuff);
+ char_u *ptr2 = strdup(&inpBuff[okuri_pos]);
+
+ dic_from = SKK_DIC_USR;
+ if (okuri_pos)
+ ptr1[okuri_pos] = 0;
+ iroha1 = skk_alpha2iroha(ptr1, SKK_RET_FND);
+ iroha2 = skk_alpha2iroha(ptr2, SKK_RET_UNK);
+ if (STRICMP(ptr2,iroha2)
+ && *(iroha2+strlen(iroha2)-1) & 0x80)
+ {
+ if (okuri_pos)
+ {
+ char_u *ptr = strdup(inpBuff);
+ ptr[okuri_pos] = 0;
+ scand = skk_alpha2cand(ptr, inpBuff[okuri_pos], &dic_from);
+ vim_free(ptr);
+
+ if (scand)
+ {
+ CandList *ocand;
+ CandList old_cand = (CandList)scand;
+
+ ptr = skk_alpha2iroha(&inpBuff[okuri_pos], SKK_RET_UNK);
+ scand = searchOkuri(scand, ptr, &ocand);
+ if (!scand)
+ scand = old_cand;
+ vim_free(ptr);
+ }
+ }
+ else
+ {
+ scand = skk_alpha2cand(inpBuff, 0, &dic_from);
+ }
+ }
+ vim_free(ptr1);
+ vim_free(ptr2);
+ if (scand)
+ {
+ iroha = malloc(strlen(scand->candword) + strlen(iroha2) + 2);
+ strcpy(iroha, scand->candword);
+ strcat(iroha, iroha2);
+ }
+ else
+ {
+ iroha = malloc(strlen(iroha1) + strlen(iroha2) + 2);
+ strcpy(iroha, iroha1);
+ strcat(iroha, "*");
+ strcat(iroha, iroha2);
+ }
+ vim_free(iroha1);
+ vim_free(iroha2);
+
+ if (input_mode == SKK_INPUT_KATA)
+ skk_hira2kata(iroha);
+ if (scand)
+ length = skk_henkan(iroha, 0, strlen(scand->candword), 2);
+ else
+ length = skk_henkan(iroha, 0, strlen(iroha), 1);
+
+ vim_free(iroha);
+ }
+ else
+ {
+ if (preedit == 1)
+ {
+ char_u *iroha;
+ iroha = skk_alpha2iroha(inpBuff, SKK_RET_UNK);
+ if (input_mode == SKK_INPUT_KATA)
+ skk_hira2kata(iroha);
+ length = skk_henkan(iroha, 0, strlen(iroha), 1);
+ vim_free(iroha);
+ }
+ else
+ length = skk_henkan(inpBuff, 0, strlen(inpBuff), 1);
+ }
+ }
+ }
+ return skk_fetch();
+}
+
+int
+skk_redraw(void)
+{
+ return TRUE;
+}
+
+char_u*
+skk_imopts(char_u *opts)
+{
+ char_u *errmsg = NULL;
+ char_u *org, *ptr;
+ char_u *name, *val;
+ org = ptr = strdup(opts);
+ usr_dic_path = NULL;
+ svr_dic_host = NULL;
+ svr_dic_port = SKK_PORT_NUMBER;
+ while(*ptr)
+ {
+ name = ptr;
+ while(*ptr != ':' && *ptr != ',' && *ptr != '\0')
+ ptr++;
+ switch(*ptr)
+ {
+ case ',':
+ *ptr++ = 0;
+ name = NULL;
+ val = NULL;
+ continue;
+ break;
+ case ':':
+ *ptr++ = 0;
+ val = ptr;
+ while(*ptr != ',' && *ptr != '\0')
+ ptr++;
+ if (*ptr != '\0')
+ *ptr++ = 0;
+ break;
+ }
+ if (!STRICMP(name, "dict"))
+ {
+ expand_T xpc;
+ if (usr_dic_path)
+ vim_free(usr_dic_path);
+ ExpandInit(&xpc);
+ xpc.xp_context = EXPAND_FILES;
+ usr_dic_path = ExpandOne(&xpc, val, NULL,
+ WILD_SILENT|WILD_USE_NL, WILD_ALL);
+ }
+ else
+ if (!STRICMP(name, "master"))
+ {
+ expand_T xpc;
+ if (mst_dic_path)
+ vim_free(mst_dic_path);
+ ExpandInit(&xpc);
+ xpc.xp_context = EXPAND_FILES;
+ mst_dic_path = ExpandOne(&xpc, val, NULL,
+ WILD_SILENT|WILD_USE_NL, WILD_ALL);
+ }
+#ifdef USE_SERVER
+ else
+ if (!STRICMP(name, "serv"))
+ {
+ if (svr_dic_host)
+ vim_free(svr_dic_host);
+ svr_dic_host = strdup(val);
+ }
+ else
+ if (!STRICMP(name, "port"))
+ {
+ svr_dic_port = (unsigned short)atoi((char*)val);
+ }
+#endif
+ else
+ errmsg = (char_u *)_("illegal imoptions");
+ }
+ if (!usr_dic_path)
+ {
+ expand_T xpc;
+ char_u *newfile;
+ ExpandInit(&xpc);
+ xpc.xp_context = EXPAND_FILES;
+ usr_dic_path = ExpandOne(&xpc, "~/", NULL,
+ WILD_SILENT|WILD_USE_NL, WILD_ALL);
+ newfile = alloc(strlen(usr_dic_path) + strlen(".skk-jisyo") + 1);
+ if (newfile) {
+ strcpy(newfile, usr_dic_path);
+ strcat(newfile, ".skk-jisyo");
+ }
+ vim_free(usr_dic_path);
+ usr_dic_path = newfile;
+ }
+ vim_free(org);
+ return errmsg;
+}
+#endif /* FEAT_SKK */
diff -Nru src.org/skklib.c src/skklib.c
--- src.org/skklib.c 1970-01-01 09:00:00.000000000 +0900
+++ src/skklib.c 2005-02-09 16:43:21.607986976 +0900
@@ -0,0 +1,728 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "skklib.h"
+
+#ifdef WIN32
+#include <winsock.h>
+#include <io.h> /* for prototypes of read(), write(), etc. */
+#pragma comment(lib, "ws2_32.lib")
+#else
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#define closesocket(s) close(s)
+#endif
+
+#ifdef INT_SIGNAL
+typedef int SignalFunc;
+#else
+typedef void SignalFunc;
+#endif
+
+#define SKK_PORT_NUMBER 1178
+#define SKK_SERVICENAME "skkserv"
+
+#ifdef BCOPY
+#define bincopy(a,b,n) bcopy(a,b,n)
+#define fillzero(a,n) bzero(a,n)
+#else
+#define bincopy(a,b,n) memcpy(b,a,n)
+#define fillzero(a,n) memset(a,0,n)
+#endif
+
+#ifdef WIN32
+static int win32skkservsock = -1;
+#endif
+static int skkservsock = -1;
+static FILE *rserv,*wserv;
+
+/*
+ * Open SKK
+ */
+Dictionary
+openSKK(char *dicname)
+{
+ FILE *f;
+ DicList ditem,ditem2;
+ DicList globaldic;
+ char buf[512];
+ char *p,c;
+ Hash *dhash;
+ Dictionary dic;
+ int i,nitem = 0;
+ int okuriAri = 1;
+ struct stat st;
+
+ dhash = (Hash*)calloc(HASHSIZE,sizeof(Hash));
+ if (!dhash)
+ return NULL;
+ memset(dhash, 0x00, sizeof(Hash));
+ dic = _NEW(Dictionary);
+ if (!dic)
+ return NULL;
+ dic->dhash = dhash;
+ dic->okuriAriFirst = NULL;
+ dic->okuriNasiFirst = NULL;
+ dic->dlist = NULL;
+ ditem2 = NULL;
+ globaldic = NULL;
+ if ((f = fopen(dicname,"r")) == NULL) {
+ return dic;
+ }
+ fstat(fileno(f),&st);
+ while (!feof(f)) {
+ while ((c = fgetc(f)) == ' ' || c == '\t' || c == '\n');
+ if (feof(f)) break;
+ if (c == ';') { /* comment */
+ i = 0;
+ while (c != '\n' && !feof(f)) {
+ c = fgetc(f);
+ buf[i++] = c;
+ }
+ buf[i] = '\0';
+ if (!strncmp(buf,"; okuri-ari entries.",20)) {
+ okuriAri = 1;
+ }
+ else if (!strncmp(buf,"; okuri-nasi entries.",21)) {
+ okuriAri = 0;
+ }
+ continue;
+ }
+ nitem++;
+ for (buf[0] = c, p = buf+1;
+ !feof(f) && (*p = fgetc(f)) != ' ';
+ p++) {
+ }
+ *p = '\0';
+ ditem = _NEW2(DicList,strlen(buf));
+ if (!ditem)
+ break;
+ ditem->nextitem = NULL;
+ if (ditem2)
+ ditem2->nextitem = ditem;
+ if (globaldic == NULL)
+ globaldic = ditem;
+ strcpy(ditem->kanaword,buf);
+ ditem->cand = getCandList(f,ditem,okuriAri);
+ if (!ditem->cand)
+ break;
+ addHash(dhash,ditem);
+ ditem2 = ditem;
+ if (okuriAri) {
+ if (!dic->okuriAriFirst)
+ dic->okuriAriFirst = ditem2;
+ }
+ else {
+ if (!dic->okuriNasiFirst)
+ dic->okuriNasiFirst = ditem2;
+ }
+ }
+ fclose(f);
+ dic->dlist = globaldic;
+ dic->mtime = st.st_mtime;
+ return dic;
+}
+
+/*
+ * Check if word is an OKURI-ARI entry or not
+ */
+isConjugate(word,l)
+char word[];
+int l;
+{
+ int r;
+ if ((word[0] & 0x80) || word[0] == '#') {
+ if (word[l-1] & 0x80)
+ r = 0;
+ else
+ r = (word[l-1] != '#');
+ }
+ else
+ r = 0;
+ return r;
+}
+
+/*
+ * Add new word entry to the dictionary
+ */
+DicList
+addNewItem(Dictionary dic, char *word, CandList clist)
+{
+ DicList ditem;
+ int l = strlen(word);
+
+ ditem = _NEW2(DicList,l);
+ if (!ditem)
+ return NULL;
+ strcpy(ditem->kanaword,word);
+ ditem->cand = clist;
+ addHash(dic->dhash,ditem);
+ if (isConjugate(word,l)) {
+ if (dic->okuriAriFirst) {
+ ditem->nextitem = dic->okuriAriFirst->nextitem;
+ dic->okuriAriFirst->nextitem = ditem;
+ }
+ else {
+ if (dic->dlist) {
+ dic->okuriAriFirst = ditem;
+ ditem->nextitem = dic->okuriNasiFirst;
+ dic->dlist = ditem;
+ }
+ else {
+ dic->dlist = ditem;
+ dic->okuriAriFirst = ditem;
+ }
+ }
+ }
+ else {
+ if (dic->okuriNasiFirst) {
+ ditem->nextitem = dic->okuriNasiFirst->nextitem;
+ dic->okuriNasiFirst->nextitem = ditem;
+ }
+ else {
+ if (dic->dlist) {
+ ditem->nextitem = dic->dlist->nextitem;
+ dic->dlist->nextitem = ditem;
+ dic->okuriNasiFirst = ditem;
+ }
+ else {
+ dic->dlist = ditem;
+ dic->okuriNasiFirst = ditem;
+ }
+ }
+ }
+ return ditem;
+}
+
+CandList
+getCandList(FILE *f, DicList ditem, int okuri)
+{
+ char buf[256];
+ CandList citem,citem2,citem0 = NULL;
+ CandList ccitem,ccitem2;
+ char c,*p;
+
+ citem2 = NULL;
+ while ((c = fgetc(f)) != '\n' && !feof(f)) {
+ if (c == 9)
+ {
+ fclose(f);
+ break;
+ }
+ if (c == '/')
+ continue;
+ if (okuri && c == '[') {
+ for (p = buf; (*p = fgetc(f)) != '/' && !feof(f); p++);
+ *p = '\0';
+ citem = _NEW2(CandList,strlen(buf));
+ if (!citem)
+ break;
+ citem->okuri = NULL;
+ citem->nextcand = NULL;
+ citem->prevcand = citem2;
+ citem->dicitem = ditem;
+ strcpy(citem->candword,buf);
+ ccitem2 = citem;
+ for (;;) {
+ if ((c = fgetc(f)) == ']' || feof(f))
+ break;
+ for (buf[0] = c, p = buf+1;
+ (*p = fgetc(f)) != '/' && !feof(f);
+ p++);
+ *p = '\0';
+ ccitem = _NEW2(CandList,strlen(buf));
+ if (!ccitem)
+ break;
+ ccitem->nextcand = NULL;
+ strcpy(ccitem->candword,buf);
+ if (ccitem2 == citem) {
+ ccitem2->okuri = ccitem;
+ ccitem->prevcand = NULL;
+ }
+ else {
+ ccitem2->nextcand = ccitem;
+ ccitem->prevcand = ccitem2;
+ }
+ ccitem2 = ccitem;
+ }
+ }
+ else {
+ for (buf[0] = c, p = buf+1;
+ (*p = fgetc(f)) != '/' && !feof(f); p++);
+ *p = '\0';
+ citem = _NEW2(CandList,strlen(buf));
+ if (!citem)
+ break;
+ citem->okuri = NULL;
+ citem->nextcand = NULL;
+ citem->prevcand = citem2;
+ citem->dicitem = ditem;
+ strcpy(citem->candword,buf);
+ }
+ if (citem2)
+ citem2->nextcand = citem;
+ else
+ citem0 = citem;
+ citem2 = citem;
+ }
+ return citem0;
+}
+
+void
+closeSKK(dic,dicname)
+Dictionary dic;
+char *dicname;
+{
+ char *buf;
+ FILE *f;
+ DicList dlist,dlist2;
+ DicList globaldic = dic->dlist;
+ int okuri = 1;
+ int l;
+ char *wd;
+ struct stat sbuf;
+ int old = 0;
+
+ if (dicname)
+ {
+ buf = alloc(256);
+ if (!buf)
+ return;
+ /* backup skk-jisyo if jisyo is not empty. */
+ sprintf(buf,"%s.BAK",dicname);
+ if ((stat(dicname, &sbuf) == 0) && (sbuf.st_size != 0)) {
+ if (dic->mtime < sbuf.st_mtime) {
+ MSG("The dictionary is changed. merging...");
+ mergeDictionary(dic,dicname);
+ }
+ rename(dicname,buf);
+ old = 1;
+ }
+ if ((f = fopen(dicname,"w")) == NULL) {
+ free(buf);
+ return;
+ }
+
+ fprintf(f,";; okuri-ari entries.\n");
+ for (dlist = globaldic;
+ dlist != NULL;
+ dlist2 = dlist, dlist = dlist->nextitem, free(dlist2)) {
+ wd = dlist->kanaword;
+ l = strlen(wd);
+ if (okuri && (!isConjugate(wd,l))) {
+ fprintf(f,";; okuri-nasi entries.\n");
+ okuri = 0;
+ }
+ fprintf(f,"%s ",dlist->kanaword);
+ printCand(dlist->cand,f,FREE_CAND);
+ }
+ fclose(f);
+ if (old)
+ chmod(dicname,sbuf.st_mode);
+
+ for (l = 0; l < HASHSIZE; l++) {
+ Hash h1, h2;
+
+ for (h1 = dic->dhash[l]; h1; h1 = h2) {
+ h2 = h1->next;
+ free(h1);
+ }
+ }
+ free(buf);
+ }
+ free(dic->dhash);
+ free(dic);
+}
+
+/* #define DEBUG_MERGE /* debug dictionary merge */
+void
+mergeDictionary(Dictionary dic, char *dicname)
+{
+ FILE *f;
+ CandList cand,dcand;
+ DicList ditem;
+ char *buf;
+ char *p,c;
+ int i;
+#ifdef DEBUG_MERGE
+ DicList change[10]; int n = 0;
+#endif
+
+ buf = alloc(512);
+ if (buf)
+ return;
+ if ((f = fopen(dicname,"r")) == NULL) {
+ free(buf);
+ return;
+ }
+ while (!feof(f)) {
+ while ((c = fgetc(f)) == ' ' || c == '\t' || c == '\n');
+ if (feof(f)) break;
+ if (c == ';') { /* comment */
+ while (c != '\n' && !feof(f)) {
+ c = fgetc(f);
+ }
+ continue;
+ }
+ for (buf[0] = c, p = buf+1;
+ !feof(f) && (*p = fgetc(f)) != ' ';
+ p++) {
+ }
+ *p = '\0';
+ i = strlen(buf);
+ dcand = getCand(dic,buf);
+ if (dcand == NULL) {
+ cand = getCandList(f,NULL,isConjugate(buf,i));
+ if (!cand)
+ break;
+ ditem = addNewItem(dic,buf,cand);
+ for (; cand; cand = cand->nextcand)
+ cand->dicitem = ditem;
+#ifdef DEBUG_MERGE
+ change[n++] = ditem;
+#endif
+ }
+ else {
+ cand = getCandList(f,dcand->dicitem,isConjugate(buf,i));
+ cand = deleteCand(cand,dcand);
+ if (cand) {
+ dcand->dicitem->cand = cand;
+ while (cand->nextcand != NULL)
+ cand = cand->nextcand;
+ cand->nextcand = dcand;
+ dcand->prevcand = cand;
+#ifdef DEBUG_MERGE
+ change[n++] = dcand->dicitem;
+#endif
+ }
+ }
+ }
+ fclose(f);
+#ifdef DEBUG_MERGE
+ for (i=0;i<n;i++) {
+ printf("i=%d; ",i); fflush(stdout);
+ printf("register(%d): %s (%x)",i,change[i]->kanaword,change[i]->cand); fflush(stdout);
+ printCand(change[i]->cand,stdout,NOFREE_CAND); putchar('\n');
+ }
+#endif
+ free(buf);
+}
+
+void
+printCand(CandList cl, FILE *f, int fre)
+{
+ CandList clist,clist2,cclist,cclist2;
+
+ fputc('/',f);
+ for (clist = cl;
+ clist != NULL;
+ clist2 = clist, clist = clist->nextcand,
+ (fre ? (free(clist2),0) : 0)) {
+ if (clist->okuri) {
+ fprintf(f,"[%s/",clist->candword);
+ for (cclist = clist->okuri;
+ cclist != NULL;
+ cclist2 = cclist,
+ cclist = cclist->nextcand,
+ (fre ? (free(cclist2),0) : 0)) {
+ fprintf(f,"%s/",cclist->candword);
+ }
+ fputs("]/",f);
+ }
+ else
+ fprintf(f,"%s/",clist->candword);
+ }
+ fputc('\n',f);
+}
+
+int
+hashVal(s)
+char *s;
+{
+ int n = 0;
+
+ while (*s) {
+ n += (*s)*(*s);
+ s++;
+ }
+ return n%HASHSIZE;
+}
+
+void
+addHash(Hash *hash, DicList ditem)
+{
+ Hash h;
+ int v;
+
+ v = hashVal(ditem->kanaword);
+ h = _NEW(Hash);
+ if (!h)
+ return;
+ h->h_index = ditem;
+ h->length = strlen(ditem->kanaword);
+ h->next = hash[v];
+ hash[v] = h;
+}
+
+CandList
+getCand(Dictionary dic, char *s)
+{
+ int l,v;
+ Hash h;
+
+ l = strlen(s);
+ v = hashVal(s);
+ for (h = dic->dhash[v]; h != NULL; h = h->next) {
+ if (h->length != l ||
+ strcmp(h->h_index->kanaword,s)) continue;
+ return h->h_index->cand;
+ }
+ return NULL;
+}
+
+void
+selectCand(CandList *first, CandList cand)
+{
+ if (cand->prevcand) {
+ cand->prevcand->nextcand = cand->nextcand;
+ if (cand->nextcand)
+ cand->nextcand->prevcand = cand->prevcand;
+ cand->prevcand = NULL;
+ }
+ if (*first != cand) {
+ (*first)->prevcand = cand;
+ cand->nextcand = *first;
+ *first = cand;
+ }
+}
+
+freeCand(cl)
+CandList cl;
+{
+ CandList clist,clist2,cclist,cclist2;
+
+ for (clist = cl;
+ clist != NULL;
+ clist2 = clist, clist = clist->nextcand, free(clist2)) {
+ if (clist->okuri) {
+ for (cclist = clist->okuri;
+ cclist != NULL;
+ cclist2 = cclist,
+ cclist = cclist->nextcand,
+ free(cclist2)) ;
+ }
+ }
+}
+
+CandList
+deleteCand(CandList frlist, CandList itlist)
+{
+ CandList l;
+ while (itlist != NULL) {
+ for (l = frlist; l != NULL; l = l->nextcand) {
+ if (!strcmp(itlist->candword, l->candword)) {
+ if (l->prevcand == NULL) {
+ frlist = l->nextcand;
+ if (l->nextcand)
+ l->nextcand->prevcand = NULL;
+ }
+ else {
+ l->prevcand->nextcand = l->nextcand;
+ if (l->nextcand)
+ l->nextcand->prevcand = l->prevcand;
+ }
+ l->nextcand = NULL;
+ freeCand(l);
+ break;
+ }
+ }
+ itlist = itlist->nextcand;
+ }
+ return frlist;
+}
+
+CandList
+firstCand(CandList l)
+{
+ while (l->prevcand)
+ l = l->prevcand;
+ return l;
+}
+
+CandList
+searchOkuri(CandList cl, char *okuri, CandList **newfirst)
+{
+ CandList ll;
+
+ for (ll = cl; ll != NULL; ll = ll->nextcand) {
+ if (ll->okuri && !strcmp(ll->candword,okuri)) {
+ if (newfirst)
+ *newfirst = &(ll->okuri);
+ return ll->okuri;
+ }
+ }
+ if (newfirst && cl->dicitem) {
+ if (cl->dicitem->cand->okuri) {
+ return NULL;
+ }
+ *newfirst = &(cl->dicitem->cand);
+ }
+ return cl;
+}
+
+int
+getSKKservStatus()
+{
+ return (skkservsock != -1);
+}
+
+int
+openSKKserv(char *svrname, unsigned short port)
+{
+ int sock;
+ struct sockaddr_in hostaddr;
+ struct hostent *entry;
+ struct servent *serv;
+ struct protoent *proto;
+ int a1,a2,a3,a4;
+ char *hostname;
+
+ if (skkservsock != -1)
+ return 0;
+
+ if (svrname)
+ hostname = svrname;
+ else if ((hostname = getenv("SKKSERVER")) == NULL) {
+ return -1;
+ }
+ if (strcmp(hostname, "!skkserv") == 0) {
+ return -1; /* specified not to use skkserv */
+ }
+
+#ifdef WIN32
+ {
+ WORD wVersionRequested;
+ WSADATA wsaData;
+ int sockopt = SO_SYNCHRONOUS_NONALERT;
+ wVersionRequested = MAKEWORD(1, 1);
+ if (WSAStartup(wVersionRequested, &wsaData) != 0) {
+ return -1;
+ }
+ /* Enable the use of sockets as filehandles */
+ setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
+ (char *)&sockopt, sizeof(sockopt));
+ }
+#endif
+ serv = getservbyname(SKK_SERVICENAME,"tcp");
+ fillzero((char*)&hostaddr,sizeof(struct sockaddr_in));
+ if ((proto = getprotobyname("tcp")) == NULL) {
+ return -1;
+ }
+
+ if ('0' <= *hostname && *hostname <= '9') {
+ if (sscanf(hostname,"%d.%d.%d.%d",&a1,&a2,&a3,&a4) != 4) {
+ return -1;
+ }
+ a1 = (a1<<24)|(a2<<16)|(a3<<8)|a4;
+ hostaddr.sin_addr.s_addr = htonl(a1);
+ }
+ else {
+ if ((entry = gethostbyname(hostname)) == NULL) {
+ return -1;
+ }
+ bincopy(entry->h_addr, &hostaddr.sin_addr, entry->h_length);
+ }
+
+ if ((sock = socket(AF_INET,SOCK_STREAM,proto->p_proto)) < 0) {
+ return -1;
+ }
+ hostaddr.sin_family = AF_INET;
+ hostaddr.sin_port = serv ? serv->s_port : htons(port);
+ if (connect(sock,(struct sockaddr *)&hostaddr,sizeof(struct sockaddr_in)) < 0) {
+ closesocket(sock);
+ return -1;
+ }
+#ifdef WIN32
+ if ((skkservsock = _open_osfhandle(sock, 0)) < 0) {
+ closesocket(sock);
+ return -1;
+ }
+ win32skkservsock = sock;
+ rserv = fdopen(skkservsock,"rb");
+ wserv = fdopen(skkservsock,"wb");
+#else
+ skkservsock = sock;
+ rserv = fdopen(sock,"r");
+ wserv = fdopen(sock,"w");
+#endif
+ return 0;
+}
+
+CandList
+getCandFromServer(s)
+char *s;
+{
+ char r;
+ CandList res;
+
+ if (skkservsock < 0)
+ return NULL;
+#ifdef WIN32
+ if (win32skkservsock < 0) {
+ closeSKKserv();
+ return NULL;
+ }
+#endif
+ if (!rserv || !wserv) {
+ closeSKKserv();
+ return NULL;
+ }
+ fprintf(wserv,"1%s \n",s);
+ fflush(wserv);
+ if (read(skkservsock,&r,1) <= 0) {
+#ifdef SIGPIPE
+ SignalFunc (*sigfunc)();
+#endif
+
+#ifdef SIGPIPE /* WIN32 may not define SIGPIPE */
+ sigfunc = signal(SIGPIPE, SIG_IGN);
+#endif
+ closeSKKserv();
+#ifdef SIGPIPE
+ signal(SIGPIPE, sigfunc);
+#endif
+ return NULL;
+ }
+ if (r == '1') { /* succeeded */
+ res = getCandList(rserv,NULL,isConjugate(s,strlen(s)));
+ return res;
+ }
+ else
+ if (r == '4')
+ {
+ read(skkservsock,&r,1);
+ return NULL;
+ }
+ else
+ while (read(skkservsock,&r,1) > 0 && r != '\n');
+ return NULL;
+}
+
+void
+closeSKKserv()
+{
+ if (skkservsock >= 0) {
+ fprintf(wserv,"0\n");
+ fflush(wserv);
+ fclose(wserv);
+ fclose(rserv);
+ closesocket(skkservsock);
+ skkservsock = -1;
+#ifdef WIN32
+ close(win32skkservsock);
+ win32skkservsock = -1;
+ WSACleanup();
+#endif
+ }
+}
diff -Nru src.org/skklib.h src/skklib.h
--- src.org/skklib.h 1970-01-01 09:00:00.000000000 +0900
+++ src/skklib.h 2005-02-08 10:56:09.000000000 +0900
@@ -0,0 +1,69 @@
+#ifndef SKKLIB_H
+#define SKKLIB_H
+
+#ifndef NO_MALLOC_H
+#include <malloc.h>
+#endif
+
+/*
+ * Structure for Dictionary
+ */
+typedef struct DicList {
+ struct CandList *cand;
+ struct DicList *nextitem;
+ char kanaword[1];
+} *DicList;
+
+/*
+ * Structure for Candidate
+ */
+typedef struct CandList {
+ struct CandList *okuri;
+ struct CandList *nextcand;
+ struct CandList *prevcand;
+ struct DicList *dicitem;
+ char candword[1];
+} *CandList;
+
+typedef struct Hash {
+ DicList h_index;
+ short length;
+ struct Hash *next;
+} *Hash;
+
+#define HASHSIZE 256
+
+typedef struct Dictionary {
+ DicList dlist;
+ DicList okuriAriFirst;
+ DicList okuriNasiFirst;
+ Hash *dhash;
+ time_t mtime;
+} *Dictionary;
+
+#define _NEW(type) ((type)malloc(sizeof(struct type)))
+#define _NEW2(type,add) ((type)malloc(sizeof(struct type)+(add)))
+
+Dictionary openSKK(char*);
+void closeSKK();
+CandList getCand(Dictionary, char*);
+CandList getCandList(FILE*, DicList, int);
+#ifdef USE_SERVER
+int openSKKserv(char *svrname, unsigned short);
+void closeSKKserv();
+CandList getCandFromServer();
+int getSKKservStatus();
+#endif
+CandList firstCand(CandList);
+CandList deleteCand(CandList, CandList);
+CandList searchOkuri(CandList, char*, CandList**);
+DicList addNewItem(Dictionary, char*, CandList);
+void addHash(Hash*,DicList);
+void mergeDictionary(Dictionary, char*);
+void printCand(CandList, FILE*, int);
+
+/* flags for printCand() */
+#define NOFREE_CAND 0
+#define FREE_CAND 1
+
+#endif /* SKKLIB_H */
diff -Nru src.org/term.c src/term.c
--- src.org/term.c 2004-09-19 07:44:46.000000000 +0900
+++ src/term.c 2005-02-08 10:56:09.000000000 +0900
@@ -3119,6 +3119,13 @@
}
cursor_on(); /* redrawing may have switched it off */
}
+#ifdef FEAT_IM_CUSTOM
+ if (im_custom_get_active)
+ {
+ if (im_custom_get_active() && im_custom_redraw)
+ im_custom_redraw();
+ }
+#endif
out_flush();
--busy;
}
diff -Nru src.org/ui.c src/ui.c
--- src.org/ui.c 2004-05-08 09:03:11.000000000 +0900
+++ src/ui.c 2005-02-08 10:56:09.000000000 +0900
@@ -3042,9 +3042,17 @@
* And don't save when the GUI is running but our window doesn't have
* input focus (e.g., when a find dialog is open). */
if (!p_imdisable && KeyTyped && !KeyStuffed
+# ifdef FEAT_IM_CUSTOM
+ && ((im_custom_enabled && im_custom_enabled(FALSE))
+# ifdef FEAT_XIM
+ || xic != NULL
+# endif
+ )
+# else
# ifdef FEAT_XIM
&& xic != NULL
# endif
+# endif
# ifdef FEAT_GUI
&& (!gui.in_use || gui.in_focus)
# endif
diff -Nru src.org/version.c src/version.c
--- src.org/version.c 2005-01-30 05:16:00.000000000 +0900
+++ src/version.c 2005-02-08 10:56:09.000000000 +0900
@@ -98,6 +98,11 @@
#else
"-byte_offset",
#endif
+#ifdef FEAT_IM_CUSTOM
+ "+im_custom",
+#else
+ "-im_custom",
+#endif
#ifdef FEAT_CINDENT
"+cindent",
#else
diff -Nru src.org/vim.h src/vim.h
--- src.org/vim.h 2004-12-06 01:14:17.000000000 +0900
+++ src/vim.h 2005-02-08 10:56:09.000000000 +0900
@@ -382,7 +382,7 @@
/*
* Check input method control.
*/
-#if defined(FEAT_XIM) || \
+#if defined(FEAT_XIM) || defined(FEAT_IM_CUSTOM) || \
(defined(FEAT_GUI) && (defined(FEAT_MBYTE_IME) || defined(GLOBAL_IME)))
# define USE_IM_CONTROL
#endif
@tyru
Copy link
Copy Markdown

tyru commented Nov 2, 2010

これなんですか?

@mattn
Copy link
Copy Markdown
Author

mattn commented Nov 2, 2010

これはvimに canna, skk(native), pobox の入力インタフェースを追加する、かつて5人くらいのネラーの中で流行ったim_customというパッチです。私が書いてました。
バージョンアップに追従するのがしんどくなって辞めました。
ちなみに、Bram氏には一度投げた事があって、「それは君がメンテしていくといいよ」と暖かい言葉を頂きました。

なーむー

@tyru
Copy link
Copy Markdown

tyru commented Nov 2, 2010

素敵パッチ!

@mattn
Copy link
Copy Markdown
Author

mattn commented Nov 2, 2010

ステテコパッチ!

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