问题
I read somewhere that orion uses tern for code completion for JavaScript but after running the server, creating a js file and then creating another file the other file is unaware of any code in the first file.
It seems that completion only works for symbols defined in the currently open file.
Is there a way to configure tern in orion so it will produce some helpful completion instead of a working demo without any real value?
回答1:
Orion has only moved to Tern for content assist proposals a couple weeks ago (mid-April 2015).
https://bugs.eclipse.org/bugs/show_bug.cgi?id=432940
We are working on enabling multi-file support.
https://bugs.eclipse.org/bugs/show_bug.cgi?id=464821
回答2:
I have implemented a hack to load files for a particular project using a .tern-config file.
It does not work with values containing * because that would require changing the server.
This is just a simple hack and would easily break but does the job for me at the moment.
Here is how I changed the code for version 9 build S20150504-1254:
in org.eclipse.orion.client.javascript_1.0.0.v20150504-1644.jar
the file: /web/javascript/handlers/ternOccurrencesHandler.js
function sortProposals the if statement checks if file is the current open file just check if it is a value starting with /file/
replace:
if(_o === args.meta.location) {
with:
if(/^\/file\//.test(_o)) {
look for the function computeProposals and add the following code before that function:
function getFile(url){
return new Promise(function(resolve,reject){
var xhr = new XMLHttpRequest();
xhr.open('GET',url);
xhr.addEventListener("load", function(e){
//@todo: have to check something I dont think this should be called on a 404 but it is
console.log('ok, done:',xhr.responseURL);
if(xhr.status!==200){
reject('file not found:',xhr.responseURL);
return;
}
resolve(xhr.responseText);
}, false);
xhr.addEventListener("error", function(e){
console.log('an error:',e);
reject(e);
}, false);
xhr.send();
});
}
var loadFilesInTern = (function(){
var loadedConfigs = [];
var currentConfig = '';
function loadJsFileIntoTernServer(fileName,ternserver){
return getFile(fileName)
.then(function resolve(val){
ternserver.addFile(fileName,val);
},function reject(err){
console.log('an error:',fileName);
return true;
});
}
return function(location,ternserver){
var p = new Promise(function(resolve){resolve(true);});
rootPath = location.split('/').slice(0,4).join('/');
console.log('got rootpath, trying to get tern-config from:',rootPath+'/.tern-config');
return p
.then(function(){
if(!loadedConfigs[rootPath]){
return getFile(rootPath+'/.tern-config');
}else {
return loadedConfigs[rootPath];
}
})
.then(function(config){
loadedConfigs[rootPath]=config;
if(config===currentConfig){
return;
};
currentConfig = config;
var settings = JSON.parse(config);
var promises = [];
settings.loadEagerly.forEach(function(fileName){
promises.push(loadJsFileIntoTernServer(rootPath + '/' + fileName,ternserver));
});
return Promise.all(promises);
})
.then(null,function reject(e){
console.log('an error:',e);
return true;
});
p.resolve('start');
};
}());
Load the config before computing proposals (the first time)
function computeProposals(ternserver, args, callback) {
if(ternserver) {
loadFilesInTern(args.meta.location,ternserver)
.then(function(){
console.log('ternserver is now:',ternserver);
ternserver.request({
//... rest of the computeProposals code
});//close the then
} else {//original code from computeProposals
callback({request: 'completions', proposals:[]});
}
You can create a a .tern-config in the project directory and add loadEagerly files:
{
"libs": [
"browser",
"ecma5",
"jquery"
],
"loadEagerly": [
"goog/base.js",
"somefile.js",
"another file.js"
],
"plugins": {
"requirejs": {
"baseURL": "./",
"paths": {}
}
}
}
libs and plugins are ignored at the moment but other files are loaded (note that this is a simple hack that probably breaks under certain circumstances)
来源:https://stackoverflow.com/questions/29961024/eclipse-orion-code-completion