add VI_SEL_END, VI_SEL_START, SI_SELECT
[nvi.git] / common / api.c
blobf9eb116b3d40ab631a8ee9949cf743612efebdce
1 /*-
2 * Copyright (c) 1992, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 1992, 1993, 1994, 1995, 1996
5 * Keith Bostic. All rights reserved.
6 * Copyright (c) 1995
7 * George V. Neville-Neil. All rights reserved.
9 * See the LICENSE file for redistribution information.
12 #include "config.h"
14 #ifndef lint
15 static const char sccsid[] = "$Id: api.c,v 8.27 1996/12/05 12:27:30 bostic Exp $ (Berkeley) $Date: 1996/12/05 12:27:30 $";
16 #endif /* not lint */
18 #include <sys/types.h>
19 #include <sys/queue.h>
20 #include <sys/time.h>
22 #include <bitstring.h>
23 #include <limits.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <termios.h>
28 #include <unistd.h>
30 #include "../common/common.h"
32 extern GS *__global_list; /* XXX */
35 * api_fscreen --
36 * Return a pointer to the screen specified by the screen id
37 * or a file name.
39 * PUBLIC: SCR *api_fscreen __P((int, char *));
41 SCR *
42 api_fscreen(id, name)
43 int id;
44 char *name;
46 GS *gp;
47 SCR *tsp;
49 gp = __global_list;
51 /* Search the displayed list. */
52 for (tsp = gp->dq.cqh_first;
53 tsp != (void *)&gp->dq; tsp = tsp->q.cqe_next)
54 if (name == NULL) {
55 if (id == tsp->id)
56 return (tsp);
57 } else if (!strcmp(name, tsp->frp->name))
58 return (tsp);
60 /* Search the hidden list. */
61 for (tsp = gp->hq.cqh_first;
62 tsp != (void *)&gp->hq; tsp = tsp->q.cqe_next)
63 if (name == NULL) {
64 if (id == tsp->id)
65 return (tsp);
66 } else if (!strcmp(name, tsp->frp->name))
67 return (tsp);
68 return (NULL);
72 * api_aline --
73 * Append a line.
75 * PUBLIC: int api_aline __P((SCR *, recno_t, char *, size_t));
77 int
78 api_aline(sp, lno, line, len)
79 SCR *sp;
80 recno_t lno;
81 char *line;
82 size_t len;
84 return (db_append(sp, 1, lno, line, len));
88 * api_dline --
89 * Delete a line.
91 * PUBLIC: int api_dline __P((SCR *, recno_t));
93 int
94 api_dline(sp, lno)
95 SCR *sp;
96 recno_t lno;
98 return (db_delete(sp, lno));
102 * api_gline --
103 * Get a line.
105 * PUBLIC: int api_gline __P((SCR *, recno_t, char **, size_t *));
108 api_gline(sp, lno, linepp, lenp)
109 SCR *sp;
110 recno_t lno;
111 char **linepp;
112 size_t *lenp;
114 int isempty;
116 if (db_eget(sp, lno, linepp, lenp, &isempty)) {
117 if (isempty)
118 msgq(sp, M_ERR, "209|The file is empty");
119 return (1);
121 return (0);
125 * api_iline --
126 * Insert a line.
128 * PUBLIC: int api_iline __P((SCR *, recno_t, char *, size_t));
131 api_iline(sp, lno, line, len)
132 SCR *sp;
133 recno_t lno;
134 char *line;
135 size_t len;
137 return (db_insert(sp, lno, line, len));
141 * api_lline --
142 * Return the line number of the last line in the file.
144 * PUBLIC: int api_lline __P((SCR *, recno_t *));
147 api_lline(sp, lnop)
148 SCR *sp;
149 recno_t *lnop;
151 return (db_last(sp, lnop));
155 * api_sline --
156 * Set a line.
158 * PUBLIC: int api_sline __P((SCR *, recno_t, char *, size_t));
161 api_sline(sp, lno, line, len)
162 SCR *sp;
163 recno_t lno;
164 char *line;
165 size_t len;
167 return (db_set(sp, lno, line, len));
171 * api_getmark --
172 * Get the mark.
174 * PUBLIC: int api_getmark __P((SCR *, int, MARK *));
177 api_getmark(sp, markname, mp)
178 SCR *sp;
179 int markname;
180 MARK *mp;
182 return (mark_get(sp, (ARG_CHAR_T)markname, mp, M_ERR));
186 * api_setmark --
187 * Set the mark.
189 * PUBLIC: int api_setmark __P((SCR *, int, MARK *));
192 api_setmark(sp, markname, mp)
193 SCR *sp;
194 int markname;
195 MARK *mp;
197 return (mark_set(sp, (ARG_CHAR_T)markname, mp, 1));
201 * api_nextmark --
202 * Return the first mark if next not set, otherwise return the
203 * subsequent mark.
205 * PUBLIC: int api_nextmark __P((SCR *, int, char *));
208 api_nextmark(sp, next, namep)
209 SCR *sp;
210 int next;
211 char *namep;
213 LMARK *mp;
215 mp = sp->ep->marks.lh_first;
216 if (next)
217 for (; mp != NULL; mp = mp->q.le_next)
218 if (mp->name == *namep) {
219 mp = mp->q.le_next;
220 break;
222 if (mp == NULL)
223 return (1);
224 *namep = mp->name;
225 return (0);
229 * api_getcursor --
230 * Get the cursor.
232 * PUBLIC: int api_getcursor __P((SCR *, MARK *));
235 api_getcursor(sp, mp)
236 SCR *sp;
237 MARK *mp;
239 mp->lno = sp->lno;
240 mp->cno = sp->cno;
241 return (0);
245 * api_setcursor --
246 * Set the cursor.
248 * PUBLIC: int api_setcursor __P((SCR *, MARK *));
251 api_setcursor(sp, mp)
252 SCR *sp;
253 MARK *mp;
255 size_t len;
257 if (db_get(sp, mp->lno, DBG_FATAL, NULL, &len))
258 return (1);
259 if (mp->cno < 0 || mp->cno > len) {
260 msgq(sp, M_ERR, "Cursor set to nonexistent column");
261 return (1);
264 /* Set the cursor. */
265 sp->lno = mp->lno;
266 sp->cno = mp->cno;
267 return (0);
271 * api_emessage --
272 * Print an error message.
274 * PUBLIC: void api_emessage __P((SCR *, char *));
276 void
277 api_emessage(sp, text)
278 SCR *sp;
279 char *text;
281 msgq(sp, M_ERR, "%s", text);
285 * api_imessage --
286 * Print an informational message.
288 * PUBLIC: void api_imessage __P((SCR *, char *));
290 void
291 api_imessage(sp, text)
292 SCR *sp;
293 char *text;
295 msgq(sp, M_INFO, "%s", text);
299 * api_edit
300 * Create a new screen and return its id
301 * or edit a new file in the current screen.
303 * PUBLIC: int api_edit __P((SCR *, char *, SCR **, int));
306 api_edit(sp, file, spp, newscreen)
307 SCR *sp;
308 char *file;
309 SCR **spp;
310 int newscreen;
312 EXCMD cmd;
314 if (file) {
315 ex_cinit(sp, &cmd, C_EDIT, 0, OOBLNO, OOBLNO, 0);
316 argv_exp0(sp, &cmd, file, strlen(file));
317 } else
318 ex_cinit(sp, &cmd, C_EDIT, 0, OOBLNO, OOBLNO, 0);
319 if (newscreen)
320 cmd.flags |= E_NEWSCREEN; /* XXX */
321 if (cmd.cmd->fn(sp, &cmd))
322 return (1);
323 *spp = sp->nextdisp;
324 return (0);
328 * api_escreen
329 * End a screen.
331 * PUBLIC: int api_escreen __P((SCR *));
334 api_escreen(sp)
335 SCR *sp;
337 EXCMD cmd;
340 * XXX
341 * If the interpreter exits anything other than the current
342 * screen, vi isn't going to update everything correctly.
344 ex_cinit(sp, &cmd, C_QUIT, 0, OOBLNO, OOBLNO, 0);
345 return (cmd.cmd->fn(sp, &cmd));
349 * api_swscreen --
350 * Switch to a new screen.
352 * PUBLIC: int api_swscreen __P((SCR *, SCR *));
355 api_swscreen(sp, new)
356 SCR *sp, *new;
359 * XXX
360 * If the interpreter switches from anything other than the
361 * current screen, vi isn't going to update everything correctly.
363 sp->nextdisp = new;
364 F_SET(sp, SC_SSWITCH);
366 return (0);
370 * api_map --
371 * Map a key.
373 * PUBLIC: int api_map __P((SCR *, char *, char *, size_t));
376 api_map(sp, name, map, len)
377 SCR *sp;
378 char *name, *map;
379 size_t len;
381 EXCMD cmd;
383 ex_cinit(sp, &cmd, C_MAP, 0, OOBLNO, OOBLNO, 0);
384 argv_exp0(sp, &cmd, name, strlen(name));
385 argv_exp0(sp, &cmd, map, len);
386 return (cmd.cmd->fn(sp, &cmd));
390 * api_unmap --
391 * Unmap a key.
393 * PUBLIC: int api_unmap __P((SCR *, char *));
395 int
396 api_unmap(sp, name)
397 SCR *sp;
398 char *name;
400 EXCMD cmd;
402 ex_cinit(sp, &cmd, C_UNMAP, 0, OOBLNO, OOBLNO, 0);
403 argv_exp0(sp, &cmd, name, strlen(name));
404 return (cmd.cmd->fn(sp, &cmd));
408 * api_opts_get --
409 * Return a option value as a string, in allocated memory.
410 * If the option is of type boolean, boolvalue is (un)set
411 * according to the value; otherwise boolvalue is -1.
413 * PUBLIC: int api_opts_get __P((SCR *, char *, char **, int *));
416 api_opts_get(sp, name, value, boolvalue)
417 SCR *sp;
418 char *name, **value;
419 int *boolvalue;
421 OPTLIST const *op;
422 int offset;
424 if ((op = opts_search(name)) == NULL) {
425 opts_nomatch(sp, name);
426 return (1);
429 offset = op - optlist;
430 if (boolvalue != NULL)
431 *boolvalue = -1;
432 switch (op->type) {
433 case OPT_0BOOL:
434 case OPT_1BOOL:
435 MALLOC_RET(sp, *value, char *, strlen(op->name) + 2 + 1);
436 (void)sprintf(*value,
437 "%s%s", O_ISSET(sp, offset) ? "" : "no", op->name);
438 if (boolvalue != NULL)
439 *boolvalue = O_ISSET(sp, offset);
440 break;
441 case OPT_NUM:
442 MALLOC_RET(sp, *value, char *, 20);
443 (void)sprintf(*value, "%lu", (u_long)O_VAL(sp, offset));
444 break;
445 case OPT_STR:
446 if (O_STR(sp, offset) == NULL) {
447 MALLOC_RET(sp, *value, char *, 2);
448 value[0] = '\0';
449 } else {
450 MALLOC_RET(sp,
451 *value, char *, strlen(O_STR(sp, offset)) + 1);
452 (void)sprintf(*value, "%s", O_STR(sp, offset));
454 break;
456 return (0);
460 * api_opts_set --
461 * Set options.
463 * PUBLIC: int api_opts_set __P((SCR *, char *, char *, u_long, int));
466 api_opts_set(sp, name, str_value, num_value, bool_value)
467 SCR *sp;
468 char *name, *str_value;
469 u_long num_value;
470 int bool_value;
472 ARGS *ap[2], a, b;
473 OPTLIST const *op;
474 int rval;
475 size_t blen;
476 char *bp;
478 if ((op = opts_search(name)) == NULL) {
479 opts_nomatch(sp, name);
480 return (1);
483 switch (op->type) {
484 case OPT_0BOOL:
485 case OPT_1BOOL:
486 GET_SPACE_RET(sp, bp, blen, 64);
487 a.len = snprintf(bp, 64, "%s%s", bool_value ? "" : "no", name);
488 break;
489 case OPT_NUM:
490 GET_SPACE_RET(sp, bp, blen, 64);
491 a.len = snprintf(bp, 64, "%s=%lu", name, num_value);
492 break;
493 case OPT_STR:
494 GET_SPACE_RET(sp, bp, blen, 1024);
495 a.len = snprintf(bp, 1024, "%s=%s", name, str_value);
496 break;
498 a.bp = bp;
499 b.len = 0;
500 b.bp = NULL;
501 ap[0] = &a;
502 ap[1] = &b;
503 rval = opts_set(sp, ap, NULL);
505 FREE_SPACE(sp, bp, blen);
507 return (rval);
511 * api_run_str --
512 * Execute a string as an ex command.
514 * PUBLIC: int api_run_str __P((SCR *, char *));
516 int
517 api_run_str(sp, cmd)
518 SCR *sp;
519 char *cmd;
521 return (ex_run_str(sp, NULL, cmd, strlen(cmd), 0, 0));