Introduction
Introduction Statistics Contact Development Disclaimer Help
samrc.c - sam - An updated version of the sam text editor.
git clone git://vernunftzentrum.de/sam.git
Log
Files
Refs
LICENSE
---
samrc.c (13604B)
---
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <strings.h>
5 #include <X11/Xlib.h>
6 #include <X11/keysym.h>
7
8 #include <u.h>
9 #include <libg.h>
10 #include <frame.h>
11 #include "flayer.h"
12 #include "samterm.h"
13
14 extern bool expandtabs;
15 extern int tabwidth;
16 extern bool autoindent;
17
18 typedef struct Namemapping Namemapping;
19 struct Namemapping{
20 const char *name;
21 int value;
22 };
23
24 static Namemapping commandmapping[] ={
25 {"none", Cnone},
26 {"default", Cdefault},
27 {"escape", Cescape},
28 {"scrolldown", Cscrolldown},
29 {"scrollup", Cscrollup},
30 {"scrolldownline", Cscrolldownline},
31 {"scrollupline", Cscrollupline},
32 {"jump", Cjump},
33 {"charright", Ccharright},
34 {"charleft", Ccharleft},
35 {"linedown", Clinedown},
36 {"lineup", Clineup},
37 {"delword", Cdelword},
38 {"delbol", Cdelbol},
39 {"delbs", Cdelbs},
40 {"del", Cdel},
41 {"snarf", Csnarf},
42 {"cut", Ccut},
43 {"paste", Cpaste},
44 {"exchange", Cexchange},
45 {"eol", Ceol},
46 {"bol", Cbol},
47 {"tab", Ctab},
48 {"send", Csend},
49 {"look", Clook},
50 {"search", Csearch},
51 {"write", Cwrite},
52 {NULL, 0}
53 };
54
55 static Namemapping targetmapping[] ={
56 {"current", Tcurrent},
57 {"mouse", Tmouse},
58 {NULL, 0}
59 };
60
61 static Namemapping buttonmapping[] ={
62 {"0", 0},
63 {"n", 0},
64 #define B1 1
65 {"1", 1},
66 #define B2 2
67 {"2", 2},
68 #define B3 4
69 {"3", 4},
70 #define B4 8
71 {"4", 8},
72 #define B5 16
73 {"5", 16},
74 {NULL, 0}
75 };
76
77 static Namemapping modmapping[] ={
78 {"*", 0},
79 {"c", ControlMask},
80 {"a", Mod1Mask},
81 {"s", ShiftMask},
82 {NULL, 0}
83 };
84
85 static int
86 lookupmapping(const char *n, Namemapping *m)
87 {
88 for (Namemapping *k = m; k->name != NULL; k++){
89 if (strcasecmp(k->name, n) == 0)
90 return k->value;
91 }
92
93 return -1;
94 }
95
96 #define nametocommand(n) lookupmapping(n, commandmapping)
97 #define nametotarget(n) lookupmapping(n, targetmapping)
98
99 typedef struct Defaultbinding Defaultbinding;
100 struct Defaultbinding{
101 int modifiers;
102 KeySym keysym;
103 int kind;
104 int command;
105 const char *arg;
106 };
107
108 static Defaultbinding defaultbindings[] ={
109 /* Suppress control key combinations unless explicitly bound. */
110 {ControlMask, XK_VoidSymbol, Kcommand, Cnone, NULL},
111
112 /* Motion commands following the WordStar diamond. */
113 {ControlMask, XK_e, Kcommand, Clineup, NULL},
114 {ControlMask, XK_x, Kcommand, Clinedown, NULL},
115 {ControlMask, XK_d, Kcommand, Ccharright, NULL},
116 {ControlMask, XK_s, Kcommand, Ccharleft, NULL},
117 {ControlMask, XK_u, Kcommand, Cdelbol, NULL},
118 {ControlMask, XK_w, Kcommand, Cdelword, NULL},
119 {ControlMask, XK_k, Kcommand, Cjump, NULL},
120 {ControlMask, XK_BackSpace, Kcommand, Cdelword, NULL},
121 {ControlMask, XK_y, Kcommand, Ccut, NULL},
122 {ControlMask, XK_c, Kcommand, Csnarf, NULL},
123 {ControlMask, XK_v, Kcommand, Cpaste, NULL},
124 {ControlMask, XK_q, Kcommand, Cexchange, NULL},
125
126 /* Handle arrow keys, page up/down, and escape. */
127 {0, XK_Up, Kcommand, Cscrollup, NULL},
128 {0, XK_Prior, Kcommand, Cscrollup, NULL},
129 {0, XK_Left, Kcommand, Cscrollup, NULL},
130 {0, XK_Down, Kcommand, Cscrolldown, NULL},
131 {0, XK_Next, Kcommand, Cscrolldown, NULL},
132 {0, XK_Right, Kcommand, Cscrolldown, NULL},
133 {0, XK_Escape, Kcommand, Cescape, NULL},
134
135 /* More fundamental stuff: backspace, delete, etc. */
136 {0, XK_BackSpace, Kcommand, Cdelbs, NULL},
137 {0, XK_Delete, Kcommand, Cdel, NULL},
138 {0, XK_Tab, Kcommand, Ctab, NULL},
139 {0, XK_Return, Kraw, '\n', NULL},
140 {0, XK_KP_Enter, Kraw, '\n', NULL},
141 {0, XK_Linefeed, Kraw, '\r', NULL},
142 {0, XK_KP_0, Kraw, '0', NULL},
143 {0, XK_KP_1, Kraw, '1', NULL},
144 {0, XK_KP_2, Kraw, '2', NULL},
145 {0, XK_KP_3, Kraw, '3', NULL},
146 {0, XK_KP_4, Kraw, '4', NULL},
147 {0, XK_KP_5, Kraw, '5', NULL},
148 {0, XK_KP_6, Kraw, '6', NULL},
149 {0, XK_KP_7, Kraw, '7', NULL},
150 {0, XK_KP_8, Kraw, '8', NULL},
151 {0, XK_KP_9, Kraw, '9', NULL},
152 {0, XK_KP_Divide, Kraw, '/', NULL},
153 {0, XK_KP_Multiply, Kraw, '*', NULL},
154 {0, XK_KP_Subtract, Kraw, '-', NULL},
155 {0, XK_KP_Add, Kraw, '+', NULL},
156 {0, XK_KP_Decimal, Kraw, '.', NULL},
157 {0, XK_hyphen, Kraw, '-', NULL},
158
159 /* Support traditional control sequences. */
160 {ControlMask, XK_bracketleft, Kcommand, Cescape, NULL},
161 {ControlMask, XK_h, Kcommand, Cdelbs, NULL},
162 {ControlMask, XK_Delete, Kcommand, Cdel, NULL},
163 {ControlMask, XK_i, Kcommand, Ctab, NULL},
164 {ControlMask, XK_j, Kraw, '\n', NULL},
165 {ControlMask, XK_m, Kraw, '\r', NULL},
166
167 /* Use Control-Tab to insert a literal tab when tab expansion is ena…
168 {ControlMask, XK_Tab, Kraw, '\t', NULL},
169
170 {0, 0, Kend, 0, NULL}
171 };
172
173 void
174 installdefaultbindings(void)
175 {
176 for (Defaultbinding *b = defaultbindings; b->kind != Kend; b++)
177 installbinding(b->modifiers, b->keysym, b->kind, b->command, b->…
178 }
179
180 typedef struct Defaultchord Defaultchord;
181 struct Defaultchord{
182 int state1;
183 int state2;
184 int command;
185 int target;
186 const char *arg;
187 };
188
189 static Defaultchord defaultchords[] ={
190 {B1, B1|B2, Ccut, Tcurrent, NULL},
191 {B1, B1|B3, Cpaste, Tcurrent, NULL},
192 {B1|B2, B1, Cnone, Tcurrent, NULL},
193 {B1|B3, B1, Cnone, Tcurrent, NULL},
194
195 {B4, 0, Cscrollupline, Tmouse, NULL},
196 {B5, 0, Cscrolldownline, Tmouse, NULL},
197
198 {0, 0, Kend, 0, NULL}
199 };
200
201 void
202 installdefaultchords(void)
203 {
204 for (Defaultchord *c = defaultchords; c->state1 != 0; c++)
205 installchord(c->state1, c->state2, c->command, c->target, c->arg…
206 }
207
208 static int
209 statetomask(const char *n, Namemapping *m)
210 {
211 int r = 0;
212 for (int i = 0; n[i] != 0; i++){
213 char s[2] = {n[i], 0};
214 int v = lookupmapping(s, m);
215 if (v < 0)
216 return -1;
217 r |= v;
218 }
219
220 return r;
221 }
222
223 #define buttontomask(n) statetomask(n, buttonmapping)
224 #define modtomask(n) statetomask(n, modmapping)
225
226 static KeySym
227 nametokeysym(const char *n)
228 {
229 KeySym k, l, u;
230
231 k = XStringToKeysym(n);
232 XConvertCase(k, &l, &u);
233 return l;
234 }
235
236 static int
237 dirfollowfocus(const char *s1, const char *s2, const char *s3, const cha…
238 {
239 if (strcasecmp(s1, "true") != 0 && strcasecmp(s1, "false") != 0)
240 return -1;
241
242 followfocus = (strcasecmp(s1, "true") == 0);
243 return 0;
244 }
245
246 static int
247 dirsnarfselection(const char *s1, const char *s2, const char *s3, const …
248 {
249 extern const char *clipatom;
250
251 if (strcasecmp(s1, "primary") == 0)
252 clipatom = "PRIMARY";
253 else if (strcasecmp(s1, "secondary") == 0)
254 clipatom = "SECONDARY";
255 else if (strcasecmp(s1, "clipboard") == 0)
256 clipatom = "CLIPBOARD";
257 else
258 return -1;
259
260 return 0;
261 }
262
263 static int
264 dirchord(const char *s1, const char *s2, const char *s3, const char *s4,…
265 {
266 return installchord(buttontomask(s1), buttontomask(s2), nametocomman…
267 }
268
269 static int
270 dirraw(const char *s1, const char *s2, const char *s3, const char *s4, c…
271 {
272 return installbinding(modtomask(s1), nametokeysym(s2), Kraw, strtol(…
273 }
274
275 static int
276 dirrawliteral(const char *s1, const char *s2, const char *s3, const char…
277 {
278 if (strlen(s3) != 1)
279 return -1;
280 return installbinding(modtomask(s1), nametokeysym(s2), Kraw, s3[0], …
281 }
282
283 static int
284 dirbind(const char *s1, const char *s2, const char *s3, const char *s4, …
285 {
286 return installbinding(modtomask(s1), nametokeysym(s2), Kcommand, nam…
287 }
288
289 static int
290 dirunbind(const char *s1, const char *s2, const char *s3, const char *s4…
291 {
292 return removebinding(modtomask(s1), nametokeysym(s2));
293 }
294
295 static int
296 dirunchord(const char *s1, const char *s2, const char *s3, const char *s…
297 {
298 return removechord(buttontomask(s1), buttontomask(s2));
299 }
300
301 static int
302 dirforeground(const char *s1, const char *s2, const char *s3, const char…
303 {
304 if (strlen(s1) == 0)
305 return -1;
306
307 strncpy(foregroundspec, s1, sizeof(foregroundspec) - 1);
308 return 0;
309 }
310
311 static int
312 dirbackground(const char *s1, const char *s2, const char *s3, const char…
313 {
314 if (strlen(s1) == 0)
315 return -1;
316
317 strncpy(backgroundspec, s1, sizeof(backgroundspec) - 1);
318 return 0;
319 }
320
321 static int
322 dirborder(const char *s1, const char *s2, const char *s3, const char *s4…
323 {
324 if (strlen(s1) == 0)
325 return -1;
326
327 strncpy(borderspec, s1, sizeof(borderspec) - 1);
328 return 0;
329 }
330
331 static int
332 dirfont(const char *s1, const char *s2, const char *s3, const char *s4, …
333 {
334 if (strlen(s1) == 0)
335 return -1;
336
337 strncpy(fontspec, s1, sizeof(fontspec) - 1);
338 return 0;
339 }
340
341 static int
342 dirtabs(const char *s1, const char *s2, const char *s3, const char *s4, …
343 {
344 int i = atoi(s1);
345 if (i <= 0 || i > 12)
346 return -1;
347
348 tabwidth = i;
349 return 0;
350 }
351
352 static int
353 direxpandtabs(const char *s1, const char *s2, const char *s3, const char…
354 {
355 if (strcasecmp(s1, "true") != 0 && strcasecmp(s1, "false") != 0)
356 return -1;
357
358 expandtabs = (strcasecmp(s1, "true") == 0);
359 return 0;
360 }
361
362 static int
363 dirautoindent(const char *s1, const char *s2, const char *s3, const char…
364 {
365 if (strcasecmp(s1, "true") != 0 && strcasecmp(s1, "false") != 0)
366 return -1;
367
368 autoindent = (strcasecmp(s1, "true") == 0);
369 return 0;
370 }
371
372 static int
373 dircomment(const char *s1, const char *s2, const char *s3, const char *s…
374 {
375 return 0;
376 }
377
378 typedef struct Directive Directive;
379 struct Directive{
380 const char *format;
381 int result;
382 int (*action)(const char *, const char *, const char *, const char *…
383 };
384
385 Directive directives[] ={
386 {" chord %5[Nn12345] %5[Nn12345] %99s %99s %1023[^\n]", 5, d…
387 {" chord %5[Nn12345] %5[Nn12345] %99s %99s", 4, d…
388 {" unchord %5[Nn12345] %5[Nn12345]", 2, d…
389 {" bind %5[*camshNCAMSH12345] %99s raw 0x%4[0-9a-fA-F]", 3, d…
390 {" bind %5[*camshNCAMSH12345] %99s raw %1s", 3, d…
391 {" bind %5[*camshNCAMSH12345] %99s command %99s %1023[^\n]", 4, d…
392 {" bind %5[*camshNCAMSH12345] %99s command %99s", 3, d…
393 {" unbind %5[*camshNCAMSH12345] %99s", 2, d…
394 {" foreground %1023s", 1, d…
395 {" background %1023s", 1, d…
396 {" border %1023s", 1, d…
397 {" font %1023[^\n]", 1, d…
398 {" tabs %2[0-9]", 1, d…
399 {" expandtabs %99s", 1, d…
400 {" autoindent %99s", 1, d…
401 {" snarfselection %99s", 1, d…
402 {" followfocus %99s", 1, d…
403 {" %1[#]", 1, d…
404 {" %1[^ ]", EOF, d…
405 {NULL, 0, NULL}
406 };
407
408 void
409 loadrcfile(FILE *f)
410 {
411 char *l = NULL;
412 size_t n = 0;
413 ssize_t r = 0;
414 size_t ln = 0;
415
416 while ((r = getline(&l, &n, f)) >= 0){
417 char s1[1024] = {0};
418 char s2[1024] = {0};
419 char s3[1024] = {0};
420 char s4[1024] = {0};
421 char s5[1024] = {0};
422 int rc = 0;
423 bool found = false;
424
425 ln++;
426 if (r == 0)
427 continue;
428
429 for (Directive *d = directives; d->format && !found; d++){
430 if (sscanf(l, d->format, s1, s2, s3, s4, s5) == d->result){
431 rc = d->action(s1, s2, s3, s4, s5);
432 found = true;
433 }
434 }
435
436 if (!found)
437 fprintf(stderr, "invalid rc line %zd\n", ln);
438
439 if (rc != 0)
440 fprintf(stderr, "invalid chord/binding on rc line %zd\n", ln…
441 }
442
443 free(l);
444 }
You are viewing proxied material from vernunftzentrum.de. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.