From a757266aea6bdeae9cc0d021c3386dde59990cbf Mon Sep 17 00:00:00 2001 From: steveluc Date: Mon, 27 Apr 2015 10:24:37 -0700 Subject: [PATCH 1/3] Make buffer reload asynchronous so that typing is never delayed by a buffer reload. --- .gitignore | 4 ++-- TypeScript.py | 23 ++++++++++++++++++----- libs/serviceproxy.py | 8 ++++++++ 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 2eb4d640..f5874de2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ *.cache -.tmpbuf +.tmpbuf* .log* built/* ~*.docx @@ -13,4 +13,4 @@ TS.log *.pyproj *.sln ptvsd/* -.vs/* \ No newline at end of file +.vs/* diff --git a/TypeScript.py b/TypeScript.py index 17a2e04f..d23af6d8 100644 --- a/TypeScript.py +++ b/TypeScript.py @@ -281,6 +281,9 @@ def __init__(self): self.fileMap = {} self.refInfo = None self.versionST2 = False + self.tempFileMap = {} + self.tempFileList = [] + self.tmpseq = 0 def ST2(self): return self.versionST2 @@ -455,21 +458,31 @@ def sendReplaceChangesForRegions(view, regions, insertString): endLocation = getLocationFromPosition(view, region.end()) cli.service.change(view.file_name(), location, endLocation, insertString) +def recvReloadAck(reloadResp): + if reloadResp.request_seq in cli.tempFileMap: + tmpfile = cli.tempFileMap.pop(reloadResp.request_seq) + if tmpfile: + cli.tempFileList.append(tmpfile) + def getTempFileName(): - return os.path.join(pluginDir, ".tmpbuf") + seq = cli.service.seq + if len(cli.tempFileList) > 0: + tmpfile = cli.tempFileList.pop() + else: + tmpfile = os.path.join(pluginDir, ".tmpbuf"+str(cli.tmpseq)) + cli.tmpseq += 1 + cli.tempFileMap[seq] = tmpfile + return tmpfile # write the buffer of view to a temporary file and have the server reload it def reloadBuffer(view, clientInfo=None): if not view.is_loading(): - t = time.time() tmpfileName = getTempFileName() tmpfile = codecs.open(tmpfileName, "w", "utf-8") text = view.substr(sublime.Region(0, view.size())) tmpfile.write(text) tmpfile.flush() - cli.service.reload(view.file_name(), tmpfileName) - et = time.time() - print("time for reload %f" % (et - t)) + cli.service.reloadAsync(view.file_name(), tmpfileName, recvReloadAck) if not cli.ST2(): if not clientInfo: clientInfo = cli.getOrAddFile(view.file_name()) diff --git a/libs/serviceproxy.py b/libs/serviceproxy.py index 9f349da6..31f96ff7 100644 --- a/libs/serviceproxy.py +++ b/libs/serviceproxy.py @@ -111,6 +111,14 @@ def reload(self, path, alternatePath): responseDict = self.__comm.sendCmdSync(jsonStr, req.seq) return jsonhelpers.fromDict(servicedefs.ReloadResponse, responseDict) + def reloadAsync(self, path, alternatePath, onCompleted): + req = servicedefs.ReloadRequest(self.incrSeq(), servicedefs.ReloadRequestArgs(path, alternatePath)) + jsonStr = jsonhelpers.encode(req) + def onCompletedJson(responseDict): + obj = jsonhelpers.fromDict(servicedefs.ReloadResponse, responseDict) + onCompleted(obj) + self.__comm.sendCmdAsync(jsonStr, req.seq, onCompletedJson) + def rename(self, path, location=Location(1, 1)): req = servicedefs.RenameRequest(self.incrSeq(), servicedefs.FileLocationRequestArgs(path, location.line, location.offset)) jsonStr = jsonhelpers.encode(req) From 3e589c8539478637b3d9c91e2a69e819b74ed6bd Mon Sep 17 00:00:00 2001 From: steveluc Date: Mon, 27 Apr 2015 11:13:00 -0700 Subject: [PATCH 2/3] Address review comments. --- TypeScript.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/TypeScript.py b/TypeScript.py index d23af6d8..6c13de6e 100644 --- a/TypeScript.py +++ b/TypeScript.py @@ -458,21 +458,23 @@ def sendReplaceChangesForRegions(view, regions, insertString): endLocation = getLocationFromPosition(view, region.end()) cli.service.change(view.file_name(), location, endLocation, insertString) -def recvReloadAck(reloadResp): +def recv_reload_response(reloadResp): if reloadResp.request_seq in cli.tempFileMap: tmpfile = cli.tempFileMap.pop(reloadResp.request_seq) if tmpfile: cli.tempFileList.append(tmpfile) def getTempFileName(): + """ Get the first unused temp file name to avoid conflicts + """ seq = cli.service.seq if len(cli.tempFileList) > 0: - tmpfile = cli.tempFileList.pop() + temp_file_name = cli.tempFileList.pop() else: - tmpfile = os.path.join(pluginDir, ".tmpbuf"+str(cli.tmpseq)) + temp_file_name = os.path.join(pluginDir, ".tmpbuf"+str(cli.tmpseq)) cli.tmpseq += 1 - cli.tempFileMap[seq] = tmpfile - return tmpfile + cli.tempFileMap[seq] = temp_file_name + return temp_file_name # write the buffer of view to a temporary file and have the server reload it def reloadBuffer(view, clientInfo=None): @@ -482,7 +484,7 @@ def reloadBuffer(view, clientInfo=None): text = view.substr(sublime.Region(0, view.size())) tmpfile.write(text) tmpfile.flush() - cli.service.reloadAsync(view.file_name(), tmpfileName, recvReloadAck) + cli.service.reloadAsync(view.file_name(), tmpfileName, recv_reload_response) if not cli.ST2(): if not clientInfo: clientInfo = cli.getOrAddFile(view.file_name()) From 42bca4b267c8a73044e809b1db7636c66a6d9b13 Mon Sep 17 00:00:00 2001 From: steveluc Date: Mon, 27 Apr 2015 11:28:42 -0700 Subject: [PATCH 3/3] Rename variables to address review feedback --- TypeScript.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/TypeScript.py b/TypeScript.py index 6c13de6e..089ef8ee 100644 --- a/TypeScript.py +++ b/TypeScript.py @@ -281,8 +281,8 @@ def __init__(self): self.fileMap = {} self.refInfo = None self.versionST2 = False - self.tempFileMap = {} - self.tempFileList = [] + self.seq_to_tempfile_name = {} + self.available_tempfile_list = [] self.tmpseq = 0 def ST2(self): @@ -459,21 +459,21 @@ def sendReplaceChangesForRegions(view, regions, insertString): cli.service.change(view.file_name(), location, endLocation, insertString) def recv_reload_response(reloadResp): - if reloadResp.request_seq in cli.tempFileMap: - tmpfile = cli.tempFileMap.pop(reloadResp.request_seq) - if tmpfile: - cli.tempFileList.append(tmpfile) + if reloadResp.request_seq in cli.seq_to_tempfile_name: + temp_file_name = cli.seq_to_tempfile_name.pop(reloadResp.request_seq) + if temp_file_name: + cli.available_tempfile_list.append(temp_file_name) def getTempFileName(): """ Get the first unused temp file name to avoid conflicts """ seq = cli.service.seq - if len(cli.tempFileList) > 0: - temp_file_name = cli.tempFileList.pop() + if len(cli.available_tempfile_list) > 0: + temp_file_name = cli.available_tempfile_list.pop() else: temp_file_name = os.path.join(pluginDir, ".tmpbuf"+str(cli.tmpseq)) cli.tmpseq += 1 - cli.tempFileMap[seq] = temp_file_name + cli.seq_to_tempfile_name[seq] = temp_file_name return temp_file_name # write the buffer of view to a temporary file and have the server reload it