void lineedit_autocomplete() { char c; if (completionCallback != NULL) { c = completeLine(&l); if (c < 0) lineedit_return(l.len); } }
/*--------------------------------------------------------------------------*/ char *completelineforjava(char *currentLine,char *stringToAdd,BOOL isFile, char *postCaretLine) { char *assembledLine = NULL; char *patternFile = getFilePartLevel(currentLine); char *patternLine = getPartLevel(currentLine); assembledLine = completeLine(currentLine,stringToAdd,patternFile,patternLine,isFile, postCaretLine); if (patternFile) {FREE(patternFile); patternFile = NULL;} if (patternLine) {FREE(patternLine); patternLine = NULL;} return assembledLine; }
static int linenoisePrompt(int fd, char *buf, size_t buflen, const char *prompt) { size_t plen = strlen(prompt); size_t pos = 0; size_t len = 0; size_t cols = getColumns(); buf[0] = '\0'; buflen--; /* Make sure there is always space for the nulterm */ /* The latest history entry is always our current buffer, that * initially is just an empty string. */ linenoiseHistoryAdd(""); history_index = history_len-1; if (write(1,prompt,plen) == -1) return -1; while(1) { char c = linenoiseReadChar(fd); if (c == 0) return len; if (c == (char)-1) { refreshLine(fd,prompt,buf,len,pos,cols); continue; } /* Only autocomplete when the callback is set. It returns < 0 when * there was an error reading from fd. Otherwise it will return the * character that should be handled next. */ if (c == 9 && completionCallback != NULL) { c = completeLine(fd,prompt,buf,buflen,&len,&pos,cols); /* Return on errors */ if (c < 0) return len; /* Read next character when 0 */ if (c == 0) continue; } switch(c) { case 13: /* enter */ history_len--; free(history[history_len]); return (int)len; case 3: /* ctrl-c */ errno = EAGAIN; return -1; case 127: /* delete */ if (len > 0 && pos < len) { memmove(buf+pos,buf+pos+1,len-pos-1); len--; buf[len] = '\0'; refreshLine(fd,prompt,buf,len,pos,cols); } break; case 8: /* backspace or ctrl-h */ if (pos > 0 && len > 0) { memmove(buf+pos-1,buf+pos,len-pos); pos--; len--; buf[len] = '\0'; refreshLine(fd,prompt,buf,len,pos,cols); } break; case 4: /* ctrl-d, remove char at right of cursor */ if (len > 1 && pos < (len-1)) { memmove(buf+pos,buf+pos+1,len-pos); len--; buf[len] = '\0'; refreshLine(fd,prompt,buf,len,pos,cols); } else if (len == 0) { history_len--; free(history[history_len]); return -1; } break; case 20: /* ctrl-t */ if (pos > 0 && pos < len) { int aux = buf[pos-1]; buf[pos-1] = buf[pos]; buf[pos] = aux; if (pos != len-1) pos++; refreshLine(fd,prompt,buf,len,pos,cols); } break; case 2: /* ctrl-b */ /* left arrow */ if (pos > 0) { pos--; refreshLine(fd,prompt,buf,len,pos,cols); } break; case 6: /* ctrl-f */ /* right arrow */ if (pos != len) { pos++; refreshLine(fd,prompt,buf,len,pos,cols); } break; case 16: /* ctrl-p */ case 14: /* ctrl-n */ /* up and down arrow: history */ if (history_len > 1) { /* Update the current history entry before to * overwrite it with tne next one. */ free(history[history_index]); history[history_index] = strdup(buf); /* Show the new entry */ history_index += (c == 16) ? -1 : 1; if (history_index < 0) { history_index = 0; break; } else if (history_index >= history_len) { history_index = history_len-1; break; } strncpy(buf,history[history_index],buflen); buf[buflen] = '\0'; len = pos = strlen(buf); refreshLine(fd,prompt,buf,len,pos,cols); } break; case 27: /* escape sequence */ break; /* should be handled by linenoiseReadChar */ default: if (len < buflen) { if (len == pos) { buf[pos] = c; pos++; len++; buf[len] = '\0'; if (plen+len < cols) { /* Avoid a full update of the line in the * trivial case. */ if (write(1,&c,1) == -1) return -1; } else { refreshLine(fd,prompt,buf,len,pos,cols); } } else { memmove(buf+pos+1,buf+pos,len-pos); buf[pos] = c; len++; pos++; buf[len] = '\0'; refreshLine(fd,prompt,buf,len,pos,cols); } } break; case 21: /* Ctrl+u, delete the whole line. */ buf[0] = '\0'; pos = len = 0; refreshLine(fd,prompt,buf,len,pos,cols); break; case 11: /* Ctrl+k, delete from current to end of line. */ buf[pos] = '\0'; len = pos; refreshLine(fd,prompt,buf,len,pos,cols); break; case 1: /* Ctrl+a, go to the start of the line */ pos = 0; refreshLine(fd,prompt,buf,len,pos,cols); break; case 5: /* ctrl+e, go to the end of the line */ pos = len; refreshLine(fd,prompt,buf,len,pos,cols); break; case 12: /* ctrl+l, clear screen */ linenoiseClearScreen(); refreshLine(fd,prompt,buf,len,pos,cols); } } return len; }
/*--------------------------------------------------------------------------*/ static void TermCompletionOnFiles(char **dictionaryFiles, int sizedictionaryFiles, char *lineBeforeCaret, char *lineAfterCaret, char *filePattern, char *defaultPattern) { if (dictionaryFiles) { if (sizedictionaryFiles == 1) { char *newline = completeLine(lineBeforeCaret, dictionaryFiles[0], filePattern, defaultPattern, TRUE, lineAfterCaret); if (newline) { clearCurrentLine(); copyLine(newline); FREE(newline); return; } } else { char *common = getCommonPart(dictionaryFiles, sizedictionaryFiles); displayCompletionDictionary(dictionaryFiles, sizedictionaryFiles, gettext("File or Directory")); displayPrompt(); newLine(); if (defaultPattern[0] == 0) { int lennewline = (int)strlen(lineBeforeCaret) + (int)strlen(lineAfterCaret); char *newline = (char*)MALLOC(sizeof(char) * (lennewline + 1)); clearCurrentLine(); if (newline) { strcpy(newline, lineBeforeCaret); strcat(newline, lineAfterCaret); copyLine(newline); FREE(newline); newline = NULL; } } else if (common) { char *newline = completeLine(lineBeforeCaret, common, filePattern, defaultPattern, TRUE, lineAfterCaret); if (newline) { clearCurrentLine(); copyLine(newline); FREE(newline); return; } else { int lennewline = (int)strlen(lineBeforeCaret) + (int)strlen(lineAfterCaret); newline = (char*)MALLOC(sizeof(char) * (lennewline + 1)); clearCurrentLine(); if (newline) { strcpy(newline, lineBeforeCaret); strcat(newline, lineAfterCaret); copyLine(newline); FREE(newline); newline = NULL; } } FREE(common); common = NULL; } } } }
/*--------------------------------------------------------------------------*/ static void TermCompletionOnAll(char *lineBeforeCaret, char *lineAfterCaret, char *defaultPattern) { if (defaultPattern) { int numberWordFound = 0; char **completionDictionaryFunctions = NULL; int sizecompletionDictionaryFunctions = 0; char **completionDictionaryCommandWords = NULL; int sizecompletionDictionaryCommandWords = 0; char **completionDictionaryMacros = NULL; int sizecompletionDictionaryMacros = 0; char **completionDictionaryVariables = NULL; int sizecompletionDictionaryVariables = 0; char **completionDictionaryHandleGraphicsProperties = NULL; int sizecompletionDictionaryHandleGraphicsProperties = 0; char **completionDictionaryFields = NULL; int sizecompletionDictionaryFields = 0; completionDictionaryFields = completionOnFields(lineBeforeCaret, defaultPattern, &sizecompletionDictionaryFields); if ((completionDictionaryFields == NULL) && strcmp(defaultPattern, "")) { completionDictionaryFunctions = completionOnFunctions(defaultPattern, &sizecompletionDictionaryFunctions); completionDictionaryCommandWords = completionOnCommandWords(defaultPattern, &sizecompletionDictionaryCommandWords); completionDictionaryMacros = completionOnMacros(defaultPattern, &sizecompletionDictionaryMacros); completionDictionaryVariables = completionOnVariablesWithoutMacros(defaultPattern, &sizecompletionDictionaryVariables); completionDictionaryHandleGraphicsProperties = completionOnHandleGraphicsProperties(defaultPattern, &sizecompletionDictionaryHandleGraphicsProperties); } numberWordFound = sizecompletionDictionaryFunctions + sizecompletionDictionaryCommandWords + sizecompletionDictionaryMacros + sizecompletionDictionaryVariables + sizecompletionDictionaryHandleGraphicsProperties + sizecompletionDictionaryFields; if (numberWordFound > 0) { if (numberWordFound == 1) { char **completionDictionary = NULL; char *new_line = NULL; if (completionDictionaryFields) { completionDictionary = completionDictionaryFields; } if (completionDictionaryFunctions) { completionDictionary = completionDictionaryFunctions; } if (completionDictionaryCommandWords) { completionDictionary = completionDictionaryCommandWords; } if (completionDictionaryMacros) { completionDictionary = completionDictionaryMacros; } if (completionDictionaryVariables) { completionDictionary = completionDictionaryVariables; } if (completionDictionaryHandleGraphicsProperties) { completionDictionary = completionDictionaryHandleGraphicsProperties; } new_line = completeLine(lineBeforeCaret, completionDictionary[0], NULL, defaultPattern, FALSE, lineAfterCaret); if (new_line) { clearCurrentLine(); copyLine(new_line); FREE(new_line); } } else { char *commonAll = NULL; if (completionDictionaryFields) { commonAll = getCommonPart(completionDictionaryFields, sizecompletionDictionaryFields); displayCompletionDictionary(completionDictionaryFields, sizecompletionDictionaryFields, (char *)_("Scilab Fields")); freeArrayOfString(completionDictionaryFields, sizecompletionDictionaryFields); } else { char *commonFunctions = getCommonPart(completionDictionaryFunctions, sizecompletionDictionaryFunctions); char *commonCommandWords = getCommonPart(completionDictionaryCommandWords, sizecompletionDictionaryCommandWords); char *commonMacros = getCommonPart(completionDictionaryMacros, sizecompletionDictionaryMacros); char *commonVariables = getCommonPart(completionDictionaryVariables, sizecompletionDictionaryVariables); char *commonHandleGraphicsProperties = getCommonPart(completionDictionaryHandleGraphicsProperties, sizecompletionDictionaryHandleGraphicsProperties); int sizecommonsDictionary = 0; char **commonsDictionary = concatenateStrings(&sizecommonsDictionary, commonFunctions, commonMacros, commonCommandWords, commonVariables, commonHandleGraphicsProperties); if (sizecommonsDictionary > 0) { if (sizecommonsDictionary == 1) { commonAll = strdup(commonsDictionary[0]); } else { commonAll = getCommonPart(commonsDictionary, sizecommonsDictionary); } freeArrayOfString(commonsDictionary, sizecommonsDictionary); } displayCompletionDictionary(completionDictionaryFunctions, sizecompletionDictionaryFunctions, (char *)_("Scilab Function")); displayCompletionDictionary(completionDictionaryCommandWords, sizecompletionDictionaryCommandWords, (char *)_("Scilab Command")); displayCompletionDictionary(completionDictionaryMacros, sizecompletionDictionaryMacros, (char *)_("Scilab Macro")); displayCompletionDictionary(completionDictionaryVariables, sizecompletionDictionaryVariables, (char *)_("Scilab Variable")); displayCompletionDictionary(completionDictionaryHandleGraphicsProperties, sizecompletionDictionaryHandleGraphicsProperties, (char *)_("Graphics handle field")); freeArrayOfString(completionDictionaryFunctions, sizecompletionDictionaryFunctions); freeArrayOfString(completionDictionaryCommandWords, sizecompletionDictionaryCommandWords); freeArrayOfString(completionDictionaryMacros, sizecompletionDictionaryMacros); freeArrayOfString(completionDictionaryVariables, sizecompletionDictionaryVariables); freeArrayOfString(completionDictionaryHandleGraphicsProperties, sizecompletionDictionaryHandleGraphicsProperties); } displayPrompt(); newLine(); if (commonAll) { char *newline = NULL; newline = completeLine(lineBeforeCaret, commonAll, NULL, defaultPattern, FALSE, lineAfterCaret); if (newline) { clearCurrentLine(); copyLine(newline); FREE(newline); } FREE(commonAll); commonAll = NULL; } } } } }
static int linenoiseEdit(struct current *current) { int history_index = 0; /* The latest history entry is always our current buffer, that * initially is just an empty string. */ linenoiseHistoryAdd(""); set_current(current, ""); refreshLine(current->prompt, current); while(1) { int dir = -1; int c = fd_read(current); #ifndef NO_COMPLETION /* Only autocomplete when the callback is set. It returns < 0 when * there was an error reading from fd. Otherwise it will return the * character that should be handled next. */ if (c == '\t' && current->pos == current->chars && completionCallback != NULL) { c = completeLine(current); /* Return on errors */ if (c < 0) return current->len; /* Read next character when 0 */ if (c == 0) continue; } #endif process_char: if (c == -1) return current->len; #ifdef USE_TERMIOS if (c == 27) { /* escape sequence */ c = check_special(current->fd); } #endif switch(c) { case '\r': /* enter */ history_len--; free(history[history_len]); return current->len; case ctrl('C'): /* ctrl-c */ errno = EAGAIN; return -1; case 127: /* backspace */ case ctrl('H'): if (remove_char(current, current->pos - 1) == 1) { refreshLine(current->prompt, current); } break; case ctrl('D'): /* ctrl-d */ if (current->len == 0) { /* Empty line, so EOF */ history_len--; free(history[history_len]); return -1; } /* Otherwise fall through to delete char to right of cursor */ case SPECIAL_DELETE: if (remove_char(current, current->pos) == 1) { refreshLine(current->prompt, current); } break; case SPECIAL_INSERT: /* Ignore. Expansion Hook. * Future possibility: Toggle Insert/Overwrite Modes */ break; case ctrl('W'): /* ctrl-w, delete word at left. save deleted chars */ /* eat any spaces on the left */ { int pos = current->pos; while (pos > 0 && get_char(current, pos - 1) == ' ') { pos--; } /* now eat any non-spaces on the left */ while (pos > 0 && get_char(current, pos - 1) != ' ') { pos--; } if (remove_chars(current, pos, current->pos - pos)) { refreshLine(current->prompt, current); } } break; case ctrl('R'): /* ctrl-r */ { /* Display the reverse-i-search prompt and process chars */ char rbuf[50]; char rprompt[80]; int rchars = 0; int rlen = 0; int searchpos = history_len - 1; rbuf[0] = 0; while (1) { int n = 0; const char *p = NULL; int skipsame = 0; int searchdir = -1; snprintf(rprompt, sizeof(rprompt), "(reverse-i-search)'%s': ", rbuf); refreshLine(rprompt, current); c = fd_read(current); if (c == ctrl('H') || c == 127) { if (rchars) { int p = utf8_index(rbuf, --rchars); rbuf[p] = 0; rlen = strlen(rbuf); } continue; } #ifdef USE_TERMIOS if (c == 27) { c = check_special(current->fd); } #endif if (c == ctrl('P') || c == SPECIAL_UP) { /* Search for the previous (earlier) match */ if (searchpos > 0) { searchpos--; } skipsame = 1; } else if (c == ctrl('N') || c == SPECIAL_DOWN) { /* Search for the next (later) match */ if (searchpos < history_len) { searchpos++; } searchdir = 1; skipsame = 1; } else if (c >= ' ') { if (rlen >= (int)sizeof(rbuf) + 3) { continue; } n = utf8_getchars(rbuf + rlen, c); rlen += n; rchars++; rbuf[rlen] = 0; /* Adding a new char resets the search location */ searchpos = history_len - 1; } else { /* Exit from incremental search mode */ break; } /* Now search through the history for a match */ for (; searchpos >= 0 && searchpos < history_len; searchpos += searchdir) { p = strstr(history[searchpos], rbuf); if (p) { /* Found a match */ if (skipsame && strcmp(history[searchpos], current->buf) == 0) { /* But it is identical, so skip it */ continue; } /* Copy the matching line and set the cursor position */ set_current(current,history[searchpos]); current->pos = utf8_strlen(history[searchpos], p - history[searchpos]); break; } } if (!p && n) { /* No match, so don't add it */ rchars--; rlen -= n; rbuf[rlen] = 0; } } if (c == ctrl('G') || c == ctrl('C')) { /* ctrl-g terminates the search with no effect */ set_current(current, ""); c = 0; } else if (c == ctrl('J')) { /* ctrl-j terminates the search leaving the buffer in place */ c = 0; } /* Go process the char normally */ refreshLine(current->prompt, current); goto process_char; } break; case ctrl('T'): /* ctrl-t */ if (current->pos > 0 && current->pos <= current->chars) { /* If cursor is at end, transpose the previous two chars */ int fixer = (current->pos == current->chars); c = get_char(current, current->pos - fixer); remove_char(current, current->pos - fixer); insert_char(current, current->pos - 1, c); refreshLine(current->prompt, current); } break; case ctrl('V'): /* ctrl-v */ if (has_room(current, 3)) { /* Insert the ^V first */ if (insert_char(current, current->pos, c)) { refreshLine(current->prompt, current); /* Now wait for the next char. Can insert anything except \0 */ c = fd_read(current); /* Remove the ^V first */ remove_char(current, current->pos - 1); if (c != -1) { /* Insert the actual char */ insert_char(current, current->pos, c); } refreshLine(current->prompt, current); } } break; case ctrl('B'): case SPECIAL_LEFT: if (current->pos > 0) { current->pos--; refreshLine(current->prompt, current); } break; case ctrl('F'): case SPECIAL_RIGHT: if (current->pos < current->chars) { current->pos++; refreshLine(current->prompt, current); } break; case SPECIAL_PAGE_UP: dir = history_len - history_index - 1; /* move to start of history */ goto history_navigation; case SPECIAL_PAGE_DOWN: dir = -history_index; /* move to 0 == end of history, i.e. current */ goto history_navigation; case ctrl('P'): case SPECIAL_UP: dir = 1; goto history_navigation; case ctrl('N'): case SPECIAL_DOWN: history_navigation: if (history_len > 1) { /* Update the current history entry before to * overwrite it with tne next one. */ free(history[history_len - 1 - history_index]); history[history_len - 1 - history_index] = strdup(current->buf); /* Show the new entry */ history_index += dir; if (history_index < 0) { history_index = 0; break; } else if (history_index >= history_len) { history_index = history_len - 1; break; } set_current(current, history[history_len - 1 - history_index]); refreshLine(current->prompt, current); } break; case ctrl('A'): /* Ctrl+a, go to the start of the line */ case SPECIAL_HOME: current->pos = 0; refreshLine(current->prompt, current); break; case ctrl('E'): /* ctrl+e, go to the end of the line */ case SPECIAL_END: current->pos = current->chars; refreshLine(current->prompt, current); break; case ctrl('U'): /* Ctrl+u, delete to beginning of line, save deleted chars. */ if (remove_chars(current, 0, current->pos)) { refreshLine(current->prompt, current); } break; case ctrl('K'): /* Ctrl+k, delete from current to end of line, save deleted chars. */ if (remove_chars(current, current->pos, current->chars - current->pos)) { refreshLine(current->prompt, current); } break; case ctrl('Y'): /* Ctrl+y, insert saved chars at current position */ if (current->capture && insert_chars(current, current->pos, current->capture)) { refreshLine(current->prompt, current); } break; case ctrl('L'): /* Ctrl+L, clear screen */ linenoiseClearScreen(); /* Force recalc of window size for serial terminals */ current->cols = 0; refreshLine(current->prompt, current); break; default: /* Only tab is allowed without ^V */ if (c == '\t' || c >= ' ') { if (insert_char(current, current->pos, c) == 1) { refreshLine(current->prompt, current); } } break; } } return current->len; }
static int linenoisePrompt(int fd, char *buf, size_t buflen, const char *prompt) { size_t plen = strlen(prompt); size_t pos = 0; size_t len = 0; size_t cols = getColumns(); int history_index = 0; #ifdef _WIN32 DWORD foo; #endif buf[0] = '\0'; buflen--; /* Make sure there is always space for the nulterm */ /* The latest history entry is always our current buffer, that * initially is just an empty string. */ linenoiseHistoryAdd(""); #ifdef _WIN32 if (!WriteConsole(hOut, prompt, (DWORD)plen, &foo, NULL)) return -1; #else if (write(fd,prompt,plen) == -1) return -1; #endif while(1) { char c; int nread; char seq[2], seq2[2]; #ifdef _WIN32 nread = win32read(&c); #else nread = read(fd,&c,1); #endif if (nread <= 0) return (int)len; /* Only autocomplete when the callback is set. It returns < 0 when * there was an error reading from fd. Otherwise it will return the * character that should be handled next. */ if (c == 9 && completionCallback != NULL) { c = completeLine(fd,prompt,buf,buflen,&len,&pos,cols); /* Return on errors */ if (c < 0) return (int)len; /* Read next character when 0 */ if (c == 0) continue; } switch(c) { case 13: /* enter */ history_len--; free(history[history_len]); return (int)len; case 3: /* ctrl-c */ errno = EAGAIN; return -1; case 127: /* backspace */ #ifdef _WIN32 /* delete in _WIN32*/ /* win32read() will send 127 for DEL and 8 for BS and Ctrl-H */ if (pos < len && len > 0) { memmove(buf+pos,buf+pos+1,len-pos); len--; buf[len] = '\0'; refreshLine(fd,prompt,buf,len,pos,cols); } break; #endif case 8: /* ctrl-h */ if (pos > 0 && len > 0) { memmove(buf+pos-1,buf+pos,len-pos); pos--; len--; buf[len] = '\0'; refreshLine(fd,prompt,buf,len,pos,cols); } break; case 4: /* ctrl-d, remove char at right of cursor */ if (len > 1 && pos < (len-1)) { memmove(buf+pos,buf+pos+1,len-pos); len--; buf[len] = '\0'; refreshLine(fd,prompt,buf,len,pos,cols); } else if (len == 0) { history_len--; free(history[history_len]); return -1; } break; case 20: /* ctrl-t */ if (pos > 0 && pos < len) { int aux = buf[pos-1]; buf[pos-1] = buf[pos]; buf[pos] = aux; if (pos != len-1) pos++; refreshLine(fd,prompt,buf,len,pos,cols); } break; case 2: /* ctrl-b */ goto left_arrow; case 6: /* ctrl-f */ goto right_arrow; case 16: /* ctrl-p */ seq[1] = 65; goto up_down_arrow; case 14: /* ctrl-n */ seq[1] = 66; goto up_down_arrow; break; case 27: /* escape sequence */ if (read(fd,seq,2) == -1) break; if (seq[0] == 91 && seq[1] == 68) { left_arrow: /* left arrow */ if (pos > 0) { pos--; refreshLine(fd,prompt,buf,len,pos,cols); } } else if (seq[0] == 91 && seq[1] == 67) { right_arrow: /* right arrow */ if (pos != len) { pos++; refreshLine(fd,prompt,buf,len,pos,cols); } } else if (seq[0] == 91 && (seq[1] == 65 || seq[1] == 66)) { up_down_arrow: /* up and down arrow: history */ if (history_len > 1) { /* Update the current history entry before to * overwrite it with tne next one. */ free(history[history_len-1-history_index]); history[history_len-1-history_index] = strdup(buf); /* Show the new entry */ history_index += (seq[1] == 65) ? 1 : -1; if (history_index < 0) { history_index = 0; break; } else if (history_index >= history_len) { history_index = history_len-1; break; } strncpy(buf,history[history_len-1-history_index],buflen); buf[buflen] = '\0'; len = pos = strlen(buf); refreshLine(fd,prompt,buf,len,pos,cols); } } else if (seq[0] == 91 && seq[1] > 48 && seq[1] < 55) { /* extended escape */ if (read(fd,seq2,2) == -1) break; if (seq[1] == 51 && seq2[0] == 126) { /* delete */ if (len > 0 && pos < len) { memmove(buf+pos,buf+pos+1,len-pos-1); len--; buf[len] = '\0'; refreshLine(fd,prompt,buf,len,pos,cols); } } } break; default: if (len < buflen) { if (len == pos) { buf[pos] = c; pos++; len++; buf[len] = '\0'; if (plen+len < cols) { /* Avoid a full update of the line in the * trivial case. */ #ifdef _WIN32 if (!WriteConsole(hOut, &c, 1, &foo, NULL)) return -1; #else if (write(fd,&c,1) == -1) return -1; #endif } else { refreshLine(fd,prompt,buf,len,pos,cols); } } else { memmove(buf+pos+1,buf+pos,len-pos); buf[pos] = c; len++; pos++; buf[len] = '\0'; refreshLine(fd,prompt,buf,len,pos,cols); } } break; case 21: /* Ctrl+u, delete the whole line. */ buf[0] = '\0'; pos = len = 0; refreshLine(fd,prompt,buf,len,pos,cols); break; case 11: /* Ctrl+k, delete from current to end of line. */ buf[pos] = '\0'; len = pos; refreshLine(fd,prompt,buf,len,pos,cols); break; case 1: /* Ctrl+a, go to the start of the line */ pos = 0; refreshLine(fd,prompt,buf,len,pos,cols); break; case 5: /* ctrl+e, go to the end of the line */ pos = len; refreshLine(fd,prompt,buf,len,pos,cols); break; case 12: /* ctrl+l, clear screen */ linenoiseClearScreen(); refreshLine(fd,prompt,buf,len,pos,cols); } } return (int)len; }
static int linenoiseEdit(char *buf, size_t buflen, const char *prompt) { struct linenoiseState l = { .buf = buf, .buflen = buflen, .prompt = prompt, .plen = strlen(prompt), .oldpos = 0, .pos = 0, .len = 0, .cols = 80, .maxrows = 0, .history_index = 0, }; /* Buffer starts empty. */ buf[0] = '\0'; buflen--; /* Make sure there is always space for the nulterm */ /* The latest history entry is always our current buffer, that * initially is just an empty string. */ linenoiseHistoryAdd(""); serial.puts(prompt); while (1) { char c; char seq[2] = {0}; c = serial.getc(); /* Only autocomplete when the callback is set. */ if (c == 9 && completionCallback != NULL) { c = completeLine(&l); /* Return on errors */ if (c < 0) return l.len; /* Read next character when 0 */ if (c == 0) continue; } switch (c) { case ENTER: /* enter */ history_len--; free(history[history_len]); return (int)l.len; case CTRL_C: return -1; case BACKSPACE: /* backspace */ case CTRL_H: /* ctrl-h */ linenoiseEditBackspace(&l); break; case CTRL_D: /* ctrl-d, remove char at right of cursor, or of the line is empty, act as end-of-file. */ if (l.len > 0) { linenoiseEditDelete(&l); } else { history_len--; free(history[history_len]); return -1; } break; case CTRL_T: /* ctrl-t, swaps current character with previous. */ if (l.pos > 0 && l.pos < l.len) { int aux = buf[l.pos - 1]; buf[l.pos - 1] = buf[l.pos]; buf[l.pos] = aux; if (l.pos != l.len - 1) l.pos++; refreshLine(&l); } break; case CTRL_B: /* ctrl-b */ linenoiseEditMoveLeft(&l); break; case CTRL_F: /* ctrl-f */ linenoiseEditMoveRight(&l); break; case CTRL_P: /* ctrl-p */ linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_PREV); break; case CTRL_N: /* ctrl-n */ linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_NEXT); break; /* escape sequence */ case ESC: seq[0] = serial.getc(); seq[1] = serial.getc(); if (seq[0] == ARROW_PREFIX && seq[1] == LEFT_ARROW) { /* Left arrow */ linenoiseEditMoveLeft(&l); } else if (seq[0] == ARROW_PREFIX && seq[1] == RIGHT_ARROW) { /* Right arrow */ linenoiseEditMoveRight(&l); } else if (seq[0] == ARROW_PREFIX && (seq[1] == UP_ARROW || seq[1] == DOWN_ARROW)) { /* Up and Down arrows */ linenoiseEditHistoryNext(&l, (seq[1] == UP_ARROW) ? LINENOISE_HISTORY_PREV : LINENOISE_HISTORY_NEXT); } //Here is also a extanded escape! break; default: linenoiseEditInsert(&l, c); break; case CTRL_U: /* Ctrl+u, delete the whole line. */ buf[0] = '\0'; l.pos = l.len = 0; refreshLine(&l); break; case CTRL_K: /* Ctrl+k, delete from current to end of line. */ buf[l.pos] = '\0'; l.len = l.pos; refreshLine(&l); break; case CTRL_A: /* Ctrl+a, go to the start of the line */ l.pos = 0; refreshLine(&l); break; case CTRL_E: /* ctrl+e, go to the end of the line */ l.pos = l.len; refreshLine(&l); break; case CTRL_L: /* ctrl+l, clear screen */ linenoiseClearScreen(); refreshLine(&l); break; case CTRL_W: /* ctrl+w, delete previous word */ linenoiseEditDeletePrevWord(&l); break; } } return l.len; } static int linenoiseRaw(char *buf, size_t buflen, const char *prompt) { int count; count = linenoiseEdit(buf, buflen, prompt); serial.puts("\n\r"); return count; }
static void TermCompletionOnAll(char *lineBeforeCaret, char *lineAfterCaret, char *defaultPattern, char **wk_buf, unsigned int *cursor, unsigned int *cursor_max) { if (defaultPattern) { int numberWordFound = 0; char **completionDictionaryFunctions = NULL; int sizecompletionDictionaryFunctions = 0; char **completionDictionaryCommandWords = NULL; int sizecompletionDictionaryCommandWords = 0; char **completionDictionaryMacros = NULL; int sizecompletionDictionaryMacros = 0; char **completionDictionaryVariables = NULL; int sizecompletionDictionaryVariables = 0; char **completionDictionaryHandleGraphicsProperties = NULL; int sizecompletionDictionaryHandleGraphicsProperties = 0; char **completionDictionaryFields = NULL; int sizecompletionDictionaryFields = 0; completionDictionaryFields = completionOnFields(lineBeforeCaret, defaultPattern, &sizecompletionDictionaryFields); if (!completionDictionaryFields && strcmp(defaultPattern, "")) { completionDictionaryFunctions = completionOnFunctions(defaultPattern, &sizecompletionDictionaryFunctions); completionDictionaryCommandWords = completionOnCommandWords(defaultPattern, &sizecompletionDictionaryCommandWords); completionDictionaryMacros = completionOnMacros(defaultPattern, &sizecompletionDictionaryMacros); completionDictionaryVariables = completionOnVariablesWithoutMacros(defaultPattern, &sizecompletionDictionaryVariables); completionDictionaryHandleGraphicsProperties = completionOnHandleGraphicsProperties(defaultPattern, &sizecompletionDictionaryHandleGraphicsProperties); } numberWordFound = sizecompletionDictionaryFunctions + sizecompletionDictionaryCommandWords + sizecompletionDictionaryMacros + sizecompletionDictionaryVariables + sizecompletionDictionaryHandleGraphicsProperties + sizecompletionDictionaryFields; if (numberWordFound > 0) { if (numberWordFound == 1) { char **completionDictionary = NULL; char *new_line = NULL; if (completionDictionaryFields) { completionDictionary = completionDictionaryFields; } if (completionDictionaryFunctions) { completionDictionary = completionDictionaryFunctions; } if (completionDictionaryCommandWords) { completionDictionary = completionDictionaryCommandWords; } if (completionDictionaryMacros) { completionDictionary = completionDictionaryMacros; } if (completionDictionaryVariables) { completionDictionary = completionDictionaryVariables; } if (completionDictionaryHandleGraphicsProperties) { completionDictionary = completionDictionaryHandleGraphicsProperties; } new_line = completeLine(lineBeforeCaret, completionDictionary[0], NULL, defaultPattern, FALSE, lineAfterCaret); if (new_line) { char buflinetmp[WK_BUF_SIZE + 1]; strcpy(buflinetmp, new_line); FREE(new_line); backspace(*cursor); erase_nchar(*cursor_max); *cursor = *cursor_max = 0; CopyLineAtPrompt(wk_buf, buflinetmp, cursor, cursor_max); } freeArrayOfString(completionDictionary, 1); } else { char *commonAll = NULL; if (completionDictionaryFields) { commonAll = getCommonPart(completionDictionaryFields, sizecompletionDictionaryFields); displayCompletionDictionary(completionDictionaryFields, sizecompletionDictionaryFields, (char *)_("Scilab Fields")); freeArrayOfString(completionDictionaryFields, sizecompletionDictionaryFields); } else { char *commonFunctions = getCommonPart(completionDictionaryFunctions, sizecompletionDictionaryFunctions); char *commonCommandWords = getCommonPart(completionDictionaryCommandWords, sizecompletionDictionaryCommandWords); char *commonMacros = getCommonPart(completionDictionaryMacros, sizecompletionDictionaryMacros); char *commonVariables = getCommonPart(completionDictionaryVariables, sizecompletionDictionaryVariables); char *commonHandleGraphicsProperties = getCommonPart(completionDictionaryHandleGraphicsProperties, sizecompletionDictionaryHandleGraphicsProperties); int sizecommonsDictionary = 0; char **commonsDictionary = concatenateStrings(&sizecommonsDictionary, commonFunctions, commonMacros, commonCommandWords, commonVariables, commonHandleGraphicsProperties); if (sizecommonsDictionary > 0) { if (sizecommonsDictionary == 1) { commonAll = strdup(commonsDictionary[0]); } else { commonAll = getCommonPart(commonsDictionary, sizecommonsDictionary); } freeArrayOfString(commonsDictionary, sizecommonsDictionary); } displayCompletionDictionary(completionDictionaryFunctions, sizecompletionDictionaryFunctions, (char *)_("Scilab Function")); displayCompletionDictionary(completionDictionaryCommandWords, sizecompletionDictionaryCommandWords, (char *)_("Scilab Command")); displayCompletionDictionary(completionDictionaryMacros, sizecompletionDictionaryMacros, (char *)_("Scilab Macro")); displayCompletionDictionary(completionDictionaryVariables, sizecompletionDictionaryVariables, (char *)_("Scilab Variable")); displayCompletionDictionary(completionDictionaryHandleGraphicsProperties, sizecompletionDictionaryHandleGraphicsProperties, (char *)_("Graphics handle field")); freeArrayOfString(completionDictionaryFunctions, sizecompletionDictionaryFunctions); freeArrayOfString(completionDictionaryCommandWords, sizecompletionDictionaryCommandWords); freeArrayOfString(completionDictionaryMacros, sizecompletionDictionaryMacros); freeArrayOfString(completionDictionaryVariables, sizecompletionDictionaryVariables); freeArrayOfString(completionDictionaryHandleGraphicsProperties, sizecompletionDictionaryHandleGraphicsProperties); } printf("\n"); backspace(*cursor); erase_nchar(*cursor_max); *cursor = *cursor_max = 0; printPrompt(WRITE_PROMPT); if (commonAll) { char *new_line = NULL; new_line = completeLine(lineBeforeCaret, commonAll, NULL, defaultPattern, FALSE, lineAfterCaret); if (new_line) { char buflinetmp[WK_BUF_SIZE + 1]; strcpy(buflinetmp, new_line); FREE(new_line); CopyLineAtPrompt(wk_buf, buflinetmp, cursor, cursor_max); } FREE(commonAll); commonAll = NULL; } } } } }
static void TermCompletionOnFiles(char **dictionaryFiles, int sizedictionaryFiles, char *lineBeforeCaret, char *lineAfterCaret, char *filePattern, char *defaultPattern, char **wk_buf, unsigned int *cursor, unsigned int *cursor_max) { if (dictionaryFiles) { if (sizedictionaryFiles == 1) { char *new_line = completeLine(lineBeforeCaret, dictionaryFiles[0], filePattern, defaultPattern, TRUE, lineAfterCaret); if (new_line) { char buflinetmp[WK_BUF_SIZE + 1]; strcpy(buflinetmp, new_line); FREE(new_line); backspace(*cursor); erase_nchar(*cursor_max); *cursor = *cursor_max = 0; CopyLineAtPrompt(wk_buf, buflinetmp, cursor, cursor_max); return; } } else { char *common = getCommonPart(dictionaryFiles, sizedictionaryFiles); displayCompletionDictionary(dictionaryFiles, sizedictionaryFiles, gettext("File or Directory")); printf("\n"); backspace(*cursor); erase_nchar(*cursor_max); *cursor = *cursor_max = 0; printPrompt(WRITE_PROMPT); if (defaultPattern[0] == 0) { int lennewline = (int)strlen(lineBeforeCaret) + (int)strlen(lineAfterCaret); char *new_line = (char *)MALLOC(sizeof(char) * (lennewline + 1)); if (new_line) { strcpy(new_line, lineBeforeCaret); strcat(new_line, lineAfterCaret); CopyLineAtPrompt(wk_buf, new_line, cursor, cursor_max); FREE(new_line); new_line = NULL; } } else if (common) { char *new_line = completeLine(lineBeforeCaret, common, filePattern, defaultPattern, TRUE, lineAfterCaret); if (new_line) { char buflinetmp[WK_BUF_SIZE + 1]; strcpy(buflinetmp, new_line); FREE(new_line); CopyLineAtPrompt(wk_buf, buflinetmp, cursor, cursor_max); } else { int lennewline = (int)strlen(lineBeforeCaret) + (int)strlen(lineAfterCaret); new_line = (char *)MALLOC(sizeof(char) * (lennewline + 1)); if (new_line) { strcpy(new_line, lineBeforeCaret); strcat(new_line, lineAfterCaret); CopyLineAtPrompt(wk_buf, new_line, cursor, cursor_max); FREE(new_line); new_line = NULL; } } } if (common) { FREE(common); common = NULL; } } } }
/* This function is the core of the line editing capability of linenoise. * It expects 'fd' to be already in "raw mode" so that every key pressed * will be returned ASAP to read(). * * The resulting string is put into 'buf' when the user type enter, or * when ctrl+d is typed. * * The function returns the length of the current buffer. */ static int linenoiseEdit(int stdin_fd, int stdout_fd, char *buf, size_t buflen, char *prompt) { struct linenoiseState l; /* Populate the linenoise state that we pass to functions implementing * specific editing functionalities. */ l.ifd = stdin_fd; l.ofd = stdout_fd; l.buf = buf; l.buflen = buflen; l.prompt = prompt; l.plen = strlen(prompt); l.oldpos = l.pos = 0; l.len = 0; l.cols = getColumns(stdin_fd, stdout_fd); l.maxrows = 0; l.history_index = 0; /* Buffer starts empty. */ l.buf[0] = '\0'; l.buflen--; /* Make sure there is always space for the nulterm */ /* The latest history entry is always our current buffer, that * initially is just an empty string. */ linenoiseHistoryAdd(""); if (write(l.ofd,prompt,l.plen) == -1) return -1; while(1) { char c; int nread; char seq[3]; nread = read(l.ifd,&c,1); if (nread <= 0) return l.len; /* Only autocomplete when the callback is set. It returns < 0 when * there was an error reading from fd. Otherwise it will return the * character that should be handled next. */ if (c == 9 && completionCallback != NULL) { c = completeLine(&l); /* Return on errors */ if (c < 0) return l.len; /* Read next character when 0 */ if (c == 0) continue; } switch(c) { case ENTER: /* enter */ history_len--; free(history[history_len]); if (mlmode) linenoiseEditMoveEnd(&l); return (int)l.len; case CTRL_C: /* ctrl-c */ errno = EAGAIN; return -1; case BACKSPACE: /* backspace */ case 8: /* ctrl-h */ linenoiseEditBackspace(&l); break; case CTRL_D: /* ctrl-d, remove char at right of cursor, or if the line is empty, act as end-of-file. */ if (l.len > 0) { linenoiseEditDelete(&l); } else { history_len--; free(history[history_len]); return -1; } break; case CTRL_T: /* ctrl-t, swaps current character with previous. */ if (l.pos > 0 && l.pos < l.len) { int aux = buf[l.pos-1]; buf[l.pos-1] = buf[l.pos]; buf[l.pos] = aux; if (l.pos != l.len-1) l.pos++; refreshLine(&l); } break; case CTRL_B: /* ctrl-b */ linenoiseEditMoveLeft(&l); break; case CTRL_F: /* ctrl-f */ linenoiseEditMoveRight(&l); break; case CTRL_P: /* ctrl-p */ linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_PREV); break; case CTRL_N: /* ctrl-n */ linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_NEXT); break; case ESC: /* escape sequence */ /* Read the next two bytes representing the escape sequence. * Use two calls to handle slow terminals returning the two * chars at different times. */ if (read(l.ifd,seq,1) == -1) break; if (read(l.ifd,seq+1,1) == -1) break; /* ESC [ sequences. */ if (seq[0] == '[') { if (seq[1] >= '0' && seq[1] <= '9') { /* Extended escape, read additional byte. */ if (read(l.ifd,seq+2,1) == -1) break; if (seq[2] == '~') { switch(seq[1]) { case '3': /* Delete key. */ linenoiseEditDelete(&l); break; } } } else { switch(seq[1]) { case 'A': /* Up */ linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_PREV); break; case 'B': /* Down */ linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_NEXT); break; case 'C': /* Right */ linenoiseEditMoveRight(&l); break; case 'D': /* Left */ linenoiseEditMoveLeft(&l); break; case 'H': /* Home */ linenoiseEditMoveHome(&l); break; case 'F': /* End*/ linenoiseEditMoveEnd(&l); break; } } } /* ESC O sequences. */ else if (seq[0] == 'O') { switch(seq[1]) { case 'H': /* Home */ linenoiseEditMoveHome(&l); break; case 'F': /* End*/ linenoiseEditMoveEnd(&l); break; } } break; default: if (linenoiseEditInsert(&l,c)) return -1; break; case CTRL_U: /* Ctrl+u, delete the whole line. */ buf[0] = '\0'; l.pos = l.len = 0; refreshLine(&l); break; case CTRL_K: /* Ctrl+k, delete from current to end of line. */ buf[l.pos] = '\0'; l.len = l.pos; refreshLine(&l); break; case CTRL_A: /* Ctrl+a, go to the start of the line */ linenoiseEditMoveHome(&l); break; case CTRL_E: /* ctrl+e, go to the end of the line */ linenoiseEditMoveEnd(&l); break; case CTRL_L: /* ctrl+l, clear screen */ linenoiseClearScreen(); refreshLine(&l); break; case CTRL_W: /* ctrl+w, delete previous word */ linenoiseEditDeletePrevWord(&l); break; } } return l.len; }