diff --git a/honoka-plugins/ascii/src/wordsdic.cpp b/honoka-plugins/ascii/src/wordsdic.cpp
index ed2f4d8..15320c8 100644
--- a/honoka-plugins/ascii/src/wordsdic.cpp
+++ b/honoka-plugins/ascii/src/wordsdic.cpp
@@ -23,6 +23,7 @@
 
 WordsDic::WordsDic(const string &filename)
 {
+    mmapptr = 0;
     fd = open(filename.c_str(),O_RDONLY);
     if (fd == -1) return;
     mmapsize = lseek(fd,0,SEEK_END);
@@ -41,6 +42,13 @@
     return;
 }
 
+WordsDic::WordsDic(char *ptr,off_t size)
+{
+    fd = -1;
+    mmapptr = ptr;
+    mmapsize = size;
+    return;
+}
 
 WordsDic::~WordsDic()
 {
@@ -54,14 +62,13 @@
 
 
 /*!
-    \fn Honoka::WordsDic::find(const string &word)
+    \fn WordsDic::find(const string &word)
  */
-set<string> Honoka::WordsDic::find(const string &word)
+set<string> WordsDic::find(const string &word)
 {
     set<string> res,bres;
-    if (fd == -1) return res;
     if (word.length() > 255) return res;
-    if (fd == -1) return res;
+    if (mmapptr == 0) return res;
     char w[256],ow[256];
     for(unsigned int i = 0;i < word.length();i ++) {
         w[i] = (char)tolower(word[i]);
@@ -71,6 +78,10 @@
     ow[word.length()] = 0;
     char *p = mmapptr;
     while(p < mmapptr + mmapsize) {
+        if (p[0] == ' ') {
+            p ++;
+            continue;
+        }
         char b[256],ob[256];
         for(unsigned int i = 0;i < word.length();i ++) {
             b[i] = (char)tolower(p[i]);
@@ -92,3 +103,45 @@
     for(set<string>::iterator it = bres.begin();it != bres.end();it ++) res.insert(*it);
     return res;
 }
+
+/*!
+    \fn WordsDic::write(const string &word)
+ */
+bool WordsDic::write(const string &word)
+{
+    char *p = mmapptr;
+    // 重複チェックしつつpを末尾へ。
+    while(p < mmapptr + mmapsize) {
+        if (strncmp(word.c_str(),p,word.length()) == 0) return false;
+        while(*p != '\n') p ++;
+        p ++;
+        if (p[0] == 0) break;
+    }
+    // 空き領域サイズを確認。
+    // サイズが足らん時は頭数単語を消してシフトする。
+    if (((mmapptr + ((mmapsize - 1) * sizeof(char))) - p) < ((word.length() + 1 ) * sizeof(char))) {
+        char *np = mmapptr;
+        while(*np != 0) {
+            while(*np != '\n') np ++;
+            np ++;
+            if ((np - mmapptr) > ((word.length() + 1 ) * sizeof(char))) {
+                char *rp = mmapptr;
+                while(*np != 0) {
+                    *rp = *np;
+                    np ++;
+                    rp ++;
+                }
+                *rp = 0;
+                p = rp;
+                break;
+            }
+        }
+    }
+    // 登録。
+    strcpy(p,word.c_str());
+    p[word.length()] = '\n';
+    p[word.length() + 1] = 0;
+    return true;
+}
+
+
diff --git a/honoka-plugins/ascii/src/wordsdic.h b/honoka-plugins/ascii/src/wordsdic.h
index a911ded..854dfe9 100644
--- a/honoka-plugins/ascii/src/wordsdic.h
+++ b/honoka-plugins/ascii/src/wordsdic.h
@@ -40,9 +40,11 @@
 class WordsDic{
 public:
     WordsDic(const string &filename);
+    WordsDic(char* ptr,off_t size);
 
     ~WordsDic();
     set<string> find(const string &word);
+    bool write(const string &word);
 
 protected:
     int fd;
diff --git a/honoka-plugins/ascii/src/wordsprediction.cpp b/honoka-plugins/ascii/src/wordsprediction.cpp
index 119baf8..8b0b5b2 100644
--- a/honoka-plugins/ascii/src/wordsprediction.cpp
+++ b/honoka-plugins/ascii/src/wordsprediction.cpp
@@ -42,6 +42,9 @@
 {
     String file = cfg->read(HONOKA_CONFIG_WORDSPREDICTION_FILE,String(HONOKA_DEFAULT_WORDSPREDICTION_FILE));
     dic = new WordsDic(file);
+    //cacheData[0] = 0;
+    strcpy(cacheData,"today\n");
+    cache = new WordsDic(cacheData,1024);
     pos = 0;
     addSpace = cfg->read(HONOKA_CONFIG_WORDSPREDICTION_ADDSAW,HONOKA_DEFAULT_WORDSPREDICTION_ADDSAW);
     limit = cfg->read(HONOKA_CONFIG_WORDSPREDICTION_LIMIT,HONOKA_DEFAULT_WORDSPREDICTION_LIMIT);
@@ -61,19 +64,33 @@
     ResultList l;
     WideString word,prewords;
     for(unsigned int i = str.length();i > 0;i --) {
-        //if (isalnum(utf8_wcstombs(str).c_str()[i - 1]))
-        if (((str[i - 1] >= 0x0041) && (str[i - 1] <= 0x005A)) ||   // ��ʸ��
-            ((str[i - 1] >= 0x0061) && (str[i - 1] <= 0x007A)) ||   // ��ʸ��
-            ((str[i - 1] >= 0x0030) && (str[i - 1] <= 0x0039)) ||   // ����
-            (str[i - 1] == 0x002D))                                 // �ϥ��ե�
+        if (((str[i - 1] >= 0x0041) && (str[i - 1] <= 0x005A)) ||
+            ((str[i - 1] >= 0x0061) && (str[i - 1] <= 0x007A)) ||
+            ((str[i - 1] >= 0x0030) && (str[i - 1] <= 0x0039)) ||
+            (str[i - 1] == 0x002D))
             word = str[i - 1] + word;
         else break;
     }
     if (!word.length()) return l;
     prewords = str.substr(0,str.length() - word.length());
     pos = prewords.length();
-    set<string> res = dic->find(utf8_wcstombs(word).c_str());
-    if (res.size() > limit) {
+    //set<string> res = dic->find(utf8_wcstombs(word).c_str());
+    set<string> res;
+    set<string> cres = cache->find(utf8_wcstombs(word).c_str());
+    for(set<string>::iterator it = cres.begin();it != cres.end();it ++) {
+        set<string> r = dic->find(*it);
+        for(set<string>::iterator rit = r.begin();rit != r.end();rit ++) {
+            res.insert(*rit);
+        }
+    }
+    if (!res.size()) res = dic->find(utf8_wcstombs(word).c_str());
+/*        l.kType = PREDICTION;
+        l.Title = utf8_mbstowcs(String(_("lookup result")));
+        for(set<string>::iterator it = cres.begin();it != cres.end();it ++) {
+            if (addSpace) l.kouho.push_back(ResultEntry(prewords + utf8_mbstowcs(*it) + utf8_mbstowcs(" "),utf8_mbstowcs(*it)));
+            else l.kouho.push_back(ResultEntry(prewords + utf8_mbstowcs(*it),utf8_mbstowcs(*it)));
+        }
+*/    if (res.size() > limit) {
         l.Title = utf8_mbstowcs(String(_("too many prediction results!")));
         l.kType = PREDICTION;
         l.kouho.push_back(ResultEntry(str,word));
@@ -141,6 +158,17 @@
  */
 void WordsPrediction::update(const WideString str,const WideString yomi)
 {
+    WideString word;
+    for(unsigned int i = str.length();i > 0;i --) {
+        if (((str[i - 1] >= 0x0041) && (str[i - 1] <= 0x005A)) ||
+            ((str[i - 1] >= 0x0061) && (str[i - 1] <= 0x007A)) ||
+            ((str[i - 1] >= 0x0030) && (str[i - 1] <= 0x0039)) ||
+            (str[i - 1] == 0x002D))
+            word = str[i - 1] + word;
+        else break;
+    }
+    if (!word.length()) return;
+    cache->write(utf8_wcstombs(word).c_str());
     return;
 }
 
diff --git a/honoka-plugins/ascii/src/wordsprediction.h b/honoka-plugins/ascii/src/wordsprediction.h
index ab411cb..71ebc2c 100644
--- a/honoka-plugins/ascii/src/wordsprediction.h
+++ b/honoka-plugins/ascii/src/wordsprediction.h
@@ -49,6 +49,8 @@
 
 protected:
     WordsDic *dic;
+    WordsDic *cache;
+    char cacheData[1024];
     int pos;
     bool addSpace;
     int limit;