From: Dmitry Volyntsev Date: Mon, 2 Jul 2018 13:10:52 +0000 (+0300) Subject: Fixed autocompletion for global objects. X-Git-Url: http://git.kaiwu.me/postgresql/log/contrib/postgres_fdw/static/gitweb.js?a=commitdiff_plain;h=1823a952c26a5a7bf8d02a4aa395ba83bd868105;p=njs.git Fixed autocompletion for global objects. This fixes #23 issue on GitHub. --- diff --git a/njs/njs_shell.c b/njs/njs_shell.c index 40dede61..36bc1334 100644 --- a/njs/njs_shell.c +++ b/njs/njs_shell.c @@ -20,8 +20,9 @@ typedef enum { - NJS_COMPLETION_GLOBAL = 0, + NJS_COMPLETION_VAR = 0, NJS_COMPLETION_SUFFIX, + NJS_COMPLETION_GLOBAL } njs_completion_phase_t; @@ -476,6 +477,11 @@ njs_completion_handler(const char *text, int start, int end) #define njs_completion(c, i) &(((nxt_str_t *) (c)->start)[i]) +#define njs_next_phase(c) \ + (c)->index = 0; \ + (c)->phase++; \ + goto next; + static char * njs_completion_generator(const char *text, int state) { @@ -489,107 +495,123 @@ njs_completion_generator(const char *text, int state) cmpl = &njs_completion; if (state == 0) { + cmpl->phase = 0; cmpl->index = 0; cmpl->length = strlen(text); - cmpl->phase = NJS_COMPLETION_GLOBAL; + cmpl->suffix_completions = NULL; nxt_lvlhsh_each_init(&cmpl->lhe, &njs_variables_hash_proto); } - if (cmpl->phase == NJS_COMPLETION_GLOBAL) { +next: + + switch (cmpl->phase) { + case NJS_COMPLETION_VAR: + if (cmpl->vm->parser == NULL) { + njs_next_phase(cmpl); + } + for ( ;; ) { - if (cmpl->index >= cmpl->completions->items) { + var = nxt_lvlhsh_each(&cmpl->vm->parser->scope->variables, + &cmpl->lhe); + + if (var == NULL) { break; } - suffix = njs_completion(cmpl->completions, cmpl->index++); - - if (suffix->start[0] == '.' || suffix->length < cmpl->length) { + if (var->name.length < cmpl->length) { continue; } - if (strncmp(text, (char *) suffix->start, - nxt_min(suffix->length, cmpl->length)) == 0) - { - return njs_editline(suffix); + if (strncmp(text, (char *) var->name.start, cmpl->length) == 0) { + return njs_editline(&var->name); } } - if (cmpl->vm->parser != NULL) { - for ( ;; ) { - var = nxt_lvlhsh_each(&cmpl->vm->parser->scope->variables, - &cmpl->lhe); - if (var == NULL || var->name.length < cmpl->length) { - break; - } - - if (strncmp(text, (char *) var->name.start, - nxt_min(var->name.length, cmpl->length)) == 0) - { - return njs_editline(&var->name); - } - } - } + njs_next_phase(cmpl); + case NJS_COMPLETION_SUFFIX: if (cmpl->length == 0) { - return NULL; + njs_next_phase(cmpl); } - /* Getting the longest prefix before a '.' */ + if (cmpl->suffix_completions == NULL) { + /* Getting the longest prefix before a '.' */ - p = &text[cmpl->length - 1]; - while (p > text && *p != '.') { p--; } + p = &text[cmpl->length - 1]; + while (p > text && *p != '.') { p--; } - if (*p != '.') { - return NULL; - } + if (*p != '.') { + njs_next_phase(cmpl); + } - expression.start = (u_char *) text; - expression.length = p - text; + expression.start = (u_char *) text; + expression.length = p - text; - cmpl->suffix_completions = njs_vm_completions(cmpl->vm, &expression); - if (cmpl->suffix_completions == NULL) { - return NULL; + cmpl->suffix_completions = njs_vm_completions(cmpl->vm, + &expression); + if (cmpl->suffix_completions == NULL) { + njs_next_phase(cmpl); + } } - cmpl->index = 0; - cmpl->phase = NJS_COMPLETION_SUFFIX; - } + /* Getting the right-most suffix after a '.' */ - /* Getting the right-most suffix after a '.' */ + len = 0; + p = &text[cmpl->length - 1]; - len = 0; - p = &text[cmpl->length - 1]; + while (p > text && *p != '.') { + p--; + len++; + } - while (p > text && *p != '.') { - p--; - len++; - } + p++; - p++; + for ( ;; ) { + if (cmpl->index >= cmpl->suffix_completions->items) { + njs_next_phase(cmpl); + } - for ( ;; ) { - if (cmpl->index >= cmpl->suffix_completions->items) { - break; - } + suffix = njs_completion(cmpl->suffix_completions, cmpl->index++); - suffix = njs_completion(cmpl->suffix_completions, cmpl->index++); + if (len != 0 && strncmp((char *) suffix->start, p, + nxt_min(len, suffix->length)) != 0) + { + continue; + } - if (len != 0 && strncmp((char *) suffix->start, p, - nxt_min(len, suffix->length)) != 0) - { - continue; + len = suffix->length + (p - text) + 1; + completion = malloc(len); + if (completion == NULL) { + return NULL; + } + + snprintf(completion, len, "%.*s%.*s", (int) (p - text), text, + (int) suffix->length, suffix->start); + return completion; } - len = suffix->length + (p - text) + 1; - completion = malloc(len); - if (completion == NULL) { - return NULL; + case NJS_COMPLETION_GLOBAL: + if (cmpl->suffix_completions != NULL) { + /* No global completions if suffixes were found. */ + njs_next_phase(cmpl); } - snprintf(completion, len, "%.*s%.*s", (int) (p - text), text, - (int) suffix->length, suffix->start); - return completion; + for ( ;; ) { + if (cmpl->index >= cmpl->completions->items) { + break; + } + + suffix = njs_completion(cmpl->completions, cmpl->index++); + + if (suffix->start[0] == '.' || suffix->length < cmpl->length) { + continue; + } + + if (strncmp(text, (char *) suffix->start, cmpl->length) == 0) { + return njs_editline(suffix); + } + } } return NULL;