-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcomment.c
171 lines (146 loc) · 3.34 KB
/
comment.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/* Copyright (C) 1988-2018 Sean MacLennan */
#include "z.h"
/** @addtogroup zedit
* @{
*/
static bool Comstate;
struct comment {
struct mark *start, *end;
struct comment *next;
};
/* Mark a new comment from start to Point. */
static void newcomment(struct mark *start)
{
struct comment *com = calloc(sizeof(struct comment), 1);
if (!com)
return;
com->start = bcremark(Bbuff);
com->end = bcremark(Bbuff);
if (!com->start || !com->end) {
bdelmark(com->start);
bdelmark(com->end);
free(com);
return;
}
mrktomrk(com->start, start);
if (!Curbuff->chead)
Curbuff->chead = com;
else
((struct comment *)Curbuff->ctail)->next = com;
Curbuff->ctail = com;
}
/* Scan an entire buffer for comments. */
static void scanbuffer(struct zbuff *buff)
{
struct mark tmark, start;
Byte comchar = Curbuff->comchar;
uncomment(buff);
/* SAM FIXME This invalidate is brutal on slow connections. We
* need a better way to handle this.
*/
invalidate_scrnmarks(0, Rowmax - 2);
zswitchto(buff);
bmrktopnt(Bbuff, &tmark);
btostart(Bbuff);
if (comchar) {
while (bcsearch(Bbuff, comchar) && !bisend(Bbuff)) {
/* skip to char *before* # */
if (bmove(Bbuff, -2) == 0) {
/* # is first character in buffer */
} else if (isspace(Buff()))
bmove1(Bbuff);
else {
bmove(Bbuff, 2);
continue;
}
/* mark to end of line as comment */
bmrktopnt(Bbuff, &start);
bcsearch(Bbuff, '\n');
bmove(Bbuff, -1);
newcomment(&start);
}
} else {
/* Look for both C and C++ comments. */
while (bcsearch(Bbuff, '/') && !bisend(Bbuff)) {
if (Buff() == '*') {
bmove(Bbuff, -1);
bmrktopnt(Bbuff, &start);
if (bm_search(Bbuff, "*/", false))
newcomment(&start);
} else if (Buff() == '/') {
bmove(Bbuff, -1);
bmrktopnt(Bbuff, &start);
toendline(Bbuff);
newcomment(&start);
}
}
}
bpnttomrk(Bbuff, &tmark);
Comstate = true;
}
/* The following are called by the innerdsp routine. */
static struct comment *start;
/* Called from innerdsp before display loop */
void resetcomments(void)
{
start = Curbuff->chead;
switch (Lfunc) {
/* Was the last command a delete of any type? */
case ZDELETE_TO_EOL:
case ZDELETE_LINE:
case ZDELETE_REGION:
case ZDELETE_WORD:
case ZDELETE_PREVIOUS_WORD:
case ZCOPY_REGION:
case ZCOPY_WORD:
case ZAPPEND_KILL:
case ZDELETE_CHAR:
case ZDELETE_PREVIOUS_CHAR:
/* Or an insert? */
case ZYANK:
case ZINSERT:
case ZC_INSERT:
/* Can be insert or delete */
case ZUNDO:
Comstate = false;
}
}
/* Called from innerdsp for each char displayed. */
void cprntchar(Byte ch)
{
int style = T_NORMAL;
if (!Comstate) {
struct wdo *wdo;
struct zbuff *was = Curbuff;
scanbuffer(Curbuff);
for (wdo = Whead; wdo; wdo = wdo->next)
if (wdo->wbuff != Curbuff)
scanbuffer(wdo->wbuff);
zswitchto(was);
start = Curbuff ? Curbuff->chead : NULL;
}
for (; start; start = start->next)
if (bisbeforemrk(Bbuff, start->start))
break;
else if (bisbeforemrk(Bbuff, start->end) ||
bisatmrk(Bbuff, start->end)) {
style = T_COMMENT;
break;
}
tstyle(style);
tprntchar(ch);
}
/* Remove all comments from buffer and mark unscanned */
void uncomment(struct zbuff *buff)
{
if (buff)
while (buff->chead) {
struct comment *com = buff->chead;
buff->chead = com->next;
bdelmark(com->start);
bdelmark(com->end);
free(com);
}
Comstate = false;
}
/* @} */