static char *do_completions(const char *ch, int c) { static char *completions = NULL; char *ptr; int len, cnt; if (c == 0) { // first time if (completions) free(completions); completions = NULL; len = strlen(ch); if (len > 0) len--; cnt = tab_complete(ch, &completions, &len); if (cnt == 0) return NULL; ptr = strtok_r(completions, "\n", &strtok_saveptr); } else { ptr = strtok_r(NULL, "\n", &strtok_saveptr); } return ptr ? strdup(ptr) : NULL; }
void do_tab_complete(text_message *input) { text_field *tf = input_widget->widget_info; struct compl_str completed = tab_complete(input, tf->cursor); if(completed.str != NULL) { size_t len; size_t i; /* Find the length of the data we're removing */ if(completed.type == NAME) { const char *last_space = strmrchr(input->data, input->data+tf->cursor, ' '); /* Name is a bit special because it can be anywhere in a string, * not just at the beginning like the other types. */ len = input->data+tf->cursor-1-(last_space ? last_space : (input->data-1)); } else if (completed.type == CHANNEL) { len = tf->cursor-2; } else { len = tf->cursor-1; } /* Erase the current input word */ for (i = tf->cursor; i <= input->len; i++) { input->data[i-len] = input->data[i]; } input->len -= len; tf->cursor -= len; paste_in_input_field((unsigned char*)completed.str); input->len = strlen(input->data); } }
void ctlSQLBox::OnAutoComplete(wxCommandEvent &rev) { if (GetReadOnly()) return; if (m_database == NULL) return; if (m_autocompDisabled) return; wxString what = GetCurLine().Left(GetCurrentPos() - PositionFromLine(GetCurrentLine()));; int spaceidx = what.Find(' ', true); char *tab_ret; if (spaceidx == -1) tab_ret = tab_complete(what.mb_str(wxConvUTF8), 0, what.Len() + 1, m_database); else tab_ret = tab_complete(what.mb_str(wxConvUTF8), spaceidx + 1, what.Len() + 1, m_database); if (tab_ret == NULL || tab_ret[0] == '\0') return; /* No autocomplete available for this string */ wxString wxRet = wxString(tab_ret, wxConvUTF8); free(tab_ret); // Switch to the generic list control. Native doesn't play well with // autocomplete on Mac. #ifdef __WXMAC__ wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), true); #endif if (spaceidx == -1) AutoCompShow(what.Len(), wxRet); else AutoCompShow(what.Len() - spaceidx - 1, wxRet); // Now switch back #ifdef __WXMAC__ wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), false); #endif }
/* Get an input line. * * Returns: 1 if there is input, 0 if the line should be ignored. */ static int get_input(char *inbuf, unsigned int *bp) { if (inbuf == NULL) { return 0; } wmstdio_flush(); while (wmstdio_getchar((uint8_t *)&inbuf[*bp]) == 1) { if (inbuf[*bp] == END_CHAR) { /* end of input line */ inbuf[*bp] = '\0'; *bp = 0; return 1; } if ((inbuf[*bp] == 0x08) || /* backspace */ (inbuf[*bp] == 0x7f)) { /* DEL */ if (*bp > 0) { (*bp)--; wmprintf("%c %c", 0x08, 0x08); } continue; } if (inbuf[*bp] == '\t') { inbuf[*bp] = '\0'; tab_complete(inbuf, bp); continue; } wmprintf("%c", inbuf[*bp]); (*bp)++; if (*bp >= INBUF_SIZE) { wmprintf("Error: input buffer overflow\r\n"); wmprintf(PROMPT); *bp = 0; return 0; } } return 0; }
void reset_tab_completer(void) { tab_complete(NULL, 0); }
/* * Convert key codes into ascii */ void console_in(uint8_t ascii) { uint8_t st; struct buffer *in = &Config.console.in; switch (ascii) { /* End of Text (^C) */ case 0x03: in_init(in); in_replace_char(in, '\0'); putchar('\n'); printf_P(prompt); break; /* End of Transmission (^D) */ case 0x04: GFLAGS &= ~GF_CONSOLE; term_console(); break; /* Delete (^H) */ case '\b': if (in->idx) { --in->idx; putchar('\b'); } break; /* Tab completion */ case '\t': in_replace_char(in, '\0'); switch (st = tab_complete()) { case TC_SUGGESTIONS: printf_P(prompt); printf(in->buf); break; case TC_NOTFOUND: case TC_INSERT: break; default: printf_P(PSTR("Tab Completion Error (%i)\n"), st); break; } break; /* Process command */ case '\n': in_replace_char(in, '\0'); in_init(in); putchar('\n'); switch (st = process_cmd(in->buf)) { case CMD_OK: /* Add to history */ break; case CMD_NOINPUT: break; case CMD_AMBIGUOUS: printf_P(PSTR("Ambiguous command\n")); break; case CMD_NOTFOUND: printf_P(PSTR("Unknown command\n")); break; default: printf_P(PSTR("Process Command Error (%i)\n"), st); break; } printf_P(prompt); break; default: input_putc(in, ascii); break; } }
void ConsoleImpl::update(float delta) { for(Buffer::iterator i = buffer.begin(); i != buffer.end(); ++i) { i->display_time += delta; } if (active) { InputEventLst events = InputManager::get_controller().get_events(); for (InputEventLst::iterator i = events.begin(); i != events.end(); ++i) { if ((*i).type == KEYBOARD_EVENT) { if ((*i).keyboard.key_type == KeyboardEvent::LETTER) { if (cursor_pos == int(command_line.size())) { command_line += (char)(*i).keyboard.code; cursor_pos += 1; } else { command_line.insert(cursor_pos, std::string(1, (char)(*i).keyboard.code)); cursor_pos += 1; } } else if ((*i).keyboard.key_type == KeyboardEvent::SPECIAL) { //console << "special: " << i->keyboard.code << std::endl; switch (i->keyboard.code) { case SDLK_BACKSPACE: if (!command_line.empty() && cursor_pos > 0) { command_line.erase(cursor_pos - 1, 1); cursor_pos -= 1; } break; case SDLK_DELETE: if (!command_line.empty()) { command_line.erase(cursor_pos, 1); } break; case SDLK_DOWN: if (!history.empty()) { history_position += 1; if (history_position > int(history.size())-1) history_position = int(history.size())-1; command_line = history[history_position]; cursor_pos = command_line.size(); } break; case SDLK_HOME: cursor_pos = 0; break; case SDLK_END: cursor_pos = command_line.size(); break; case SDLK_PAGEUP: console.scroll(10); break; case SDLK_PAGEDOWN: console.scroll(-10); break; case SDLK_TAB: tab_complete(); break; case SDLK_UP: if (!history.empty()) { history_position -= 1; if (history_position < 0) history_position = 0; command_line = history[history_position]; cursor_pos = command_line.size(); } break; case SDLK_LEFT: cursor_pos -= 1; if (cursor_pos < 0) cursor_pos = 0; break; case SDLK_RIGHT: cursor_pos += 1; if (cursor_pos > int(command_line.size())) cursor_pos = command_line.size(); break; case SDLK_RETURN: eval_command_line(); break; case SDLK_ESCAPE: case SDLK_F1: console.deactive(); break; } } } } } }
int main(int argc, char *argv[], char *envp[]) { read_config(); //read the config file char c; //reading one letter at time here //building a command line which will eventually get parsed line = (char *)malloc(sizeof(char) * 100); memset(line,0,100); char *cmd = (char *)malloc(sizeof(char) * 100); //the program (command w/o args) char *printBuff = (char *)malloc(sizeof(char)*100); //a printing buffer (for use with raw tty) //holder for history if stuff is typed, then history is used to go back to typed stuff char *historyHold = (char *)malloc(sizeof(char)*100); path = (char*)malloc(sizeof(char)*100); fullPath = (char*)malloc(sizeof(char)*100); memset(printBuff,0,100); memset(historyHold,0,100); memset(cmd,0,100); signal(SIGINT, handle_sig); //register interrupt signal (for CTRL+C) int promptLen; //making sure we dont backspace the prompt int fromHistory = 0; //a type of check to see if our line is from history (not user typed) if(fork() == 0) { execve("/usr/bin/clear", argv, envp); //simply clear the screen exit(1); } else { wait(NULL); //wait to clear screen } get_path(); //gets the 2dir path for prompt tty_raw_mode();//set terminal into raw mode sprintf(printBuff,"%s:%s",path,PROMPT); //build print buff promptLen = strlen(printBuff); curPos = promptLen; //leave a space write(1,printBuff,promptLen); //print initial prompt memset(printBuff,0,100); //clear printBuff clear_args(); //just get any initial crap out /* MAIN LOOP */ while(1) { read(0,&c,1); //read 1 character from stdin if(((c >= 32) && c!=127) || c == 10) { //here, we only want to process characters that are //"readable" (or enter). special characters will be //handled differently tabPressNo = 0; //they didnt press tab write(1,&c,1); //write char (echo is off for raw mode) ++curPos; switch(c) { case '\n': //end of the line (enter was pressed after input) if(line[0] == '\0') { //they didnt type anything sprintf(printBuff,"%s:%s",path,PROMPT); write(1,printBuff,promptLen); } else if(strcmp(line,"exit")==0) { printf("\n"); //for niceness quit_raw_mode(); //play nice and restore term state return 0; //quit if they type "exit" } else { //prepare to actually process strncat(line,"\0",1); if(line[0] != '!') { add_history(line); //add command to history } int pipe = 0; int separ = check_separ(line); if(!separ){ pipe = check_pipe(line); } if(!separ && !pipe){ //try to execute the command if there werent pipes or semicolons parse_args(line); //build array of arguments strcpy(cmd, args[0]); //cmd = program to run execute(cmd); clear_args(); //resets all arg array strings } c = '\0'; memset(cmd, 0, 100); //clear the cmd array //reprint prompt sprintf(printBuff,"%s:%s",path,PROMPT); promptLen = strlen(printBuff); curPos = promptLen; write(1,printBuff,promptLen); } memset(line,0,100); //clear line array memset(historyHold,0,100);//clear history hold break; default: strncat(line, &c, 1);//build the line break; } } else if(c == 8) { //backspace pressed if(curPos > promptLen) { backspace(); //backspace until we reach prompt line[strlen(line)-1] = 0; //thank god this finally works --curPos; } } else if(c == 27) { //the user pressed some sort of //escape sequence char c1; char c2; read(0,&c1,1); read(0,&c2,1); //ok, we have the two parts of the //escape sequence in c1 and c2 if(c1 == 91 && c2 == 65) { //this is the escape for the up arrow //which we want to use for history //browsing char *tmpLine; tmpLine = prev_history(); if(tmpLine != 0) { if(line[0] != '\0' && fromHistory==0) { //store what user currently has typed (if anything) memset(historyHold,0,100); strncpy(historyHold,line,strlen(line)); } clear_line(strlen(line)); //clears whatever is at the prompt memset(line,0,100); strncpy(line,tmpLine,strlen(tmpLine)); //copy this command free(tmpLine); //play nice write(1,line,strlen(line)); //write old command fromHistory = 1; //current line has been replaced by history curPos = strlen(line) + promptLen; //so we know where are } } else if(c1 == 91 && c2 == 66) { //this is the escape for the down arrow //which should make us go "forward" //in history (if we are back in it) char *tmpLine; tmpLine = next_history(); //get the next history if(tmpLine != 0) { //next_history gave us a line clear_line(strlen(line)); //clear old line from screen memset(line,0,100); //clear old line in mem strncpy(line,tmpLine,strlen(tmpLine)); //copy new line to old line write(1,line,strlen(line)); //write new line to screen curPos = strlen(line) + promptLen; //update pos free(tmpLine); } else if(historyHold[0] != '\0') { //if we dont have a next_line, lets see if //we had some buffer before browsing history clear_line(strlen(line)); memset(line,0,100); strncpy(line,historyHold,strlen(historyHold)); write(1,line,strlen(line)); curPos = strlen(line) +promptLen; fromHistory = 0; //back to user typed } else { //it was blank before history was browsed clear_line(strlen(line)); memset(line,0,100); curPos = promptLen; } } } else if(c == '\t') { //tab press. should i dare try to do tab //completion? i guess... //if this is the 2nd time in a row pressing tab //they want a listing of everything that can be //completed if(tabPressNo) { //print everything in tabHold tabPressNo = 0; if(tabCompHold[0] != NULL) { int i = 1; char *x = tabCompHold[0]; char *tmp = (char*)malloc(sizeof(char)*100); memset(tmp,0,100); write(1,"\n",1); while(x != NULL) { sprintf(tmp,"%s\t",x); write(1,tmp,strlen(tmp)); memset(tmp,0,100); x = tabCompHold[i]; ++i; } write(1,"\n",1); //reprint prompt sprintf(printBuff,"%s:%s",path,PROMPT); promptLen = strlen(printBuff); curPos = promptLen + strlen(line); write(1,printBuff,promptLen); //write the line again write(1,line,strlen(line)); clear_tab_hold(); } } else { //otherwise just let tab_complete //print a single completion char *tabcomp; tabcomp = tab_complete(line); if(tabcomp != NULL) { //tab comp found a single thing, so //lets just complete it int i = 1; char c = tabcomp[0]; while(c!='\0') { write(1,&c,1); strncat(line,&c,1); c = tabcomp[i]; ++i; } curPos += strlen(tabcomp); //set our new position free(tabcomp); } ++tabPressNo; } } else if(c == '\177') { //other form of backspace if(curPos > promptLen) { backspace(); //backspace until we reach prompt line[strlen(line)-1] = 0; //thank god this finally works --curPos; } } memset(printBuff,0,100); //clear printing buffer } printf("\n"); //for niceness quit_raw_mode(); //so we dont get stuck in it return 0; //goodbye }