/* * CMDINPUT.C - handles command input (tab completion, history, etc.) * * * * Comments: * * 01/14/95 (Tim Norman) ------------------------------------------------- * started. * * 08/08/95 (Matt Rains) ------------------------------------------------- * i have cleaned up the source code. changes now bring this source into * guidelines for recommended programming practice. * * i have added some constants to help making changes easier. * * 12/12/95 (Tim Norman) ------------------------------------------------- * added findxy() function to get max x/y coordinates to display * correctly on larger screens * * 12/14/95 (Tim Norman) ------------------------------------------------- * fixed the Tab completion code that Matt Rains broke by moving local * variables to a more global scope and forgetting to initialize them * when needed * */ #include #include #include #include #include #define D_BS 8 #define D_DELETE 256+83 #define D_TAB 9 #define D_HOME 256+71 #define D_END 256+79 #define D_UP 256+72 #define D_DOWN 256+80 #define D_LEFT 256+75 #define D_RIGHT 256+77 #define D_ENTER 13 #define D_ESC 27 #define D_BEEP printf("\a") void history(int, char *); /* prototype for the command-line history */ /* this is inefficient to call each time something is changed */ /* make it better */ void reprint(char *str, int x, int *y, int place, int maxx, int maxy) { int gox; int goy; str[127] = 0; /* truncate in case it's too long */ gotoxy(x, *y); /* figure out if it's going to scroll... */ gox = x + strlen(str); goy = *y; while(gox > maxx) { gox -= maxx; goy++; } while(goy > maxy) { goy--; (*y)--; } printf(str); clreol(); gox = x + place; goy = *y; while(gox > maxx) { gox -= maxx; goy++; } gotoxy (gox, goy); return; } /* reposition the cursor */ void reposition(int curx, int cury, int place, int maxx) { int gox; int goy; gox = curx + place; goy = cury; while(gox > maxx) { gox -= maxx; goy++; } gotoxy(gox, goy); return; } /* get the size of the screen */ void findxy (int *maxx, int *maxy) { struct text_info t; gettextinfo (&t); *maxx = t.screenwidth; *maxy = t.screenheight; } /* read in a command line */ void readcommand(char *str, int maxlen) { struct ffblk file; int place = 0; int len = 0; int ch; int curx; int cury; int count; int y; int maxx, maxy; /* varibles found within code */ int found_dot = 0; int curplace = 0; int start; int perfectmatch = 1; char path[128]; char fname[14]; char maxmatch[13] = ""; char directory[128]; /* find the bounds of the current screen */ findxy (&maxx, &maxy); curx = wherex(); cury = wherey(); str[0] = 0; do { ch = getch(); if(ch == 0) /* special key */ { ch = 256 + getch(); } switch(ch) { case D_BS : { /* delete character to left of cursor */ if(place != 0) { place--; for(count = place; count < len; count++) { str[count] = str[count + 1]; } len--; if(wherex() != 1) { printf ("\b \b"); } else { y = wherey(); gotoxy(maxx, y - 1); printf(" "); gotoxy(maxx, y - 1); } reprint(str, curx, &cury, place, maxx, maxy); } break; } case D_DELETE : { /* delete character under cursor */ if (place != len) { for(count = place; count < len; count++) { str[count] = str[count + 1]; } len--; if(place != 0) { if(wherex() != 1) { printf("\b \b"); } else { y = wherey(); gotoxy(maxx, y - 1); printf(" "); gotoxy(maxx, y - 1); } } reprint (str, curx, &cury, place, maxx, maxy); } break; } case D_HOME : { /* goto beginning of string */ gotoxy(curx, cury); place = 0; break; } case D_END : { /* goto end of string */ place = len; reposition(curx, cury, place, maxx); break; } case D_TAB : { maxmatch[0] = 0; found_dot = 0; curplace = 0; perfectmatch = 1; /* expand current file name */ if(place == len) /* only works at end of line */ { count = len - 1; while(count > 0 && str[count] != ' ') /* find front of word */ { count--; } if(str[count] == ' ') /* if not at beginning, go forward 1 */ { count++; } start = count; /* extract directory from word */ strcpy (directory, &str[start]); curplace = strlen (directory) - 1; while (curplace >= 0 && directory[curplace] != '\\' && directory[curplace] != ':') { directory[curplace] = 0; curplace--; } strcpy(path, &str[start]); /* look for a . in the filename */ for(count = strlen (directory); path[count] != 0; count++) { if(path[count] == '.') { found_dot = 1; break; } } if(found_dot) { strcat(path, "*"); } else { strcat(path, "*.*"); } curplace = 0; /* current fname */ if(findfirst(path, &file, 0x3F) == 0) /* find anything */ { do { if(file.ff_name[0] == '.') /* ignore . and .. */ { continue; } strcpy(fname, file.ff_name); if(file.ff_attrib == FA_DIREC) { strcat(fname, "\\"); } else { strcat(fname, " "); } if(!maxmatch[0] && perfectmatch) { strcpy(maxmatch, fname); } else { for (count = 0; maxmatch[count] && fname[count];count++) { if (maxmatch[count] != fname[count]) { perfectmatch = 0; maxmatch[count] = 0; break; } } } } while(findnext(&file) == 0); strcpy(&str[start], directory); strcat(&str[start], maxmatch); len = strlen(str); place = len; reprint(str, curx, &cury, place, maxx, maxy); if(!perfectmatch) { D_BEEP; } } else { D_BEEP; } } else { D_BEEP; } break; } case D_ENTER : { /* end input, return to main */ if(str[0]) { history(0, str); /* add to the history */ } place = len; reprint(str, curx, &cury, place, maxx, maxy); printf("\n\n"); break; } case D_ESC : { /* clear str */ gotoxy(curx, cury); for(count = 0; count < strlen(str); count++) { printf (" "); } place = len = str[0] = 0; gotoxy(curx, cury); break; } case D_UP : { /* get previous command from buffer */ gotoxy(curx, cury); for(count = 0; str[count]; count++) { printf(" "); } history(-1, str); len = strlen(str); place = len; reprint(str, curx, &cury, place, maxx, maxy); break; } case D_DOWN : { /* get next command from buffer */ gotoxy(curx, cury); for(count = 0; count < strlen(str); count++) { printf(" "); } history(1, str); len = strlen(str); place = len; reprint(str, curx, &cury, place, maxx, maxy); break; } case D_LEFT : { /* move cursor left */ if(place != 0) { place--; } else { D_BEEP; } reposition(curx, cury, place, maxx); break; } case D_RIGHT : { /* move cursor right */ if(place != len) { place++; } reposition(curx, cury, place, maxx); break; } default: { if(ch >= 32 && ch <= 255 && len != maxlen - 2) { /* insert character into string... */ for(count = len + 1; count > place; count--) { str[count] = str[count - 1]; } str[place] = ch; place++; len++; reprint(str, curx, &cury, place, maxx, maxy); } else { D_BEEP; } break; } } } while(ch != D_ENTER); return; }