Possible implementation of global TabAutocompletion for commands
lastuniverse opened this issue ยท 17 comments
my implementation for global TAB completers of commands and some samples of plugins, such as /warp /spawn /fly /god and sign for lifts and teleports to warps and spawn
https://github.com/lastuniverse/scripcraft_plugins/blob/master/modules/last/completer.js
A living examples of using the module completer.js see links
https://github.com/lastuniverse/scripcraft_plugins/blob/master/plugins/last/last_economy.js
after line 135
https://github.com/lastuniverse/scripcraft_plugins/blob/master/plugins/last/last_warp.js
after line 564
https://github.com/lastuniverse/scripcraft_plugins/blob/master/plugins/last/last_chat.js
after line 541
https://github.com/lastuniverse/scripcraft_plugins/blob/master/plugins/last/last_spawn.js
after line 152
https://github.com/lastuniverse/scripcraft_plugins/blob/master/plugins/last/last_party.js
Starting with line 152 and up to line 251
I admit that I don't undersstand this very well yet. We'll try to make sure that this great contribution isn't lost, but I don't think it should be built-in to the plugin itself. The new website will support plugin developers and community contributions like this. I propose that when the site goes live that we focus on this code as being one of those projects.
Suggestions for all of us who will be looking at this:
- The code has Cyrillic / Russian in-line. I propose that it should be more generic, bringing in the user language at runtime.
- It needs documentation.
- It needs examples of use.
- There are many mis-spellings of English words in the code. I completely understand that English isn't your first language - and your English is much better than my Russian, Spacibo! But over time I think it would be good to get those errors corrected for anyone else who wants to read the code.
I'm not asking for these changes to be made now - I'm saying this can be a community project soon. I'll leave this task open. If you do make changes to your code, your repo would be the best place for that, and we'll just refer to the repo later.
Thanks for your patience.
I beg your pardon for my English. I have plans to make a complete translation of all comments and documentation in English for each module, library and plug-in. But unfortunately this will not happen soon. Excuse me.
Updated the contents of the repository. Incorporating the latest developments.
In https://github.com/lastuniverse/scripcraft_plugins/blob/master/modules/last/completer.js significant changes have been made, comments and examples have been added (unfortunately the comments are still in Russian). My knowledge of English does not allow for an adequate translation. I will be glad to any help in this matter.
As an example of use (with an attempt to translate comments into English):
// we connect the module of registration and autocompletion of commands
var completer = require ('last / completer');
// register the {/youcomand} command and treat it as a command for the client chat
var command = completer.addPlayerCommand ('youcomand', function (...) {...});
// register the {/youcomand help} command and treat it as a command for the client's chat
command.addComplete ('help', function (...) {...});
// register the {/youcomand data} command without the handler as a command for the client chat
var command_data = command.addComplete ('data');
// register the {/youcomand data get } command and treat it as a command for the client chat
command_data.addComplete ('get'). addComplete ('@user', function (...) {...});
// register the command {/youcomand data set } and treat it as a command for the client's chat
command_data.addComplete ('get'). addComplete ('@user'). addComplete ('@re/\d+/', function (...) {...});
// now the /youcomand command with all its parameters will be available as global, and will be autocomplete by pressing TAB
PS: thank you for taking the time. Sincerely, Lastuniverse.
Thanks for continuing the effort. We'll get to this eventually... Dosvidanya tovarish.
I think back when I forked off ScriptCraft into JSC, I was able to implement a global command registration and tab complete system: https://github.com/skewten-incubator/JSC/blob/master/src/java/net/sq10/JSC/JSCPlugin.java#L201-L226
I don't quite remember how well it worked though, but if it was in master, then I guess it worked well enough.
Note that I pass down the tabComplete event to Javascript, so it's not all done in Java, only the difficult to achieve otherwise parts (i.e. "cleanly" registering global commands). ๐
https://github.com/skewten-incubator/JSC/blob/master/src/javascript/core/lib/tabcomplete.js
I just had problems with registering global commands from javascript and tabcomplete for them. Global commands registered through the commando very much did not want autocomplete)
The main reason for which I published my version for global commands and autocompletion, and asked to include in the core scriptcraft:
To do this in JAVA is not so difficult. It was not easy to do this in JavaScript (ScriptCraft). I chose a somewhat non-standard approach. But I like the result more than all the alternatives with which I worked.
Translation of the description of this module is my first on the line.
In this example, you will learn how to register commands:
/description help
/description set {username} {you description}
/description set {username} {email}
/description delete {username}
/description list
where:
{username}
- the name of the online or offline player (online players are auto-complete by TAB)
{you description}
- any text
// We connect the module of registration and autocompletion of commands
var completer = require('last/completer');
// Create/load a data warehouse for description
var store = persist('description', {} );
// Create an array with commands and their descriptions
var help_messages = [
"/description help - this help\n",
"/description set {username} {you description} - remember for the player {username} description {you description}\n",
"/description set {username} {email} - remember for the player {username} the email address {email}\n",
"/description delete {username} - remove player description {username}\n",
"/description list - Show the list of players and their descriptions\n"
];
// We register the command `/description` without the handler
var point = completer.addPlayerCommand( 'description' );
// We register the command `/description help` and its handler as a command for the client chat
point.addComplete('help', cmd_help );
// We register the command `/description help` and its handler as a command for the client chat
point.addComplete('list', cmd_list );
// Register the command `/description set {username}` without the handler.
// Note that the third argument passed to the function, userlist_to_autocomlete.
// It returns an associative array whose keys will be added to the autocomplete list for the `/description set` command
// It's not rational to display all online and offline players as an auto-completion of the `/description set` command.
// But we do this to demonstrate the capabilities of the module `last/completer`.
// The `@any` tag is matched with any input after the `/description set` command, adding the already entered characters to the list of auto-completions.
// In our case, it will be matched against the entered user names, including the users offline.
var point_set = point.addComplete('set', undefined, userlist_to_autocomlete )
.addComplete('@any');
// Register the command `/description set {username} {email}` and set the handler for it.
point_set.addComplete('@re/(\\w+([-+.\']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*)/', cmd_set_email);
// Register the command `/description set {username} {description}` and set the handler for it.
point_set.addComplete('@any', cmd_set_description);
// Register the command `/description delete {username}`.
// We could register the processors of the `/description delete {username}` command in the same way as for the `/description set {username} ...` command.
// But to demonstrate the possibilities, I did it this way:
var point_delete = point.addComplete('delete');
// the tag `@user` will add all users online to the `/description delete` list of auto-completions.
// when processing the entered text, the `@user` tag will be matched to the names of the users online.
point_delete.addComplete('@user',cmd_delete);
// To be able to specify nicknames of offline players after the `/description delete` command, use the `@any` tag.
// Pay attention to the fact that nicknames of offline players will not be autocomplete.
// And also to the fact that the `@any` tag is matched with any input.
// So we use it last in the chain of autocomplete for the command `/description delete`.
point_delete.addComplete('@any',cmd_delete);
// handler function for the `/description` and `/description help` commands
// in `params[0]` is a `description`
// in `params[1]` is a `help`
function cmd_help(params, sender){
echo(sender, help_messages);
}
// handler function for the `/description list` command
// in `params[0]` is a `description`
// in `params[1]` is a `list`
function cmd_list(params, sender){
var description_msg = ["List of users for whom there is a description:"];
for(var name in store ){
str = name + " - ";
if( store[name].email )
str += "<"+store[name].email+"> ";
if( store[name].info )
str += store[name].info;
str+="\n";
description_msg.push(str);
}
echo(sender, description_msg);
}
// handler function for the `/description set {username} {email}` commands
// in `params[0]` is a `description`
// in `params[1]` is a `set`
// in `params[2]` is a `{username}`
// in `params[3]` is a `{email}`
function cmd_set_email(params, sender){
var name = params[2];
var email = params[3];
if( !store[name] )
store[name] = {};
store[name].email = email;
echo(sender, "e-mail address <"+email+"> has been successfully added to "+name+"'s description");
}
// handler function for the `/description set {username} {you description}` commands
// in `params[0]` is a `description`
// in `params[1]` is a `set`
// in `params[2]` is a `{username}`
// in `params[3]` is a `{you description}`
function cmd_set_description(params, sender){
params.shift();
params.shift();
var name = params.shift();
var info = params.join(" ");
if( !store[name] )
store[name] = {};
store[name].info = info;
echo(sender, "information was successfully added to "+name+"'s description");
}
// handler function for the `/description delete {username}` commands
// in `params[0]` is a `description`
// in `params[1]` is a `delete`
// in `params[2]` is a `{username}`
function cmd_delete(params, sender){
var name = params[2];
if( store[name] ){
delete store[name];
echo(sender, "description for user "+name+" successfully deleted");
}else{
echo(sender, "no user description for "+name);
}
}
// function returns an associative array whose keys are nicknames of all users registered on the server
function userlist_to_autocomlete(sender,patern){
var result = {};
var users = org.bukkit.Bukkit.getOfflinePlayers();
for(var user in users){
var name = users[user].name;
result[name] = true;
}
return result;
}
That's really great, thanks. I'd like to get the current release into production (as 3.3.0) and then put this into the very next release (3.4). It would help if someone can help to implement, test, and/or translate the contribution by @lastuniverse and his sample. The less I need to do the faster it will make it into the public eye.
For my part, I can minimize the dependencies for module completer.js, and make the documentation, and a translation for what remains. But I can not guarantee the quality of the translation. It will be necessary to attract an English-speaking person so that he reads and edits the text and comments where necessary.
I'll do it soon.
While doing work on minimizing dependencies, I had questions / suggestions:
1. Localization module
https://github.com/lastuniverse/scripcraft_plugins/blob/master/modules/last/locales.js
https://github.com/lastuniverse/scripcraft_plugins/tree/master/data/locales/plugins/last/last_viptools -
examples of localization files for Russian and English.
- used in almost all my developments, including completer.js.
I would like to leave it. Is it possible?
- currently I use the following path to store localization files
scriptcraft/data/locales/{modules|lib|plugins}/{name_of_modules|lib|plugins}/
https://github.com/lastuniverse/scripcraft_plugins/tree/master/data/locales
If you agree to include it in the modules then: I will be glad to know your opinion about where the localization files should be stored?
2. Permission module for users and groups
https://github.com/lastuniverse/scripcraft_plugins/blob/master/modules/last/permissions.js
https://github.com/lastuniverse/scripcraft_plugins/tree/master/data/config - examples of configurations for users and groups.
- used in almost all my developments, including completer.js. I have not found an alternative plug-in that can store not only information about the permissions, but also the parameters of the modules. It is very convenient for fine-tuning the capabilities of plug-ins for various groups and users. function addComplete(...) the fourth argument can take the name of the permission. If this permission is not set for the user, the command he entered will not be executed.
sample:
// the "/test" command will be executed if the user has the permission "test_plugin_name.allow_test:
var point = completer.addPlayerCommand( 'test',handler_function_1, undefined, "test_plugin_name.allow_test" );
// the command "/test user" will be executed if the permissions for the user are set to "test_plugin_name.allow_test" and "test_plugin_name.allow_test_user"
point.addComplete('user', handler_function_2, undefined, "test_plugin_name.allow_test_user" );
I would like to leave it. Is it possible?
- currently I use the path to store all the settings files
scriptcraft/data/config/{modules|lib|plugins}/{name_of_modules|lib|plugins}
https://github.com/lastuniverse/scripcraft_plugins/tree/master/data/config
If you agree to include it in the modules then: I'm happy to know your opinion on where the configuration files should be stored?
3. Modules:
- https://github.com/lastuniverse/scripcraft_plugins/blob/master/modules/last/users.js - used for centralized storage of information by various plug-ins. The information is tied to the user. The module has a primitive cache for quick access to online user data. It is planned to finalize.
- https://github.com/lastuniverse/scripcraft_plugins/blob/master/modules/last/eventemmiter.js - third-party implementation of EventEmmiter.
- https://github.com/lastuniverse/scripcraft_plugins/blob/master/modules/last/eventex.js - a wrapper that creates a global instance of the EventEmmiter class.
I would like to leave these modules too. Is it possible?
made a description of the module locales.js
I just got back from a trip and honestly do not yet understand the recent proposals, but will get into it in-depth as possible.
@walterhiggins has been careful not to add bulk to the ScriptCraftJS code with non-critical code, and that policy will be respected in upcoming releases. You've already added your code into modules, which is where contributions like this are intended to go. Rather than adding your contribution into this plugin itself, it might be better to offer your code in GitHub as a separate ScriptCraftJS module, with separate doc as you have them, and instructions for copying files into the scriptcraft/modules folder.
One of the features of the new website is that it will provide a catalog of contributions like this which people can add to their servers - like a Bukkit repo but just for this plugin. Eventually people will be able to rate and discuss these addons.
In any case, please keep topics focused- we'll eventually process your tab completion in this ticket and we can discuss localization separately.
Thanks!
I'm looking forward to the new site and the opportunity to spread on it my work
I will be grateful if you answer a few questions.
- How long is the estimated time before launching a new site with voiced capabilities?
- In which languages / frameworks is this site built?
- How can I speed up site commissioning?
- What kind of help can I give you for the site?
PS: I have perfectly mastered express.js and webix. If my knowledge will be useful to you, I will be happy to help.
I just posted a blog on the topic.