1 /*-------------------------------------------------------*/
2 /* edit.c ( NTHU CS MapleBBS Ver 2.36 ) */
3 /*-------------------------------------------------------*/
4 /* target : simple ANSI/Chinese editor */
5 /* create : 1995/03/29 */
6 /* update : 2009/12/18 Dopin: �屼���Ϊ� */
7 /*-------------------------------------------------------*/
8
9 #include <stdlib.h>
10 #include <sys/param.h>
11 #include "bbs.h"
12
13 #define KEEP_EDITING -2
14 #define SCR_WIDTH 80
15 #define BACKUP_LIMIT 100
16
17 textline *firstline = NULL;
18 textline *lastline = NULL;
19 textline *currline = NULL;
20 textline *blockline = NULL;
21 textline *top_of_win = NULL;
22 textline *deleted_lines = NULL;
23
24 extern int KEY_ESC_arg;
25 extern int local_article;
26
27 char line[WRAPMARGIN + 2];
28 int currpnt, currln, totaln;
29 int curr_window_line;
30 int redraw_everything;
31 int insert_character;
32 int my_ansimode;
33 int raw_mode;
34 int edit_margin;
35 int phone_mode;
36 int blockln = -1;
37 int blockpnt;
38 int prevln = -1;
39 int prevpnt;
40 int modified;
41 int indent_mode = 1;
42 int insert_c = ' ';
43 struct stat st0;
44 char reset_color[4] = "[m";
45 char* FPath;
46
47 char fp_bak[] = "bak";
48 char *my_edit_mode[2] =
49 {"���N", "���J"};
50
51 char save_title[STRLEN];
52
53 /* ----------------------------------------------------- */
54 /* �O����z�P�s��B�z */
55 /* ----------------------------------------------------- */
56
indigestion(i)57 static void indigestion(i)
58 {
59 fprintf(stderr, "�Y������ %d\n", i);
60 }
61
62 /* ----------------------------------------------------- */
63 /* Thor: ansi �y���ഫ for color �s��Ҧ� */
64 /* ----------------------------------------------------- */
65
ansi2n(int ansix,textline * line)66 static int ansi2n(int ansix, textline * line)
67 {
68 register char *data, *tmp;
69 register char ch;
70
71 data = tmp = line->data;
72
73 while(*tmp) {
74 if (*tmp == KEY_ESC)
75 {
76 while((ch = *tmp) && !isalpha(ch))
77 tmp++;
78 if (ch)
79 tmp++;
80 continue;
81 }
82 if (ansix <= 0) break;
83 tmp++;
84 ansix--;
85 }
86 return tmp - data;
87 }
88
n2ansi(int nx,textline * line)89 static int n2ansi(int nx, textline * line)
90 {
91 register ansix = 0;
92 register char *tmp,*nxp;
93 register char ch;
94
95 tmp = nxp = line->data;
96 nxp += nx;
97
98 while(*tmp){
99 if (*tmp == KEY_ESC)
100 {
101 while((ch = *tmp) && !isalpha(ch))
102 tmp++;
103 if (ch)
104 tmp++;
105 continue;
106 }
107 if (tmp >= nxp) break;
108 tmp++;
109 ansix++;
110 }
111 return ansix;
112 }
113
114 /* ----------------------------------------------------- */
115 /* �ù��B�z�G���U�T���B��ܽs�褺�e */
116 /* ----------------------------------------------------- */
117
edit_msg(void)118 static void edit_msg(void)
119 {
120 static char *edit_mode[2] = {"���N", "���J"};
121 register int n = currpnt;
122
123 if (my_ansimode) /* Thor: �@ ansi �s�� */
124 n = n2ansi(n, currline);
125 n++;
126 move(b_lines, 0);
127 clrtoeol();
128 prints("\033[%sm �s��峹 \033[31;47m (Ctrl-G)\033[30m �u�W���U���� \033[31m(^X,^Q)\033[30m �ɮ׳B�z ��%s�x%c%c%c%c�� %3d:%3d \033[m",
129 (modified == -1) ? "34;46" : "37;44",
130 edit_mode[insert_character],
131 my_ansimode ? 'A' : 'a', indent_mode ? 'I' : 'i',
132 phone_mode ? 'P' : 'p', raw_mode ? 'R' : 'r',
133 currln + 1, n);
134 }
135
back_line(pos,num)136 static textline * back_line(pos, num)
137 register textline *pos;
138 int num;
139 {
140 while (num-- > 0)
141 {
142 register textline *item;
143
144 if (pos && (item = pos->prev))
145 {
146 pos = item;
147 currln--;
148 }
149 }
150 return pos;
151 }
152
153
forward_line(pos,num)154 static textline *forward_line(pos, num)
155 register textline *pos;
156 int num;
157 {
158 while (num-- > 0)
159 {
160 register textline *item;
161
162 if (pos && (item = pos->next))
163 {
164 pos = item;
165 currln++;
166 }
167 }
168 return pos;
169 }
170
getlineno()171 static int getlineno()
172 {
173 int cnt = 0;
174 textline *p = currline;
175
176 while (p && (p != top_of_win))
177 {
178 cnt++;
179 p = p->prev;
180 }
181 return cnt;
182 }
183
killsp(s)184 static char *killsp(s)
185 char *s;
186 {
187 while (*s == ' ')
188 s++;
189 return s;
190 }
191
alloc_line()192 static textline *alloc_line()
193 {
194 extern void *malloc();
195 register textline *p;
196
197 if (p = (textline *) malloc(sizeof(textline)))
198 {
199 memset(p, 0, sizeof(textline));
200 return p;
201 }
202
203 indigestion(13);
204 abort_bbs();
205 }
206
207 /* ----------------------------------------------------- */
208 /* append p after line in list. keeps up with last line */
209 /* ----------------------------------------------------- */
210
append(p,line)211 static void append(p, line)
212 register textline *p, *line;
213 {
214 register textline *n;
215
216 if (p->next = n = line->next)
217 n->prev = p;
218 else
219 lastline = p;
220 line->next = p;
221 p->prev = line;
222 }
223
224
225 /* ----------------------------------------------------- */
226 /* delete_line deletes 'line' from the list, */
227 /* and maintains the lastline, and firstline pointers. */
228 /* ----------------------------------------------------- */
229
delete_line(line)230 static void delete_line(line)
231 register textline *line;
232 {
233 register textline *p = line->prev;
234 register textline *n = line->next;
235
236 if (!p && !n)
237 {
238 line->data[0] = line->len = 0;
239 return;
240 }
241 if (n)
242 n->prev = p;
243 else
244 lastline = p;
245 if (p)
246 p->next = n;
247 else
248 firstline = n;
249 strcat(line->data, "\n");
250 line->prev = deleted_lines;
251 deleted_lines = line;
252 totaln--;
253 modified = -2;
254 }
255
256 /* woju */
257
undelete_line()258 undelete_line()
259 {
260 textline* p = deleted_lines;
261
262 textline* currline0 = currline;
263 textline* top_of_win0 = top_of_win;
264 int currpnt0 = currpnt;
265 int currln0 = currln;
266 int curr_window_line0 = curr_window_line;
267 int indent_mode0 = indent_mode;
268
269
270 if (!deleted_lines)
271 return 0;
272
273 indent_mode = 0;
274 insert_string(deleted_lines->data);
275 indent_mode = indent_mode0;
276 deleted_lines = deleted_lines->prev;
277 free(p);
278
279 currline = currline0;
280 top_of_win = top_of_win0;
281 currpnt = currpnt0;
282 currln = currln0;
283 curr_window_line = curr_window_line0;
284 modified = -2;
285 }
286
indent_spcs()287 int indent_spcs()
288 {
289 textline* p;
290 int spcs;
291
292 if (!indent_mode)
293 return 0;
294
295 for (p = currline; p; p = p->prev) {
296 for (spcs = 0; p->data[spcs] == ' '; ++spcs)
297 ;
298 if (p->data[spcs])
299 return spcs;
300 }
301 return 0;
302 }
303
304 /* ----------------------------------------------------- */
305 /* split 'line' right before the character pos */
306 /* ----------------------------------------------------- */
307
split(line,pos)308 static void split(line, pos)
309 register textline *line;
310 register int pos;
311 {
312 if (pos <= line->len)
313 {
314 register textline *p = alloc_line();
315 register char *ptr;
316 int spcs = indent_spcs();
317
318 totaln++;
319
320 p->len = line->len - pos + spcs;
321 line->len = pos;
322
323 memset(p->data, ' ', spcs);
324 p->data[spcs] = 0;
325 strcat(p->data, (ptr = line->data + pos));
326 ptr[0] = '\0';
327 append(p, line);
328 if (line == currline && pos <= currpnt)
329 {
330 currline = p;
331 if (pos == currpnt)
332 currpnt = spcs;
333 else
334 currpnt -= pos;
335 curr_window_line++;
336 currln++;
337 }
338 redraw_everything = YEA;
339 modified = -2;
340 }
341 }
342
343 /* ----------------------------------------------------- */
344 /* 1) lines were joined and one was deleted */
345 /* 2) lines could not be joined */
346 /* 3) next line is empty */
347 /* returns false if: */
348 /* 1) Some of the joined line wrapped */
349 /* ----------------------------------------------------- */
350
join(line)351 static int join(line)
352 register textline *line;
353 {
354 register textline *n;
355 register int ovfl;
356
357 if (!(n = line->next))
358 return YEA;
359 if (!*killsp(n->data))
360 return YEA;
361
362 modified = -2;
363 ovfl = line->len + n->len - WRAPMARGIN;
364 if (ovfl < 0)
365 {
366 strcat(line->data, n->data);
367 line->len += n->len;
368 delete_line(n);
369 return YEA;
370 }
371 else
372 {
373 register char *s;
374
375 s = n->data + n->len - ovfl - 1;
376 while (s != n->data && *s == ' ')
377 s--;
378 while (s != n->data && *s != ' ')
379 s--;
380 if (s == n->data)
381 return YEA;
382 split(n, (s - n->data) + 1);
383 if (line->len + n->len >= WRAPMARGIN)
384 {
385 indigestion(0);
386 return YEA;
387 }
388 join(line);
389 n = line->next;
390 ovfl = n->len - 1;
391 if (ovfl >= 0 && ovfl < WRAPMARGIN - 2)
392 {
393 s = &(n->data[ovfl]);
394 if (*s != ' ')
395 {
396 strcpy(s, " ");
397 n->len++;
398 }
399 }
400 return NA;
401 }
402 }
403
insert_char(ch)404 static void insert_char(ch)
405 register int ch;
406 {
407 register textline *p = currline;
408 register int i = p->len;
409 register char *s;
410 int wordwrap = YEA;
411
412 if (currpnt > i)
413 {
414 indigestion(1);
415 return;
416 }
417 if (currpnt < i && !insert_character)
418 {
419 p->data[currpnt++] = ch;
420 if (my_ansimode) /* Thor: ansi �s��, �i�Hoverwrite, ���\�� ansi code */
421 currpnt = ansi2n(n2ansi(currpnt, p),p);
422 }
423 else
424 {
425 while (i >= currpnt)
426 {
427 p->data[i + 1] = p->data[i];
428 i--;
429 }
430 p->data[currpnt++] = ch;
431 i = ++(p->len);
432 }
433 if (i < WRAPMARGIN)
434 return;
435 split(p, WRAPMARGIN / 2);
436 }
437
insert_string(str)438 insert_string(str)
439 char *str;
440 {
441 int ch;
442
443 while (ch = *str++)
444 {
445
446 #ifdef BIT8
447 if (isprint2(ch) || ch == '')
448 #else
449 if (isprint(ch))
450 #endif
451
452 {
453 insert_char(ch);
454 }
455 else if (ch == '\t')
456 {
457 do
458 {
459 insert_char(' ');
460 } while (currpnt & 0x7);
461 }
462 else if (ch == '\n')
463 split(currline, currpnt);
464 }
465 }
466
delete_char()467 static void delete_char()
468 {
469 register int len;
470
471 if (len = currline->len)
472 {
473 register int i;
474 register char *s;
475
476 if (currpnt >= len)
477 {
478 indigestion(1);
479 return;
480 }
481 for (i = currpnt, s = currline->data + i; i != len; i++, s++)
482 s[0] = s[1];
483 currline->len--;
484 }
485 }
486
load_file(fp)487 static void load_file(fp)
488 FILE *fp;
489 {
490 int indent_mode0 = indent_mode;
491
492 indent_mode = 0;
493 while (fgets(line, WRAPMARGIN + 2, fp))
494 insert_string(line);
495 fclose(fp);
496 indent_mode = indent_mode0;
497 }
498
499
500 /* ----------------------------------------------------- */
501 /* �Ȧs�� */
502 /* ----------------------------------------------------- */
503
ask_tmpbuf()504 static char *ask_tmpbuf()
505 {
506 static char fp_buf[10] = "buf.0";
507 static char msg[] = "�п�ܼȦs�� (0-9)[0]: ";
508
509 msg[19] = fp_buf[4];
510 do
511 {
512 if (!getdata(3, 0, msg, fp_buf + 4, 4, DOECHO))
513 fp_buf[4] = msg[19];
514 } while (fp_buf[4] < '0' || fp_buf[4] > '9');
515 return fp_buf;
516 }
517
read_tmpbuf(int n)518 static void read_tmpbuf(int n)
519 {
520 FILE *fp;
521 char fp_tmpbuf[80];
522 char tmpfname[] = "buf.0";
523 char *tmpf;
524 char ans[4] = "y";
525
526 if (0 <= n && n <= 9) {
527 tmpfname[4] = '0' + n;
528 tmpf = tmpfname;
529 }
530 else {
531 tmpf = ask_tmpbuf();
532 n = tmpf[4] - '0';
533 }
534
535 setuserfile(fp_tmpbuf, tmpf);
536
537 /* woju */
538 if (n != 0 && n != 5 && more(fp_tmpbuf, NA) != -1)
539 getdata(b_lines - 1, 0, "�T�wŪ�J��(Y/N)?[Y]", ans, 4, LCECHO);
540 if (*ans != 'n' && (fp = fopen(fp_tmpbuf, "r")))
541 {
542 modified = -2;
543 prevln = currln;
544 prevpnt = currpnt;
545 load_file(fp);
546 while (curr_window_line >= b_lines)
547 {
548 curr_window_line--;
549 top_of_win = top_of_win->next;
550 }
551 }
552 }
553
write_tmpbuf()554 static void write_tmpbuf()
555 {
556 FILE *fp;
557 char fp_tmpbuf[80], ans[4];
558 textline *p;
559
560 setuserfile(fp_tmpbuf, ask_tmpbuf());
561 if (dashf(fp_tmpbuf))
562 {
563 more(fp_tmpbuf, NA);
564 getdata(b_lines - 1, 0, "�Ȧs�ɤw����� (A)���[ (W)�мg (Q)�����H[A] ",
565 ans, 4, LCECHO);
566
567 if (ans[0] == 'q')
568 return;
569 }
570
571 fp = fopen(fp_tmpbuf, (ans[0] == 'w' ? "w" : "a+"));
572 for (p = firstline; p; p = p->next)
573 {
574 if (p->next || p->data[0])
575 fprintf(fp, "%s\n", p->data);
576 }
577 fclose(fp);
578 }
579
erase_tmpbuf()580 static void erase_tmpbuf()
581 {
582 char fp_tmpbuf[80];
583 char ans[4] = "n";
584
585 setuserfile(fp_tmpbuf, ask_tmpbuf());
586 /* woju */
587 if (more(fp_tmpbuf, NA) != -1)
588 getdata(b_lines - 1, 0, "�T�w�R����(Y/N)?[N]", ans, 4, LCECHO);
589 if (*ans == 'y')
590 unlink(fp_tmpbuf);
591 }
592
593 /* ----------------------------------------------------- */
594 /* �ɮ׳B�z�GŪ�ɡB�s�ɡB���D�Bñ�W�� */
595 /* ----------------------------------------------------- */
596
read_file(fpath)597 static void read_file(fpath)
598 char *fpath;
599 {
600 FILE *fp;
601
602 if ((fp = fopen(fpath, "r")) == NULL)
603 return;
604 load_file(fp);
605 }
606
write_file(fpath,saveheader)607 static int write_file(fpath, saveheader)
608 char *fpath;
609 int saveheader;
610 {
611 FILE *fp;
612 textline *p, *v;
613 char ans[TTLEN], *msg;
614 int aborted = 0;
615
616 if (!saveheader) {
617 stand_title("�ɮ׳B�z");
618 getdata(1, 0, "[S]�x�s (A)��� (E)�~�� (R/W/D)Ū�g�R�Ȧs�ɡH", ans, 4, LCECHO);
619 }
620 else
621 *ans = 's';
622
623 switch (ans[0])
624 {
625 case 'a':
626 outs("�峹[1m �S�� [0m�s�J");
627 aborted = -1;
628 break;
629
630 case 'r':
631 read_tmpbuf(-1);
632
633 case 'e':
634 return KEEP_EDITING;
635
636 case 'w':
637 write_tmpbuf();
638 return KEEP_EDITING;
639
640 case 'd':
641 erase_tmpbuf();
642 return KEEP_EDITING;
643
644 case 'S':
645 saveheader = YEA;
646 case 's':
647 local_article = 0;
648 break;
649 }
650
651 if (!aborted) {
652 struct stat st;
653
654 if (stat(FPath, &st) != -1 && st.st_mtime != st0.st_mtime) {
655 char buf[200];
656
657 sprintf(buf, "�g�Jĵ�i: %s �w�Q�䥦�{����ʹL", FPath);
658 stand_title(buf);
659 getdata(1, 0, "�T�w�x�s(Y/N)�H[N]", ans, 4, LCECHO);
660 if (*ans != 'y')
661 return KEEP_EDITING;
662 }
663 if ((fp = fopen(fpath, "w")) == NULL) {
664 stand_title("�g�J����: ��g��Ȧs��");
665 write_tmpbuf();
666 return KEEP_EDITING;
667 }
668 }
669
670 for (p = firstline; p; p = v)
671 {
672 v = p->next;
673 if (!aborted)
674 {
675 strncpy(line, p->data, WRAPMARGIN - 1);
676 if (v || line[0])
677 {
678 trim(line);
679 fprintf(fp, "%s\n", line);
680 }
681 }
682 if (!saveheader)
683 free(p);
684 }
685 if (!saveheader)
686 currline = NULL;
687
688 if (!aborted) {
689 fclose(fp);
690 stat(FPath, &st0);
691 modified = -1;
692 }
693
694 return saveheader ? KEEP_EDITING : aborted;
695 }
696
edit_outs(text)697 edit_outs(text)
698 char *text;
699 {
700 register int column = 0;
701 register char ch;
702
703 while ((ch = *text++) && (++column < SCR_WIDTH))
704 {
705 outch(ch == 27 ? '*' : ch);
706 }
707 }
708
block_outs(char * text,int column)709 block_outs(char* text, int column)
710 {
711 register char ch;
712
713 while ((ch = *text++) && (++column < SCR_WIDTH))
714 {
715 outch(ch == 27 ? '*' : ch);
716 }
717 }
718
719 int outs();
720
display_buffer()721 static void display_buffer()
722 {
723 register textline *p;
724 register int i;
725 int inblock;
726 char buf[WRAPMARGIN + 2];
727 int min, max;
728 int (*OUTS)();
729
730 if (currpnt > blockpnt) {
731 min = blockpnt;
732 max = currpnt;
733 }
734 else {
735 min = currpnt;
736 max = blockpnt;
737 }
738
739 OUTS = my_ansimode ? outs : edit_outs;
740
741 for (p = top_of_win, i = 0; i < b_lines; i++)
742 {
743
744 move(i, 0);
745 clrtoeol();
746 /*
747 woju
748 */
749 if (blockln >= 0
750 && (blockln <= currln
751 && blockln <= (currln - curr_window_line + i)
752 && (currln - curr_window_line + i) <= currln
753 ||
754 currln <= (currln - curr_window_line + i)
755 && (currln - curr_window_line + i) <= blockln)) {
756 outs("[7m");
757 inblock = 1;
758 }
759 else
760 inblock = 0;
761 if (p)
762 {
763 if (currln == blockln && p == currline && max > min) {
764 if (min > edit_margin) {
765 outs("[0m");
766 strncpy(buf, p->data + edit_margin, min - edit_margin);
767 buf[min - edit_margin] = 0;
768 block_outs(buf, 0);
769 }
770 outs("[7m");
771 if (min > edit_margin) {
772 strncpy(buf, p->data + min, max - min);
773 buf[max - min] = 0;
774 block_outs(buf, min - edit_margin);
775 }
776 else {
777 strncpy(buf, p->data + edit_margin, max - edit_margin);
778 buf[max - edit_margin] = 0;
779 block_outs(buf, 0);
780 }
781 outs("[0m");
782 block_outs(p->data + max, max - edit_margin);
783 }
784 else
785 OUTS(&p->data[edit_margin]);
786 p = p->next;
787 if (inblock)
788 outs("[0m");
789 }
790 else
791 outch('~');
792 }
793 edit_msg();
794 }
795
796 static char *vedithelp[] =
797 {
798 "\01�@����O",
799 "^X �ɮ׳B�z ^L ���s��ܵe��",
800 "^V ����ANSI��m ^G ��ܥ��D�U�e��",
801 "\01��в��ʫ��O",
802 "�� ���Ჾ�ʤ@�� ^A,Home ���즹��}�Y",
803 "�� ���e���ʤ@�� ^E,End ���즹�浲��",
804 "��,^P ���W���ʤ@�� (ESC-,) �����ɮ}�Y",
805 "��,^N ���U���ʤ@�� (ESC-.),^T �����ɮ���",
806 "^B,PgUp ���W���ʤ@�� ^F,PgDn ���U���ʤ@��",
807 "\01�R�����J���O",
808 "^O,Ins ���ܼҦ��� ���J/�л\\[m",
809 "^H,BS �R���e�@�Ӧr��",
810 "(ESC-l) �аO�϶�",
811 "^D,Del �R���ثe���r�� ANSI�x�¬�����ŵ��Q��",
812 "^K �R����Ф���ܦ�� �e���x[47;30;1m30[31m31[32m32[33m33[34m34[35m35[36m36[37m37[0m",
813 "^Y �R���ثe�o�� �I���x[40;33;1m40[41m41[42m42[43m43[44m44[45m45[46m46[47m47[0m",
814 "\01�S����O",
815 "^U ��J ESC �X(�H * ���) ^C �٭�/�]�w ANSI ��m",
816 "��ԲӪ�����: ve.hlp",
817 NULL};
818
819 void
show_help(helptext)820 show_help(helptext)
821 char *helptext[];
822 {
823 char *str;
824 int i;
825 char resolvedname[MAXPATHLEN], *rp;
826
827 clear();
828 for (i = 0; (str = helptext[i]); i++)
829 {
830 if (*str == '\0')
831 prints("[1m�i %s �j[0m\n", str + 1);
832 else if (*str == '\01')
833 prints("\n[36m�i %s �j[m\n", str + 1);
834 else
835 prints(" %s\n", str);
836 }
837 move(0, 0);
838 prints((rp = realpath(FPath, resolvedname)) ? resolvedname : FPath);
839
840 pressanykey();
841 }
842
843 /*
844 woju
845 lino == 0 for prompt
846 */
847
goto_line(int lino)848 goto_line(int lino)
849 {
850 char buf[10];
851
852 if (lino > 0 || getdata(b_lines - 1, 0, "���ܲĴX��:", buf, 10, DOECHO)
853 && sscanf(buf, "%d", &lino) && lino > 0) {
854 textline* p;
855
856 prevln = currln;
857 prevpnt = currpnt;
858 p = firstline;
859 currln = lino - 1;
860
861 while (--lino && p->next)
862 p = p->next;
863
864 if (p)
865 currline = p;
866 else {
867 currln = totaln;
868 currline = lastline;
869 }
870 currpnt = 0;
871 if (currln < 11) {
872 top_of_win = firstline;
873 curr_window_line = currln;
874 }
875 else {
876 int i;
877 curr_window_line = 11;
878
879 for (i = curr_window_line; i; i--)
880 p = p->prev;
881 top_of_win = p;
882 }
883 }
884 redraw_everything = YEA;
885 }
886
887
strcasestr(const char * big,const char * little)888 char *strcasestr(const char* big, const char* little)
889 {
890 char* ans = (char*)big;
891 int len = strlen(little);
892 char* endptr = (char*)big + strlen(big) - len;
893
894 while (ans <= endptr)
895 if (!strncasecmp(ans, little, len))
896 return ans;
897 else
898 ans++;
899 return 0;
900 }
901
902
903 /*
904 woju
905 mode:
906 0: prompt
907 1: forward
908 -1: backward
909 */
search_str(int mode)910 search_str(int mode)
911 {
912 static char str[80];
913 char buf[100];
914 typedef char* (*FPTR)();
915 static FPTR fptr;
916 char ans[4] = "n";
917
918 if (!mode) {
919 sprintf(buf, "�M��r��[%s]", str);
920 if (getdata(b_lines - 1, 0, buf, buf, 40, DOECHO))
921 strcpy(str, buf);
922 if (*str)
923 if (getdata(b_lines - 1, 0, "�Ϥ��j�p�g(Y/N/Q)? [N] ", ans, 4, LCECHO)
924 && *ans == 'y')
925 fptr = strstr;
926 else
927 fptr = strcasestr;
928 }
929
930 if (*str && *ans != 'q') {
931 textline* p;
932 char* pos = 0;
933 int lino;
934
935 if (mode >= 0) {
936 for (lino = currln, p = currline; p; p = p->next, lino++) {
937 if (*str == KEY_ESC) {
938 if (!strncmp(str + 1, p->data, strlen(str + 1))
939 && (lino != currln || currpnt)) {
940 pos = p->data;
941 break;
942 }
943 }
944 else if ((pos =
945 fptr(p->data + (lino == currln ? currpnt + 1 : 0), str))
946 && (lino != currln || pos - p->data != currpnt))
947 break;
948 }
949 }
950 else {
951 for (lino = currln, p = currline; p; p = p->prev, lino--) {
952 if (*str == KEY_ESC) {
953 if (!strncmp(str + 1, p->data, strlen(str + 1))
954 && (lino != currln || currpnt)) {
955 pos = p->data;
956 break;
957 }
958 }
959 if ((pos = fptr(p->data, str))
960 && (lino != currln || pos - p->data != currpnt))
961 break;
962 else
963 pos = 0;
964 }
965 }
966 if (pos) {
967 prevln = currln;
968 prevpnt = currpnt;
969 currline = p;
970 currln = lino;
971 currpnt = pos - p->data;
972 if (lino < 11) {
973 top_of_win = firstline;
974 curr_window_line = currln;
975 }
976 else {
977 int i;
978 curr_window_line = 11;
979
980 for (i = curr_window_line; i; i--)
981 p = p->prev;
982 top_of_win = p;
983 }
984 redraw_everything = YEA;
985 }
986 }
987 if (!mode)
988 redraw_everything = YEA;
989 }
990
match_paren()991 void match_paren()
992 {
993 static char parens[] = "()[]{}<>";
994 int type, mode;
995 int parenum = 0;
996 char *ptype;
997 textline* p;
998 int lino;
999 int c, i;
1000
1001 if (!(ptype = strchr(parens, currline->data[currpnt])))
1002 return;
1003
1004 type = (ptype - parens) / 2;
1005 parenum += ((ptype - parens) % 2) ? -1 : 1;
1006
1007
1008 if (parenum > 0) {
1009 for (lino = currln, p = currline; p; p = p->next, lino++) {
1010 lino = lino;
1011 for (i = (lino == currln) ? currpnt + 1 : 0; i < strlen(p->data); i++)
1012 if (p->data[i] == '/' && p->data[++i] == '*') {
1013 ++i;
1014 while (1) {
1015 while(i < strlen(p->data) - 1
1016 && !(p->data[i] == '*' && p->data[i + 1] == '/'))
1017 i++;
1018 if (i >= strlen(p->data) - 1 && p->next) {
1019 p = p->next;
1020 ++lino;
1021 i = 0;
1022 }
1023 else
1024 break;
1025 }
1026 }
1027 else if ((c = p->data[i]) == '\'' || c == '"') {
1028 while (1) {
1029 while (i < (int)(strlen(p->data) - 1))
1030 if (p->data[++i] == '\\' && i < strlen(p->data) - 2)
1031 ++i;
1032 else if (p->data[i] == c)
1033 goto end_quote;
1034 if (i >= strlen(p->data) - 1 && p->next) {
1035 p = p->next;
1036 ++lino;
1037 i = -1;
1038 }
1039 else
1040 break;
1041 }
1042 end_quote:
1043 ;
1044 }
1045 else if ((ptype = strchr(parens, p->data[i]))
1046 && (ptype - parens) / 2 == type)
1047 if (!(parenum += ((ptype - parens) % 2) ? -1 : 1))
1048 goto p_outscan;
1049 }
1050 }
1051 else {
1052 for (lino = currln, p = currline; p; p = p->prev, lino--)
1053 for (i = (lino == currln) ? currpnt - 1 : strlen(p->data) - 1;
1054 i >= 0; i--)
1055 if (p->data[i] == '/' && p->data[--i] == '*' && i >= 0) {
1056 --i;
1057 while (1) {
1058 while(i > 0
1059 && !(p->data[i] == '*' && p->data[i - 1] == '/'))
1060 i--;
1061 if (i <= 0 && p->prev) {
1062 p = p->prev;
1063 --lino;
1064 i = strlen(p->data) - 1;
1065 }
1066 else
1067 break;
1068 }
1069 }
1070 else if ((c = p->data[i]) == '\'' || c == '"') {
1071 while (1) {
1072 while (i > 0)
1073 if (i > 1 && p->data[i - 2] == '\\')
1074 i -= 2;
1075 else if ((p->data[--i]) == c)
1076 goto begin_quote;
1077 if (i <= 0 && p->prev) {
1078 p = p->prev;
1079 --lino;
1080 i = strlen(p->data);
1081 }
1082 else
1083 break;
1084 }
1085 begin_quote:
1086 ;
1087 }
1088 else if ((ptype = strchr(parens, p->data[i]))
1089 && (ptype - parens) / 2 == type)
1090 if (!(parenum += ((ptype - parens) % 2) ? -1 : 1))
1091 goto p_outscan;
1092 }
1093
1094 p_outscan:
1095
1096 if (!parenum) {
1097 int top = currln - curr_window_line;
1098 int bottom = currln - curr_window_line + b_lines - 1;
1099
1100 currpnt = i;
1101 currline = p;
1102 curr_window_line += lino - currln;
1103 currln = lino;
1104
1105 if (lino < top || lino > bottom) {
1106 if (lino < 11) {
1107 top_of_win = firstline;
1108 curr_window_line = currln;
1109 }
1110 else {
1111 int i;
1112 curr_window_line = 11;
1113
1114 for (i = curr_window_line; i; i--)
1115 p = p->prev;
1116 top_of_win = p;
1117 }
1118 redraw_everything = YEA;
1119 }
1120 }
1121 }
1122
1123
block_del(int hide)1124 block_del(int hide)
1125 {
1126 if (blockln < 0) {
1127 blockln = currln;
1128 blockpnt = currpnt;
1129 blockline = currline;
1130 }
1131 else {
1132 char fp_tmpbuf[80];
1133 FILE* fp;
1134 textline *begin, *end, *p;
1135 int lines;
1136 char tmpfname[10] = "buf.0";
1137 char ans[6] = "w+n";
1138
1139 move(b_lines - 1, 0);
1140 clrtoeol();
1141 if (hide == 1)
1142 tmpfname[4] = 'q';
1143 else if (!hide && !getdata(b_lines - 1, 0, "��϶����ܼȦs�� (0:Cut, 5:Copy, 6-9, q: Cancel)[0] ", tmpfname + 4, 4, LCECHO))
1144 tmpfname[4] = '0';
1145 if (tmpfname[4] < '0' || tmpfname[4] > '9')
1146 tmpfname[4] = 'q';
1147 if ('1' <= tmpfname[4] && tmpfname[4] <= '9') {
1148 setuserfile(fp_tmpbuf, tmpfname);
1149 if (tmpfname[4] != '5' && dashf(fp_tmpbuf)) {
1150 more(fp_tmpbuf, NA);
1151 getdata(b_lines - 1, 0, "�Ȧs�ɤw����� (A)���[ (W)�мg (Q)�����H[W] ", ans, 4, LCECHO);
1152 if (*ans == 'q')
1153 tmpfname[4] = 'q';
1154 else if (*ans != 'a')
1155 *ans = 'w';
1156 }
1157 if (tmpfname[4] != '5') {
1158 getdata(b_lines - 1, 0, "�R���϶�(Y/N)?[N] ", ans + 2, 4, LCECHO);
1159 if (ans[2] != 'y')
1160 ans[2] = 'n';
1161 }
1162 }
1163 else if (hide != 3)
1164 ans[2] = 'y';
1165
1166 tmpfname[5] = ans[1] = ans[3] = 0;
1167 if (tmpfname[4] != 'q') {
1168 if (currln >= blockln) {
1169 begin = blockline;
1170 end = currline;
1171 }
1172 else {
1173 begin = currline;
1174 end = blockline;
1175 }
1176
1177 if (ans[2] == 'y' && !(begin == end && currpnt != blockpnt)) {
1178 if (currln > blockln) {
1179 curr_window_line -= (currln - blockln);
1180 currln = blockln;
1181 if (curr_window_line < 0) {
1182 curr_window_line = 0;
1183 if (end->next)
1184 top_of_win = end->next;
1185 else
1186 top_of_win = begin->prev;
1187 }
1188 }
1189 if (!curr_window_line)
1190 if (end->next)
1191 top_of_win = end->next;
1192 else
1193 top_of_win = begin->prev;
1194
1195 if (begin->prev)
1196 begin->prev->next = end->next;
1197 else if (end->next)
1198 top_of_win = firstline = end->next;
1199 else {
1200 currline = top_of_win = firstline = lastline = alloc_line();
1201
1202 currln = curr_window_line = edit_margin = 0;
1203 }
1204
1205 if (end->next)
1206 (currline = end->next)->prev = begin->prev;
1207 else if (begin->prev) {
1208 currline = (lastline = begin->prev);
1209 currln--;
1210 if (curr_window_line > 0)
1211 curr_window_line--;
1212 }
1213 }
1214
1215 setuserfile(fp_tmpbuf, tmpfname);
1216 if (fp = fopen(fp_tmpbuf, ans)) {
1217 if (begin == end && currpnt != blockpnt) {
1218 char buf[WRAPMARGIN + 2];
1219
1220 if (currpnt > blockpnt) {
1221 strcpy(buf, begin->data + blockpnt);
1222 buf[currpnt - blockpnt] = 0;
1223 }
1224 else {
1225 strcpy(buf, begin->data + currpnt);
1226 buf[blockpnt - currpnt] = 0;
1227 }
1228 fputs(buf, fp);
1229 }
1230 else {
1231 for (p = begin; p != end; p = p->next)
1232 fprintf(fp, "%s\n", p->data);
1233 fprintf(fp, "%s\n", end->data);
1234 }
1235 fclose(fp);
1236 }
1237
1238 if (ans[2] == 'y') {
1239 modified = -2;
1240 if (begin == end && currpnt != blockpnt) {
1241 int min, max;
1242
1243 if (currpnt > blockpnt) {
1244 min = blockpnt;
1245 max = currpnt;
1246 }
1247 else {
1248 min = currpnt;
1249 max = blockpnt;
1250 }
1251 strcpy(begin->data + min, begin->data + max);
1252 begin->len -= max - min;
1253 currpnt = min;
1254 }
1255 else {
1256 for (p = begin; p != end; totaln--)
1257 free((p = p->next)->prev);
1258 free(end);
1259 totaln--;
1260 currpnt = 0;
1261 }
1262 }
1263 }
1264 blockln = -1;
1265 redraw_everything = YEA;
1266 }
1267 }
1268
block_shift_left()1269 block_shift_left()
1270 {
1271 textline *begin, *end, *p;
1272
1273 if (currln >= blockln) {
1274 begin = blockline;
1275 end = currline;
1276 }
1277 else {
1278 begin = currline;
1279 end = blockline;
1280 }
1281 p = begin;
1282 while (1) {
1283 if (p->len) {
1284 strcpy(p->data, p->data + 1);
1285 --p->len;
1286 }
1287 if (p == end)
1288 break;
1289 else
1290 p = p->next;
1291 }
1292 if (currpnt > currline->len)
1293 currpnt = currline->len;
1294 modified = -2;
1295 redraw_everything = YEA;
1296 }
1297
block_shift_right()1298 block_shift_right()
1299 {
1300 textline *begin, *end, *p;
1301
1302 if (currln >= blockln) {
1303 begin = blockline;
1304 end = currline;
1305 }
1306 else {
1307 begin = currline;
1308 end = blockline;
1309 }
1310 p = begin;
1311 while (1) {
1312 if (p->len < WRAPMARGIN) {
1313 int i = p->len + 1;
1314
1315 while (i--)
1316 p->data[i + 1] = p->data[i];
1317 p->data[0] = insert_character ? ' ' : insert_c;
1318 ++p->len;
1319 }
1320 if (p == end)
1321 break;
1322 else
1323 p = p->next;
1324 }
1325 if (currpnt > currline->len)
1326 currpnt = currline->len;
1327 modified = -2;
1328 redraw_everything = YEA;
1329 }
1330
1331
transform_to_color(char * line)1332 transform_to_color(char* line)
1333 {
1334 while (line[0] && line[1])
1335 if (line[0] == '*' && line[1] == '[') {
1336 modified = -2;
1337 line[0] = KEY_ESC;
1338 line += 2;
1339 }
1340 else
1341 ++line;
1342 }
1343
1344
block_color()1345 block_color()
1346 {
1347 textline *begin, *end, *p;
1348
1349 if (currln >= blockln) {
1350 begin = blockline;
1351 end = currline;
1352 }
1353 else {
1354 begin = currline;
1355 end = blockline;
1356 }
1357 p = begin;
1358 while (1) {
1359 transform_to_color(p->data);
1360 if (p == end)
1361 break;
1362 else
1363 p = p->next;
1364 }
1365 block_del(1);
1366 }
1367
1368
1369 /* ----------------------------------------------------- */
1370 /* �s��B�z�G�D�{���B��L�B�z */
1371 /* ----------------------------------------------------- */
1372
1373 extern int my_write();
1374
vedit(fpath,saveheader)1375 int vedit(fpath, saveheader)
1376 char *fpath;
1377 int saveheader;
1378 {
1379 int ch, foo;
1380 int lastindent = -1;
1381 int last_margin;
1382 int line_dirty = 0;
1383 char* pstr;
1384 extern char* phone_char();
1385
1386 FPath = fpath;
1387 stat(FPath, &st0);
1388
1389 insert_character = redraw_everything = 1;
1390
1391 currpnt = totaln = my_ansimode = 0;
1392 if (currline == NULL)
1393 currline = top_of_win = firstline = lastline = alloc_line();
1394
1395 if (*fpath)
1396 {
1397 read_file(fpath);
1398 }
1399
1400 currline = firstline;
1401 currpnt = currln = curr_window_line = edit_margin = last_margin = 0;
1402 modified = -1;
1403
1404 while (1)
1405 {
1406 if (redraw_everything || blockln >=0)
1407 {
1408 display_buffer();
1409 redraw_everything = NA;
1410 }
1411 if (my_ansimode)
1412 ch = n2ansi(currpnt, currline);
1413 else
1414 ch = currpnt - edit_margin;
1415 move(curr_window_line, ch);
1416 if (!line_dirty && strcmp(line, currline->data))
1417 strcpy(line, currline->data);
1418 ch = igetkey();
1419
1420 if (raw_mode)
1421 switch (ch) {
1422 case Ctrl('S'):
1423 case Ctrl('Q'):
1424 case Ctrl('T'):
1425 continue;
1426 break;
1427 }
1428
1429 /*
1430 if (ch == Ctrl('J') && !raw_mode)
1431 goto_line(0);
1432 */
1433 else if (phone_mode && (pstr = phone_char(ch)) || ch < 0x100 && isprint2(ch))
1434 {
1435 if (phone_mode && pstr)
1436 insert_string(pstr);
1437 else
1438 insert_char(ch);
1439 lastindent = -1;
1440 if (modified > -2)
1441 modified = currln;
1442 line_dirty = 1;
1443 }
1444 else
1445 {
1446 if (ch == Ctrl('P') || ch == KEY_UP || ch == KEY_DOWN || ch == Ctrl('N'))
1447 {
1448 if (lastindent == -1)
1449 lastindent = currpnt;
1450 }
1451 else
1452 lastindent = -1;
1453
1454 /*
1455 woju
1456 */
1457 if (ch == KEY_ESC)
1458 switch (KEY_ESC_arg) {
1459 case ',':
1460 ch = Ctrl(']');
1461 break;
1462 case '.':
1463 ch = Ctrl('T');
1464 break;
1465 case 'v':
1466 ch = KEY_PGUP;
1467 break;
1468 case 'a':
1469 case 'A':
1470 ch = Ctrl('V');
1471 break;
1472 case 'X':
1473 ch = Ctrl('X');
1474 break;
1475 case 'q':
1476 ch = Ctrl('Q');
1477 break;
1478 case 'o':
1479 ch = Ctrl('O');
1480 break;
1481 case '-':
1482 ch = Ctrl('_');
1483 break;
1484 case 's':
1485 ch = Ctrl('S');
1486 break;
1487 }
1488
1489 switch (ch)
1490 {
1491 case Ctrl('X'): /* Save and exit */
1492 foo = write_file(fpath, saveheader);
1493 if (foo != KEEP_EDITING)
1494 {
1495 return foo;
1496 }
1497 line_dirty = 1;
1498 redraw_everything = YEA;
1499 break;
1500
1501 case Ctrl('W'):
1502 if (blockln >= 0)
1503 block_del(2);
1504 line_dirty = 1;
1505 break;
1506
1507 case Ctrl('Q'): /* Quit without saving */
1508 ch = ask("���������x�s (Y/N)? [N]: ");
1509 if (ch == 'y' || ch == 'Y') {
1510 clear();
1511 return 0;
1512 }
1513 line_dirty = 1;
1514 redraw_everything = YEA;
1515 break;
1516
1517 case Ctrl('C'):
1518 ch = insert_character;
1519 insert_character = redraw_everything = YEA;
1520
1521 if (!my_ansimode)
1522 {
1523 insert_string(reset_color);
1524 if (modified > -2)
1525 modified = currln;
1526 }
1527 else
1528 {
1529 char ans[4];
1530 move(b_lines - 2, 55);
1531 outs("\033[1;33;40mB\033[41mR\033[42mG\033[43mY\033[44mL\033[45mP\033[46mC\033[47mW\033[m");
1532 if (getdata(b_lines - 1, 0, "�п�J �G��/�e��/�I��[���`�զr�©�][0wb]�G", ans, 4, LCECHO))
1533 {
1534 char t[] = "BRGYLPCW";
1535 char color[15];
1536 char *tmp, *apos = ans;
1537 int fg, bg;
1538
1539 if (!strchr(ans, 'q')) {
1540 strcpy(color, "\033[");
1541 if (isdigit(*apos))
1542 {
1543 sprintf(color, "%s%c", color, *(apos++));
1544 if (*apos)
1545 sprintf(color, "%s;", color);
1546 }
1547 if (*apos)
1548 {
1549 if (tmp = strchr(t, toupper(*(apos++))))
1550 fg = tmp - t + 30;
1551 else
1552 fg = 37;
1553 sprintf(color, "%s%d", color, fg);
1554 }
1555 if (*apos)
1556 {
1557 if (tmp = strchr(t, toupper(*(apos++))))
1558 bg = tmp - t + 40;
1559 else
1560 bg = 40;
1561 sprintf(color, "%s;%d", color, bg);
1562 }
1563 sprintf(color, "%sm", color);
1564 insert_string(color);
1565 if (modified > -2)
1566 modified = currln;
1567 }
1568 }
1569 else {
1570 insert_string(reset_color);
1571 if (modified > -2)
1572 modified = currln;
1573 }
1574 }
1575 insert_character = ch;
1576 line_dirty = 1;
1577 break;
1578
1579 case KEY_ESC:
1580 line_dirty = 0;
1581 switch (KEY_ESC_arg) {
1582 case 'w':
1583 ch = ask("�T�w�s�� (Y/N)? [Y]: ");
1584 if (!(ch == 'n' || ch == 'N'))
1585 write_file(fpath, YEA);
1586 line_dirty = 1;
1587 redraw_everything = YEA;
1588 break;
1589 case 'x':
1590 if (prevln >= 0) {
1591 int prevln0 = prevln;
1592 int prevpnt0 = prevpnt;
1593 prevln = currln;
1594 prevpnt = currpnt;
1595 goto_line(prevln0 + 1);
1596 currpnt = prevpnt0;
1597 }
1598 break;
1599 case 'n':
1600 search_str(1);
1601 edit_margin = currpnt < SCR_WIDTH - 1 ? 0 : currpnt / 72 * 72;
1602 if (edit_margin != last_margin)
1603 redraw_everything = NA;
1604 break;
1605 case 'p':
1606 search_str(-1);
1607 edit_margin = currpnt < SCR_WIDTH - 1 ? 0 : currpnt / 72 * 72;
1608 if (edit_margin != last_margin)
1609 redraw_everything = NA;
1610 break;
1611 case 'J':
1612 case 'L':
1613 case 'g':
1614 goto_line(0);
1615 break;
1616 case ']':
1617 match_paren();
1618 break;
1619 case '0':
1620 case '5':
1621 case '6':
1622 case '7':
1623 case '8':
1624 case '9':
1625 {
1626 int currln0 = currln;
1627 int currpnt0 = currpnt;
1628
1629 read_tmpbuf(KEY_ESC_arg - '0');
1630 redraw_everything = (currln0 == currln && currpnt0 != currpnt) ? NA : YEA;
1631 }
1632 break;
1633 case 'l': /* block delete */
1634 case ' ':
1635 block_del(0);
1636 line_dirty = 1;
1637 break;
1638 case 'u':
1639 if (blockln >= 0)
1640 block_del(1);
1641 line_dirty = 1;
1642 break;
1643 case 'c':
1644 if (blockln >= 0)
1645 block_del(3);
1646 line_dirty = 1;
1647 break;
1648 case 'y':
1649 undelete_line();
1650 break;
1651 case 'P':
1652 phone_mode ^= 1;
1653 line_dirty = 1;
1654 break;
1655 case 'R':
1656 raw_mode ^= 1;
1657 line_dirty = 1;
1658 break;
1659 case 'I':
1660 indent_mode ^= 1;
1661 line_dirty = 1;
1662 break;
1663 case 'j':
1664 if (blockln >= 0)
1665 block_shift_left();
1666 else if (currline->len) {
1667 int currpnt0 = currpnt;
1668 if (modified > -2)
1669 modified = currln;
1670 currpnt = 0;
1671 delete_char();
1672 currpnt = (currpnt0 <= currline->len) ? currpnt0 : currpnt0 - 1;
1673 if (my_ansimode)
1674 currpnt = ansi2n(n2ansi(currpnt, currline),currline);
1675 }
1676 line_dirty = 1;
1677 break;
1678 case 'k':
1679 if (blockln >= 0)
1680 block_shift_right();
1681 else {
1682 int currpnt0 = currpnt;
1683 if (modified > -2)
1684 modified = currln;
1685 currpnt = 0;
1686 insert_char(' ');
1687 currpnt = currpnt0;
1688 }
1689 line_dirty = 1;
1690 break;
1691 case 'f':
1692 while (currpnt < currline->len && isalnum(currline->data[++currpnt]))
1693 ;
1694 while (currpnt < currline->len && isspace(currline->data[++currpnt]))
1695 ;
1696 line_dirty = 1;
1697 break;
1698 case 'b':
1699 while (currpnt && isalnum(currline->data[--currpnt]))
1700 ;
1701 while (currpnt && isspace(currline->data[--currpnt]))
1702 ;
1703 line_dirty = 1;
1704 break;
1705 case 'd':
1706 if (modified > -2)
1707 modified = currln;
1708 while (currpnt < currline->len) {
1709 delete_char();
1710 if (!isalnum(currline->data[currpnt]))
1711 break;
1712 }
1713 while (currpnt < currline->len && isspace(currline->data[currpnt]))
1714 delete_char();
1715 line_dirty = 1;
1716 break;
1717 default:
1718 line_dirty = 1;
1719 }
1720 break;
1721 case Ctrl('S'):
1722 search_str(0);
1723 edit_margin = currpnt < SCR_WIDTH - 1 ? 0 : currpnt / 72 * 72;
1724 if (edit_margin != last_margin)
1725 redraw_everything = NA;
1726 break;
1727 case Ctrl('_'):
1728 if (strcmp(line, currline->data)) {
1729 char buf[WRAPMARGIN];
1730
1731 strcpy(buf, currline->data);
1732 strcpy(currline->data, line);
1733 strcpy(line, buf);
1734 currline->len = strlen(currline->data);
1735 currpnt = 0;
1736 line_dirty = 1;
1737 if (modified == currln)
1738 modified = -1;
1739 }
1740 break;
1741 case Ctrl('U'):
1742 if (modified > -2)
1743 modified = currln;
1744 insert_char('');
1745 line_dirty = 1;
1746 break;
1747
1748 case Ctrl('V'): /* Toggle ANSI color */
1749 my_ansimode ^= 1;
1750 if (my_ansimode && blockln >= 0)
1751 block_color();
1752 clear();
1753 redraw_everything = YEA;
1754 line_dirty = 1;
1755 break;
1756
1757 case Ctrl('I'):
1758 if (modified > -2)
1759 modified = currln;
1760 do
1761 {
1762 insert_char(' ');
1763 }
1764 while (currpnt & 0x7);
1765 line_dirty = 1;
1766 break;
1767
1768 case '\r':
1769 case '\n':
1770 split(currline, currpnt);
1771 line_dirty = 0;
1772 break;
1773 case Ctrl('Z'):
1774 clear();
1775 refresh();
1776 reset_tty();
1777 system(getenv("SHELL"));
1778 restore_tty();
1779 clear();
1780 redraw_everything = YEA;
1781 line_dirty = 1;
1782 break;
1783 case Ctrl('L'):
1784 clear();
1785 redraw_everything = YEA;
1786 line_dirty = 1;
1787 break;
1788 case Ctrl('G'):
1789 show_help(vedithelp);
1790 redraw_everything = YEA;
1791 line_dirty = 1;
1792 break;
1793
1794 case KEY_LEFT:
1795 if (currpnt) {
1796 if (my_ansimode)
1797 currpnt = n2ansi(currpnt, currline);
1798 currpnt--;
1799 if (my_ansimode)
1800 currpnt = ansi2n(currpnt, currline);
1801 line_dirty = 1;
1802 }
1803 else if (currline->prev)
1804 {
1805 curr_window_line--;
1806 currln--;
1807 currline = currline->prev;
1808 currpnt = currline->len;
1809 line_dirty = 0;
1810 }
1811 break;
1812
1813 case KEY_RIGHT:
1814 if (currline->len != currpnt) {
1815 if (my_ansimode)
1816 currpnt = n2ansi(currpnt, currline);
1817 currpnt++;
1818 if (my_ansimode)
1819 currpnt = ansi2n(currpnt, currline);
1820 line_dirty = 1;
1821 }
1822 else if (currline->next)
1823 {
1824 currpnt = 0;
1825 curr_window_line++;
1826 currln++;
1827 currline = currline->next;
1828 line_dirty = 0;
1829 }
1830 break;
1831
1832 case KEY_UP:
1833 case Ctrl('P'):
1834 if (currline->prev)
1835 {
1836 if (my_ansimode)
1837 ch = n2ansi(currpnt,currline);
1838 curr_window_line--;
1839 currln--;
1840 currline = currline->prev;
1841 if (my_ansimode)
1842 currpnt = ansi2n(ch , currline);
1843 else
1844 currpnt = (currline->len > lastindent) ? lastindent : currline->len;
1845 line_dirty = 0;
1846 }
1847 break;
1848
1849 case KEY_DOWN:
1850 case Ctrl('N'):
1851 if (currline->next)
1852 {
1853 if (my_ansimode)
1854 ch = n2ansi(currpnt,currline);
1855 currline = currline->next;
1856 curr_window_line++;
1857 currln++;
1858 if (my_ansimode)
1859 currpnt = ansi2n(ch , currline);
1860 else
1861 currpnt = (currline->len > lastindent) ? lastindent : currline->len;
1862 line_dirty = 0;
1863 }
1864 break;
1865 case Ctrl('B'):
1866 case KEY_PGUP:
1867 redraw_everything = currln;
1868 top_of_win = back_line(top_of_win, 22);
1869 currln = redraw_everything;
1870 currline = back_line(currline, 22);
1871 curr_window_line = getlineno();
1872 if (currpnt > currline->len)
1873 currpnt = currline->len;
1874 redraw_everything = YEA;
1875 line_dirty = 0;
1876 break;
1877
1878 case KEY_PGDN:
1879 case Ctrl('F'):
1880 redraw_everything = currln;
1881 top_of_win = forward_line(top_of_win, 22);
1882 currln = redraw_everything;
1883 currline = forward_line(currline, 22);
1884 curr_window_line = getlineno();
1885 if (currpnt > currline->len)
1886 currpnt = currline->len;
1887 redraw_everything = YEA;
1888 line_dirty = 0;
1889 break;
1890
1891 case KEY_END:
1892 case Ctrl('E'):
1893 trim(currline->data);
1894 currpnt = currline->len = strlen(currline->data);
1895 line_dirty = 1;
1896 break;
1897
1898 case Ctrl(']'): /* start of file */
1899 prevln = currln;
1900 prevpnt = currpnt;
1901 currline = top_of_win = firstline;
1902 currpnt = currln = curr_window_line = 0;
1903 redraw_everything = YEA;
1904 line_dirty = 0;
1905 break;
1906
1907 case Ctrl('T'): /* tail of file */
1908 prevln = currln;
1909 prevpnt = currpnt;
1910 top_of_win = back_line(lastline, 23);
1911 currline = lastline;
1912 curr_window_line = getlineno();
1913 currln = totaln;
1914 redraw_everything = YEA;
1915 currpnt = 0;
1916 line_dirty = 0;
1917 break;
1918
1919 case KEY_HOME:
1920 case Ctrl('A'):
1921 currpnt = 0;
1922 line_dirty = 1;
1923 break;
1924
1925 case KEY_INS: /* Toggle insert/overwrite */
1926 case Ctrl('O'):
1927 if (blockln >= 0 && insert_character) {
1928 char ans[4];
1929
1930 getdata(b_lines - 1, 0, "�϶��L�եk�����J�r��(�w�]���ťզr��)", ans, 4);
1931 insert_c = (*ans) ? *ans : ' ';
1932 }
1933 insert_character ^= 1;
1934 line_dirty = 1;
1935 break;
1936
1937 case Ctrl('H'):
1938 case '\177': /* backspace */
1939 line_dirty = 1;
1940 if (my_ansimode) {
1941 my_ansimode = 0;
1942 clear();
1943 redraw_everything = YEA;
1944 }
1945 else {
1946 if (currpnt == 0) {
1947 textline *p;
1948
1949 if (!currline->prev)
1950 {
1951 break;
1952 }
1953 line_dirty = 0;
1954 curr_window_line--;
1955 currln--;
1956 currline = currline->prev;
1957 currpnt = currline->len;
1958 redraw_everything = YEA;
1959 if (*killsp(currline->next->data) == '\0')
1960 {
1961 delete_line(currline->next);
1962 break;
1963 }
1964 p = currline;
1965 while (!join(p))
1966 {
1967 p = p->next;
1968 if (p == NULL)
1969 {
1970 indigestion(2);
1971 abort_bbs();
1972 }
1973 }
1974 break;
1975 }
1976 if (modified > -2)
1977 modified = currln;
1978 currpnt--;
1979 delete_char();
1980 }
1981 break;
1982
1983 case Ctrl('D'):
1984 case KEY_DEL: /* delete current character */
1985 line_dirty = 1;
1986 if (currline->len == currpnt)
1987 {
1988 textline *p = currline;
1989
1990 while (!join(p))
1991 {
1992 p = p->next;
1993 if (p == NULL)
1994 {
1995 indigestion(2);
1996 abort_bbs();
1997 }
1998 }
1999 line_dirty = 0;
2000 redraw_everything = YEA;
2001 }
2002 else {
2003 delete_char();
2004 if (modified > -2)
2005 modified = currln;
2006 if (my_ansimode)
2007 currpnt = ansi2n(n2ansi(currpnt, currline),currline);
2008 }
2009 break;
2010
2011 case Ctrl('Y'): /* delete current line */
2012 modified = -2;
2013 currline->len = currpnt = 0;
2014
2015 case Ctrl('K'): /* delete to end of line */
2016 if (currline->len == 0)
2017 {
2018 textline *p = currline->next;
2019
2020 if (!p)
2021 {
2022 p = currline->prev;
2023 if (!p)
2024 {
2025 break;
2026 }
2027 if (curr_window_line > 0)
2028 {
2029 curr_window_line--;
2030 currln--;
2031 }
2032 }
2033 if (currline == top_of_win)
2034 top_of_win = p;
2035 delete_line(currline);
2036 currline = p;
2037 redraw_everything = YEA;
2038 modified = -2;
2039 line_dirty = 0;
2040 break;
2041 }
2042
2043 if (currline->len == currpnt)
2044 {
2045 textline *p = currline;
2046
2047 while (!join(p))
2048 {
2049 p = p->next;
2050 if (p == NULL)
2051 {
2052 indigestion(2);
2053 abort_bbs();
2054 }
2055 }
2056 redraw_everything = YEA;
2057 line_dirty = 0;
2058 break;
2059 }
2060 currline->len = currpnt;
2061 currline->data[currpnt] = '\0';
2062 line_dirty = 1;
2063 if (modified > -2)
2064 modified = currln;
2065 break;
2066 }
2067
2068 if (currln < 0)
2069 currln = 0;
2070 if (curr_window_line < 0)
2071 {
2072 curr_window_line = 0;
2073 if (!top_of_win->prev)
2074 {
2075 indigestion(6);
2076 }
2077 else
2078 {
2079 top_of_win = top_of_win->prev;
2080 rscroll();
2081 }
2082 }
2083 if (curr_window_line == b_lines)
2084 {
2085 curr_window_line = t_lines - 2;
2086 if (!top_of_win->next)
2087 {
2088 indigestion(7);
2089 }
2090 else
2091 {
2092 top_of_win = top_of_win->next;
2093 move(b_lines, 0);
2094 clrtoeol();
2095 scroll();
2096 }
2097 }
2098 }
2099 edit_margin = currpnt < SCR_WIDTH - 1 ? 0 : currpnt / 72 * 72;
2100
2101 if (!redraw_everything)
2102 {
2103 if (edit_margin != last_margin)
2104 {
2105 last_margin = edit_margin;
2106 redraw_everything = YEA;
2107 }
2108 else
2109 {
2110 move(curr_window_line, 0);
2111 clrtoeol();
2112 if (my_ansimode)
2113 outs(currline->data);
2114 else
2115 edit_outs(&currline->data[edit_margin]);
2116 edit_msg();
2117 }
2118 }
2119 }
2120 }
2121