Introduction
Introduction Statistics Contact Development Disclaimer Help
main.c - sam - An updated version of the sam text editor.
git clone git://vernunftzentrum.de/sam.git
Log
Files
Refs
LICENSE
---
main.c (23368B)
---
1
2 /* Copyright (c) 1998 Lucent Technologies - All rights reserved. */
3 #include <u.h>
4 #include <libg.h>
5 #include <frame.h>
6 #include <unistd.h>
7 #include "flayer.h"
8 #include "samterm.h"
9
10 extern uint64_t _bgpixel;
11 extern void hmoveto(int, int64_t, Flayer *);
12
13 Text cmd;
14 wchar_t *scratch;
15 int64_t nscralloc;
16 extern Bitmap screen;
17 unsigned int cursor;
18 Mouse mouse;
19 Flayer *which = NULL;
20 Flayer *flast = NULL;
21 Flayer *work = NULL;
22 int64_t snarflen;
23 int64_t typestart = -1;
24 int64_t typeend = -1;
25 int64_t typeesc = -1;
26 bool modified = false; /* strange lookahead for menus */
27 char lock = 1;
28 bool hasunlocked = false;
29 bool expandtabs = false;
30 bool autoindent = false;
31 char *machine = "localhost";
32 int exfd = -1;
33 const char *exname;
34 bool followfocus = false;
35
36 void
37 removeext(void)
38 {
39 if (exname)
40 unlink(exname);
41 }
42
43 int
44 main(int argc, char *argv[])
45 {
46 int i, got, scr, opt;
47 Text *t;
48 Rectangle r;
49 Flayer *nwhich;
50 char rcpath[PATH_MAX + 1] = {0};
51 FILE *rc = NULL;
52
53 setlocale(LC_ALL, "");
54 installdefaultbindings();
55 installdefaultchords();
56
57 if (getenv("SAMRC"))
58 strncpy(rcpath, getenv("SAMRC"), PATH_MAX);
59 else
60 snprintf(rcpath, PATH_MAX, "%s/.samrc", getenv("HOME") ? getenv(…
61
62 while ((opt = getopt(argc, argv, "ef:n:r:")) != -1){
63 switch (opt){
64 case 'r':
65 machine = optarg;
66 break;
67
68 case 'f':
69 exfd = atoi(optarg);
70 break;
71
72 case 'n':
73 exname = optarg;
74 atexit(removeext);
75 break;
76 }
77 }
78
79 rc = fopen(rcpath, "r");
80 if (rc){
81 loadrcfile(rc);
82 fclose(rc);
83 }
84
85 getscreen(argc, argv);
86 initio();
87 scratch = alloc(100*RUNESIZE);
88 nscralloc = 100;
89 r = screen.r;
90 r.max.y = r.min.y+Dy(r)/5;
91 flstart(screen.clipr);
92 rinit(&cmd.rasp);
93 flnew(&cmd.l[0], stgettext, 1, &cmd);
94 cmd.l[0].bg = getbg();
95 flinit(&cmd.l[0], r, font, cmd.l[0].bg);
96 cmd.nwin = 1;
97 which = &cmd.l[0];
98 cmd.tag = Untagged;
99 outTs(Tversion, VERSION);
100 startnewfile(Tstartcmdfile, &cmd);
101
102 got = 0;
103 for(;;got = waitforio()){
104 if(hasunlocked && RESHAPED())
105 reshape();
106 if(got&RHost)
107 rcv();
108 if(got&RExtern){
109 for(i=0; cmd.l[i].textfn==0; i++)
110 ;
111 current(&cmd.l[i]);
112 flsetselect(which, cmd.rasp.nrunes, cmd.rasp.nrunes);
113 type(which);
114 }
115 if(got&RKeyboard){
116 if(which)
117 type(which);
118 else
119 kbdblock();
120 }
121 if(got&RMouse){
122 if(lock==2 || !ptinrect(mouse.xy, screen.r)){
123 mouseunblock();
124 continue;
125 }
126 nwhich = flwhich(mouse.xy);
127 scr = which && ptinrect(mouse.xy, which->scroll);
128 if(mouse.buttons)
129 flushtyping(true);
130 if(mouse.buttons&1){
131 if(nwhich){
132 if(nwhich!=which)
133 current(nwhich);
134 else if(scr)
135 scroll(which, 1, 1);
136 else{
137 t=(Text *)which->user1;
138 if(flselect(which)){
139 outTsl(Tdclick, t->tag, which->p0);
140 t->lock++;
141 }else if(t!=&cmd)
142 outcmd();
143 }
144 }
145 }else if((mouse.buttons&2) && which){
146 if(scr)
147 scroll(which, 2, 2);
148 else
149 menu2hit();
150 }else if((mouse.buttons&4)){
151 if(scr)
152 scroll(which, 3, 3);
153 else
154 menu3hit();
155 }else if(followfocus && nwhich && nwhich!=which){
156 current(nwhich);
157 }
158 mouseunblock();
159 }
160 }
161
162 return EXIT_SUCCESS;
163 }
164
165
166 void
167 reshape(void)
168 {
169 int i;
170
171 flreshape(screen.clipr);
172 for(i = 0; i<nname; i++)
173 if(text[i])
174 hcheck(text[i]->tag);
175 }
176
177 void
178 current(Flayer *nw)
179 {
180 Text *t;
181
182 if(which)
183 flborder(which, false);
184 if(nw){
185 flushtyping(true);
186 if (!followfocus)
187 flupfront(nw);
188 flborder(nw, true);
189 buttons(Up);
190 t = (Text *)nw->user1;
191 t->front = nw-&t->l[0];
192 if(t != &cmd)
193 work = nw;
194 }
195 which = nw;
196 }
197
198 void
199 closeup(Flayer *l)
200 {
201 Text *t=(Text *)l->user1;
202 int m;
203
204 m = whichmenu(t->tag);
205 if(m < 0)
206 return;
207 flclose(l);
208 if(l == which){
209 which = 0;
210 current(flwhich(Pt(0, 0)));
211 }
212 if(l == flast)
213 flast = 0;
214 if(l == work)
215 work = 0;
216 if(--t->nwin == 0){
217 rclear(&t->rasp);
218 free(t);
219 text[m] = 0;
220 }else if(l == &t->l[t->front]){
221 for(m=0; m<NL; m++) /* find one; any one will do */
222 if(t->l[m].textfn){
223 t->front = m;
224 return;
225 }
226 panic("close");
227 }
228 }
229
230 Flayer *
231 findl(Text *t)
232 {
233 int i;
234 for(i = 0; i<NL; i++)
235 if(t->l[i].textfn==0)
236 return &t->l[i];
237 return 0;
238 }
239
240 void
241 duplicate(Flayer *l, Rectangle r, XftFont *f, int close)
242 {
243 Text *t=(Text *)l->user1;
244 Flayer *nl = findl(t);
245 wchar_t *rp;
246 uint64_t n;
247
248 if(nl){
249 flnew(nl, stgettext, l->user0, (char *)t);
250 flinit(nl, r, f, l->bg);
251 nl->origin = l->origin;
252 rp = (*l->textfn)(l, l->f.nchars, &n);
253 flinsert(nl, rp, rp+n, l->origin);
254 flsetselect(nl, l->p0, l->p1);
255 if(close){
256 flclose(l);
257 if(l==which)
258 which = 0;
259 }else
260 t->nwin++;
261 current(nl);
262 hcheck(t->tag);
263 }
264 cursorswitch(cursor);
265 }
266
267 void
268 buttons(int updown)
269 {
270 while(((mouse.buttons&7)!=0) != updown)
271 frgetmouse();
272 }
273
274 int
275 getr(Rectangle *rp)
276 {
277 Point p;
278 Rectangle r;
279
280 *rp = getrect(3, &mouse);
281 if(rp->max.x && rp->max.x-rp->min.x<=5 && rp->max.y-rp->min.y<=5){
282 p = rp->min;
283 r = cmd.l[cmd.front].entire;
284 *rp = screen.r;
285 if(cmd.nwin==1){
286 if (p.y <= r.min.y)
287 rp->max.y = r.min.y;
288 else if (p.y >= r.max.y)
289 rp->min.y = r.max.y;
290 if (p.x <= r.min.x)
291 rp->max.x = r.min.x;
292 else if (p.x >= r.max.x)
293 rp->min.x = r.max.x;
294 }
295 }
296 return rectclip(rp, screen.r) &&
297 rp->max.x-rp->min.x>100 && rp->max.y-rp->min.y>40;
298 }
299
300 void
301 snarf(Text *t, int w)
302 {
303 Flayer *l = &t->l[w];
304
305 if(l->p1>l->p0){
306 snarflen = l->p1-l->p0;
307 outTsll(Tsnarf, t->tag, l->p0, l->p1);
308 }
309 }
310
311 void
312 cut(Text *t, int w, bool save, bool check)
313 {
314 int64_t p0, p1;
315 Flayer *l;
316
317 l = &t->l[w];
318 p0 = l->p0;
319 p1 = l->p1;
320 if(p0 == p1)
321 return;
322 if(p0 < 0)
323 panic("cut");
324 if(save)
325 snarf(t, w);
326 outTsll(Tcut, t->tag, p0, p1);
327 flsetselect(l, p0, p0);
328 t->lock++;
329 hcut(t->tag, p0, p1-p0);
330 if(check)
331 hcheck(t->tag);
332 }
333
334 void
335 paste(Text *t, int w)
336 {
337 if(snarflen){
338 cut(t, w, false, false);
339 t->lock++;
340 outTsl(Tpaste, t->tag, t->l[w].p0);
341 }
342 }
343
344 void
345 scrorigin(Flayer *l, int but, int64_t p0)
346 {
347 Text *t=(Text *)l->user1;
348
349 switch(but){
350 case 1:
351 outTslll(Torigin, t->tag, l->origin, p0, getlayer(l, t));
352 break;
353 case 2:
354 outTslll(Torigin, t->tag, p0, 1L, getlayer(l, t));
355 break;
356 case 3:
357 horigin(t->tag, p0, NULL);
358 }
359 }
360
361 int
362 raspc(Rasp *r, int64_t p)
363 {
364 uint64_t n;
365 rload(r, p, p+1, &n);
366 if(n)
367 return scratch[0];
368 return 0;
369 }
370
371 int64_t
372 ctlw(Rasp *r, int64_t o, int64_t p)
373 {
374 int c;
375
376 if(--p < o)
377 return o;
378 if(raspc(r, p)=='\n')
379 return p;
380 for(; p>=o && !iswalnum(c=raspc(r, p)); --p)
381 if(c=='\n')
382 return p+1;
383 for(; p>o && iswalnum(raspc(r, p-1)); --p)
384 ;
385 return p>=o? p : o;
386 }
387
388 int64_t
389 ctlu(Rasp *r, int64_t o, int64_t p)
390 {
391 for(; p-1>=o && raspc(r, p-1)!='\n'; --p)
392 ;
393 return p>=o? p : o;
394 }
395
396 int64_t
397 indent(Flayer *l, long p)
398 {
399 Text *t = (Text *)l->user1;
400 static wchar_t sbuf[7] = {' ',' ',' ',' ',' ',' ',' '};
401 static wchar_t tbuf[7] = {'\t','\t','\t','\t','\t','\t','\t'};
402 int i, is, it, q, c, space;
403
404 q = p - 1; is = 0; it = 0; space = true;
405 while(--q >= l->origin) {
406 c = raspc(&t->rasp, q);
407 if(c == '\n') {
408 break;
409 } else if(c == '\t') {
410 ++it;
411 } else if(c == ' ') {
412 ++is;
413 } else {
414 it = is = 0;
415 space = false;
416 }
417 }
418 if(space)
419 it = is = 0;
420
421 while(it != 0) {
422 i = it>7?7:it;
423 hgrow(t->tag, p, i, 0);
424 t->lock++;
425 hdatarune(t->tag, p, tbuf, i);
426 it -= i; p += i;
427 }
428 while(is != 0) {
429 i = is > 7? 7 : is;
430 hgrow(t->tag, p, i, 0);
431 t->lock++;
432 hdatarune(t->tag, p, sbuf, i);
433 is -= i; p += i;
434 }
435
436 return typeend = l->p0 = l->p1 = p;
437 }
438
439 int
440 center(Flayer *l, int64_t a)
441 {
442 Text *t = l->user1;
443
444 if (!t->lock && (a < l->origin || l->origin + l->f.nchars < a)){
445 a = (a > t->rasp.nrunes) ? t->rasp.nrunes : a;
446 outTslll(Torigin, t->tag, a, 2L, getlayer(l, t));
447 return 1;
448 }
449
450 return 0;
451 }
452
453 int
454 onethird(Flayer *l, int64_t a)
455 {
456 Text *t;
457 Rectangle s;
458 int64_t lines;
459
460 t = l->user1;
461 if(!t->lock && (a<l->origin || l->origin+l->f.nchars<a)){
462 if(a > t->rasp.nrunes)
463 a = t->rasp.nrunes;
464 s = inset(l->scroll, 1);
465 lines = ((s.max.y-s.min.y)/l->f.fheight+1)/3;
466 if (lines < 2)
467 lines = 2;
468 outTslll(Torigin, t->tag, a, lines, getlayer(l, t));
469 return 1;
470 }
471 return 0;
472 }
473
474
475 int
476 XDisplay(Display *);
477
478 extern Display * _dpy;
479
480 void
481 flushtyping(bool clearesc)
482 {
483 Text *t;
484 uint64_t n;
485
486 if (clearesc)
487 typeesc = -1;
488 if (typestart == typeend){
489 modified = false;
490 return;
491 }
492 t = which->user1;
493 if(t != &cmd)
494 modified = true;
495 rload(&t->rasp, typestart, typeend, &n);
496 scratch[n] = 0;
497 if(t==&cmd && typeend==t->rasp.nrunes && scratch[typeend-typestart-1…
498 setlock();
499 outcmd();
500 }
501 outTslS(Ttype, t->tag, typestart, scratch);
502 typestart = -1;
503 typeend = -1;
504 XFlush(_dpy);
505 }
506
507 static int64_t
508 cmdscrolldown(Flayer *l, int64_t a, Text *t, const char *arg)
509 {
510 flushtyping(false);
511 center(l, l->origin + l->f.nchars + 1);
512 return a;
513 }
514
515 static int64_t
516 cmdscrollup(Flayer *l, int64_t a, Text *t, const char *arg)
517 {
518 flushtyping(false);
519 outTslll(Torigin, t->tag, l->origin, l->f.maxlines + 1, getlayer(l, …
520 return a;
521 }
522
523 static int64_t
524 cmdcharleft(Flayer *l, int64_t a, Text *t, const char *arg)
525 {
526 flsetselect(l, a, a);
527 flushtyping(false);
528 if (a > 0)
529 a--;
530 flsetselect(l, a, a);
531 center(l, a);
532
533 return a;
534 }
535
536 static int64_t
537 cmdcharright(Flayer *l, int64_t a, Text *t, const char *arg)
538 {
539 flsetselect(l, a, a);
540 flushtyping(false);
541 if (a < t->rasp.nrunes)
542 a++;
543 flsetselect(l, a, a);
544 center(l, a);
545
546 return a;
547 }
548
549 static int64_t
550 cmdeol(Flayer *l, int64_t a, Text *t, const char *arg)
551 {
552 flsetselect(l, a, a);
553 flushtyping(true);
554 while(a < t->rasp.nrunes)
555 if(raspc(&t->rasp, a++) == '\n') {
556 a--;
557 break;
558 }
559
560 flsetselect(l, a, a);
561 center(l, a);
562
563 return a;
564 }
565
566 static int64_t
567 cmdbol(Flayer *l, int64_t a, Text *t, const char *arg)
568 {
569 flsetselect(l, a, a);
570 flushtyping(true);
571 while (a > 0){
572 if (raspc(&t->rasp, --a) == '\n'){
573 a++;
574 break;
575 }
576 }
577
578 flsetselect(l, a, a);
579 center(l, a);
580
581 return a;
582 }
583
584 static int64_t
585 cmdscrollupline(Flayer *l, int64_t a, Text *t, const char *arg)
586 {
587 if (l->origin > 0)
588 hmoveto(t->tag, l->origin - 1, l);
589 return a;
590 }
591
592 static int64_t
593 cmdscrolldownline(Flayer *l, int64_t a, Text *t, const char *arg)
594 {
595 int64_t e = t->rasp.nrunes;
596
597 horigin(t->tag,
598 l->origin + frcharofpt(&l->f,Pt(l->f.r.min.x, l->f.r.min.y +…
599 l);
600
601 return a;
602 }
603
604 static int64_t
605 cmdlineup(Flayer *l, int64_t a, Text *t, const char *arg)
606 {
607 flsetselect(l, a, a);
608 flushtyping(true);
609 if (a > 0){
610 int64_t n0, n1, count = 0;
611 while (a > 0 && raspc(&t->rasp, a - 1) != '\n'){
612 a--;
613 count++;
614 }
615 if (a > 0){
616 n1 = a;
617 a--;
618 while (a > 0 && raspc(&t->rasp, a - 1) != '\n')
619 a--;
620
621 n0 = a;
622 a = (n0 + count >= n1) ? n1 - 1 : n0 + count;
623 flsetselect(l, a, a);
624 center(l, a);
625 }
626 }
627
628 return a;
629 }
630
631 static int64_t
632 cmdlinedown(Flayer *l, int64_t a, Text *t, const char *arg)
633 {
634 flsetselect(l, a, a);
635 flushtyping(true);
636 if (a < t->rasp.nrunes){
637 int64_t p0, count = 0;
638
639 p0 = a;
640 while (a > 0 && raspc(&t->rasp, a - 1) != '\n'){
641 a--;
642 count++;
643 }
644
645 a = p0;
646 while (a < t->rasp.nrunes && raspc(&t->rasp, a) != '\n')
647 a++;
648
649 if (a < t->rasp.nrunes){
650 a++;
651 while (a < t->rasp.nrunes && count > 0 && raspc(&t->rasp, a)…
652 a++;
653 count--;
654 }
655 if (a != p0){
656 flsetselect(l, a, a);
657 center(l, a);
658 }
659 }
660 }
661
662 return a;
663 }
664
665 static int64_t
666 cmdjump(Flayer *l, int64_t a, Text *u, const char *arg)
667 {
668 Text *t = NULL;
669
670 if (which == &cmd.l[cmd.front] && flast)
671 current(flast);
672 else{
673 l = &cmd.l[cmd.front];
674 t = (Text *)l->user1;
675 flast = which;
676 current(l);
677 flushtyping(false);
678 flsetselect(l, t->rasp.nrunes, t->rasp.nrunes);
679 center(l, a);
680 }
681
682 return a;
683 }
684
685 static int64_t
686 cmdlook(Flayer *l, int64_t a, Text *t, const char *arg)
687 {
688 outTsll(Tlook, t->tag, which->p0, which->p1);
689 setlock();
690 return a;
691 }
692
693 static int64_t
694 cmdsearch(Flayer *l, int64_t a, Text *t, const char *arg)
695 {
696 if (t != &cmd && haspat()){
697 outcmd();
698 outT0(Tsearch);
699 setlock();
700 }
701 return a;
702 }
703
704 static int64_t
705 cmdwrite(Flayer *l, int64_t a, Text *t, const char *arg)
706 {
707 cursorswitch(BullseyeCursor);
708 if (t != &cmd){
709 outTs(Twrite, t->tag);
710 setlock();
711 }
712 cursorswitch(cursor);
713 return a;
714 }
715
716 static int64_t
717 cmdescape(Flayer *l, int64_t a, Text *t, const char *arg)
718 {
719 if (typeesc >= 0){
720 l->p0 = typeesc;
721 l->p1 = a;
722 flushtyping(true);
723 }
724
725 for (l = t->l; l < &t->l[NL]; l++)
726 if (l->textfn)
727 flsetselect(l, l->p0, l->p1);
728
729 return a;
730 }
731
732 static int64_t
733 cmddelword(Flayer *l, int64_t a, Text *t, const char *arg)
734 {
735 if (l->f.p0 > 0 && a > 0)
736 l->p0 = ctlw(&t->rasp, l->origin, a);
737
738 l->p1 = a;
739 if (l->p1 != l->p0){
740 if(typestart<=l->p0 && l->p1<=typeend){
741 t->lock++; /* to call hcut */
742 hcut(t->tag, l->p0, l->p1-l->p0);
743 /* hcheck is local because we know rasp is contiguous */
744 hcheck(t->tag);
745 }else{
746 flushtyping(false);
747 cut(t, t->front, false, true);
748 }
749 }
750
751 return a;
752 }
753
754 static int64_t
755 cmddelbol(Flayer *l, int64_t a, Text *t, const char *arg)
756 {
757 if (l->f.p0 > 0 && a > 0)
758 l->p0 = ctlu(&t->rasp, l->origin, a);
759
760 l->p1 = a;
761 if (l->p1 != l->p0){
762 if(typestart<=l->p0 && l->p1<=typeend){
763 t->lock++; /* to call hcut */
764 hcut(t->tag, l->p0, l->p1-l->p0);
765 /* hcheck is local because we know rasp is contiguous */
766 hcheck(t->tag);
767 }else{
768 flushtyping(false);
769 cut(t, t->front, false, true);
770 }
771 }
772
773 return a;
774 }
775
776 static int64_t
777 cmddelbs(Flayer *l, int64_t a, Text *t, const char *arg)
778 {
779 if (l->f.p0 > 0 && a > 0)
780 l->p0 = a - 1;
781
782 l->p1 = a;
783 if (l->p1 != l->p0){
784 if(typestart <= l->p0 && l->p1 <= typeend){
785 t->lock++; /* to call hcut */
786 hcut(t->tag, l->p0, l->p1 - l->p0);
787 /* hcheck is local because we know rasp is contiguous */
788 hcheck(t->tag);
789 }else{
790 flushtyping(false);
791 cut(t, t->front, false, true);
792 }
793 }
794
795 return a;
796 }
797
798 static int64_t
799 cmddel(Flayer *l, int64_t a, Text *t, const char *arg)
800 {
801 l->p0 = a;
802 if (a < t->rasp.nrunes)
803 l->p1 = a + 1;
804 if (l->p1 != l->p0){
805 if(typestart <= l->p0 && l->p1 <= typeend){
806 t->lock++; /* to call hcut */
807 hcut(t->tag, l->p0, l->p1 - l->p0);
808 /* hcheck is local because we know rasp is contiguous */
809 hcheck(t->tag);
810 }else{
811 flushtyping(false);
812 cut(t, t->front, false, true);
813 }
814 }
815
816 return a;
817 }
818
819 int
820 getlayer(const Flayer *l, const Text *t)
821 {
822 int i;
823 for (i = 0; i < NL; i++){
824 if (&t->l[i] == l)
825 return i;
826 }
827
828 return -1;
829 }
830
831 static int64_t
832 cmdexchange(Flayer *l, int64_t a, Text *t, const char *arg)
833 {
834 int w = getlayer(l, t);
835 if (w >= 0){
836 snarf(t, w);
837 outT0(Tstartsnarf);
838 setlock();
839 }
840
841 return a;
842 }
843
844 static int64_t
845 cmdsnarf(Flayer *l, int64_t a, Text *t, const char *arg)
846 {
847 flushtyping(false);
848
849 int w = getlayer(l, t);
850 if (w >= 0)
851 snarf(t, w);
852
853 return a;
854 }
855
856 static int64_t
857 cmdcut(Flayer *l, int64_t a, Text *t, const char *arg)
858 {
859 flushtyping(false);
860
861 int w = getlayer(l, t);
862 if (w >= 0)
863 cut(t, w, true, true);
864
865 return a;
866 }
867
868 static int64_t
869 cmdpaste(Flayer *l, int64_t a, Text *t, const char *arg)
870 {
871 flushtyping(false);
872
873 int w = getlayer(l, t);
874 if (w >= 0)
875 paste(t, w);
876
877 return a;
878 }
879
880 static int64_t
881 cmdtab(Flayer *l, int64_t a, Text *t, const char *arg)
882 {
883 flushtyping(false);
884
885 if (!expandtabs)
886 pushkbd('\t');
887 else{
888 int col = 0, nspaces = 8, off = a;
889 int i;
890 while (off > 0 && raspc(&t->rasp, off - 1) != '\n')
891 off--, col++;
892
893 nspaces = tabwidth - col % tabwidth;
894 for (i = 0; i < nspaces; i++)
895 pushkbd(' ');
896 }
897
898 return a;
899 }
900
901 static int64_t
902 cmdsend(Flayer *l, int64_t a, Text *t, const char *arg)
903 {
904 bool dojump = (t != &cmd);
905
906 flushtyping(false);
907 if (dojump)
908 cmdjump(l, a, t, NULL);
909
910 for (const char *c = arg; *c; c++){
911 pushkbd(*c);
912 type(&cmd.l[cmd.front]);
913 flushtyping(false);
914 }
915 pushkbd('\n');
916 type(&cmd.l[cmd.front]);
917 flushtyping(false);
918
919 if (dojump)
920 cmdjump(l, a, t, NULL);
921
922 return a;
923 }
924
925 static int64_t
926 cmdnone(Flayer *l, int64_t a, Text *t, const char *arg)
927 {
928 return a;
929 }
930
931 typedef int64_t (*Commandfunc)(Flayer *, int64_t, Text *, const char *);
932 typedef struct CommandEntry CommandEntry;
933 struct CommandEntry{
934 Commandfunc f;
935 bool unlocked;
936 bool docut;
937 };
938
939 CommandEntry commands[Cmax] ={
940 [Cnone] = {cmdnone, false, false},
941 [Cscrolldown] = {cmdscrolldown, false, false},
942 [Cscrollup] = {cmdscrollup, false, false},
943 [Cscrolldownline] = {cmdscrolldownline, false, false},
944 [Cscrollupline] = {cmdscrollupline, false, false},
945 [Ccharleft] = {cmdcharleft, false, false},
946 [Ccharright] = {cmdcharright, false, false},
947 [Clineup] = {cmdlineup, false, false},
948 [Clinedown] = {cmdlinedown, false, false},
949 [Cjump] = {cmdjump, false, false},
950 [Cescape] = {cmdescape, false, false},
951 [Csnarf] = {cmdsnarf, false, false},
952 [Ccut] = {cmdcut, false, false},
953 [Cpaste] = {cmdpaste, false, false},
954 [Cexchange] = {cmdexchange, false, false},
955 [Cdelword] = {cmddelword, true, false},
956 [Cdelbol] = {cmddelbol, true, false},
957 [Cdelbs] = {cmddelbs, true, true},
958 [Cdel] = {cmddel, true, true},
959 [Ceol] = {cmdeol, false, false},
960 [Cbol] = {cmdbol, false, false},
961 [Ctab] = {cmdtab, false, false},
962 [Csend] = {cmdsend, false, false},
963 [Clook] = {cmdlook, false, false},
964 [Csearch] = {cmdsearch, false, false},
965 [Cwrite] = {cmdwrite, false, false}
966 };
967
968
969 void
970 type(Flayer *l) /* what a bloody mess this is -- but it's getting bet…
971 {
972 Text *t = (Text *)l->user1;
973 wchar_t buf[100];
974 Keystroke k = {0};
975 wchar_t *p = buf;
976 int64_t a;
977
978 if(lock || t->lock){
979 kbdblock();
980 return;
981 }
982
983 k = qpeekc();
984 a = l->p0;
985 if (a != l->p1 && (k.k != Kcommand || commands[k.c].docut)){
986 flushtyping(true);
987 cut(t, t->front, true, true);
988 return; /* it may now be locked */
989 }
990
991 while (((k = kbdchar()), k.c) > 0) {
992 if (k.k == Kcommand)
993 break;
994
995 *p++ = k.c;
996 if (k.c == '\n' || p >= buf + sizeof(buf) / sizeof(buf[0]))
997 break;
998 }
999
1000 if (k.k == Kcommand){
1001 flushtyping(false);
1002 if (k.c < 0 || k.c >= Cmax || commands[k.c].f == NULL)
1003 panic("command table miss");
1004
1005 CommandEntry *e = &commands[k.c];
1006 if (!e->unlocked || !lock){
1007 if (k.t == Tcurrent)
1008 a = e->f(l, a, t, k.a);
1009 else{
1010 Flayer *lt = flwhich(k.p);
1011 if (lt)
1012 lt->p0 = e->f(lt, lt->p0, (Text *)lt->user1, k.a);
1013 }
1014 }
1015 }
1016
1017 if (p > buf){
1018 if (typestart < 0)
1019 typestart = a;
1020
1021 if (typeesc < 0)
1022 typeesc = a;
1023
1024 hgrow(t->tag, a, p-buf, 0);
1025 t->lock++; /* pretend we Trequest'ed for hdatarune*/
1026 hdatarune(t->tag, a, buf, p-buf);
1027 a += p-buf;
1028 l->p0 = a;
1029 l->p1 = a;
1030 typeend = a;
1031 if (autoindent && k.c == '\n' && t!=&cmd)
1032 a = indent(l, a);
1033 if (k.c == '\n' || typeend - typestart > 100)
1034 flushtyping(false);
1035 onethird(l, a);
1036 }
1037
1038 if (typeesc >= l->p0)
1039 typeesc = l->p0;
1040
1041 if (typestart >= 0){
1042 if(typestart >= l->p0)
1043 typestart = l->p0;
1044 typeend = l->p0;
1045 if (typestart == typeend){
1046 typestart = -1;
1047 typeend = -1;
1048 modified = false;
1049 }
1050 }
1051 }
1052
1053 void
1054 outcmd(void)
1055 {
1056 if(work)
1057 outTsll(Tworkfile, ((Text *)work->user1)->tag, work->p0, work->p…
1058 }
1059
1060 void
1061 panic(char *s)
1062 {
1063 fprintf(stderr, "samterm:panic: ");
1064 perror(s);
1065 abort();
1066 }
1067
1068 wchar_t*
1069 stgettext(Flayer *l, int64_t n, uint64_t *np)
1070 {
1071 Text *t;
1072
1073 t = l->user1;
1074 rload(&t->rasp, l->origin, l->origin+n, np);
1075 return scratch;
1076 }
1077
1078 int64_t
1079 scrtotal(Flayer *l)
1080 {
1081 return ((Text *)l->user1)->rasp.nrunes;
1082 }
1083
1084 void*
1085 alloc(uint64_t n)
1086 {
1087 void *p;
1088
1089 p = malloc(n);
1090 if(p == 0)
1091 panic("alloc");
1092 memset(p, 0, n);
1093 return p;
1094 }
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.