2014-01-02 19:46:46 +01:00
|
|
|
'use strict';
|
2013-12-27 23:50:13 +01:00
|
|
|
var tabCompleteJSP = require('tabcomplete-jsp');
|
|
|
|
/*
|
|
|
|
Tab Completion of the /js and /jsp commands
|
|
|
|
*/
|
|
|
|
var _isJavaObject = function(o){
|
|
|
|
var result = false;
|
|
|
|
try {
|
2014-01-29 20:49:15 +01:00
|
|
|
o.hasOwnProperty( 'testForJava' );
|
2014-03-11 00:17:58 +01:00
|
|
|
} catch (e) {
|
2013-12-27 23:50:13 +01:00
|
|
|
// java will throw an error when an attempt is made to access the
|
|
|
|
// hasOwnProperty method. (it won't exist for Java objects)
|
|
|
|
result = true;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
};
|
|
|
|
var _javaLangObjectMethods = [
|
2014-01-29 20:49:15 +01:00
|
|
|
'equals'
|
|
|
|
,'getClass'
|
|
|
|
,'class'
|
|
|
|
,'getClass'
|
|
|
|
,'hashCode'
|
|
|
|
,'notify'
|
|
|
|
,'notifyAll'
|
|
|
|
,'toString'
|
|
|
|
,'wait'
|
|
|
|
,'clone'
|
|
|
|
,'finalize'
|
2013-12-27 23:50:13 +01:00
|
|
|
];
|
2014-01-29 20:49:15 +01:00
|
|
|
|
|
|
|
var _getProperties = function( o ) {
|
|
|
|
var result = [],
|
|
|
|
i,
|
|
|
|
j,
|
|
|
|
isObjectMethod,
|
|
|
|
typeofProperty;
|
2014-03-11 00:17:58 +01:00
|
|
|
|
2014-01-29 20:49:15 +01:00
|
|
|
if ( _isJavaObject( o ) ) {
|
2014-03-11 20:57:40 +01:00
|
|
|
/*
|
|
|
|
fix for issue #115 - java objects are not iterable
|
|
|
|
see: http://mail.openjdk.java.net/pipermail/nashorn-dev/2014-March/002790.html
|
|
|
|
*/
|
|
|
|
if ( typeof Object.bindProperties === 'function' ) {
|
|
|
|
var placeholder = {};
|
|
|
|
Object.bindProperties(placeholder, o);
|
|
|
|
o = placeholder;
|
|
|
|
}
|
2014-01-29 20:49:15 +01:00
|
|
|
propertyLoop:
|
|
|
|
for ( i in o ) {
|
|
|
|
//
|
|
|
|
// don't include standard Object methods
|
|
|
|
//
|
|
|
|
isObjectMethod = false;
|
|
|
|
for ( j = 0; j < _javaLangObjectMethods.length; j++ ) {
|
|
|
|
if ( _javaLangObjectMethods[j] == i ) {
|
|
|
|
continue propertyLoop;
|
2014-03-11 20:57:40 +01:00
|
|
|
}
|
2014-01-29 20:49:15 +01:00
|
|
|
}
|
|
|
|
typeofProperty = null;
|
|
|
|
try {
|
|
|
|
typeofProperty = typeof o[i];
|
|
|
|
} catch( e ) {
|
|
|
|
if ( e.message == 'java.lang.IllegalStateException: Entity not leashed' ) {
|
|
|
|
// wph 20131020 fail silently for Entity leashing in craftbukkit
|
|
|
|
} else {
|
|
|
|
throw e;
|
2013-12-27 23:50:13 +01:00
|
|
|
}
|
2014-01-29 20:49:15 +01:00
|
|
|
}
|
|
|
|
if ( typeofProperty == 'function' ) {
|
|
|
|
result.push( i+'()' );
|
|
|
|
} else {
|
|
|
|
result.push( i );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ( o.constructor == Array ) {
|
|
|
|
return result;
|
2013-12-27 23:50:13 +01:00
|
|
|
}
|
2014-01-29 20:49:15 +01:00
|
|
|
for ( i in o ) {
|
|
|
|
if ( i.match( /^[^_]/ ) ) {
|
|
|
|
if ( typeof o[i] == 'function' ) {
|
|
|
|
result.push( i+'()' );
|
2014-03-11 20:57:40 +01:00
|
|
|
} else {
|
2014-01-29 20:49:15 +01:00
|
|
|
result.push( i );
|
2014-03-11 20:57:40 +01:00
|
|
|
}
|
2014-01-29 20:49:15 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result.sort();
|
2013-12-27 23:50:13 +01:00
|
|
|
};
|
|
|
|
|
2014-01-29 20:49:15 +01:00
|
|
|
var onTabCompleteJS = function( result, cmdSender, pluginCmd, cmdAlias, cmdArgs ) {
|
2013-12-30 22:33:12 +01:00
|
|
|
|
2014-01-29 20:49:15 +01:00
|
|
|
var _globalSymbols,
|
|
|
|
lastArg,
|
|
|
|
propsOfLastArg,
|
|
|
|
statement,
|
|
|
|
statementSyms,
|
|
|
|
lastSymbol,
|
|
|
|
parts,
|
|
|
|
name,
|
|
|
|
symbol,
|
|
|
|
lastGoodSymbol,
|
2014-03-16 20:50:18 +01:00
|
|
|
lastArgProp,
|
2014-01-29 20:49:15 +01:00
|
|
|
i,
|
|
|
|
objectProps,
|
|
|
|
candidate,
|
|
|
|
re,
|
|
|
|
li,
|
|
|
|
possibleCompletion;
|
2014-01-13 22:06:17 +01:00
|
|
|
|
2014-01-29 20:49:15 +01:00
|
|
|
cmdArgs = Array.prototype.slice.call( cmdArgs, 0 );
|
2014-01-06 21:54:53 +01:00
|
|
|
|
2014-01-29 20:49:15 +01:00
|
|
|
if ( pluginCmd.name == 'jsp' ) {
|
|
|
|
return tabCompleteJSP( result, cmdSender, pluginCmd, cmdAlias, cmdArgs );
|
|
|
|
}
|
2014-03-11 00:17:58 +01:00
|
|
|
|
2014-01-29 20:49:15 +01:00
|
|
|
global.self = cmdSender; // bring in self just for autocomplete
|
2014-01-05 18:20:54 +01:00
|
|
|
|
2014-01-29 20:49:15 +01:00
|
|
|
_globalSymbols = _getProperties(global);
|
2014-01-06 21:54:53 +01:00
|
|
|
|
2014-03-11 00:17:58 +01:00
|
|
|
lastArg = cmdArgs.length ? cmdArgs[ cmdArgs.length - 1 ] + '' : null;
|
2014-01-29 20:49:15 +01:00
|
|
|
propsOfLastArg = [];
|
|
|
|
statement = cmdArgs.join(' ');
|
|
|
|
|
|
|
|
statement = statement.replace(/^\s+/,'').replace(/\s+$/,'');
|
|
|
|
|
|
|
|
if ( statement.length == 0 ) {
|
|
|
|
propsOfLastArg = _globalSymbols;
|
|
|
|
} else {
|
|
|
|
statementSyms = statement.split(/[^\$a-zA-Z0-9_\.]/);
|
2014-03-11 00:17:58 +01:00
|
|
|
|
2014-01-29 20:49:15 +01:00
|
|
|
lastSymbol = statementSyms[statementSyms.length-1];
|
|
|
|
//print('DEBUG: lastSymbol=[' + lastSymbol + ']');
|
|
|
|
//
|
|
|
|
// try to complete the object ala java IDEs.
|
|
|
|
//
|
|
|
|
parts = lastSymbol.split(/\./);
|
|
|
|
name = parts[0];
|
2014-03-11 00:17:58 +01:00
|
|
|
|
2014-01-29 20:49:15 +01:00
|
|
|
symbol = global[name];
|
2014-03-11 00:17:58 +01:00
|
|
|
|
2014-03-11 20:57:40 +01:00
|
|
|
//print('DEBUG: name=' + name + ',symbol=' + symbol);
|
|
|
|
|
2014-01-29 20:49:15 +01:00
|
|
|
lastGoodSymbol = symbol;
|
2014-03-11 00:17:58 +01:00
|
|
|
if ( typeof symbol !== 'undefined' ) {
|
2014-01-29 20:49:15 +01:00
|
|
|
for ( i = 1; i < parts.length; i++ ) {
|
|
|
|
name = parts[i];
|
2014-03-11 00:17:58 +01:00
|
|
|
if ( !name ) { // fix issue #115
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
symbol = symbol[name]; // this causes problem in jre8 if name is ''
|
2014-01-29 20:49:15 +01:00
|
|
|
if ( typeof symbol == 'undefined' ) {
|
|
|
|
break;
|
2014-03-11 20:57:40 +01:00
|
|
|
}
|
|
|
|
// nashorn - object[missingProperty] returns null not undefined
|
|
|
|
if ( symbol == null ) {
|
|
|
|
break;
|
|
|
|
}
|
2014-01-29 20:49:15 +01:00
|
|
|
lastGoodSymbol = symbol;
|
|
|
|
}
|
2014-03-11 20:57:40 +01:00
|
|
|
if ( typeof symbol == 'undefined' || symbol === null) {
|
2013-12-27 23:50:13 +01:00
|
|
|
//
|
2014-01-29 20:49:15 +01:00
|
|
|
// look up partial matches against last good symbol
|
2013-12-27 23:50:13 +01:00
|
|
|
//
|
2014-01-29 20:49:15 +01:00
|
|
|
objectProps = _getProperties( lastGoodSymbol );
|
|
|
|
if ( name == '' ) {
|
|
|
|
// if the last symbol looks like this..
|
2014-03-16 20:50:18 +01:00
|
|
|
// server.
|
2014-01-29 20:49:15 +01:00
|
|
|
//
|
2014-03-16 20:50:18 +01:00
|
|
|
//print('debug:case Y1: server.');
|
2014-01-29 20:49:15 +01:00
|
|
|
|
2014-03-11 00:17:58 +01:00
|
|
|
for ( i = 0; i < objectProps.length; i++ ) {
|
2014-01-29 20:49:15 +01:00
|
|
|
candidate = lastSymbol + objectProps[i];
|
|
|
|
re = new RegExp( lastSymbol + '$', 'g' );
|
|
|
|
propsOfLastArg.push( lastArg.replace( re, candidate ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
// it looks like this..
|
2014-03-16 20:50:18 +01:00
|
|
|
// server.wo
|
2014-01-29 20:49:15 +01:00
|
|
|
//
|
2014-03-16 20:50:18 +01:00
|
|
|
//print('debug:case Y2: server.wo');
|
2014-01-29 20:49:15 +01:00
|
|
|
|
2014-03-11 20:57:40 +01:00
|
|
|
li = statement.lastIndexOf(name);
|
|
|
|
for ( i = 0; i < objectProps.length; i++ ) {
|
2014-01-29 20:49:15 +01:00
|
|
|
if ( objectProps[i].indexOf(name) == 0 ) {
|
|
|
|
candidate = lastSymbol.substring( 0, lastSymbol.lastIndexOf( name ) );
|
|
|
|
candidate = candidate + objectProps[i];
|
|
|
|
re = new RegExp( lastSymbol + '$', 'g' );
|
|
|
|
propsOfLastArg.push( lastArg.replace( re, candidate ) );
|
2013-12-27 23:50:13 +01:00
|
|
|
}
|
2014-01-29 20:49:15 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2014-03-16 20:50:18 +01:00
|
|
|
//print('debug:case Y3: server');
|
2014-01-29 20:49:15 +01:00
|
|
|
objectProps = _getProperties( symbol );
|
|
|
|
for ( i = 0; i < objectProps.length; i++ ) {
|
|
|
|
re = new RegExp( lastSymbol+ '$', 'g' );
|
2014-03-16 20:50:18 +01:00
|
|
|
lastArgProp = lastArg.replace( re, lastSymbol + '.' + objectProps[i] ) ;
|
|
|
|
lastArgProp = lastArgProp.replace(/\.\./g,'.');
|
|
|
|
propsOfLastArg.push( lastArgProp );
|
2014-01-29 20:49:15 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for ( i = 0; i < _globalSymbols.length; i++ ) {
|
|
|
|
if ( _globalSymbols[i].indexOf(lastSymbol) == 0 ) {
|
|
|
|
possibleCompletion = _globalSymbols[i];
|
|
|
|
re = new RegExp( lastSymbol+ '$', 'g' );
|
|
|
|
propsOfLastArg.push( lastArg.replace( re, possibleCompletion ) );
|
2013-12-27 23:50:13 +01:00
|
|
|
}
|
2014-01-29 20:49:15 +01:00
|
|
|
}
|
2013-12-27 23:50:13 +01:00
|
|
|
}
|
2014-01-29 20:49:15 +01:00
|
|
|
}
|
|
|
|
for ( i = 0; i < propsOfLastArg.length; i++ ) {
|
|
|
|
result.add( propsOfLastArg[i] );
|
|
|
|
}
|
2014-01-05 18:20:54 +01:00
|
|
|
|
2014-01-29 20:49:15 +01:00
|
|
|
delete global.self; // delete self when no longer needed for autocomplete
|
2013-12-27 23:50:13 +01:00
|
|
|
};
|
|
|
|
module.exports = onTabCompleteJS;
|