00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <conio.h>
00024 #include <assert.h>
00025 #include <string.h>
00026 #include <malloc.h>
00027 #include "readline.h"
00028
00029 #define HISTORY_SIZE 8
00030
00031 static char *history[HISTORY_SIZE];
00032 static int numlines = 0;
00033
00034
00042 static void addline(char *s)
00043 {
00044 if (numlines == HISTORY_SIZE) {
00045 if (history[0])
00046 free(history[0]);
00047 for (int i=0; i<numlines-1; i++)
00048 history[i] = history[i+1];
00049 numlines--;
00050 }
00051
00052 history[numlines++] = strdup(s);
00053 }
00054
00055
00063 static char* getline(int line)
00064 {
00065 if (line>=0 || line<numlines)
00066 return history[line];
00067 else
00068 return NULL;
00069 }
00070
00071
00085 char *readline(char *s, int n)
00086 {
00087 int c, cursor=0, len=0, line=numlines-1;
00088 bool reprint = true;
00089
00090 *s = '\0';
00091 printf("\033[s");
00092 while ((c=getch()) != '\r') {
00093
00094
00095 switch (c) {
00096 case 0x1b:
00097 if (getch() == '[')
00098 switch(getch()) {
00099 case 'A':
00100 strncpy(s, getline(line), n-1);
00101 if (line>0)
00102 line--;
00103 cursor = len = strlen(s);
00104 reprint = true;
00105 break;
00106 case 'B':
00107 if (line<numlines-1)
00108 line++;
00109 strncpy(s, getline(line), n-1);
00110 cursor = len = strlen(s);
00111 reprint = true;
00112 break;
00113 case 'C':
00114 if (cursor<len) {
00115 cursor++;
00116 printf("\033[C");
00117 }
00118 break;
00119 case 'D':
00120 if (cursor>0) {
00121 cursor--;
00122 printf("\033[D");
00123 }
00124 break;
00125 }
00126 break;
00127
00128 case 0x08:
00129 if (cursor>0) {
00130 len--;
00131 cursor--;
00132 for (int i=cursor; i<len; i++)
00133 s[i] = s[i+1];
00134 reprint = true;
00135 }
00136 break;
00137
00138 case 0x7f:
00139 if (cursor < len) {
00140 len--;
00141 for (int i=cursor; i<len; i++)
00142 s[i] = s[i+1];
00143 reprint = true;
00144 }
00145 break;
00146
00147 default:
00148 if (len<n-1) {
00149 for (int i=len; i>=cursor; i--)
00150 s[i+1] = s[i];
00151 s[cursor]=c;
00152 len++;
00153 cursor++;
00154 reprint = true;
00155 } else printf("\a");
00156 break;
00157 }
00158 assert(len >= 0); assert(len < n);
00159 assert(cursor >= 0); assert(cursor <= len);
00160 s[len] = '\0';
00161
00162
00163
00164 if (reprint) {
00165 printf("\033[u\033[s");
00166 printf("%s \b", s);
00167 if (len-cursor > 0)
00168 printf("\033[%dD", len-cursor);
00169 reprint = false;
00170 }
00171 };
00172 if (len>0)
00173 addline(s);
00174
00175 return s;
00176 }
00177