jim

Simple, lightweight, modal, vim-inspired text editor
git clone git://git.janpasierb.com/jim.git
Log | Files | Refs | README | LICENSE

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 }