Add support for tab-completion when selecting by rule
[alpine.git] / pico / main.c
blob65b6e3f8831508c6531af51f9c361b629c21b62c
1 /*
2 * ========================================================================
3 * Copyright 2006-2008 University of Washington
4 * Copyright 2013-2022 Eduardo Chappa
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * ========================================================================
16 * Program: Main stand-alone Pine Composer routines
19 * WEEMACS/PICO NOTES:
21 * 08 Jan 92 - removed PINE defines to simplify compiling
23 * 08 Apr 92 - removed PINE stub calls
27 #include "headers.h"
28 #include "../c-client/mail.h"
29 #include "../c-client/rfc822.h"
30 #include "../c-client/utf8.h"
31 #include "../pith/osdep/collate.h"
32 #include "../pith/charconv/filesys.h"
33 #include "../pith/charconv/utf8.h"
34 #include "../pith/conf.h"
37 * Useful internal prototypes
39 #ifdef _WINDOWS
40 int pico_file_drop(int, int, char *);
41 #endif
44 * this isn't defined in the library, because it's a pine global
45 * which we use for GetKey's timeout
47 int timeoutset = 0;
50 int my_timer_period = (300 * 1000);
53 * function key mappings
55 static UCS fkm[12][2] = {
56 { F1, (CTRL|'G')},
57 { F2, (CTRL|'X')},
58 { F3, (CTRL|'O')},
59 { F4, (CTRL|'J')},
60 { F5, (CTRL|'R')},
61 { F6, (CTRL|'W')},
62 { F7, (CTRL|'Y')},
63 { F8, (CTRL|'V')},
64 { F9, (CTRL|'K')},
65 { F10, (CTRL|'U')},
66 { F11, (CTRL|'C')},
67 #ifdef SPELLER
68 { F12, (CTRL|'T')}
69 #else
70 { F12, (CTRL|'D')}
71 #endif
74 char *pico_args(int, char **, int *, int *, int *);
75 void pico_args_help(void);
76 void pico_vers_help(void);
77 void pico_display_args_err(char *, char **, int);
78 #ifndef _WINDOWS
79 PCOLORS *pico_set_global_colors(int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int);
80 void display_color_codes(void);
81 #endif /* ! _WINDOWS */
83 /* TRANSLATORS: An error message about an unknown flag (option)
84 on the command line */
85 char args_pico_missing_flag[] = N_("unknown flag \"%c\"");
86 /* TRANSLATORS: error message about command line */
87 char args_pico_missing_arg[] = N_("missing or empty argument to \"%c\" flag");
88 char args_pico_missing_arg_s[] = N_("missing or empty argument to \"%s\" flag");
89 char args_pico_missing_num[] = N_("non numeric argument for \"%c\" flag");
90 char args_pico_missing_color[] = N_("missing color for \"%s\" flag");
91 char args_pico_missing_charset[] = N_("missing character set for \"%s\" flag");
92 char args_pico_input_charset[] = N_("input character set \"%s\" is unsupported");
93 char args_pico_output_charset[] = N_("output character set \"%s\" is unsupported");
95 char *args_pico_args[] = {
96 /* TRANSLATORS: little help printed out when incorrect arguments
97 are given to pico program. */
98 N_("Possible Starting Arguments for Pico editor:"),
99 "",
100 N_("\tArgument\t\tMeaning"),
101 N_("\t -e \t\tComplete - allow file name completion"),
102 N_("\t -k \t\tCut - let ^K cut from cursor position to end of line"),
103 N_("\t -a \t\tShowDot - show dot files in file browser"),
104 N_("\t -j \t\tGoto - allow 'Goto' command in file browser"),
105 N_("\t -g \t\tShow - show cursor in file browser"),
106 N_("\t -m \t\tMouse - turn on mouse support"),
107 N_("\t -x \t\tNoKeyhelp - suppress keyhelp"),
108 N_("\t -p \t\tPreserveStartStop - preserve \"start\"(^Q) and \"stop\"(^S) characters"),
109 N_("\t -q \t\tTermdefWins - termcap or terminfo takes precedence over defaults"),
110 N_("\t -Q <quotestr> \tSet quote string (eg. \"> \") esp. for composing email"),
111 N_("\t -d \t\tRebind - let delete key delete current character"),
112 N_("\t -f \t\tKeys - force use of function keys"),
113 N_("\t -b \t\tReplace - allow search and replace"),
114 N_("\t -h \t\tHelp - give this list of options"),
115 N_("\t -r[#cols] \tFill - set fill column to #cols columns, default=72"),
116 N_("\t -n[#s] \tMail - notify about new mail every #s seconds, default=180"),
117 N_("\t -s <speller> \tSpeller - specify alternative speller"),
118 N_("\t -t \t\tShutdown - enable special shutdown mode"),
119 N_("\t -o <dir>\tOperation - specify the operating directory"),
120 N_("\t -z \t\tSuspend - allow use of ^Z suspension"),
121 N_("\t -w \t\tNoWrap - turn off word wrap"),
122 N_("\t -W <wordseps> \tSet word separators other than whitespace"),
123 #ifndef _WINDOWS
124 N_("\t -dcs <display_character_set> \tdefault uses LANG or LC_CTYPE from environment"),
125 N_("\t -kcs <keyboard_character_set> \tdefaults to display_character_set"),
126 N_("\t -syscs\t\tuse system-supplied translation routines"),
127 #endif /* ! _WINDOWS */
128 #ifdef _WINDOWS
129 N_("\t -dict \"dict1,dict2\" a comma separated list of dictionaries, e.g. en_US, de_DE, es_ES, etc."),
130 N_("\t -cnf color \tforeground color"),
131 N_("\t -cnb color \tbackground color"),
132 N_("\t -crf color \treverse foreground color"),
133 N_("\t -crb color \treverse background color"),
134 #endif /* _WINDOWS */
135 #ifndef _WINDOWS
136 N_("\t -color_code \tdisplay number codes for different colors"),
137 N_("\t -ncolors number \tnumber of colors for screen (8, 16, or 256)"),
138 N_("\t -ntfc number \tnumber of color of foreground text"),
139 N_("\t -ntbc number \tnumber of color of the background"),
140 N_("\t -rtfc number \tnumber of color of reverse text"),
141 N_("\t -rtbc number \tnumber of color of reverse background"),
142 N_("\t -tbfc number \tnumber of color of foreground (text) of the title bar"),
143 N_("\t -tbbc number \tnumber of color of background of the title bar"),
144 N_("\t -klfc number \tnumber of color of foreground (text) of the key label"),
145 N_("\t -klbc number \tnumber of color of background of the key label"),
146 N_("\t -knfc number \tnumber of color of foreground (text) of the key name"),
147 N_("\t -knbc number \tnumber of color of background of the key name"),
148 N_("\t -stfc number \tnumber of color of foreground (text) of the status line"),
149 N_("\t -stbc number \tnumber of color of background of the status line"),
150 N_("\t -prfc number \tnumber of color of foreground (text) of a prompt"),
151 N_("\t -prbc number \tnumber of color of background of a prompt"),
152 N_("\t -q1fc number \tnumber of color of foreground (text) of level one of quoted text"),
153 N_("\t -q1bc number \tnumber of color of background of level one of quoted text"),
154 N_("\t -q2fc number \tnumber of color of foreground (text) of level two of quoted text"),
155 N_("\t -q2bc number \tnumber of color of background of level two of quoted text"),
156 N_("\t -q3fc number \tnumber of color of foreground (text) of level three of quoted text"),
157 N_("\t -q3bc number \tnumber of color of background of level three of quoted text"),
158 N_("\t -sbfc number \tnumber of color of foreground of signature block text"),
159 N_("\t -sbbc number \tnumber of color of background of signature block text"),
160 #endif /* !_WINDOWS */
161 N_("\t +[line#] \tLine - start on line# line, default=1"),
162 N_("\t -v \t\tView - view file"),
163 N_("\t -no_setlocale_collate\tdo not do setlocale(LC_COLLATE)"),
164 N_("\t -version\tPico version number"),
165 "",
166 N_("\t All arguments may be followed by a file name to display."),
168 NULL
173 * main standalone pico routine
175 #ifdef _WINDOWS
177 app_main (int argc, char *argv[])
178 #else
180 main(int argc, char *argv[])
181 #endif
183 UCS c;
184 register int f;
185 register int n;
186 register BUFFER *bp;
187 int viewflag = FALSE; /* are we starting in view mode?*/
188 int starton = 0; /* where's dot to begin with? */
189 int setlocale_collate = 1;
190 char bname[NBUFN]; /* buffer name of file to read */
191 char *file_to_edit = NULL;
192 char *display_charmap = NULL, *dc;
193 char *keyboard_charmap = NULL;
194 int use_system = 0;
195 char *err = NULL;
197 #ifndef _WINDOWS
198 utf8_parameters(SET_UCS4WIDTH, (void *) pith_ucs4width);
199 #else /* _WINDOWS */
200 chosen_dict = -1; /* do not commit any dictionary when starting */
201 #endif /* _WINDOWS */
203 set_input_timeout(600);
204 Pmaster = NULL; /* turn OFF composer functionality */
205 km_popped = 0;
208 * Read command line flags before initializing, otherwise, we never
209 * know to init for f_keys...
211 file_to_edit = pico_args(argc, argv, &starton, &viewflag, &setlocale_collate);
213 set_collation(setlocale_collate, 1);
215 #define cpstr(s) strcpy((char *)fs_get(1+strlen(s)), s)
217 #ifdef _WINDOWS
218 init_utf8_display(1, NULL);
219 #else /* UNIX */
222 if(display_character_set)
223 display_charmap = cpstr(display_character_set);
224 #if HAVE_LANGINFO_H && defined(CODESET)
225 else if((dc = nl_langinfo_codeset_wrapper()) != NULL)
226 display_charmap = cpstr(dc);
227 #endif
229 if(!display_charmap)
230 display_charmap = cpstr("US-ASCII");
232 if(keyboard_character_set)
233 keyboard_charmap = cpstr(keyboard_character_set);
234 else
235 keyboard_charmap = cpstr(display_charmap);
238 if(use_system_translation){
239 #if PREREQ_FOR_SYS_TRANSLATION
240 use_system++;
241 /* This modifies its arguments */
242 if(setup_for_input_output(use_system, &display_charmap, &keyboard_charmap,
243 &input_cs, &err) == -1){
244 fprintf(stderr, "%s\n", err ? err : "trouble with character set");
245 exit(1);
247 else if(err){
248 fprintf(stderr, "%s\n", err);
249 fs_give((void **) &err);
251 #endif
254 if(!use_system){
255 if(setup_for_input_output(use_system, &display_charmap, &keyboard_charmap,
256 &input_cs, &err) == -1){
257 fprintf(stderr, "%s\n", err ? err : "trouble with character set");
258 exit(1);
260 else if(err){
261 fprintf(stderr, "%s\n", err);
262 fs_give((void **) &err);
266 if(keyboard_charmap){
267 set_locale_charmap(keyboard_charmap);
268 free((void *) keyboard_charmap);
271 if(display_charmap)
272 free((void *) display_charmap);
274 #endif /* UNIX */
277 * There are a couple arguments that we need to be sure
278 * are converted for internal use.
280 if(alt_speller)
281 alt_speller = cpstr(fname_to_utf8(alt_speller));
283 if(opertree && opertree[0]){
284 strncpy(opertree, fname_to_utf8(opertree), sizeof(opertree));
285 opertree[sizeof(opertree)-1] = '\0';
288 if(glo_quote_str_orig)
289 glo_quote_str = utf8_to_ucs4_cpystr(fname_to_utf8(glo_quote_str_orig));
291 if(glo_wordseps_orig)
292 glo_wordseps = utf8_to_ucs4_cpystr(fname_to_utf8(glo_wordseps_orig));
294 if(file_to_edit)
295 file_to_edit = cpstr(fname_to_utf8(file_to_edit));
297 #undef cpstr
299 #if defined(DOS) || defined(OS2)
300 if(file_to_edit){ /* strip quotes? */
301 int l;
303 if(strchr("'\"", file_to_edit[0])
304 && (l = strlen(file_to_edit)) > 1
305 && file_to_edit[l-1] == file_to_edit[0]){
306 file_to_edit[l-1] = '\0'; /* blat trailing quote */
307 file_to_edit++; /* advance past leading quote */
310 #endif
312 if(!vtinit()) /* Displays. */
313 exit(1);
315 strncpy(bname, "main", sizeof(bname)); /* default buffer name */
316 bname[sizeof(bname)-1] = '\0';
317 edinit(bname); /* Buffers, windows. */
319 update(); /* let the user know we are here */
320 sgarbf = TRUE; /* next update, repaint all */
322 #ifdef _WINDOWS
323 mswin_setwindow(NULL, NULL, NULL, NULL, NULL, NULL);
324 mswin_showwindow();
325 mswin_showcaret(1); /* turn on for main window */
326 mswin_allowpaste(MSWIN_PASTE_FULL);
327 mswin_setclosetext("Use the ^X command to exit Pico.");
328 mswin_setscrollcallback (pico_scroll_callback);
329 #endif
331 #if defined(USE_TERMCAP) || defined(USE_TERMINFO) || defined(VMS)
332 if(kbesc == NULL){ /* will arrow keys work ? */
333 (*term.t_putchar)('\007');
334 emlwrite("Warning: keypad keys may be non-functional", NULL);
336 #endif /* USE_TERMCAP/USE_TERMINFO/VMS */
338 if(file_to_edit){ /* Any file to edit? */
340 makename(bname, file_to_edit); /* set up a buffer for this file */
342 bp = curbp; /* read in first file */
343 makename(bname, file_to_edit);
344 strncpy(bp->b_bname, bname, sizeof(bp->b_bname));
345 bp->b_bname[sizeof(bp->b_bname)-1] = '\0';
347 if(strlen(file_to_edit) >= NFILEN){
348 char buf[128];
350 snprintf(buf, sizeof(buf), "Filename \"%.10s...\" too long", file_to_edit);
351 emlwrite(buf, NULL);
352 file_to_edit = NULL;
354 else{
355 strncpy(bp->b_fname, file_to_edit, sizeof(bp->b_fname));
356 bp->b_fname[sizeof(bp->b_fname)-1] = '\0';
357 if (((gmode&MDTREE) && !in_oper_tree(file_to_edit)) ||
358 readin(file_to_edit, (viewflag==FALSE), TRUE) == ABORT) {
359 if ((gmode&MDTREE) && !in_oper_tree(file_to_edit)){
360 EML eml;
361 eml.s = opertree;
362 emlwrite(_("Can't read file from outside of %s"), &eml);
365 file_to_edit = NULL;
369 if(!file_to_edit){
370 strncpy(bp->b_bname, "main", sizeof(bp->b_bname));
371 bp->b_bname[sizeof(bp->b_bname)-1] = '\0';
372 strncpy(bp->b_fname, "", sizeof(bp->b_fname));
373 bp->b_fname[sizeof(bp->b_fname)-1] = '\0';
376 bp->b_dotp = bp->b_linep;
377 bp->b_doto = 0;
379 if (viewflag) /* set the view mode */
380 bp->b_mode |= MDVIEW;
383 /* setup to process commands */
384 lastflag = 0; /* Fake last flags. */
385 curbp->b_mode |= gmode; /* and set default modes*/
387 curwp->w_flag |= WFMODE; /* and force an update */
389 if(timeoutset){
390 EML eml;
392 eml.s = comatose(get_input_timeout());
393 emlwrite(_("Checking for new mail every %s seconds"), &eml);
397 forwline(0, starton - 1); /* move dot to specified line */
399 while(1){
401 if(Pcolors)
402 pico_set_colorp(Pcolors->ntcp, PSC_NONE);
404 if(km_popped){
405 km_popped--;
406 if(km_popped == 0) /* cause bottom three lines to be repainted */
407 curwp->w_flag |= WFHARD;
410 if(km_popped){ /* temporarily change to cause menu to be painted */
411 term.t_mrow = 2;
412 curwp->w_ntrows -= 2;
413 curwp->w_flag |= WFMODE;
414 movecursor(term.t_nrow-2, 0); /* clear status line, too */
415 peeol();
418 update(); /* Fix up the screen */
419 if(km_popped){
420 term.t_mrow = 0;
421 curwp->w_ntrows += 2;
424 #ifdef MOUSE
425 #ifdef EX_MOUSE
426 /* New mouse function for real mouse text selection. */
427 register_mfunc(mouse_in_pico, 2, 0, term.t_nrow - (term.t_mrow + 1),
428 term.t_ncol);
429 #else
430 mouse_in_content(KEY_MOUSE, -1, -1, 0, 0);
431 register_mfunc(mouse_in_content, 2, 0, term.t_nrow - (term.t_mrow + 1),
432 term.t_ncol);
433 #endif
434 #endif
435 #ifdef _WINDOWS
436 mswin_setdndcallback (pico_file_drop);
437 mswin_mousetrackcallback(pico_cursor);
438 #endif
439 c = GetKey();
440 #ifdef MOUSE
441 #ifdef EX_MOUSE
442 clear_mfunc(mouse_in_pico);
443 #else
444 clear_mfunc(mouse_in_content);
445 #endif
446 #endif
447 #ifdef _WINDOWS
448 mswin_cleardndcallback ();
449 mswin_mousetrackcallback(NULL);
450 #endif
452 if(timeoutset && (c == NODATA || time_to_check())){
453 if(pico_new_mail())
454 emlwrite(_("You may possibly have new mail."), NULL);
457 if(km_popped)
458 switch(c){
459 case NODATA:
460 case (CTRL|'L'):
461 km_popped++;
462 break;
464 default:
465 /* clear bottom three lines */
466 mlerase();
467 break;
470 if(c == NODATA)
471 continue;
473 if(mpresf){ /* erase message line? */
474 if(mpresf++ > MESSDELAY)
475 mlerase();
478 f = FALSE;
479 n = 1;
481 #ifdef MOUSE
482 clear_mfunc(mouse_in_content);
483 #endif
484 /* Do it. */
485 execute(normalize_cmd(c, fkm, 1), f, n);
489 #ifndef _WINDOWS
490 void
491 display_color_codes(void)
493 #define SPACES " "
494 int i, k, l, a;
495 int ncolors;
496 COLOR_PAIR *lastc = NULL, *newcp;
498 /* this is the format "SPACE COLORED_SPACES = CODE SPACE" */
499 vtterminalinfo(gmode & MDTCAPWINS);
500 (*term.t_open)();
501 (*term.t_rev)(FALSE);
503 pico_toggle_color(0);
504 if((ncolors = pico_count_in_color_table()) <= 0){
505 fprintf(stderr, "%s", "Your screen does not support colors\r\n");
506 exit(1);
509 if(term.t_ncol < 62 || term.t_nrow < 23){
510 fprintf(stderr, "%s", "Screen must have at least 24 rows and 63 columns\r\n");
511 exit(1);
514 if(ncolors & 1) ncolors--; /* eliminate transparent colors at this time */
516 fprintf(stdout, "%s", "The code of a color is the number in the same row plus\r\n");
517 fprintf(stdout, "%s", "the number in the same column as that color.\r\n\r\n");
519 lastc = pico_get_cur_color();
520 switch(ncolors){
521 case 8: pico_set_color_options(COLOR_ANSI8_OPT|COLOR_TRANS_OPT); break;
522 case 16: pico_set_color_options(COLOR_ANSI16_OPT|COLOR_TRANS_OPT); break;
523 case 256: pico_set_color_options(COLOR_ANSI256_OPT|COLOR_TRANS_OPT); break;
524 default : fprintf(stderr, "Unknown number of colors %d\n", ncolors);
525 exit(1);
526 break;
529 pico_toggle_color(1);
530 if(ncolors < 256){
531 for(k = -1; 16*k < ncolors; k++){
532 for(l = -1; l < ncolors; l++){
533 if(k == -1){
534 if(l == -1)
535 fprintf(stdout, "%s", " ");
536 else
537 fprintf(stdout, "%3d", l);
539 else{
540 if(l == -1){
541 pico_toggle_color(1);
542 fprintf(stdout, "%3d ", k);
544 else{
545 if(ncolors || l < 8){
546 i = 16*k + l;
547 newcp = new_color_pair(colorx(0), colorx(i));
548 pico_set_colorp(newcp, PSC_NONE);
549 fprintf(stdout, "%s", SPACES);
550 pico_set_colorp(lastc, PSC_NONE);
555 pico_toggle_color(0);
556 if(k == -1)
557 fprintf(stdout, " (%d colors)", ncolors);
558 fprintf(stdout, "%s", "\r\n");
560 } else {
561 fprintf(stdout, "%s", "Codes for terminal with 256 colors:\r\n");
562 a = 16;
563 for(k = -1; 36*k < ncolors; k++){
564 for(l = -1; l < ncolors && l < 16; l++){
565 if(k == -1){
566 if(l == -1)
567 fprintf(stdout, "%s", " ");
568 else
569 fprintf(stdout, "%3d", l);
571 else{
572 if(l == -1){
573 pico_toggle_color(1);
574 fprintf(stdout, "%3d ", 36*k);
576 else{
577 i = 36*k + l;
578 newcp = new_color_pair(colorx(0), colorx(i));
579 pico_set_colorp(newcp, PSC_NONE);
580 fprintf(stdout, "%s", SPACES);
581 pico_set_colorp(lastc, PSC_NONE);
585 pico_toggle_color(0);
586 fprintf(stdout, "%s", "\r\n");
588 a = 20;
589 for(k = -1; 16 + 36*k < ncolors; k++){
590 for(l = -1; l < ncolors && l < a; l++){
591 if(k == -1){
592 if(l == -1)
593 fprintf(stdout, "%s", " ");
594 else
595 fprintf(stdout, "%3d", l);
597 else{
598 if(l == -1){
599 pico_toggle_color(1);
600 fprintf(stdout, "%3d ", 16 + 36*k);
602 else{
603 i = 16 + 36*k + l;
604 newcp = new_color_pair(colorx(0), colorx(i));
605 pico_set_colorp(newcp, PSC_NONE);
606 fprintf(stdout, "%s", SPACES);
607 pico_set_colorp(lastc, PSC_NONE);
611 pico_toggle_color(0);
612 fprintf(stdout, "%s", "\r\n");
615 pico_set_colorp(lastc, PSC_NONE);
617 #endif /* ! _WINDOWS */
621 * Parse the command line args.
623 * Args ac
624 * av
625 * starton -- place to return starton value
626 * viewflag -- place to return viewflag value
628 * Result: command arguments parsed
629 * possible printing of help for command line
630 * various global flags set
631 * returns the name of any file to open, else NULL
633 char *
634 pico_args(int ac, char **av, int *starton, int *viewflag, int *setlocale_collate)
636 int c, usage = 0;
637 char *str;
638 char tmp_1k_buf[1000]; /* tmp buf to contain err msgs */
639 #ifndef _WINDOWS
640 int ncolors, ntfc, ntbc, rtfc, rtbc;
641 int tbfc, tbbc, klfc, klbc, knfc, knbc, stfc, stbc, prfc, prbc;
642 int q1fc, q1bc, q2fc, q2bc, q3fc, q3bc, sbfc, sbbc;
644 ncolors = 0;
645 ntfc = ntbc = rtfc = rtbc = tbfc = tbbc = klfc = klbc = knfc =
646 knbc = stfc = stbc = prfc = prbc = q1fc = q1bc = q2fc = q2bc =
647 q3fc = q3bc = sbfc = sbbc = -1;
648 #endif /* ! _WINDOWS */
650 Loop:
651 /* while more arguments with leading - or + */
652 while(--ac > 0 && (**++av == '-' || **av == '+')){
653 if(**av == '+'){
654 if(*++*av)
655 str = *av;
656 else if(--ac)
657 str = *++av;
658 else{
659 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_arg), '+');
660 pico_display_args_err(tmp_1k_buf, NULL, 1);
661 usage++;
662 goto Loop;
665 if(!isdigit((unsigned char)str[0])){
666 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_num), '+');
667 pico_display_args_err(tmp_1k_buf, NULL, 1);
668 usage++;
671 if(starton)
672 *starton = atoi(str);
674 goto Loop;
677 /* while more chars in this argument */
678 else while(*++*av){
680 if(strcmp(*av, "version") == 0){
681 pico_vers_help();
683 #ifndef _WINDOWS /* color configuration disabled in Windows at this time */
684 else if(strcmp(*av, "ntfc") == 0
685 || strcmp(*av, "ntbc") == 0
686 || strcmp(*av, "rtfc") == 0
687 || strcmp(*av, "rtbc") == 0
688 || strcmp(*av, "tbfc") == 0
689 || strcmp(*av, "tbbc") == 0
690 || strcmp(*av, "klfc") == 0
691 || strcmp(*av, "klbc") == 0
692 || strcmp(*av, "knfc") == 0
693 || strcmp(*av, "knbc") == 0
694 || strcmp(*av, "stfc") == 0
695 || strcmp(*av, "stbc") == 0
696 || strcmp(*av, "prfc") == 0
697 || strcmp(*av, "prbc") == 0
698 || strcmp(*av, "q1fc") == 0
699 || strcmp(*av, "q1bc") == 0
700 || strcmp(*av, "q2fc") == 0
701 || strcmp(*av, "q2bc") == 0
702 || strcmp(*av, "q3fc") == 0
703 || strcmp(*av, "q3bc") == 0
704 || strcmp(*av, "sbfc") == 0
705 || strcmp(*av, "sbbc") == 0
706 || strcmp(*av, "ncolors") == 0){
707 str = *av;
708 if(--ac)
709 ++av;
710 else{
711 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_arg), '-');
712 pico_display_args_err(tmp_1k_buf, NULL, 1);
713 usage++;
714 goto Loop;
717 if(!isdigit((unsigned char)**av)){
718 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_num), '-');
719 pico_display_args_err(tmp_1k_buf, NULL, 1);
720 usage++;
722 if(strcmp(str, "ntfc") == 0) ntfc = atoi(*av);
723 else if (strcmp(str, "ntbc") == 0) ntbc = atoi(*av);
724 else if (strcmp(str, "rtfc") == 0) rtfc = atoi(*av);
725 else if (strcmp(str, "rtbc") == 0) rtbc = atoi(*av);
726 else if (strcmp(str, "tbfc") == 0) tbfc = atoi(*av);
727 else if (strcmp(str, "tbbc") == 0) tbbc = atoi(*av);
728 else if (strcmp(str, "klfc") == 0) klfc = atoi(*av);
729 else if (strcmp(str, "klbc") == 0) klbc = atoi(*av);
730 else if (strcmp(str, "knfc") == 0) knfc = atoi(*av);
731 else if (strcmp(str, "knbc") == 0) knbc = atoi(*av);
732 else if (strcmp(str, "stfc") == 0) stfc = atoi(*av);
733 else if (strcmp(str, "stbc") == 0) stbc = atoi(*av);
734 else if (strcmp(str, "prfc") == 0) prfc = atoi(*av);
735 else if (strcmp(str, "prbc") == 0) prbc = atoi(*av);
736 else if (strcmp(str, "q1fc") == 0) q1fc = atoi(*av);
737 else if (strcmp(str, "q1bc") == 0) q1bc = atoi(*av);
738 else if (strcmp(str, "q2fc") == 0) q2fc = atoi(*av);
739 else if (strcmp(str, "q2bc") == 0) q2bc = atoi(*av);
740 else if (strcmp(str, "q3fc") == 0) q3fc = atoi(*av);
741 else if (strcmp(str, "q3bc") == 0) q3bc = atoi(*av);
742 else if (strcmp(str, "sbfc") == 0) sbfc = atoi(*av);
743 else if (strcmp(str, "sbbc") == 0) sbbc = atoi(*av);
744 else if (strcmp(str, "ncolors") == 0) ncolors = atoi(*av);
745 if(!strcmp(str, "ncolors")){
746 switch(ncolors){
747 case 8: pico_set_color_options(COLOR_ANSI8_OPT|COLOR_TRANS_OPT); break;
748 case 16: pico_set_color_options(COLOR_ANSI16_OPT|COLOR_TRANS_OPT); break;
749 case 256: pico_set_color_options(COLOR_ANSI256_OPT|COLOR_TRANS_OPT); break;
750 default : snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _("Unsupported number of colors: %d"), ncolors);
751 pico_display_args_err(tmp_1k_buf, NULL, 1);
752 exit(1);
753 break;
756 goto Loop;
758 else if(strcmp(*av, "color_code") == 0){
759 display_color_codes();
760 exit(0);
762 #endif /* ! _WINDOWS */
763 else if(strcmp(*av, "no_setlocale_collate") == 0){
764 *setlocale_collate = 0;
765 goto Loop;
767 #ifndef _WINDOWS
768 else if(strcmp(*av, "syscs") == 0){
769 use_system_translation = !use_system_translation;
770 goto Loop;
772 #endif /* ! _WINDOWS */
773 #ifdef _WINDOWS
774 else if(strcmp(*av, "dict") == 0){
775 char *cmd = *av; /* save it to use below */
776 str = *++av;
777 if(--ac){
778 int i = 0;
779 char *s;
780 #define MAX_DICTIONARY 10
781 while(str && *str){
782 if(dictionary == NULL){
783 dictionary = fs_get((MAX_DICTIONARY + 1)*sizeof(char *));
784 memset((void *) dictionary, 0, (MAX_DICTIONARY+1)*sizeof(char *));
785 if(dictionary == NULL)
786 goto Loop; /* get out of here */
788 if((s = strpbrk(str, " ,")) != NULL)
789 *s++ = '\0';
790 dictionary[i] = fs_get(strlen(str) + 1);
791 strcpy(dictionary[i++], str);
792 if(s != NULL)
793 for(; *s && (*s == ' ' || *s == ','); s++);
794 else
795 goto Loop;
796 if(i == MAX_DICTIONARY + 1)
797 goto Loop;
798 else
799 str = s;
802 else{
803 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_arg_s), cmd);
804 pico_display_args_err(tmp_1k_buf, NULL, 1);
805 usage++;
808 goto Loop;
810 else if(strcmp(*av, "cnf") == 0
811 || strcmp(*av, "cnb") == 0
812 || strcmp(*av, "crf") == 0
813 || strcmp(*av, "crb") == 0){
815 char *cmd = *av; /* save it to use below */
817 if(--ac){
818 str = *++av;
819 if(cmd[1] == 'n'){
820 if(cmd[2] == 'f')
821 pico_nfcolor(str);
822 else if(cmd[2] == 'b')
823 pico_nbcolor(str);
825 else if(cmd[1] == 'r'){
826 if(cmd[2] == 'f')
827 pico_rfcolor(str);
828 else if(cmd[2] == 'b')
829 pico_rbcolor(str);
832 else{
833 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_color), cmd);
834 pico_display_args_err(tmp_1k_buf, NULL, 1);
835 usage++;
838 goto Loop;
840 #endif /* _WINDOWS */
841 #ifndef _WINDOWS
842 else if(strcmp(*av, "dcs") == 0 || strcmp(*av, "kcs") == 0){
843 char *cmd = *av;
845 if(--ac){
846 if(strcmp(*av, "dcs") == 0){
847 display_character_set = *++av;
848 if(!output_charset_is_supported(display_character_set)){
849 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_output_charset), display_character_set);
850 pico_display_args_err(tmp_1k_buf, NULL, 1);
851 usage++;
854 else{
855 keyboard_character_set = *++av;
856 if(!input_charset_is_supported(keyboard_character_set)){
857 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_input_charset), keyboard_character_set);
858 pico_display_args_err(tmp_1k_buf, NULL, 1);
859 usage++;
863 else{
864 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_charset), cmd);
865 pico_display_args_err(tmp_1k_buf, NULL, 1);
866 usage++;
869 goto Loop;
871 #endif /* ! _WINDOWS */
874 * Single char options.
876 switch(c = **av){
878 * These don't take arguments.
880 case 'a':
881 gmode ^= MDDOTSOK; /* show dot files */
882 break;
883 case 'b':
884 #ifdef notdef
886 * Make MDREPLACE always on instead
887 * Don't leave this to allow turning off of MDREPLACE because the
888 * polarity of -b will have changed. Don't think anybody wants to
889 * turn it off.
891 gmode ^= MDREPLACE; /* -b for replace string in where is command */
892 #endif
893 break;
894 case 'd': /* -d for rebind delete key */
895 bindtokey(0x7f, forwdel);
896 break;
897 case 'e': /* file name completion */
898 gmode ^= MDCMPLT;
899 break;
900 case 'f': /* -f for function key use */
901 gmode ^= MDFKEY;
902 break;
903 case 'g': /* show-cursor in file browser */
904 gmode ^= MDSHOCUR;
905 break;
906 case 'h':
907 usage++;
908 break;
909 case 'j': /* allow "Goto" in file browser */
910 gmode ^= MDGOTO;
911 break;
912 case 'k': /* kill from dot */
913 gmode ^= MDDTKILL;
914 break;
915 case 'm': /* turn on mouse support */
916 gmode ^= MDMOUSE;
917 break;
918 case 'p':
919 preserve_start_stop = 1;
920 break;
921 case 'q': /* -q for termcap takes precedence */
922 gmode ^= MDTCAPWINS;
923 break;
924 case 't': /* special shutdown mode */
925 gmode ^= MDTOOL;
926 rebindfunc(wquit, quickexit);
927 break;
928 case 'v': /* -v for View File */
929 case 'V':
930 *viewflag = !*viewflag;
931 break; /* break back to inner-while */
932 case 'w': /* -w turn off word wrap */
933 gmode ^= MDWRAP;
934 break;
935 case 'x': /* suppress keyhelp */
936 sup_keyhelp = !sup_keyhelp;
937 break;
938 case 'z': /* -z to suspend */
939 gmode ^= MDSSPD;
940 break;
943 * These do take arguments.
945 case 'r': /* set fill column */
946 case 'n': /* -n for new mail notification */
947 case 's' : /* speller */
948 case 'o' : /* operating tree */
949 case 'Q' : /* Quote string */
950 case 'W' : /* Word separators */
951 if(*++*av)
952 str = *av;
953 else if(--ac)
954 str = *++av;
955 else{
956 if(c == 'r')
957 str= "72";
958 else if(c == 'n')
959 str = "180";
960 else{
961 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_arg), c);
962 pico_display_args_err(tmp_1k_buf, NULL, 1);
963 usage++;
964 goto Loop;
968 switch(c){
969 case 's':
970 alt_speller = str;
971 break;
972 case 'o':
973 strncpy(opertree, str, NLINE);
974 gmode ^= MDTREE;
975 break;
976 case 'Q':
977 glo_quote_str_orig = str;
978 break;
979 case 'W':
980 glo_wordseps_orig = str;
981 break;
983 /* numeric args */
984 case 'r':
985 case 'n':
986 if(!isdigit((unsigned char)str[0])){
987 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_num), c);
988 pico_display_args_err(tmp_1k_buf, NULL, 1);
989 usage++;
992 if(c == 'r'){
993 if((userfillcol = atoi(str)) < 1)
994 userfillcol = 72;
996 else{
997 timeoutset = 1;
998 set_input_timeout(180);
999 if(set_input_timeout(atoi(str)) < 30)
1000 set_input_timeout(180);
1003 break;
1006 goto Loop;
1008 default: /* huh? */
1009 snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_flag), c);
1010 pico_display_args_err(tmp_1k_buf, NULL, 1);
1011 usage++;
1012 break;
1017 if(usage)
1018 pico_args_help();
1020 #ifndef _WINDOWS
1021 Pcolors = pico_set_global_colors(ncolors, ntfc, ntbc, rtfc, rtbc,
1022 tbfc, tbbc, klfc, klbc, knfc, knbc, stfc, stbc, prfc, prbc,
1023 q1fc, q1bc, q2fc, q2bc, q3fc, q3bc, sbfc, sbbc);
1025 if(Pcolors)
1026 pico_toggle_color(1);
1027 #endif /* ! _WINDOWS */
1029 /* return the first filename for editing */
1030 if(ac > 0)
1031 return(*av);
1032 else
1033 return(NULL);
1037 #ifndef _WINDOWS
1038 PCOLORS *
1039 pico_set_global_colors(int nc, int ntfg, int ntbg, int rtfg, int rtbg,
1040 int tbfg, int tbbg, int klfg, int klbg,
1041 int knfg, int knbg, int stfg, int stbg, int prfg, int prbg,
1042 int q1fg, int q1bg, int q2fg, int q2bg, int q3fg, int q3bg,
1043 int sbfg, int sbbg)
1045 PCOLORS *pcolors = NULL;
1046 char *fg, *bg;
1048 if(nc != 0 && nc != 8 && nc != 16 && nc != 256){
1049 fprintf(stderr, "number of colors must be either 8, 16 or 256\n");
1050 exit(1);
1053 if(nc == 0){
1054 if(ntfg != -1 || ntbg != -1 || tbfg != -1 || tbbg != -1 ||
1055 klfg != -1 || klbg != -1 || knfg != -1 || knbg != -1 ||
1056 stfg != -1 || stbg != -1 || prfg != -1 || prbg != -1 ||
1057 q1fg != -1 || q1bg != -1 || q2fg != -1 || q1bg != -1 ||
1058 q3fg != -1 || q3bg != -1 || sbfg != -1 || sbbg != -1 ||
1059 rtfg != -1 || rtbg != -1){
1060 fprintf(stderr, "can not specify color numbers without specifying number of colors\n");
1061 exit(1);
1063 else
1064 return pcolors; /* no colors used */
1067 if(ntfg >= nc || ntbg >= nc || tbfg >= nc || tbbg >= nc
1068 || klfg >= nc || klbg >= nc || knfg >= nc || knbg >= nc
1069 || stfg >= nc || stbg >= nc || prfg >= nc || prbg >= nc
1070 || q1fg >= nc || q1bg >= nc || q2fg >= nc || q2bg >= nc
1071 || q3fg >= nc || q3bg >= nc || sbfg >= nc || sbbg >= nc
1072 || rtfg >= nc || rtbg >= nc){
1073 fprintf(stderr, "Error: specified a color bigger than number of colors\n");
1074 exit(1);
1077 /* Finally, we set up colors */
1078 pico_toggle_color(0);
1079 switch(nc){
1080 case 8: pico_set_color_options(COLOR_ANSI8_OPT|COLOR_TRANS_OPT); break;
1081 case 16: pico_set_color_options(COLOR_ANSI16_OPT|COLOR_TRANS_OPT); break;
1082 case 256: pico_set_color_options(COLOR_ANSI256_OPT|COLOR_TRANS_OPT); break;
1083 default : break; /* impossible case */
1085 pico_toggle_color(1);
1087 pcolors = (PCOLORS *) malloc(sizeof(PCOLORS));
1088 memset((void *)pcolors, 0, sizeof(PCOLORS));
1089 /* ignore bad pair settings, also we set tbcp backwards because it will
1090 * be reversed later in the modeline function, so tbcp->fg is actually
1091 * tbcp->bg and vice versa.
1093 if(ntfg >= 0 && ntbg >= 0){ /* set normal text color */
1094 fg = colorx(ntfg); bg = colorx(ntbg);
1095 pcolors->ntcp = new_color_pair(fg, bg);
1096 pico_nfcolor(fg);
1097 pico_nbcolor(bg);
1099 /* reverse means reverse of normal text */
1100 if((rtfg < 0 || rtbg < 0) && (ntfg >= 0 && ntbg >= 0)){
1101 rtfg = ntbg;
1102 rtbg = ntfg;
1104 if(rtfg >= 0 && rtbg >= 0){ /* set reverse text color */
1105 fg = colorx(rtfg); bg = colorx(rtbg);
1106 pcolors->rtcp = new_color_pair(fg, bg);
1107 pico_rfcolor(fg);
1108 pico_rbcolor(bg);
1110 /* If the user does not specify this, we will set up all
1111 * backgrounds for text to the normal text background
1113 if(ntbg >= 0){
1114 if(knbg < 0) knbg = ntbg;
1115 if(q1bg < 0) q1bg = ntbg;
1116 if(q2bg < 0) q2bg = ntbg;
1117 if(q3bg < 0) q3bg = ntbg;
1118 if(sbbg < 0) sbbg = ntbg;
1120 if(rtfg >= 0 && rtbg >= 0){ /* set default reverse */
1121 if(tbfg < 0 || tbbg < 0){ /* set titlebar colors to reverse color if any missing*/
1122 tbfg = rtfg; tbbg = rtbg;
1124 if(klfg < 0 || klbg < 0){ /* set key label colors */
1125 klfg = rtfg; klbg = rtbg;
1127 if(stfg < 0 || stbg < 0){ /* set status colors */
1128 stfg = rtfg; stbg = rtbg;
1130 if(prfg >= 0 && prbg >= 0){ /* set prompt colors */
1131 prfg = rtfg; prbg = rtbg;
1134 if(tbfg >= 0 && tbbg >= 0) /* set titlebar colors */
1135 pcolors->tbcp = new_color_pair(colorx(tbbg), colorx(tbfg));
1136 if(klfg >= 0 && klbg >= 0) /* set key label colors */
1137 pcolors->klcp = new_color_pair(colorx(klfg), colorx(klbg));
1138 if(knfg >= 0 && knbg >= 0) /* set key name colors */
1139 pcolors->kncp = new_color_pair(colorx(knfg), colorx(knbg));
1140 if(stfg >= 0 && stbg >= 0) /* set status colors */
1141 pcolors->stcp = new_color_pair(colorx(stfg), colorx(stbg));
1142 if(prfg >= 0 && prbg >= 0) /* set prompt colors */
1143 pcolors->prcp = new_color_pair(colorx(prfg), colorx(prbg));
1144 if(q1fg >= 0 && q1bg >= 0) /* set quote level 1 colors */
1145 pcolors->qlcp = new_color_pair(colorx(q1fg), colorx(q1bg));
1146 if(q2fg >= 0 && q2bg >= 0) /* set quote level 2 colors */
1147 pcolors->qllcp = new_color_pair(colorx(q2fg), colorx(q2bg));
1148 if(q3fg >= 0 && q3bg >= 0) /* set quote level 3 colors */
1149 pcolors->qlllcp = new_color_pair(colorx(q3fg), colorx(q3bg));
1150 if(sbfg >= 0 && sbbg >= 0) /* set signature block colors */
1151 pcolors->sbcp = new_color_pair(colorx(sbfg), colorx(sbbg));
1153 if(pico_usingcolor())
1154 pico_set_normal_color();
1156 return pcolors;
1158 #endif /* ! _WINDOWS */
1160 #ifdef _WINDOWS
1165 pico_file_drop(int x, int y, char *filename)
1168 * if current buffer is unchanged
1169 * *or* "new buffer" and no current text
1171 if(((curwp->w_bufp->b_flag & BFCHG) == 0)
1172 || (curwp->w_bufp->b_fname[0] == '\0'
1173 && curwp->w_bufp->b_linep == lforw(curwp->w_bufp->b_linep)
1174 && curwp->w_doto == 0)){
1175 register BUFFER *bp = curwp->w_bufp;
1176 char bname[NBUFN];
1178 makename(bname, filename);
1179 strncpy(bp->b_bname, bname, sizeof(bp->b_bname));
1180 bp->b_bname[sizeof(bp->b_bname)-1] = '\0';
1181 strncpy(bp->b_fname, filename, sizeof(bp->b_fname));
1182 bp->b_fname[sizeof(bp->b_fname)-1] = '\0';
1183 bp->b_flag &= ~BFCHG; /* turn off change bit */
1184 if (readin(filename, 1, 1) == ABORT) {
1185 strncpy(bp->b_bname, "", sizeof(bp->b_bname));
1186 bp->b_bname[sizeof(bp->b_bname)-1] = '\0';
1187 strncpy(bp->b_fname, "", sizeof(bp->b_fname));
1188 bp->b_fname[sizeof(bp->b_fname)-1] = '\0';
1191 bp->b_dotp = bp->b_linep;
1192 bp->b_doto = 0;
1194 else{
1195 EML eml;
1197 ifile(filename);
1198 curwp->w_flag |= WFHARD;
1199 update();
1200 eml.s = filename;
1201 emlwrite("Inserted dropped file \"%s\"", &eml);
1204 curwp->w_flag |= WFHARD;
1205 update(); /* restore cursor */
1206 return(1);
1208 #endif
1211 /*----------------------------------------------------------------------
1212 print a few lines of help for command line arguments
1214 Args: none
1216 Result: prints help messages
1217 ----------------------------------------------------------------------*/
1218 void
1219 pico_args_help(void)
1221 char **a;
1222 char *pp[2];
1224 pp[1] = NULL;
1226 /** print out possible starting arguments... **/
1228 for(a=args_pico_args; a && *a; a++){
1229 pp[0] = _(*a);
1230 pico_display_args_err(NULL, pp, 0);
1233 exit(1);
1237 void
1238 pico_vers_help(void)
1240 char v0[100];
1241 char *v[2];
1243 snprintf(v0, sizeof(v0), "Pico %.50s", version);
1244 v[0] = v0;
1245 v[1] = NULL;
1247 pico_display_args_err(NULL, v, 0);
1248 exit(1);
1252 /*----------------------------------------------------------------------
1253 write argument error to the display...
1255 Args: none
1257 Result: prints help messages
1258 ----------------------------------------------------------------------*/
1259 void
1260 pico_display_args_err(char *s, char **a, int err)
1262 char errstr[256], *errp;
1263 FILE *fp = err ? stderr : stdout;
1264 #ifdef _WINDOWS
1265 char tmp_20k_buf[SIZEOF_20KBUF];
1266 #endif
1269 if(err && s)
1270 snprintf(errp = errstr, sizeof(errstr), _("Argument Error: %.200s"), s);
1271 else
1272 errp = s;
1274 #ifdef _WINDOWS
1275 if(errp)
1276 mswin_messagebox(errp, err);
1278 if(a && *a){
1279 strncpy(tmp_20k_buf, *a++, SIZEOF_20KBUF);
1280 tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
1281 while(a && *a){
1282 strncat(tmp_20k_buf, "\n", SIZEOF_20KBUF-strlen(tmp_20k_buf)-1);
1283 tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
1284 strncat(tmp_20k_buf, *a++, SIZEOF_20KBUF-strlen(tmp_20k_buf)-1);
1285 tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
1288 mswin_messagebox(tmp_20k_buf, err);
1290 #else
1291 if(errp)
1292 fprintf(fp, "%s\n", errp);
1294 while(a && *a)
1295 fprintf(fp, "%s\n", *a++);
1296 #endif