add expansions of IDs and references to IDs

This commit is contained in:
Axel Kohlmeyer
2020-10-04 06:02:14 -04:00
parent 9dfb715296
commit 2eb07f7427

View File

@ -52,6 +52,9 @@ const char *lmp_style[] = {"atom", "integrate", "minimize", "pair", "bond",
"angle", "dihedral", "improper", "kspace", "fix",
"compute", "region", "dump"};
enum { COMPUTE_ID, DUMP_ID, FIX_ID, MOLECULE_ID, REGION_ID, VARIABLE_ID };
const char *lmp_id[] = {"compute", "dump", "fix", "molecule", "region", "variable"};
std::vector<std::string> commands;
// this list of commands is generated by:
@ -152,6 +155,46 @@ template <int STYLE> char *style_generator(const char *text, int state)
return nullptr;
}
template <int ID> char *id_generator(const char *text, int state)
{
static int idx, num, len;
if (!state) {
idx = 0;
num = lammps_id_count(lmp, lmp_id[ID]);
len = strlen(text);
}
while (idx < num) {
lammps_id_name(lmp, lmp_id[ID], idx, buf, buflen);
++idx;
if ((len == 0) || (strncmp(text, buf, len) == 0)) return dupstring(buf);
}
return nullptr;
}
template <int ID, char PREFIX> char *ref_generator(const char *text, int state)
{
char prefix[] = "X_";
prefix[0] = PREFIX;
if (strncmp(text, prefix, 2) == 0) {
char *id = id_generator<ID>(text + 2, state);
char *ref = nullptr;
if (id) {
ref = (char *)malloc(strlen(id) + 3);
if (ref) {
ref[0] = PREFIX;
ref[1] = '_';
ref[2] = 0;
strcat(ref, id);
}
free(id);
}
return ref;
}
return nullptr;
}
extern "C" {
static char *cmd_generator(const char *text, int state)
{
@ -168,6 +211,57 @@ static char *cmd_generator(const char *text, int state)
return nullptr;
}
static char *compute_id_generator(const char *text, int state)
{
return id_generator<COMPUTE_ID>(text, state);
}
static char *compute_ref_generator(const char *text, int state)
{
return ref_generator<COMPUTE_ID, 'c'>(text, state);
}
static char *dump_id_generator(const char *text, int state)
{
return id_generator<DUMP_ID>(text, state);
}
static char *fix_id_generator(const char *text, int state)
{
return id_generator<FIX_ID>(text, state);
}
static char *fix_ref_generator(const char *text, int state)
{
return ref_generator<FIX_ID, 'f'>(text, state);
}
static char *variable_ref_generator(const char *text, int state)
{
return ref_generator<VARIABLE_ID, 'v'>(text, state);
}
static char *variable_expand_generator(const char *text, int state)
{
if (strncmp(text, "${", 2) == 0) {
char *id = id_generator<VARIABLE_ID>(text + 2, state);
char *ref = nullptr;
if (id) {
ref = (char *)malloc(strlen(id) + 4);
if (ref) {
ref[0] = '$';
ref[1] = '{';
ref[2] = 0;
strcat(ref, id);
strcat(ref, "}");
}
free(id);
}
return ref;
}
return nullptr;
}
static char *atom_generator(const char *text, int state)
{
return style_generator<ATOM_STYLE>(text, state);
@ -262,10 +356,18 @@ static char **cmd_completion(const char *text, int start, int)
matches = rl_completion_matches(text, cmd_generator);
} else {
// try to provide context specific matches
// first split the already completed text
// first split the already completed text into words for position specific expansion
auto words = utils::split_words(std::string(rl_line_buffer).substr(0, start));
if (words.size() == 1) { // expand second word
if (strncmp(text, "c_", 2) == 0) { // expand references to computes or fixes
matches = rl_completion_matches(text, compute_ref_generator);
} else if (strncmp(text, "f_", 2) == 0) {
matches = rl_completion_matches(text, fix_ref_generator);
} else if (strncmp(text, "v_", 2) == 0) {
matches = rl_completion_matches(text, variable_ref_generator);
} else if (strncmp(text, "${", 2) == 0) {
matches = rl_completion_matches(text, variable_expand_generator);
} else if (words.size() == 1) { // expand second word
if (words[0] == "atom_style") {
matches = rl_completion_matches(text, atom_generator);
} else if (words[0] == "pair_style") {
@ -284,6 +386,12 @@ static char **cmd_completion(const char *text, int start, int)
matches = rl_completion_matches(text, integrate_generator);
} else if (words[0] == "min_style") {
matches = rl_completion_matches(text, minimize_generator);
} else if (words[0] == "compute_modify") {
matches = rl_completion_matches(text, compute_id_generator);
} else if (words[0] == "dump_modify") {
matches = rl_completion_matches(text, dump_id_generator);
} else if (words[0] == "fix_modify") {
matches = rl_completion_matches(text, fix_id_generator);
}
} else if (words.size() == 2) { // expand third word
@ -431,6 +539,7 @@ int main(int argc, char **argv)
char *line;
std::string trimmed;
std::cout << "LAMMPS Shell version 1.0\n";
lmp = lammps_open_no_mpi(argc, argv, nullptr);
if (lmp == nullptr) return 1;