/* * A generic file completion routine. */ static unsigned char file_complete(EditLine *el, int ch) { static char word[LINESIZE]; const LineInfo *lf; size_t word_len; int dolist; lf = el_line(el); #ifdef EMACS_CTRL_D_BINDING_HACK { int cc_ret; if ((cc_ret = emacs_ctrl_d(el, lf, ch)) != -1) return cc_ret; } #endif /* EMACS_CTRL_D_BINDING_HACK */ word_len = lf->cursor - lf->buffer; if (word_len + 1 > sizeof(word)) return CC_ERROR; (void)strlcpy(word, lf->buffer, word_len + 1); /* do not use estrlcpy here! */ if ((dolist = get_dolist(lf)) == -1) return CC_ERROR; return complete_filename(el, word, dolist); }
graphicsLib_gSurface *draw::get_object_graphic(int obj_id) { std::map<unsigned int, graphicsLib_gSurface>::iterator it; graphicsLib_gSurface temp_sprite; it = objects_sprite_list.find(obj_id); if (it == objects_sprite_list.end()) { // there is no graphic with this key yet, add it std::string graphic_filename(game_data.objects[obj_id].graphic_filename); std::string complete_filename(FILEPATH + "data/images/sprites/objects/" + graphic_filename); graphLib.surfaceFromFile(complete_filename, &temp_sprite); objects_sprite_list.insert(std::pair<unsigned int, graphicsLib_gSurface>(obj_id, temp_sprite)); } else { return &(*it).second; } }
/* read in a command line */ void readcommandEnhanced(char * const str, const int maxlen) { unsigned char insert = 1; unsigned ch; #ifdef FEATURE_FILENAME_COMPLETION unsigned lastch = 0; #endif #ifdef FEATURE_HISTORY int histLevel = 0; char prvLine[MAX_INTERNAL_COMMAND_SIZE]; #endif unsigned curx; unsigned cury; int count; unsigned current = 0; unsigned charcount = 0; assert(str); assert(maxlen <= MAX_INTERNAL_COMMAND_SIZE); /* if echo off, don't print prompt */ if(echo) printprompt(); orgx = wherex(); orgy = wherey(); memset(str, 0, maxlen); _setcursortype(_NORMALCURSOR); #ifdef FEATURE_HISTORY histGet(histLevel - 1, prvLine, sizeof(prvLine)); #endif do { ch = cgetchar(); if(cbreak) ch = KEY_CTL_C; switch(ch) { case KEY_BS: /* delete character to left of cursor */ if(current > 0 && charcount > 0) { if(current == charcount) { /* if at end of line */ str[current - 1] = 0; if (wherex() != 1) outs("\b \b"); else { goxy(MAX_X, wherey() - 1); outblank(); goxy(MAX_X, wherey() - 1); } } else { for (count = current - 1; count < charcount; count++) str[count] = str[count + 1]; if (wherex() != 1) goxy(wherex() - 1, wherey()); else goxy(MAX_X, wherey() - 1); curx = wherex(); cury = wherey(); outsblank(&str[current - 1]); goxy(curx, cury); } charcount--; current--; } break; case KEY_INSERT: /* toggle insert/overstrike mode */ insert ^= 1; if (insert) _setcursortype(_NORMALCURSOR); else _setcursortype(_SOLIDCURSOR); break; case KEY_DELETE: /* delete character under cursor */ if (current != charcount && charcount > 0) { for (count = current; count < charcount; count++) str[count] = str[count + 1]; charcount--; curx = wherex(); cury = wherey(); outsblank(&str[current]); goxy(curx, cury); } break; case KEY_HOME: /* goto beginning of string */ if (current != 0) { goxy(orgx, orgy); current = 0; } break; case KEY_END: /* goto end of string */ if (current != charcount) { goxy(orgx, orgy); outs(str); current = charcount; } break; #ifdef FEATURE_FILENAME_COMPLETION case KEY_TAB: /* expand current file name */ if(current == charcount) { /* only works at end of line */ if(lastch != KEY_TAB) { /* if first TAB, complete filename */ complete_filename(str, charcount); charcount = strlen(str); current = charcount; goxy(orgx, orgy); outs(str); if ((strlen(str) > (MAX_X - orgx)) && (orgy == MAX_Y + 1)) orgy--; } else { /* if second TAB, list matches */ if (show_completion_matches(str, charcount)) { printprompt(); orgx = wherex(); orgy = wherey(); outs(str); } } } else beep(); break; #endif case KEY_ENTER: /* end input, return to main */ #ifdef FEATURE_HISTORY if(str[0]) histSet(0, str); /* add to the history */ #endif outc('\n'); break; case KEY_CTL_C: /* ^C */ case KEY_ESC: /* clear str Make this callable! */ clrcmdline(str, maxlen, orgx, orgy); current = charcount = 0; if(ch == KEY_CTL_C && !echo) { /* enable echo to let user know that's this is the command line */ echo = 1; printprompt(); } break; case KEY_RIGHT: /* move cursor right */ if (current != charcount) { current++; if (wherex() == MAX_X) goxy(1, wherey() + 1); else goxy(wherex() + 1, wherey()); break; } /* cursor-right at end of string grabs the next character from the previous line */ /* FALL THROUGH */ #ifndef FEATURE_HISTORY break; #else case KEY_F1: /* get character from last command buffer */ if (current < strlen(prvLine)) { outc(str[current] = prvLine[current]); charcount = ++current; } break; case KEY_F3: /* get previous command from buffer */ if(charcount < strlen(prvLine)) { outs(strcpy(&str[charcount], &prvLine[charcount])); current = charcount = strlen(str); } break; case KEY_UP: /* get previous command from buffer */ if(!histGet(--histLevel, prvLine, sizeof(prvLine))) ++histLevel; /* failed -> keep current command line */ else { clrcmdline(str, maxlen, orgx, orgy); strcpy(str, prvLine); current = charcount = strlen(str); outs(str); histGet(histLevel - 1, prvLine, sizeof(prvLine)); } break; case KEY_DOWN: /* get next command from buffer */ if(histLevel) { clrcmdline(str, maxlen, orgx, orgy); strcpy(prvLine, str); histGet(++histLevel, str, maxlen); current = charcount = strlen(str); outs(str); } break; case KEY_F5: /* keep cmdline in F3/UP buffer and move to next line */ strcpy(prvLine, str); clrcmdline(str, maxlen, orgx, orgy); outc('@'); if(orgy >= MAX_Y) { outc('\n'); /* Force scroll */ orgy = MAX_Y; } else { ++orgy; } goxy(orgx, orgy); current = charcount = 0; break; #endif case KEY_LEFT: /* move cursor left */ if(current > 0) { current--; if (wherex() == 1) goxy(MAX_X, wherey() - 1); else goxy(wherex() - 1, wherey()); } break; case KEY_CTRL_LEFT: /* move cursor left to begin of word */ while(current > 0) { current--; if (wherex() == 1) goxy(MAX_X, wherey() - 1); else goxy(wherex() - 1, wherey()); if(isworddelimiter(str[current-1]) /* ignore current == 0 */ && !isworddelimiter(str[current])) break; } break; case KEY_CTRL_RIGHT: /* move cursor right to begin of word */ while(current < charcount) { current++; if (wherex() == MAX_X) goxy(1, wherey() + 1); else goxy(wherex() + 1, wherey()); if(isworddelimiter(str[current-1]) && !isworddelimiter(str[current])) break; } break; default: /* insert character into string... */ if ((ch >= 32 && ch <= 255) && (charcount != (maxlen - 2))) { if (insert && current != charcount) { for (count = charcount; count > current; count--) str[count] = str[count - 1]; str[current++] = ch; curx = wherex() + 1; cury = wherey(); outs(&str[current - 1]); if ((strlen(str) > (MAX_X - orgx)) && (orgy == MAX_Y + 1)) cury--; goxy(curx, cury); charcount++; } else { if (current == charcount) charcount++; str[current++] = ch; outc(ch); } if ((strlen(str) > (MAX_X - orgx)) && (orgy == MAX_Y + 1)) orgy--; } else beep(); break; } #ifdef FEATURE_FILENAME_COMPLETION lastch = ch; #endif } while(ch != KEY_ENTER); _setcursortype(_NORMALCURSOR); }
char *request(const char *prompt, const char * const default_string, const bool alpha_allowed, const int completion_type, const bool prefer_utf8) { set_attr(0); input_buffer[pos = len = offset = 0] = 0; encoding = ENC_ASCII; x = start_x = print_prompt(prompt); init_history(); if (default_string) { strncpy(input_buffer, default_string, MAX_INPUT_LINE_LEN); len = strlen(input_buffer); encoding = detect_encoding(input_buffer, len); input_refresh(); } bool first_char_typed = true, last_char_completion = false, selection = false; while(true) { assert(input_buffer[len] == 0); move_cursor(ne_lines - 1, x); int c; input_class ic; do c = get_key_code(); while((ic = CHAR_CLASS(c)) == IGNORE); /* ISO 10646 characters *above 256* can be added only to UTF-8 lines, or ASCII lines (making them, of course, UTF-8). */ if (ic == ALPHA && c > 0xFF && encoding != ENC_ASCII && encoding != ENC_UTF8) ic = INVALID; if (ic != TAB) last_char_completion = false; if (ic == TAB && !completion_type) ic = ALPHA; switch(ic) { case INVALID: alert(); break; case ALPHA: if (first_char_typed) { input_buffer[len = 0] = 0; clear_to_eol(); } if (encoding == ENC_ASCII && c > 0x7F) encoding = prefer_utf8 || c > 0xFF ? ENC_UTF8 : ENC_8_BIT; int c_len = encoding == ENC_UTF8 ? utf8seqlen(c) : 1; int c_width = output_width(c); assert(c_len > 0); if (len <= MAX_INPUT_LINE_LEN - c_len && (alpha_allowed || (c < 0x100 && isxdigit(c)) || c=='X' || c=='x')) { memmove(&input_buffer[pos + c_len], &input_buffer[pos], len - pos + 1); if (c_len == 1) input_buffer[pos] = c; else utf8str(c, &input_buffer[pos]); len += c_len; move_cursor(ne_lines - 1, x); if (x < ne_columns - c_width) { if (pos == len - c_len) output_char(c, 0, encoding); else if (char_ins_del_ok) insert_char(c, 0, encoding); else input_refresh(); } input_move_right(true); } break; case RETURN: selection = true; break; case TAB: if (completion_type == COMPLETE_FILE || completion_type == COMPLETE_SYNTAX) { bool quoted = false; char *prefix, *completion, *p; if (len && input_buffer[len - 1] == '"') { input_buffer[len - 1] = 0; if (prefix = strrchr(input_buffer, '"')) { quoted = true; prefix++; } else input_buffer[len - 1] = '"'; } if (!quoted) { prefix = strrchr(input_buffer, ' '); if (prefix) prefix++; else prefix = input_buffer; } if (last_char_completion || completion_type == COMPLETE_SYNTAX) { if (completion_type == COMPLETE_FILE ) completion = p = request_files(prefix, true); else completion = p = request_syntax(prefix, true); reset_window(); if (completion) { if (*completion) selection = true; else completion++; } } else { if (completion_type == COMPLETE_FILE ) completion = p = complete_filename(prefix); else completion = p = request_syntax(prefix, true); last_char_completion = true; if (!completion) alert(); } if (completion && (prefix - input_buffer) + strlen(completion) + 1 < MAX_INPUT_LINE_LEN) { const encoding_type completion_encoding = detect_encoding(completion, strlen(completion)); if (encoding == ENC_ASCII || completion_encoding == ENC_ASCII || encoding == completion_encoding) { strcpy(prefix, completion); if (quoted) strcat(prefix, "\""); len = strlen(input_buffer); pos = offset = 0; x = start_x; if (encoding == ENC_ASCII) encoding = completion_encoding; input_move_to_eol(); if (quoted) input_move_left(false); input_refresh(); } else alert(); } else if (quoted) strcat(prefix, "\""); free(p); } break; case COMMAND: if (c < 0) c = -c - 1; const int a = parse_command_line(key_binding[c], NULL, NULL, false); if (a >= 0) { switch(a) { case LINEUP_A: case LINEDOWN_A: case MOVESOF_A: case MOVEEOF_A: case PAGEUP_A: case PAGEDOWN_A: case NEXTPAGE_A: case PREVPAGE_A: if (history_buff) { switch(a) { case LINEUP_A: line_up(history_buff); break; case LINEDOWN_A: line_down(history_buff); break; case MOVESOF_A: move_to_sof(history_buff); break; case MOVEEOF_A: move_to_bof(history_buff); break; case PAGEUP_A: case PREVPAGE_A: prev_page(history_buff); break; case PAGEDOWN_A: case NEXTPAGE_A: next_page(history_buff); break; } /* In some cases, the default displayed on the command line will be the same as the first history item. In that case we skip it. */ if (first_char_typed == true && a == LINEUP_A && history_buff->cur_line_desc->line && !strncmp(history_buff->cur_line_desc->line, input_buffer, history_buff->cur_line_desc->line_len)) line_up(history_buff); if (history_buff->cur_line_desc->line) { strncpy(input_buffer, history_buff->cur_line_desc->line, min(history_buff->cur_line_desc->line_len,MAX_INPUT_LINE_LEN)); input_buffer[min(history_buff->cur_line_desc->line_len,MAX_INPUT_LINE_LEN)] = 0; len = strlen(input_buffer); encoding = detect_encoding(input_buffer, len); } else { input_buffer[len = 0] = 0; encoding = ENC_ASCII; } x = start_x; pos = 0; offset = 0; input_refresh(); } break; case MOVELEFT_A: input_move_left(true); break; case MOVERIGHT_A: input_move_right(true); break; case BACKSPACE_A: if (pos == 0) break; input_move_left(true); case DELETECHAR_A: if (len > 0 && pos < len) { int c_len = encoding == ENC_UTF8 ? utf8len(input_buffer[pos]) : 1; int c_width = get_char_width(&input_buffer[pos], encoding); memmove(&input_buffer[pos], &input_buffer[pos + c_len], len - pos - c_len + 1); len -= c_len; if (input_buffer_is_ascii()) encoding = ENC_ASCII; if (char_ins_del_ok) { int i, j; move_cursor(ne_lines - 1, x); delete_chars(c_width); for(i = x, j = pos; j < len && i + get_char_width(&input_buffer[j], encoding) < ne_columns - c_width; i += get_char_width(&input_buffer[j], encoding), j = next_pos(input_buffer, j, encoding)); if (j < len) { move_cursor(ne_lines - 1, i); while(j < len && i + get_char_width(&input_buffer[j], encoding) < ne_columns) { output_char(get_char(&input_buffer[j], encoding), 0, encoding); i += get_char_width(&input_buffer[j], encoding); j = next_pos(input_buffer, j, encoding); } } } else input_refresh(); } break; case DELETELINE_A: move_cursor(ne_lines - 1, start_x); clear_to_eol(); input_buffer[len = pos = offset = 0] = 0; encoding = ENC_ASCII; x = start_x; break; case DELETEEOL_A: input_buffer[len = pos] = 0; clear_to_eol(); if (input_buffer_is_ascii()) encoding = ENC_ASCII; break; case MOVEINCUP_A: if (x != start_x) { pos = offset; x = start_x; break; } case MOVESOL_A: input_move_to_sol(); break; case MOVEINCDOWN_A: { int i, j; for(i = x, j = pos; j < len && i + get_char_width(&input_buffer[j], encoding) < ne_columns; i += get_char_width(&input_buffer[j], encoding), j = next_pos(input_buffer, j, encoding)); if (j != pos && j < len) { pos = j; x = i; break; } } case MOVEEOL_A: input_move_to_eol(); break; case TOGGLESEOL_A: case TOGGLESEOF_A: if (pos != 0) input_move_to_sol(); else input_move_to_eol(); break; case PREVWORD_A: input_prev_word(); break; case NEXTWORD_A: input_next_word(); break; case REFRESH_A: input_refresh(); break; case PASTE_A: input_paste(); break; case AUTOCOMPLETE_A: input_autocomplete(); break; case ESCAPE_A: return NULL; default: break; } } break; default: break; } if (selection) { const line_desc * const last = (line_desc *)history_buff->line_desc_list.tail_pred->prev; assert(input_buffer[len] == 0); if (history_buff->num_lines == 0 || len != last->line_len || strncmp(input_buffer, last->line, last->line_len)) add_to_history(input_buffer); return input_buffer; } first_char_typed = false; } }
/* * A generic complete routine for the mail command line. */ static unsigned char mail_complete(EditLine *el, int ch) { LineInfo *li; const LineInfo *lf; const char *cmplarray; int dolist; int cmpltype; char *word; lf = el_line(el); #ifdef EMACS_CTRL_D_BINDING_HACK { int cc_ret; if ((cc_ret = emacs_ctrl_d(el, lf, ch)) != -1) return cc_ret; } #endif /* EMACS_CTRL_D_BINDING_HACK */ if ((dolist = get_dolist(lf)) == -1) return CC_ERROR; if ((li = split_line(&cmplarray, lf)) == NULL) return CC_ERROR; if ((word = split_word(&cmpltype, cmplarray, li)) == NULL) return CC_ERROR; switch (cmpltype) { case 'a': /* alias complete */ case 'A': return complete_alias(el, word, dolist); case 'c': /* command complete */ case 'C': return complete_command(el, word, dolist); case 'f': /* filename complete */ case 'F': return complete_filename(el, word, dolist); case 'm': case 'M': return complete_smopts(el, word, dolist); case 'n': /* no complete */ case 'N': /* no complete */ return CC_ERROR; case 's': case 'S': return complete_set(el, word, dolist); #ifdef THREAD_SUPPORT case 't': case 'T': return complete_thread_key(el, word, dolist); #endif case 'x': /* executable complete */ case 'X': return complete_executable(el, word, dolist); default: warnx("unknown complete type `%c'", cmpltype); #if 0 assert(/*CONSTCOND*/0); #endif return CC_ERROR; } /* NOTREACHED */ }