19162c3688
Some of the plugins are not yet supported. If you're feeling brave you can build from source using ant.
256 lines
6.7 KiB
JavaScript
256 lines
6.7 KiB
JavaScript
'use strict';
|
|
var tabCompleteJSP = require('tabcomplete-jsp'),
|
|
isJavaObject = require('java-utils').isJavaObject;
|
|
|
|
/*
|
|
Tab Completion of the /js and /jsp commands
|
|
*/
|
|
var _javaLangObjectMethods = [
|
|
'equals'
|
|
,'getClass'
|
|
,'class'
|
|
,'getClass'
|
|
,'hashCode'
|
|
,'notify'
|
|
,'notifyAll'
|
|
,'toString'
|
|
,'wait'
|
|
,'clone'
|
|
,'finalize'
|
|
];
|
|
|
|
var _getProperties = function( o ) {
|
|
var result = [],
|
|
i,
|
|
j,
|
|
isObjectMethod,
|
|
propValue,
|
|
typeofProperty;
|
|
|
|
if ( isJavaObject( o ) ) {
|
|
/*
|
|
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;
|
|
}
|
|
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;
|
|
}
|
|
}
|
|
typeofProperty = null;
|
|
try {
|
|
propValue = o[i];
|
|
typeofProperty = typeof propValue;
|
|
} catch( e ) {
|
|
if ( e.message == 'java.lang.IllegalStateException: Entity not leashed' ) {
|
|
// wph 20131020 fail silently for Entity leashing in craftbukkit
|
|
} else {
|
|
// don't throw an error during tab completion just make a best effort to
|
|
// do the job.
|
|
}
|
|
}
|
|
if ( typeofProperty == 'function' ) {
|
|
result.push( i+'()' );
|
|
} else {
|
|
result.push( i );
|
|
}
|
|
}
|
|
} else {
|
|
if ( o.constructor == Array ) {
|
|
return result;
|
|
}
|
|
for ( i in o ) {
|
|
if ( i.match( /^[^_]/ ) ) {
|
|
if ( typeof o[i] == 'function'){
|
|
if ( ! (o[i] instanceof java.lang.Object) ) {
|
|
try {
|
|
if (o[i].constructor){} // throws error for java objects in jre7
|
|
result.push(i + '()');
|
|
} catch (e ){
|
|
result.push(i);
|
|
}
|
|
|
|
}else {
|
|
result.push( i );
|
|
}
|
|
} else {
|
|
result.push( i );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return result.sort();
|
|
};
|
|
|
|
var onTabCompleteJS = function( ) {
|
|
|
|
var _globalSymbols,
|
|
lastArg,
|
|
propsOfLastArg,
|
|
statement,
|
|
statementSyms,
|
|
lastSymbol,
|
|
parts,
|
|
name,
|
|
symbol,
|
|
lastGoodSymbol,
|
|
lastArgProp,
|
|
i,
|
|
objectProps,
|
|
candidate,
|
|
re,
|
|
li,
|
|
possibleCompletion,
|
|
result,
|
|
cmdSender,
|
|
pluginCmd,
|
|
cmdArgs;
|
|
|
|
result = arguments[0];
|
|
cmdSender = arguments[1];
|
|
if (__plugin.bukkit){
|
|
pluginCmd = arguments[2].name;
|
|
cmdArgs = arguments[4];
|
|
}
|
|
if (__plugin.canary){
|
|
cmdArgs = arguments[2];
|
|
pluginCmd = arguments[3];
|
|
}
|
|
cmdArgs = Array.prototype.slice.call( cmdArgs, 0 );
|
|
|
|
if (__plugin.canary){
|
|
// if 1st element is 'js' then splice
|
|
// there's probably a better way to do this
|
|
if (cmdArgs[0] == 'js'){
|
|
cmdArgs = cmdArgs.slice(1);
|
|
}
|
|
}
|
|
if ( pluginCmd == 'jsp' ) {
|
|
return tabCompleteJSP( result, cmdArgs );
|
|
}
|
|
|
|
global.self = cmdSender; // bring in self just for autocomplete
|
|
|
|
_globalSymbols = _getProperties(global);
|
|
|
|
lastArg = cmdArgs.length ? cmdArgs[ cmdArgs.length - 1 ] + '' : null;
|
|
propsOfLastArg = [];
|
|
statement = cmdArgs.join(' ');
|
|
|
|
statement = statement.replace(/^\s+/,'').replace(/\s+$/,'');
|
|
|
|
if ( statement.length == 0 ) {
|
|
propsOfLastArg = _globalSymbols;
|
|
} else {
|
|
if (statement.match(/\)$/)){
|
|
return;
|
|
}
|
|
statementSyms = statement.split(/[^\$a-zA-Z0-9_\.]/);
|
|
|
|
lastSymbol = statementSyms[statementSyms.length-1];
|
|
//print('DEBUG: lastSymbol=[' + lastSymbol + ']');
|
|
//
|
|
// try to complete the object ala java IDEs.
|
|
//
|
|
parts = lastSymbol.split(/\./);
|
|
name = parts[0];
|
|
|
|
symbol = global[name];
|
|
|
|
//print('DEBUG: name=' + name + ',symbol=' + symbol);
|
|
|
|
lastGoodSymbol = symbol;
|
|
if ( typeof symbol !== 'undefined' ) {
|
|
for ( i = 1; i < parts.length; i++ ) {
|
|
name = parts[i];
|
|
if ( !name ) { // fix issue #115
|
|
break;
|
|
}
|
|
try {
|
|
// this causes problems in jre if symbol is an enum and name is partial-match
|
|
symbol = symbol[name]; // this causes problem in jre8 if name is ''
|
|
} catch (e){
|
|
symbol = null;
|
|
break;
|
|
}
|
|
if ( typeof symbol == 'undefined' ) {
|
|
break;
|
|
}
|
|
// nashorn - object[missingProperty] returns null not undefined
|
|
if ( symbol == null ) {
|
|
break;
|
|
}
|
|
lastGoodSymbol = symbol;
|
|
}
|
|
if ( typeof symbol == 'undefined' || symbol === null) {
|
|
//
|
|
// look up partial matches against last good symbol
|
|
//
|
|
objectProps = _getProperties( lastGoodSymbol );
|
|
if ( name == '' ) {
|
|
// if the last symbol looks like this..
|
|
// server.
|
|
//
|
|
//print('debug:case Y1: server.');
|
|
|
|
for ( i = 0; i < objectProps.length; i++ ) {
|
|
candidate = lastSymbol + objectProps[i];
|
|
re = new RegExp( lastSymbol + '$', 'g' );
|
|
propsOfLastArg.push( lastArg.replace( re, candidate ) );
|
|
}
|
|
|
|
} else {
|
|
// it looks like this..
|
|
// server.wo
|
|
//
|
|
//print('debug:case Y2: server.wo');
|
|
|
|
li = statement.lastIndexOf(name);
|
|
for ( i = 0; i < objectProps.length; i++ ) {
|
|
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 ) );
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
//print('debug:case Y3: server');
|
|
objectProps = _getProperties( symbol );
|
|
for ( i = 0; i < objectProps.length; i++ ) {
|
|
re = new RegExp( lastSymbol+ '$', 'g' );
|
|
lastArgProp = lastArg.replace( re, lastSymbol + '.' + objectProps[i] ) ;
|
|
lastArgProp = lastArgProp.replace(/\.\./g,'.');
|
|
propsOfLastArg.push( lastArgProp );
|
|
}
|
|
}
|
|
} 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 ) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
for ( i = 0; i < propsOfLastArg.length; i++ ) {
|
|
result.add( propsOfLastArg[i] );
|
|
}
|
|
|
|
delete global.self; // delete self when no longer needed for autocomplete
|
|
};
|
|
module.exports = onTabCompleteJS;
|