forked from phcode-dev/staging.phcode.dev
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathDocumentSync.js
More file actions
1 lines (1 loc) · 5.97 KB
/
Copy pathDocumentSync.js
File metadata and controls
1 lines (1 loc) · 5.97 KB
1
define(function(require,exports,module){const DocumentManager=require("document/DocumentManager"),EditorManager=require("editor/EditorManager"),CHANGE_DEBOUNCE_MS=400,SYNC_FULL=1,SYNC_INCREMENTAL=2;function _syncKind(client){const tds=client&&client.capabilities&&client.capabilities.textDocumentSync;if(null==tds)return SYNC_FULL;const kind="object"==typeof tds?tds.change:tds;return kind===SYNC_INCREMENTAL?SYNC_INCREMENTAL:SYNC_FULL}function _toIncrementalChanges(changeList){if(!changeList||!changeList.length)return null;const changes=[];for(let i=0;i<changeList.length;i++){const c=changeList[i];if(!(c&&c.from&&c.to&&c.text))return null;changes.push({range:{start:{line:c.from.line,character:c.from.ch},end:{line:c.to.line,character:c.to.ch}},text:c.text.join("\n")})}return changes}function _offsetAt(text,pos){let line=0,i=0;for(;line<pos.line;){const nl=text.indexOf("\n",i);if(-1===nl)return-1;i=nl+1,line++}const nextNl=text.indexOf("\n",i),lineEnd=-1===nextNl?text.length:nextNl;return i+pos.character>lineEnd?-1:i+pos.character}function _applyIncremental(text,changes){for(let i=0;i<changes.length;i++){const ch=changes[i],s=_offsetAt(text,ch.range.start),e=_offsetAt(text,ch.range.end);if(-1===s||-1===e||e<s)return null;text=text.slice(0,s)+ch.text+text.slice(e)}return text}function _contentChangesFor(syncKind,lastSentText,pendingChanges,fullResync,text){return!fullResync&&syncKind===SYNC_INCREMENTAL&&pendingChanges.length&&_applyIncremental(lastSentText,pendingChanges)===text?pendingChanges:[{text:text}]}let initialized=!1;const registeredClients=[],tracked=new Map;function _isSupported(client,doc){return!!(client&&client.capabilities&&doc)&&((!doc.isUntitled||!doc.isUntitled())&&-1!==client.languages.indexOf(doc.getLanguage().getId()))}function _clientForDoc(doc){for(let i=0;i<registeredClients.length;i++)if(_isSupported(registeredClients[i],doc))return registeredClients[i];return null}function _lspLanguageId(client,doc){const langId=doc.getLanguage().getId(),map=client.config&&client.config.languageIdMap;return map&&map[langId]||langId}function _open(client,doc){const vfsPath=doc.file.fullPath,text=doc.getText(),state={client:client,version:1,open:!0,pendingTimer:null,lastSentText:text,pendingChanges:[],fullResync:!1};tracked.set(vfsPath,state);const opened=client.notifyDidOpen(client.uriForPath(vfsPath),_lspLanguageId(client,doc),state.version,text);opened&&opened.catch&&opened.catch(function(){state.open=!1})}function _change(client,doc){const vfsPath=doc.file.fullPath,state=tracked.get(vfsPath);if(!state||!state.open)return void _open(client,doc);const text=doc.getText(),contentChanges=_contentChangesFor(_syncKind(client),state.lastSentText,state.pendingChanges,state.fullResync,text);state.version+=1,state.lastSentText=text,state.pendingChanges=[],state.fullResync=!1;const sent=client.notifyDidChange(client.uriForPath(vfsPath),state.version,contentChanges);sent&&sent.catch&&sent.catch(function(){state.fullResync=!0})}function _close(doc){const vfsPath=doc.file.fullPath,state=tracked.get(vfsPath);state&&(state.pendingTimer&&clearTimeout(state.pendingTimer),state.client.notifyDidClose(state.client.uriForPath(vfsPath)),tracked.delete(vfsPath))}function _onDocumentChange(event,doc,changeList){const client=_clientForDoc(doc);if(!client)return;const state=tracked.get(doc.file.fullPath);if(state&&state.open){if(!state.fullResync&&_syncKind(client)===SYNC_INCREMENTAL){const mapped=_toIncrementalChanges(changeList);if(mapped)for(let i=0;i<mapped.length;i++)state.pendingChanges.push(mapped[i]);else state.fullResync=!0,state.pendingChanges=[]}state.pendingTimer&&clearTimeout(state.pendingTimer),state.pendingTimer=setTimeout(function(){state.pendingTimer=null,_change(client,doc)},CHANGE_DEBOUNCE_MS)}else _open(client,doc)}function _onAfterDocumentCreate(event,doc){const client=_clientForDoc(doc);client&&!tracked.has(doc.file.fullPath)&&_open(client,doc)}function _onBeforeDocumentDelete(event,doc){_close(doc)}function _onDocumentRefreshed(event,doc){if(!tracked.has(doc.file.fullPath))return;_close(doc);const client=_clientForDoc(doc);client&&_open(client,doc)}function _onActiveEditorChange(event,current){if(!current||!current.document)return;const doc=current.document,client=_clientForDoc(doc),state=tracked.get(doc.file.fullPath);!client||state&&state.open||_open(client,doc)}function init(){initialized||(initialized=!0,DocumentManager.on(DocumentManager.EVENT_DOCUMENT_CHANGE,_onDocumentChange),DocumentManager.on(DocumentManager.EVENT_AFTER_DOCUMENT_CREATE,_onAfterDocumentCreate),DocumentManager.on(DocumentManager.EVENT_BEFORE_DOCUMENT_DELETE,_onBeforeDocumentDelete),DocumentManager.on(DocumentManager.EVENT_DOCUMENT_REFRESHED,_onDocumentRefreshed),EditorManager.on("activeEditorChange",_onActiveEditorChange))}function registerClient(client){-1===registeredClients.indexOf(client)&®isteredClients.push(client)}function openSupportedDocuments(client){const docs=DocumentManager.getAllOpenDocuments().slice(),activeEditor=EditorManager.getActiveEditor();activeEditor&&activeEditor.document&&-1===docs.indexOf(activeEditor.document)&&docs.push(activeEditor.document),docs.forEach(function(doc){_isSupported(client,doc)&&_open(client,doc)})}function flush(client,vfsPath){return new Promise(function(resolve){const doc=DocumentManager.getOpenDocumentForPath(vfsPath);if(!doc)return void resolve();const state=tracked.get(vfsPath);state&&state.open?(state.pendingTimer&&(clearTimeout(state.pendingTimer),state.pendingTimer=null),doc.getText()!==state.lastSentText&&_change(client,doc)):_open(client,doc),resolve()})}function clearServer(client){tracked.forEach(function(state,vfsPath){state.client===client&&(state.pendingTimer&&clearTimeout(state.pendingTimer),tracked.delete(vfsPath))})}exports.init=init,exports.registerClient=registerClient,exports.openSupportedDocuments=openSupportedDocuments,exports.flush=flush,exports.clearServer=clearServer,exports._toIncrementalChanges=_toIncrementalChanges,exports._applyIncremental=_applyIncremental,exports._contentChangesFor=_contentChangesFor,exports._SYNC_INCREMENTAL=SYNC_INCREMENTAL});