Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 291 lines (257 sloc) 7.295 kb
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
1 /* display.c */
2 /* Copyright 1995 by Steve Kirkendall */
3
4
5 #include "elvis.h"
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
6 #ifdef FEATURE_RCSID
7 char id_display[] = "$Id: display.c,v 2.23 2003/10/17 17:41:23 steve Exp $";
8 #endif
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
9
10 /* This is a list of all known display modes. The last mode is the default. */
11 DISPMODE *allmodes[] =
12 {
13 #ifdef DISPLAY_HEX
14 &dmhex,
15 #endif
3a9bb55 @mbert Import Elvis 2.1_3 (written by Steve Kirkendall)
authored
16 #ifdef DISPLAY_HTML
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
17 &dmhtml,
3a9bb55 @mbert Import Elvis 2.1_3 (written by Steve Kirkendall)
authored
18 #endif
19 #ifdef DISPLAY_MAN
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
20 &dmman,
3a9bb55 @mbert Import Elvis 2.1_3 (written by Steve Kirkendall)
authored
21 #endif
22 #ifdef DISPLAY_TEX
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
23 &dmtex,
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
24 #endif
25 #ifdef DISPLAY_SYNTAX
26 &dmsyntax,
27 #endif
28 &dmnormal
29 };
30
31
32 /* List the available modes */
33 void displist(win)
34 WINDOW win;
35 {
36 int i;
37 char text[100];
38
39 for (i = 0; i < QTY(allmodes); i++)
40 {
41 sprintf(text, " %c%-6s %s\n",
42 win->md == allmodes[i] ? '*' : ' ',
43 allmodes[i]->name,
44 allmodes[i]->desc);
45 drawextext(win, toCHAR(text), (int)strlen(text));
46 }
47 }
48
49
50 /* Set the edit mode of a given window. If the name of the new mode is NULL,
51 * then the default display mode is used. If the name doesn't match any known
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
52 * mode, then an error message is issued and dispset() returns ElvFalse;
53 * normally it returns ElvTrue.
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
54 */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
55 ELVBOOL dispset(win, newmode)
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
56 WINDOW win; /* window whose edit mode is to be changed */
57 char *newmode; /* name of the new display mode */
58 {
59 int i, len;
60
61 /* if no name given, use the default mode */
62 if (!newmode || !*newmode)
63 {
64 i = QTY(allmodes) - 1;
65 newmode = allmodes[i]->name;
66 len = strlen(newmode);
67 }
68 else /* find the requested mode */
69 {
70 for (len = 0; newmode[len] && newmode[len] != ' '; len++)
71 {
72 }
73 for (i = 0; i < QTY(allmodes) && strncmp(allmodes[i]->name, newmode, len); i++)
74 {
75 }
76 if (i >= QTY(allmodes))
77 {
78 msg(MSG_ERROR, "[s]bad display mode $1", newmode);
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
79 return ElvFalse;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
80 }
81 }
82
83 /* if previous mode, then terminate it */
84 if (win->md)
85 {
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
86 #ifdef FEATURE_AUTOCMD
87 (void)auperform(win, ElvFalse, NULL, AU_DISPLAYLEAVE, o_display(win));
88 #endif
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
89 (*win->md->term)(win->mi);
90 if (optflags(o_display(win)) & OPT_FREE)
91 {
92 safefree(o_display(win));
93 optflags(o_display(win)) &= ~OPT_FREE;
94 }
95 }
96
97 /* store the display mode */
98 win->md = allmodes[i];
99 o_display(win) = CHARdup(toCHAR(newmode));
100 optflags(o_display(win)) |= OPT_FREE;
101 win->mi = allmodes[i]->init(win);
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
102 #ifdef FEATURE_AUTOCMD
103 (void)auperform(win, ElvFalse, NULL, AU_DISPLAYENTER, o_display(win));
104 #endif
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
105
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
106 return ElvTrue;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
107 }
108
109
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
110 /* This function is called twice: once before "elvis.ini" is interpreted, and
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
111 * again afterward. This function makes EVERY display mode's global options
112 * available via ":set" so they can be initialized to user-defined values.
113 */
114 void dispinit(before)
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
115 ELVBOOL before; /* ElvTrue before "elvis.ini", and ElvFalse after */
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
116 {
117 int i;
118 /* for each display mode... */
119 for (i = 0; i < QTY(allmodes); i++)
120 {
121 /* if the mode has global options... */
122 if (allmodes[i]->nglobopts > 0)
123 {
124 /* either add its options, or delete them */
125 if (before)
126 {
127 /* allow the mode to initialize its options */
128 (void)(*allmodes[i]->init)(NULL);
129
130 /* make them accessible to :set */
131 optinsert(allmodes[i]->name,
132 allmodes[i]->nglobopts,
133 allmodes[i]->globoptd,
134 allmodes[i]->globoptv);
135 }
136 else
137 {
138 optdelete(allmodes[i]->globoptv);
139 }
140 }
141 }
142 }
143
144
145 /* This function makes a given mode be the default mode... meaning that its
146 * options are available to the ":set" command.
147 */
148 void dispoptions(mode, info)
149 DISPMODE *mode; /* the display mode */
150 DMINFO *info; /* window-dependent options of this mode */
151 {
152 static DMINFO *curinfo;
153 static OPTVAL *curglob;
154
155 /* If the global mode options are changing... */
156 if (!mode || mode->globoptv != curglob)
157 {
158 /* delete the old global options, if any */
159 if (curglob)
160 {
161 optdelete(curglob);
162 }
163
164 /* insert the new global options, if any */
165 if (mode != NULL && mode->nglobopts > 0)
166 {
167 optinsert(mode->name, mode->nglobopts, mode->globoptd, mode->globoptv);
168 curglob = mode->globoptv;
169 }
170 else
171 {
172 curglob = NULL;
173 }
174 }
175
176 /* if the window-dependent mode options are changing... */
177 if (info != curinfo)
178 {
179 /* delete old window-dependent mode options, if any */
180 if (curinfo)
181 {
182 optdelete((OPTVAL *)curinfo);
183 }
184
185 /* insert new window-dependent mode options, if any */
186 if (mode != NULL && info != NULL && mode->nwinopts > 0)
187 {
188 optinsert("windisp", mode->nwinopts, mode->winoptd, (OPTVAL *)info);
189 curinfo = info;
190 }
191 else
192 {
193 curinfo = NULL;
194 }
195 }
196 }
197
198
199 /* This function calls the "move" function for a mode. If the state stack
200 * of the given window indicates that we're editing the window's main buffer,
201 * then the window's mode is used; otherwise, dmnormal is always used.
202 * If in the original visual command state, then the move function will be
203 * called for "cmd" behavior.
204 */
205 MARK dispmove(win, linedelta, wantcol)
206 WINDOW win; /* the window whose mode to use */
207 long linedelta; /* line movement */
208 long wantcol; /* desired column number */
209 {
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
210 ELVBOOL cmd;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
211
212 /* use "cmd" behavior if in vi command state */
213 cmd = viiscmd(win);
214
215 /* call the right function */
216 if (win->state->acton)
217 {
218 /* editing a history buffer - use dmnormal */
219 return (*dmnormal.move)(win, win->state->cursor, linedelta, wantcol, cmd);
220 }
221 else
222 {
223 /* editing window's main buffer - use window's mode */
224 return (*win->md->move)(win, win->state->cursor, linedelta, wantcol, cmd);
225 }
226 }
227
228
229 /* This function calls the "mark2col" function for a mode. If the state stack
230 * of the given window indicates that we're editing the window's main buffer,
231 * then the window's mode is used; otherwise, dmnormal is always used.
232 * If in the original visual command state, then the move function will be
233 * called for "cmd" behavior.
234 */
235 long dispmark2col(win)
236 WINDOW win; /* window whose mode to use */
237 {
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
238 ELVBOOL cmd = ElvFalse ;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
239
240 /* use "cmd" behavior if in vi command state */
241 if (!win->state->pop)
242 {
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
243 cmd = ElvTrue;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
244 }
245
246 /* call the right function */
247 if (win->state->acton)
248 {
249 /* editing a history buffer - use dmnormal */
250 return (*dmnormal.mark2col)(win, win->state->cursor, cmd);
251 }
252 else
253 {
254 /* editing window's main buffer - use window's mode */
255 return (*win->md->mark2col)(win, win->state->cursor, cmd);
256 }
257 }
258
259
260 /* This function implements autoindent. Given the MARK of a newly created
261 * line, insert a copy of the indentation from another line. The line whose
262 * indentation is to be copied is specified as a line delta. Usually, this
263 * will be -1 so the new line has the same indentation as a previous line.
264 * The <Shift-O> command uses a linedelta of 1 so the new line will have the
265 * same indentation as the following line.
266 */
267 void dispindent(w, line, linedelta)
268 WINDOW w; /* windows whose options are used */
269 MARK line; /* new line to adjust */
270 long linedelta; /* -1 to copy from previous line, etc. */
271 {
272 /* autoindent only works if supported and turned on, and even then
273 * only if we're editing the window's main edit buffer.
274 */
275 if (!w->md->indent
276 || !o_autoindent(markbuffer(w->cursor))
277 || markbuffer(w->cursor) != markbuffer(line))
278 {
279 return;
280 }
281
282 /* call the mode's indent function */
283 (*w->md->indent)(w, line, linedelta);
284
285 /* if necessary, extend the edit region to include the cursor's
286 * new position.
287 */
288 if (markoffset(w->state->cursor) > markoffset(w->state->bottom))
289 marksetoffset(w->state->bottom, markoffset(w->state->cursor));
290 }
Something went wrong with that request. Please try again.