]> pd.if.org Git - pd_readline/blob - pd_readline.c
Very good progress.
[pd_readline] / pd_readline.c
1 \r
2 \r
3 /*  pd_readline.c                                           */  \r
4 /*  Status (as at 26th Aug 2012) : useful progress.         */ \r
5 /*  Keystroke sequences (along with the special flags       */ \r
6 /*  like Esc, Ctrl, Alt etc are now stored in a buffer      */ \r
7 /*  ( an array of structs ).                                */    \r
8 /*  It will still be some time before this is a REAL        */ \r
9 /*  readline, but we are "on the way"......                 */     \r
10 /*  This code is released to the public domain.             */ \r
11 /*  "Share and enjoy...."  ;)                               */  \r
12 \r
13 \r
14 #include <string.h>   \r
15 #include <stdio.h> \r
16 #include <termios.h>  /* For getch()  */  \r
17 \r
18 /* This implementation of getch() is from here - */ \r
19 /* http://wesley.vidiqatch.org/                  */ \r
20 /* Thanks, Wesley!                               */  \r
21 static struct termios old, new;\r
22 \r
23 /* Initialize new terminal i/o settings */\r
24 void initTermios(int echo) {\r
25     tcgetattr(0, &old); /* grab old terminal i/o settings */\r
26     new = old; /* make new settings same as old settings */\r
27     new.c_lflag &= ~ICANON; /* disable buffered i/o */\r
28     new.c_lflag &= echo ? ECHO : ~ECHO; /* set echo mode */\r
29     tcsetattr(0, TCSANOW, &new); /* use these new terminal i/o settings now */\r
30 }\r
31 \r
32 \r
33 /* Restore old terminal i/o settings */\r
34 void resetTermios(void) {\r
35     tcsetattr(0, TCSANOW, &old);\r
36 }\r
37 \r
38 \r
39 /* Read 1 character - echo defines echo mode */\r
40 char getch_(int echo) {\r
41     char ch;\r
42     initTermios(echo);\r
43     ch = getchar();\r
44     resetTermios();\r
45     return ch;\r
46 }\r
47 \r
48 \r
49 /* Read 1 character without echo */\r
50 char getch(void) {\r
51     return getch_(0);\r
52 }\r
53 \r
54 \r
55 /* Read 1 character with echo */\r
56 char getche(void) {\r
57     return getch_(1);\r
58\r
59 \r
60 \r
61 \r
62 /*  Helper function, to let us see if a .history file */ \r
63 /*  exists in the current directory.  */ \r
64 int fexists(char *fname)\r
65 {  \r
66 \r
67    FILE *fptr ;         \r
68         \r
69    fptr = fopen(fname, "r") ;  \r
70    \r
71    if ( !fptr )  return -1 ;  /* File does not exist in dir. */         \r
72          \r
73    fclose(fptr);  \r
74    return 0;    /* File DOES exist in dir.  */          \r
75 \r
76\r
77 \r
78 \r
79  /* Struct to store key sequences */ \r
80 typedef struct { \r
81            int fnkey; \r
82            int ctrl; \r
83            int alt ; \r
84        int shf ; \r
85        int esc ; \r
86        int lbr ;  /* For left-bracket ([) of escape sequences */ \r
87        int key; \r
88    } keyseq ;         \r
89 \r
90 \r
91 \r
92 \r
93 \r
94 int main(void)\r
95 {\r
96         \r
97   printf("Public Domain Readline \n");              \r
98   printf("NOTE! - at the moment, we are using \n");  \r
99   printf("NON-echoing reads, storing the keystrokes \n");  \r
100   printf("in a buffer \n");   \r
101     \r
102   \r
103   /* Buffer - an array of keyseq structs.                     */  \r
104   /* Note - now that we store the keystrokes in here,         */ \r
105   /* we can look at the various flags and decide whether to   */ \r
106   /* "echo" the key (as normal) or suppress it (as with an    */ \r
107   /* arrow key).                                              */    \r
108   keyseq buffer[80] ;   \r
109   \r
110   /* Buffer "pointer"  */ \r
111   int bufpnt = 0; \r
112   \r
113   \r
114   /* Test for existence of history file. */  \r
115   int exists;  \r
116   exists = fexists(".history"); \r
117   printf("Result: %d \n", exists);  \r
118   \r
119   while(1) \r
120     {  \r
121                    \r
122       int key = getch(); \r
123        \r
124       /* Printable chars. */  \r
125       if ( (key >= 32)  && (key <= 126) ) \r
126       {                 \r
127         buffer[bufpnt].key = key;  \r
128         bufpnt += 1; \r
129       }  \r
130                                                                        \r
131       /* Up arrow is 27, 91, 65.    ( ESC [ A )   */   \r
132       /* Down arrow is 27, 91, 66.  ( ESC [ B )   */ \r
133       /* Right arrow is 27, 91, 67. ( ESC [ C )   */ \r
134       /* Left arrow is 27, 91, 68.  ( ESC [ D )   */    \r
135       /* Function keys.     */ \r
136       /* F2 is 27, 79, 81.  */  \r
137       /* F3 is 27, 79, 82.  */  \r
138       /* F4 is 27, 79, 83.  */  \r
139            \r
140                 \r
141       else if(key == 27)        \r
142           {  \r
143                           \r
144                           buffer[bufpnt].esc = 1;                        \r
145                           key = getch(); \r
146               if(key == 91)               \r
147               buffer[bufpnt].lbr = 1;                \r
148               key = getch(); \r
149               if( (key >= 65) && (key <= 68) )  \r
150                {                                 \r
151                                  buffer[bufpnt].key = key;                  \r
152                }                                  \r
153             bufpnt += 1;            \r
154           } \r
155               \r
156                                           \r
157                                                  \r
158     /* The Enter key exits. Enter is 10 decimal */        \r
159         else if(key == 10)  \r
160                 { \r
161                          int j ; \r
162                    /* Print the array of structs. */ \r
163                      for (j=0; j<10; j++)       \r
164                      { \r
165                             printf("Fnkey: %d ", buffer[j].fnkey  ) ; \r
166                             printf("Ctrl:  %d ", buffer[j].ctrl   ) ;   \r
167                             printf("Alt:   %d ", buffer[j].alt    ) ; \r
168                             printf("Shf:   %d ", buffer[j].shf    ) ; \r
169                             printf("Esc:   %d ", buffer[j].esc    ) ; \r
170                             printf("Lbr:   %d ", buffer[j].lbr    ) ;  \r
171                     printf("Key:   %d \n", buffer[j].key  ) ; \r
172                  }                      \r
173                                           \r
174              break;           \r
175          }  /* Key = Enter */   \r
176     }                \r
177                                       \r
178         return 0;\r
179 }  \r
180 \r
181 \r
182 \r
183 \r