[from now] 2013/03/08 09:04:01

diff --git a/ac-typescript-client.el b/ac-typescript-client.el
index 44c9e36..c0f01c4 100644
--- a/ac-typescript-client.el
+++ b/ac-typescript-client.el
@@ -54,21 +54,24 @@
   "Second to connection timeout from server")

 (defvar ac-typescript-client/add-file-message-format
-  "{method:'add', file: '%s'}"
+  "{\"method\":\"add\", \"file\": \"%s\"}"
   "Format when send request to server to add file for using completion")

 (defvar ac-typescript-client/update-buffer-message-format
-  "{method: 'update', file: '%s', line:%d, col: %d, text:'%s'}"
+  "{\"method\": \"update\", \"file\": \"%s\", \"line\":%d, \"column\": %d, \"text\":\"%s\"}"
   "Format when send request to server to update region of file for using completion")

 (defvar ac-typescript-client/update-file-message-format
-  "{method: 'update-file', file: '%s'}"
+  "{\"method\": \"update-file\", \"file\": \"%s\"}"
   "Format when send request to server to update file for using completion")

 (defvar ac-typescript-client/completion-message-format
-  "{method: 'completion', file:'%s',line:%d,column:%d}"
+  "{\"method\": \"completion\", \"file\":\"%s\",\"line\":%d,\"column\":%d}"
   "Format when send request to server to get completion list")

+(defvar ac-typescript-client/candidate nil)
+(defvar ac-typescript-client/completion-sync nil)
+
 (defun ac-typescript-client/logger (log)
   "output log to client's log buffer"
   (when ac-typescript-client/debug-mode
@@ -81,10 +84,13 @@
 (defun ac-typescript-client/make-address ()
   (concat ac-typescript-client/server-address ":"
           (symbol-value ac-typescript-client/server-port-variable)
-          "/socket.io/1/websocket/"))
+          ))

 (defun ac-typescript-client/ws-message (websocket frame)
-  (message "ws frame: %S" (websocket-frame-payload frame)))
+  (let ((completion (websocket-frame-payload frame)))
+    (setq ac-typescript-client/candidate completion))
+  (when ac-typescript/completion-sync
+    (setq ac-typescript/completion-sync nil)))

 (defun ac-typescript-client/ws-opened (websocket)
   "Execute when websocket connection is opened."
@@ -127,7 +133,7 @@ If connecting it failed, websocket structure set nil
   (unless (ac-typescript-client/ws-open-p)
     (ac-typescript-client/open-websocket))
   (websocket-send-text ac-typescript-client/ws
-                       (json-encode message))
+                       message)
   )

 (defun ac-typescript-clinet/close-websocket ()
@@ -206,12 +212,21 @@ If connecting it failed, websocket structure set nil
                          (url-hexify-string (expand-file-name filename)) line column
                          (if (not member) 0 1))))
       (ac-typescript-client/logger (format "Get completion list : query : %s" query))
+      (setq ac-typescript-client/completion-sync t)
       (ac-typescript-client/send-message
        (format ac-typescript-client/completion-message-format
                (expand-file-name filename) line column (if (not member)
-                                                                               0 1)))
-        )
-       ))
+                                                           0 1)))
+      (let ((timeout 3) (time 0))
+        (while (and (> timeout time) ac-typescript-client/completion-sync)
+          (sit-for 0.1)
+          (setq time (+ time 0.1))))
+      (setq ac-typescript-client/completion-sync nil)
+      (let ((candidate ac-typescript-client/candidate))
+        (setq ac-typescript-client/candidate nil)
+        (json-read-from-string candidate))
+      )
+    ))

 (defun ac-typescript-client/current-pos ()
   "Get current buffer position as line and column"
diff --git a/ac-typescript.el b/ac-typescript.el
index de0a004..67bbf48 100644
--- a/ac-typescript.el
+++ b/ac-typescript.el
@@ -130,10 +130,10 @@
       ))
   )

