1 /* @(#)edit.c 1.29 18/09/16 Copyright 1984-2018 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static UConst char sccsid[] =
5 "@(#)edit.c 1.29 18/09/16 Copyright 1984-2018 J. Schilling";
6 #endif
7 /*
8 * Main editing loop of VED (Visual EDitor)
9 *
10 * Copyright (c) 1984-2018 J. Schilling
11 */
12 /*
13 * The contents of this file are subject to the terms of the
14 * Common Development and Distribution License, Version 1.0 only
15 * (the "License"). You may not use this file except in compliance
16 * with the License.
17 *
18 * See the file CDDL.Schily.txt in this distribution for details.
19 * A copy of the CDDL is also available via the Internet at
20 * http://www.opensource.org/licenses/cddl1.txt
21 *
22 * When distributing Covered Code, include this CDDL HEADER in each
23 * file and include the License file CDDL.Schily.txt from this distribution.
24 */
25
26 #include "ved.h"
27 #include <schily/signal.h>
28 #include <schily/setjmp.h>
29 #include <schily/jmpdefs.h>
30
31 extern void (*nctab[NCTAB]) __PR((ewin_t *));
32 extern void (*chartab[NCTAB][256]) __PR((ewin_t *));
33 extern int ctabidx; /* The table idx where we take commands from */
34
35 LOCAL sigjmp_buf jmp;
36 extern sigjmps_t *sjp;
37
38 extern long charstyped;
39
40 LOCAL void intr __PR((int sig));
41 EXPORT void edit __PR((ewin_t *wp));
42
43 /* ARGSUSED */
44 LOCAL void
intr(sig)45 intr(sig)
46 int sig;
47 {
48 signal(SIGINT, intr);
49 if (sjp)
50 siglongjmp(sjp->jb, TRUE);
51 else
52 siglongjmp(jmp, TRUE);
53 }
54
55 EXPORT void
edit(wp)56 edit(wp)
57 ewin_t *wp;
58 {
59 register void (*f) __PR((ewin_t *));
60 register echar_t c;
61 register Uchar cc; /* Used to index the binding arrays */
62 register epos_t sdot;
63 BOOL in_command = FALSE;
64
65 extern int intrchar;
66 extern BOOL interrupted;
67
68 vedstartstats();
69
70 sdot = wp->dot;
71 if (sigsetjmp(jmp, 1)) {
72 if (in_command) {
73 /* dot = sdot;*/
74 update(wp);
75 writemsg(wp, C NULL);
76 writenum(wp, wp->curnum = wp->number = 1L);
77 abortmsg(wp);
78 flush();
79 } else {
80 if (intrchar > 0)
81 interrupted++;
82 }
83 } else {
84 signal(SIGINT, intr);
85 }
86 for (;;) {
87 sdot = wp->dot;
88 in_command = FALSE;
89 /*
90 * We never come here with c == EOF
91 */
92 c = gchar(wp);
93 charstyped++;
94 /*cdbg("got: '%c' (%d)", c, c);*/
95 in_command = TRUE;
96 cc = c & 0xFF;
97 wp->lastch = c;
98
99 /*
100 * Choose the right function to call for the current character.
101 * Refresh the system line or parts of it if needed.
102 */
103 if (c != cc) {
104 /*
105 * Handle chars outside the single byte range as normal
106 */
107 f = nctab[ctabidx];
108 } else {
109 f = chartab[ctabidx][cc];
110 }
111 ctabidx = CTAB;
112 refreshsysline(wp);
113
114 /*
115 * Call the function bound to the current character and update
116 * the display if needed.
117 * esccmd/altcmd/altesccmd may be set here.
118 */
119 (*f)(wp);
120 update(wp);
121
122 /*
123 * We want to keep the cursor on the same column if possible
124 * but shorter lines may force us to move the cursor to the
125 * left. To achieve this, we keep a remembered copy of the
126 * actual column that is not updated on corsur up/down
127 * movement.
128 */
129 if ((wp->eflags & COLUPDATE) != 0)
130 wp->column = cursor.hp;
131 else
132 wp->eflags |= COLUPDATE;
133
134 /*
135 * Make a curnum copy of number to allow anyone to modify it.
136 * Reset number to 1 except when the last character changed
137 * only the state or the last command requested us to save it.
138 */
139 wp->curnum = wp->number;
140 if (wp->number != 1 && ctabidx == CTAB) {
141 if ((wp->eflags & SAVENUM) != 0) {
142 wp->eflags &= ~SAVENUM;
143 } else {
144 writenum(wp, wp->curnum = wp->number = 1L);
145 }
146 }
147
148 /*
149 * If KEEPDEL is not set the next delete operation will remove
150 * the current content of the delete/rubout buffer first.
151 * A delete operation will set DELDONE. We transform this
152 * into KEEPDEL if the current command did not only change
153 * the state. If the last command did not move the cursor
154 * keep the deletions too.
155 */
156 if ((wp->eflags & KEEPDEL) != 0 && sdot == wp->dot)
157 wp->eflags |= DELDONE;
158
159 if ((wp->eflags & (KEEPDEL|DELDONE)) != 0 && ctabidx == CTAB) {
160 wp->eflags &= ~KEEPDEL;
161
162 if ((wp->eflags & DELDONE) != 0)
163 wp->eflags |= KEEPDEL;
164
165 wp->eflags &= ~DELDONE;
166 }
167 /*
168 * Usually, all deletions are saved into the delete/rubout
169 * buffer. However take operations have their own buffer.
170 * Set SAVEDEL here to choose standard behavior, take routines
171 * will clear it later to prevent wasting the delete buffer.
172 */
173 wp->eflags |= SAVEDEL;
174
175 /*
176 * Now write out everything that is in the screen buffer.
177 */
178 flush();
179 /* writeerr("wp, eflags: 0x%X", wp->eflags);*/
180 }
181 }
182