input.c (8008B)
1 #include"input.h" 2 #include"jim.h" 3 #include"editor.h" 4 #include"row.h" 5 #include"file.h" 6 #include"find.h" 7 #include"output.h" 8 #include"term.h" 9 #include<stdlib.h> 10 #include<ctype.h> 11 12 void processClusterKey(char c) { 13 switch(E.clusterkey) { 14 case SCREEN_POS: 15 switch(c) { 16 case SCREEN_POS: 17 { 18 int mid = E.cy - E.screenrows / 2; 19 E.rowoff = mid < 0 ? 0 : mid; 20 } 21 break; 22 case T: 23 E.rowoff = E.cy; 24 break; 25 case B: 26 { 27 int bottom = E.cy - E.screenrows; 28 E.rowoff = bottom < 0 ? 0 : bottom; 29 } 30 break; 31 } 32 break; 33 case FORCE: 34 switch(c) { 35 case QUIT: 36 editorClearAndResetScreen(); 37 exit(0); 38 } 39 break; 40 } 41 42 E.clusterkey = '\0'; 43 } 44 45 void editorReplaceChar(char c) { 46 E.isreplace = 0; 47 erow* row = (E.cy >= E.numrows) ? NULL : &E.row[E.cy]; 48 49 if(row && row->size == 0) 50 return; 51 52 editorDelChar(); 53 editorInsertChar(c); 54 55 if(row && E.cx >= row->size - 1) 56 E.cx--; 57 } 58 59 char* editorPrompt(char* prompt, void (*callback)(char*, int)) { 60 size_t bufsize = 128; 61 char* buf = malloc(bufsize); 62 size_t buflen = 0; 63 buf[0] = '\0'; 64 65 while(1) { 66 editorSetStatusMessage(prompt, buf); 67 editorRefreshScreen(); 68 69 char c = editorReadKey(); 70 switch(c) { 71 case BACKSPACE: 72 if(buflen != 0) 73 buf[--buflen] = '\0'; 74 break; 75 case ESCAPE: 76 if(callback) 77 callback(buf, c); 78 free(buf); 79 return NULL; 80 break; 81 case RETURN: 82 if(buflen != 0) { 83 if(callback) 84 callback(buf, c); 85 return buf; 86 } 87 break; 88 default: 89 if(!iscntrl(c)) { 90 if(buflen == bufsize - 1) { 91 bufsize *= 2; 92 buf = realloc(buf, bufsize); 93 } 94 95 buf[buflen++] = c; 96 buf[buflen] = '\0'; 97 } 98 break; 99 } 100 101 if(callback) 102 callback(buf, c); 103 } 104 } 105 106 void editorMoveCursor(char key) { 107 erow* row = (E.cy >= E.numrows) ? NULL : &E.row[E.cy]; 108 109 switch(key) { 110 case LEFT: 111 if(E.cx != 0) { 112 E.cx--; 113 } 114 break; 115 case RIGHT: 116 if(row && E.cx < row->size - 1) { 117 E.cx++; 118 } 119 break; 120 case UP: 121 if(E.cy != 0) { 122 E.cy--; 123 } 124 break; 125 case DOWN: 126 if(E.cy + 1 < E.numrows) { 127 E.cy++; 128 } 129 break; 130 } 131 132 row = (E.cy >= E.numrows) ? NULL : &E.row[E.cy]; 133 int rowlen = row ? row->size : 0; 134 if(E.cx >= rowlen) { 135 E.cx = rowlen ? rowlen - 1 : 0; 136 } 137 } 138 139 void editorProcessKeypress() { 140 char c = editorReadKey(); 141 142 if(E.mode == INSERT) { 143 switch(c) { 144 case RETURN: 145 editorInsertNewline(); 146 break; 147 case DEL: 148 editorDelChar(); 149 break; 150 case BACKSPACE: 151 editorBackspaceChar(); 152 break; 153 case ESCAPE: 154 if(E.cx > 0) { 155 E.cx--; 156 } 157 E.mode = NORMAL; 158 editorSetDefaultStatusMessage(); 159 break; 160 default: 161 editorInsertChar(c); 162 break; 163 } 164 } 165 else if(E.mode == COMMAND) { 166 switch(c) { 167 case ESCAPE: 168 E.mode = NORMAL; 169 editorSetDefaultStatusMessage(); 170 break; 171 } 172 } 173 else if(E.mode == NORMAL) { 174 editorSetDefaultStatusMessage(); 175 176 if(E.clusterkey != '\0') { 177 processClusterKey(c); 178 } else if (E.isreplace) { 179 editorReplaceChar(c); 180 } else { 181 switch(c) { 182 case QUIT: 183 if(E.dirty) { 184 E.isbold = 1; 185 E.isr = 0; 186 editorSetStatusMessage("There are unwritten changes (prepend '!' to override)"); 187 } else { 188 editorClearAndResetScreen(); 189 exit(0); 190 } 191 break; 192 case S: 193 if(!editorSave()) { 194 editorClearAndResetScreen(); 195 exit(0); 196 } else { 197 editorSetDefaultStatusMessage(); 198 } 199 break; 200 case COLON: 201 E.mode = COMMAND; 202 E.isr = 0; 203 editorSetStatusMessage(":"); 204 break; 205 case DELETE_LINE: 206 editorDelRow(E.cy); 207 E.cx = 0; 208 break; 209 case INSERT_LINE: 210 E.cx = 0; 211 E.mode = INSERT; 212 E.isbold = 1; 213 editorSetStatusMessage("-- INSERT --"); 214 break; 215 case APPEND_LINE: 216 if(E.row[E.cy].size > 0) 217 E.cx = E.row[E.cy].size - 1; 218 //fallthrough 219 case APPEND: 220 if(E.row[E.cy].size > 0) 221 E.cx++; 222 //fallthrough 223 case INS: 224 E.mode = INSERT; 225 E.isbold = 1; 226 editorSetStatusMessage("-- INSERT --"); 227 break; 228 case NEWLINE_ABOVE: 229 case NEWLINE_BELOW: 230 editorJumpToNewline(c); 231 E.mode = INSERT; 232 E.isbold = 1; 233 editorSetStatusMessage("-- INSERT --"); 234 break; 235 case DEL_NOR: 236 editorDelChar(); 237 if(E.row) 238 if(E.cx == E.row[E.cy].size) 239 E.cx--; 240 break; 241 case REPLACE: 242 E.isreplace = 1; 243 break; 244 case SAVE: 245 if(editorSave()) 246 editorSetDefaultStatusMessage(); 247 break; 248 case LEFT: 249 case DOWN: 250 case UP: 251 case RIGHT: 252 editorMoveCursor(c); 253 break; 254 case GOTO: 255 E.cy = 0; 256 E.cx = 0; 257 break; 258 case FORCE: 259 case SCREEN_POS: 260 E.clusterkey = c; 261 break; 262 case FILE_BOTTOM: 263 E.cx = 0; 264 E.cy = E.numrows - 1; 265 break; 266 case LINE_START: 267 E.cx = 0; 268 break; 269 case LINE_END: 270 if(E.cy < E.numrows) 271 E.cx = E.row[E.cy].size - 1; 272 break; 273 case CTRL_KEY(B): 274 E.cy = E.rowoff; 275 int back = E.cy - E.screenrows; 276 E.rowoff = back < 0 ? 0 : back; 277 break; 278 case CTRL_KEY(F): 279 E.cy = E.rowoff + E.screenrows - 1; 280 if(E.cy > E.numrows) E.cy = E.numrows; 281 E.rowoff = E.cy + E.screenrows - 1; 282 break; 283 case SEARCH: 284 editorFind(); 285 break; 286 } 287 } 288 } 289 }