-(defun ac-typescript/update (&rest target-buffer)
+(defun ac-typescript/update (target-buffer)
   "Register current buffer file to completion server."
   (interactive)
-  (when (eq major-mode 'typescript-mode)
+  (with-current-buffer target-buffer
     (let* ((buffer (if target-buffer target-buffer (current-buffer)))
            (buffer-filename (buffer-file-name buffer))
            (contents (buffer-substring-no-properties (point-min) (point-max)))
@@ -183,32 +183,32 @@
                                  'ac-typescript/auto-update-each-buffer)))
   (add-hook 'after-save-hook 'ac-typescript/register)

-  (defadvice ac-handle-pre-command (before ac-typescript/save-current-position () activate)
-    (when (ac-typescript/typescriptp (current-buffer))
-      (setq ac-typescript/modify-position-store (point))
-      (setq ac-typescript/buffer-modified-tick (buffer-modified-tick (current-buffer)))))
-
-  (defadvice ac-handle-post-command (before ac-typescript/update-script-with-modified () activate)
-    (when (and (ac-typescript/typescriptp (current-buffer))
-               ac-typescript/modify-position-store
-               (not (equal ac-typescript/buffer-modified-tick
-                                        (buffer-modified-tick (current-buffer))))
-               )
-      (let* ((current (point))
-             (previous ac-typescript/modify-position-store)
-             (text (if (and (not (equal ac-typescript/buffer-modified-tick
-                                        (buffer-modified-tick (current-buffer))))
-                            (> current previous))
-                       (buffer-substring-no-properties previous current)
-                     "")))
-        (setq ac-typescript/buffer-modified-tick (buffer-modified-tick (current-buffer)))
-        (ac-typescript/edit-script (current-buffer) previous
-                                   current text))
-      )
-    )
-
-  (ad-enable-advice 'ac-handle-pre-command 'before 'ac-typescript/save-current-position)
-  (ad-enable-advice 'ac-handle-post-command 'before 'ac-typescript/update-script-with-modified)
+  ;; (defadvice ac-handle-pre-command (before ac-typescript/save-current-position () activate)
+  ;;   (when (ac-typescript/typescriptp (current-buffer))
+  ;;     (setq ac-typescript/modify-position-store (point))
+  ;;     (setq ac-typescript/buffer-modified-tick (buffer-modified-tick (current-buffer)))))
+
+  ;; (defadvice ac-handle-post-command (before ac-typescript/update-script-with-modified () activate)
+  ;;   (when (and (ac-typescript/typescriptp (current-buffer))
+  ;;              ac-typescript/modify-position-store
+  ;;              (not (equal ac-typescript/buffer-modified-tick
+  ;;                                       (buffer-modified-tick (current-buffer))))
+  ;;              )
+  ;;     (let* ((current (point))
+  ;;            (previous ac-typescript/modify-position-store)
+  ;;            (text (if (and (not (equal ac-typescript/buffer-modified-tick
+  ;;                                       (buffer-modified-tick (current-buffer))))
+  ;;                           (> current previous))
+  ;;                      (buffer-substring-no-properties previous current)
+  ;;                    "")))
+  ;;       (setq ac-typescript/buffer-modified-tick (buffer-modified-tick (current-buffer)))
+  ;;       (ac-typescript/edit-script (current-buffer) previous
+  ;;                                  current text))
+  ;;     )
+  ;;   )
+
+  ;; (ad-enable-advice 'ac-handle-pre-command 'before 'ac-typescript/save-current-position)
+  ;; (ad-enable-advice 'ac-handle-post-command 'before 'ac-typescript/update-script-with-modified)

   (when (and ac-typescript/auto-register
              (ac-typescript-server/server-running-p))
diff --git a/bin/isense.js b/bin/isense.js
index 5fe134a..a1034a6 100644
--- a/bin/isense.js
+++ b/bin/isense.js
@@ -1,155 +1,157 @@
-var OptionItem = (function () {
-    function OptionItem(longname, shortname, required, value) {
-        if (typeof required === "undefined") { required = false; }
-        if (typeof value === "undefined") { value = true; }
-        this.longname = longname;
-        this.shortname = shortname;
-        this.required = required;
-        this.value = value;
-    }
-    return OptionItem;
-})();
-var Options = (function () {
-    function Options() { }
-    Options.prototype.findOption = function (argv, options) {
-        var prefix = argv.match(/^(-+)(.+)$/);
-        var isLong = true;
-        var isValidOption = true;
-        if(prefix == null) {
-            return null;
-        }
-        if(prefix.length > 1) {
-            if(prefix[1] == '-') {
-                isLong = false;
-            } else if(prefix[1] == '--') {
-                isLong = true;
-            } else {
-                isValidOption = false;
-            }
-        }
-        if(isValidOption) {
-            var result = null;
-            options.forEach(function (option) {
-                if(isLong) {
-                    if(option.longname === prefix[2]) {
-                        result = option;
-                    }
-                } else {
-                    if(option.shortname === prefix[2]) {
-                        result = option;
-                    }
-                }
-            });
-            return result;
-        } else {
-            return null;
-        }
-    };
-    Options.prototype.getValue = function (option, index, argv) {
-        if(index >= argv.length) {
-            throw "less value for option : " + option.longname;
-        }
-        return argv[index + 1];
-    };
-    Options.prototype.parse = function (options) {
-        var result = {
-        };
-        var rest = [];
-        for(var i = 2; i < process.argv.length; ++i) {
-            var option = this.findOption(process.argv[i], options);
-            if(option) {
-                if(option.value) {
-                    var value = this.getValue(option, i, process.argv);
-                    result[option.longname] = value;
-                    i++;
-                }
-            } else {
-                rest.push(process.argv[i]);
-            }
-        }
-        result['rest'] = rest;
-        return result;
-    };
-    return Options;
-})();
-var fs = require('fs');
-var opts = new Options().parse([
-    new OptionItem("port", "p"),
-    new OptionItem("debug", "d", false, false)
-]);
-var port = parseInt(opts['port']) || 8124;
-var services = require('./typeScriptCompletion')
-var typescriptLS = new services.TypeScriptLS();
-typescriptLS.addDefaultLibrary();
-var ws = require('socket.io');
-var http = require('http');
-var lsCache = null;
-function addFile(query) {
-    if(query['file']) {
-        typescriptLS.addFile(query['file'], true);
-        console.log('add file : ' + query['file']);
-        lsCache = typescriptLS.getLanguageService();
-    }
-    return '';
-}
-function basename(fname) {
-    var index = fname.lastIndexOf('/');
-    if(index == -1) {
-        return fname;
-    }
-    return fname.slice(index);
-}
-function completion(query) {
-    if(!query['file'] || !query['line'] || !query['column']) {
-        throw "parameter for completion not enough";
-    }
-    var isMember = false;
-    if(query['member']) {
-        isMember = query['member'] === '1' ? true : false;
-    }
-    var base = query['file'];
-    var line = parseInt(query['line']);
-    var column = parseInt(query['column']);
-    console.log('completion start : file [' + query['file'] + "] line : " + line + " column : " + column);
-    if(lsCache == null) {
-        lsCache = typescriptLS.getLanguageService();
-    }
-    var position = typescriptLS.lineColToPosition(base, line, column);
-    return lsCache.languageService.getCompletionsAtPosition(base, position, isMember).entries;
-}
-function updateFile(query, post) {
-    console.log('update file : file [' + query['file'] + ']');
-    typescriptLS.updateScript(query['file'], post, true);
-    lsCache = typescriptLS.getLanguageService();
-    return '';
-}
-function updateScript(query) {
-    console.log('update range in file : ' + query['file'] + " : " + query['prev'] + ' : ' + query['next'] + ' => ' + query['text']);
-    typescriptLS.editScript(query['file'], parseInt(query['prev']), parseInt(query['next']), query['text']);
-    lsCache = typescriptLS.getLanguageService();
-    return '';
-}
-var methodHandler = {
-    'add': addFile,
-    'completion': completion,
-    'update-file': updateFile,
-    'update': updateScript
-};
-var server = http.createServer(function () {
-}).listen(port, '127.0.0.1');
-var io = ws.listen(server);
-io.set("destroy upgrade", false);
-io.on('connection', function (socket) {
-    socket.on('message', function (data) {
-        console.log(data);
-        var data = JSON.parse(data);
-        if(data['method'] && methodHandler[data['method']]) {
-            response = methodHandler[data['method']](data);
-        }
-        if(data['method'] && data['method'] === 'completion') {
-            server.clients.forEach(function (client) {
-                client.send(JSON.stringify(response));
-            });
-        }
-    });
-});
+var OptionItem = (function () {
+    function OptionItem(longname, shortname, required, value) {
+        if (typeof required === "undefined") { required = false; }
+        if (typeof value === "undefined") { value = true; }
+        this.longname = longname;
+        this.shortname = shortname;
+        this.required = required;
+        this.value = value;
+    }
+    return OptionItem;
+})();
+var Options = (function () {
+    function Options() { }
+    Options.prototype.findOption = function (argv, options) {
+        var prefix = argv.match(/^(-+)(.+)$/);
+        var isLong = true;
+        var isValidOption = true;
+        if(prefix == null) {
+            return null;
+        }
+        if(prefix.length > 1) {
+            if(prefix[1] == '-') {
+                isLong = false;
+            } else if(prefix[1] == '--') {
+                isLong = true;
+            } else {
+                isValidOption = false;
+            }
+        }
+        if(isValidOption) {
+            var result = null;
+            options.forEach(function (option) {
+                if(isLong) {
+                    if(option.longname === prefix[2]) {
+                        result = option;
+                    }
+                } else {
+                    if(option.shortname === prefix[2]) {
+                        result = option;
+                    }
+                }
+            });
+            return result;
+        } else {
+            return null;
+        }
+    };
+    Options.prototype.getValue = function (option, index, argv) {
+        if(index >= argv.length) {
+            throw "less value for option : " + option.longname;
+        }
+        return argv[index + 1];
+    };
+    Options.prototype.parse = function (options) {
+        var result = {
+        };
+        var rest = [];
+        for(var i = 2; i < process.argv.length; ++i) {
+            var option = this.findOption(process.argv[i], options);
+            if(option) {
+                if(option.value) {
+                    var value = this.getValue(option, i, process.argv);
+                    result[option.longname] = value;
+                    i++;
+                }
+            } else {
+                rest.push(process.argv[i]);
+            }
+        }
+        result['rest'] = rest;
+        return result;
+    };
+    return Options;
+})();
+var fs = require('fs');
+var opts = new Options().parse([
+    new OptionItem("port", "p"),
+    new OptionItem("debug", "d", false, false)
+]);
+var port = parseInt(opts['port']) || 8124;
+var services = require('./typeScriptCompletion')
+var typescriptLS = new services.TypeScriptLS();
+typescriptLS.addDefaultLibrary();
+var http = require('http');
+var lsCache = null;
+function addFile(query) {
+    if(query['file']) {
+        typescriptLS.addFile(query['file'], true);
+        console.log('add file : ' + query['file']);
+        lsCache = typescriptLS.getLanguageService();
+    }
+    return '';
+}
+function basename(fname) {
+    var index = fname.lastIndexOf('/');
+    if(index == -1) {
+        return fname;
+    }
+    return fname.slice(index);
+}
+function completion(query) {
+    if(!query['file'] || !query['line'] || !query['column']) {
+        throw "parameter for completion not enough";
+    }
+    var isMember = false;
+    if(query['member']) {
+        isMember = query['member'] === '1' ? true : false;
+    }
+    var base = query['file'];
+    var line = parseInt(query['line']);
+    var column = parseInt(query['column']);
+    console.log('completion start : file [' + query['file'] + "] line : " + line + " column : " + column);
+    if(lsCache == null) {
+        lsCache = typescriptLS.getLanguageService();
+    }
+    var position = typescriptLS.lineColToPosition(base, line, column);
+    return lsCache.languageService.getCompletionsAtPosition(base, position, isMember).entries;
+}
+function updateFile(query) {
+    console.log('update file : file [' + query['file'] + ']');
+    typescriptLS.addFile(query['file'], true);
+    lsCache = typescriptLS.getLanguageService();
+    return '';
+}
+function updateScript(query) {
+    console.log('update range in file : ' + query['file'] + " : " + query['prev'] + ' : ' + query['next'] + ' => ' + query['text']);
+    typescriptLS.editScript(query['file'], parseInt(query['prev']), parseInt(query['next']), query['text']);
+    lsCache = typescriptLS.getLanguageService();
+    return '';
+}
+var methodHandler = {
+    'add': addFile,
+    'completion': completion,
+    'update-file': updateFile,
+    'update': updateScript
+};
+var WebSocketServer = require('ws').Server, wss = new WebSocketServer({
+    port: port
+});
+wss.on('connection', function (ws) {
+    console.log("client connected");
+    ws.on('message', function (data) {
+        var json = JSON.parse(data);
+        if(json['method'] && methodHandler[json['method']]) {
+            var response = "";
+            try  {
+                response = methodHandler[json['method']](json);
+            } catch (e) {
+                console.log(e);
+            }
+            if(json['method'] && json['method'] === 'completion') {
+                ws.send(JSON.stringify(response));
+            }
+        }
+    });
+});
+console;
diff --git a/bin/isense.ts b/bin/isense.ts
index 147636d..413f015 100644
--- a/bin/isense.ts
+++ b/bin/isense.ts
@@ -88,7 +88,6 @@ var typescriptLS = new services.TypeScriptLS();

 typescriptLS.addDefaultLibrary();

-var ws = require('socket.io');
 var http = require('http');

 var lsCache = null;
@@ -134,9 +133,10 @@ function completion(query) {
     return lsCache.languageService.getCompletionsAtPosition(base, position, isMember).entries;
 }

-function updateFile(query, post) {
+function updateFile(query) {
     console.log('update file : file [' + query['file'] + ']');
-    typescriptLS.updateScript(query['file'], post, true);
+    typescriptLS.addFile(query['file'], true);
+
     lsCache = typescriptLS.getLanguageService();
     return '';
 }
@@ -158,24 +158,23 @@ var methodHandler = {
     'update' : updateScript
 };

-var server = http.createServer(function () {}).listen(port, '127.0.0.1');
-
-var io = ws.listen(server);
-io.set("destroy upgrade", false);
+var WebSocketServer = require('ws').Server, wss = new WebSocketServer({port: port});

- io.on('connection', (socket) => {
-    socket.on('message', (data) => {
-        console.log(data);
-        var data = JSON.parse(data);
-
-        if (data['method'] && methodHandler[data['method']]) {
-            response = methodHandler[data['method']](data);
-        }
+wss.on('connection', (ws) => {
+    console.log("client connected");
+    ws.on('message', (data) => {
+        var json = JSON.parse(data);

-        if (data['method'] && data['method'] === 'completion') {
-            server.clients.forEach((client) => {
-                client.send(JSON.stringify(response));
-            });
+        if (json['method'] && methodHandler[json['method']]) {
+            var response = "";
+            try {
+                response = methodHandler[json['method']](json);
+            } catch (e) {
+                console.log(e);
+            }
+            if (json['method'] && json['method'] === 'completion') {
+                 ws.send(JSON.stringify(response));
+            }
         }
     });
 });
diff --git a/bin/typeScriptCompletion.js b/bin/typeScriptCompletion.js
index 7e7247c..369f278 100644
--- a/bin/typeScriptCompletion.js
+++ b/bin/typeScriptCompletion.js
@@ -78,7 +78,7 @@ var TypeScriptLS = (function () {
             if(err) {
                 throw err;
             }
-            _this.addScript(name, data, isResident);
+            _this.updateScript(name, data, isResident);
         });
     };
     TypeScriptLS.prototype.addScript = function (name, content, isResident) {
diff --git a/bin/typeScriptCompletion.ts b/bin/typeScriptCompletion.ts
index 8e427f5..7aebba1 100644
--- a/bin/typeScriptCompletion.ts
+++ b/bin/typeScriptCompletion.ts
@@ -83,7 +83,7 @@ export class TypeScriptLS implements Services.ILanguageServiceShimHost {
     public addFile(name: string, isResident = false) {
         fs.readFile(name, 'utf8', (err, data:string) => {
             if (err) throw err;
-            this.addScript(name, data, isResident);
+            this.updateScript(name, data, isResident);
         });
     }