blob: f18748144506e105bdd702364599573477d889b2 [file] [log] [blame]
Chris Allegretta11b00112000-08-06 21:13:45 +00001/* $Id$ */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002/**************************************************************************
3 * nano.c *
4 * *
5 * Copyright (C) 1999 Chris Allegretta *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 1, or (at your option) *
9 * any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
19 * *
20 **************************************************************************/
21
Chris Allegretta6efda542001-04-28 18:03:52 +000022#include "config.h"
23
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000024#include <stdio.h>
25#include <stdlib.h>
26#include <stdarg.h>
27#include <signal.h>
Chris Allegretta08020882001-01-29 23:37:54 +000028#include <setjmp.h>
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000029#include <unistd.h>
30#include <string.h>
31#include <fcntl.h>
32#include <sys/stat.h>
33#include <sys/ioctl.h>
34#include <sys/param.h>
Chris Allegretta27eb13f2000-11-05 16:52:21 +000035#include <sys/types.h>
36#include <sys/wait.h>
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000037#include <errno.h>
38#include <ctype.h>
39#include <locale.h>
40#include <limits.h>
Adam Rogoyski77f36de2000-06-07 03:56:54 +000041#include <assert.h>
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000042
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000043#include "proto.h"
44#include "nano.h"
45
46#ifndef NANO_SMALL
47#include <libintl.h>
48#define _(string) gettext(string)
49#else
50#define _(string) (string)
51#endif
52
53#ifdef HAVE_TERMIOS_H
54#include <termios.h>
55#endif
56
57#ifdef HAVE_TERMIO_H
58#include <termio.h>
59#endif
60
61#ifdef HAVE_GETOPT_H
62#include <getopt.h>
63#endif
64
65/* Former globals, now static */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000066int fill = 0; /* Fill - where to wrap lines, basically */
Rocco Corsiaf5c3022001-01-12 07:51:05 +000067
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000068struct termios oldterm; /* The user's original term settings */
Chris Allegretta18f8be02000-09-04 03:20:38 +000069static struct sigaction act; /* For all out fun signal handlers */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000070
Rocco Corsiaf5c3022001-01-12 07:51:05 +000071#ifndef DISABLE_HELP
Chris Allegretta6b58acd2001-04-12 03:01:53 +000072static char *help_text_init = ""; /* Initial message, not including shortcuts */
Chris Allegretta65121632000-12-18 07:05:27 +000073#endif
74
Chris Allegretta27eb13f2000-11-05 16:52:21 +000075char *last_search = NULL; /* Last string we searched for */
76char *last_replace = NULL; /* Last replacement string */
77int search_last_line; /* Is this the last search line? */
78
Chris Allegretta08020882001-01-29 23:37:54 +000079static sigjmp_buf jmpbuf; /* Used to return to mainloop after SIGWINCH */
80
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000081/* What we do when we're all set to exit */
82RETSIGTYPE finish(int sigage)
83{
Chris Allegrettac08f50d2001-01-06 18:12:43 +000084
85 keypad(edit, TRUE);
86 keypad(bottomwin, TRUE);
87
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000088 if (!ISSET(NO_HELP)) {
89 mvwaddstr(bottomwin, 1, 0, hblank);
90 mvwaddstr(bottomwin, 2, 0, hblank);
Chris Allegretta4da1fc62000-06-21 03:00:43 +000091 } else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000092 mvwaddstr(bottomwin, 0, 0, hblank);
Chris Allegretta6b58acd2001-04-12 03:01:53 +000093
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000094 wrefresh(bottomwin);
95 endwin();
96
97 /* Restore the old term settings */
Chris Allegretta4da1fc62000-06-21 03:00:43 +000098 tcsetattr(0, TCSANOW, &oldterm);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000099
100 exit(sigage);
101}
102
103/* Die (gracefully?) */
104void die(char *msg, ...)
105{
106 va_list ap;
Chris Allegretta3dbb2782000-12-02 04:36:50 +0000107 char *name;
108 int i;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000109
110 va_start(ap, msg);
111 vfprintf(stderr, msg, ap);
112 va_end(ap);
113
114 /* if we can't save we have REAL bad problems,
Robert Siemborskifcf32bf2000-07-17 03:04:54 +0000115 * but we might as well TRY. */
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000116 if (filename[0] == '\0') {
Chris Allegretta3dbb2782000-12-02 04:36:50 +0000117 name = "nano.save";
118 i = write_file(name, 1);
Robert Siemborskifcf32bf2000-07-17 03:04:54 +0000119 } else {
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000120
Chris Allegrettae7a58932000-12-02 02:36:22 +0000121 char *buf = nmalloc(strlen(filename) + 6);
122 strcpy(buf, filename);
123 strcat(buf, ".save");
Chris Allegretta3dbb2782000-12-02 04:36:50 +0000124 i = write_file(buf, 1);
125 name = buf;
Robert Siemborskifcf32bf2000-07-17 03:04:54 +0000126 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000127 /* Restore the old term settings */
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000128 tcsetattr(0, TCSANOW, &oldterm);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000129
130 clear();
131 refresh();
132 resetty();
133 endwin();
134
135 fprintf(stderr, msg);
Chris Allegretta3dbb2782000-12-02 04:36:50 +0000136 if (i != -1)
137 fprintf(stderr, _("\nBuffer written to %s\n"), name);
138 else
Chris Allegretta9756d622000-12-03 03:06:45 +0000139 fprintf(stderr, _("\nNo %s written (file exists?)\n"), name);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000140
141 exit(1); /* We have a problem: exit w/ errorlevel(1) */
142}
143
Chris Allegrettae61e8302001-01-14 05:18:27 +0000144/* Die with an error message that the screen was too small if, well, the
145 screen is too small */
146void die_too_small(void)
147{
148 char *too_small_msg = _("Window size is too small for Nano...");
149
150 die(too_small_msg);
151
152}
153
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000154void print_view_warning(void)
155{
156 statusbar(_("Key illegal in VIEW mode"));
157}
158
Chris Allegretta1a6e9042000-12-14 13:56:28 +0000159void clear_filename(void)
160{
161 if (filename != NULL)
162 free(filename);
163 filename = nmalloc(1);
164 filename[0] = 0;
165}
Chris Allegretta1cc0b7f2000-11-03 01:29:04 +0000166
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000167/* Initialize global variables - no better way for now */
168void global_init(void)
169{
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000170 current_x = 0;
171 current_y = 0;
Chris Allegrettae61e8302001-01-14 05:18:27 +0000172
173 if ((editwinrows = LINES - 5 + no_help()) < MIN_EDITOR_ROWS)
174 die_too_small();
175
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000176 fileage = NULL;
177 cutbuffer = NULL;
178 current = NULL;
179 edittop = NULL;
180 editbot = NULL;
181 totlines = 0;
182 placewewant = 0;
Chris Allegrettae61e8302001-01-14 05:18:27 +0000183
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000184 if (!fill)
Chris Allegrettae61e8302001-01-14 05:18:27 +0000185 fill = COLS - CHARS_FROM_EOL;
186
187 if (fill < MIN_FILL_LENGTH)
188 die_too_small();
189
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000190 hblank = nmalloc(COLS + 1);
Chris Allegretta0a06e072001-01-23 02:35:04 +0000191 memset(hblank, ' ', COLS);
192 hblank[COLS] = 0;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000193}
194
Rocco Corsiaf5c3022001-01-12 07:51:05 +0000195#ifndef DISABLE_HELP
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000196void init_help_msg(void)
197{
198
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000199 help_text_init =
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000200 _(" nano help text\n\n "
201 "The nano editor is designed to emulate the functionality and "
202 "ease-of-use of the UW Pico text editor. There are four main "
203 "sections of the editor: The top line shows the program "
204 "version, the current filename being edited, and whether "
205 "or not the file has been modified. Next is the main editor "
206 "window showing the file being edited. The status line is "
207 "the third line from the bottom and shows important messages. "
208 "The bottom two lines show the most commonly used shortcuts "
209 "in the editor.\n\n "
210 "The notation for shortcuts is as follows: Control-key "
Chris Allegrettae49f1232000-09-02 07:20:39 +0000211 "sequences are notated with a caret (^) symbol and are entered "
Chris Allegrettad56bd792000-09-02 07:27:10 +0000212 "with the Control (Ctrl) key. Escape-key sequences are notated "
213 "with the Meta (M) symbol and can be entered using either the "
214 "Esc, Alt or Meta key depending on your keyboard setup. The "
215 "following keystrokes are available in the main editor window. "
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000216 "Optional keys are shown in parentheses:\n\n");
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000217
218}
Rocco Corsiaf5c3022001-01-12 07:51:05 +0000219#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000220
221/* Make a copy of a node to a pointer (space will be malloc()ed) */
222filestruct *copy_node(filestruct * src)
223{
224 filestruct *dst;
225
226 dst = nmalloc(sizeof(filestruct));
227 dst->data = nmalloc(strlen(src->data) + 1);
228
229 dst->next = src->next;
230 dst->prev = src->prev;
231
232 strcpy(dst->data, src->data);
233 dst->lineno = src->lineno;
234
235 return dst;
236}
237
238/* Unlink a node from the rest of the struct */
239void unlink_node(filestruct * fileptr)
240{
241 if (fileptr->prev != NULL)
242 fileptr->prev->next = fileptr->next;
243
244 if (fileptr->next != NULL)
245 fileptr->next->prev = fileptr->prev;
246}
247
248void delete_node(filestruct * fileptr)
249{
Chris Allegretta17dcb722001-01-20 21:40:07 +0000250 if (fileptr == NULL)
251 return;
252
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000253 if (fileptr->data != NULL)
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000254 free(fileptr->data);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000255 free(fileptr);
256}
257
258/* Okay, now let's duplicate a whole struct! */
259filestruct *copy_filestruct(filestruct * src)
260{
261 filestruct *dst, *tmp, *head, *prev;
262
263 head = copy_node(src);
264 dst = head; /* Else we barf on copying just one line */
265 head->prev = NULL;
266 tmp = src->next;
267 prev = head;
268
269 while (tmp != NULL) {
270 dst = copy_node(tmp);
271 dst->prev = prev;
272 prev->next = dst;
273
274 prev = dst;
275 tmp = tmp->next;
276 }
277
278 dst->next = NULL;
279 return head;
280}
281
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000282int free_filestruct(filestruct * src)
283{
284 filestruct *fileptr = src;
285
286 if (src == NULL)
287 return 0;
288
289 while (fileptr->next != NULL) {
290 fileptr = fileptr->next;
Chris Allegretta17dcb722001-01-20 21:40:07 +0000291 delete_node(fileptr->prev);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000292
293#ifdef DEBUG
Chris Allegretta17dcb722001-01-20 21:40:07 +0000294 fprintf(stderr, _("delete_node(): free'd a node, YAY!\n"));
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000295#endif
296 }
Chris Allegretta17dcb722001-01-20 21:40:07 +0000297 delete_node(fileptr);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000298#ifdef DEBUG
Chris Allegretta17dcb722001-01-20 21:40:07 +0000299 fprintf(stderr, _("delete_node(): free'd last node.\n"));
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000300#endif
301
302 return 1;
303}
304
305int renumber_all(void)
306{
307 filestruct *temp;
308 long i = 1;
309
310 for (temp = fileage; temp != NULL; temp = temp->next) {
311 temp->lineno = i++;
312 }
313
314 return 0;
315}
316
317int renumber(filestruct * fileptr)
318{
319 filestruct *temp;
320
321 if (fileptr == NULL || fileptr->prev == NULL || fileptr == fileage) {
322 renumber_all();
323 return 0;
324 }
325 for (temp = fileptr; temp != NULL; temp = temp->next) {
Chris Allegretta5146fec2000-12-10 05:44:02 +0000326 if (temp->prev != NULL)
327 temp->lineno = temp->prev->lineno + 1;
328 else
329 temp->lineno = 1;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000330 }
331
332 return 0;
333}
334
335/* Fix the memory allocation for a string */
336void align(char **strp)
337{
338 /* There was a serious bug here: the new address was never
339 stored anywhere... */
340
341 *strp = nrealloc(*strp, strlen(*strp) + 1);
342}
343
Chris Allegretta6925bbd2000-07-28 01:41:29 +0000344/* Null a string at a certain index and align it */
345void null_at(char *data, int index)
346{
347 data[index] = 0;
348 align(&data);
349}
350
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000351void usage(void)
352{
353#ifdef HAVE_GETOPT_LONG
354 printf(_("Usage: nano [GNU long option] [option] +LINE <file>\n\n"));
355 printf(_("Option Long option Meaning\n"));
Chris Allegretta6724a7e2000-06-19 23:19:07 +0000356 printf(_
Chris Allegrettae9a2d032001-01-21 16:08:21 +0000357 (" -T [num] --tabsize=[num] Set width of a tab to num\n"));
Chris Allegretta805c26d2000-09-06 13:39:17 +0000358#ifdef HAVE_REGEX_H
Chris Allegretta9fc8d432000-07-07 01:49:52 +0000359 printf(_
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000360 (" -R --regexp Use regular expressions for search\n"));
Chris Allegretta47805612000-07-07 02:35:34 +0000361#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000362 printf
363 (_
364 (" -V --version Print version information and exit\n"));
365 printf(_
366 (" -c --const Constantly show cursor position\n"));
367 printf(_
368 (" -h --help Show this message\n"));
Chris Allegrettad55655f2000-12-27 03:36:47 +0000369 printf(_
370 (" -i --autoindent Automatically indent new lines\n"));
Chris Allegrettad19e9912000-07-12 18:14:51 +0000371#ifndef NANO_SMALL
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000372 printf(_
Chris Allegretta627de192000-07-12 02:09:17 +0000373 (" -k --cut Let ^K cut from cursor to end of line\n"));
Chris Allegrettad19e9912000-07-12 18:14:51 +0000374#endif
Chris Allegretta627de192000-07-12 02:09:17 +0000375 printf(_
Chris Allegretta71348ee2000-10-02 04:21:23 +0000376 (" -l --nofollow Don't follow symbolic links, overwrite\n"));
Chris Allegretta84de5522001-04-12 14:51:48 +0000377#ifndef DISABLE_MOUSE
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000378#ifdef NCURSES_MOUSE_VERSION
379 printf(_(" -m --mouse Enable mouse\n"));
380#endif
381#endif
Chris Allegrettad55655f2000-12-27 03:36:47 +0000382 printf(_
383 (" -p --pico Emulate Pico as closely as possible\n"));
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000384 printf
385 (_
386 (" -r [#cols] --fill=[#cols] Set fill cols to (wrap lines at) #cols\n"));
Rocco Corsiaf5c3022001-01-12 07:51:05 +0000387#ifndef DISABLE_SPELLER
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000388 printf(_
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000389 (" -s [prog] --speller=[prog] Enable alternate speller\n"));
Rocco Corsiaf5c3022001-01-12 07:51:05 +0000390#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000391 printf(_
392 (" -t --tempfile Auto save on exit, don't prompt\n"));
393 printf(_
394 (" -v --view View (read only) mode\n"));
Chris Allegrettacef7fbb2001-04-02 05:36:08 +0000395#ifndef DISABLE_WRAPPING
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000396 printf(_
397 (" -w --nowrap Don't wrap long lines\n"));
Chris Allegrettacef7fbb2001-04-02 05:36:08 +0000398#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000399 printf(_
400 (" -x --nohelp Don't show help window\n"));
401 printf(_
402 (" -z --suspend Enable suspend\n"));
403 printf(_
404 (" +LINE Start at line number LINE\n"));
405#else
406 printf(_("Usage: nano [option] +LINE <file>\n\n"));
407 printf(_("Option Meaning\n"));
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000408 printf(_(" -T [num] Set width of a tab to num\n"));
Chris Allegretta9fc8d432000-07-07 01:49:52 +0000409 printf(_(" -R Use regular expressions for search\n"));
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000410 printf(_(" -V Print version information and exit\n"));
411 printf(_(" -c Constantly show cursor position\n"));
412 printf(_(" -h Show this message\n"));
Chris Allegrettad55655f2000-12-27 03:36:47 +0000413 printf(_(" -i Automatically indent new lines\n"));
Chris Allegrettad19e9912000-07-12 18:14:51 +0000414#ifndef NANO_SMALL
Chris Allegretta627de192000-07-12 02:09:17 +0000415 printf(_(" -k Let ^K cut from cursor to end of line\n"));
Chris Allegrettad19e9912000-07-12 18:14:51 +0000416#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000417 printf(_
Chris Allegretta71348ee2000-10-02 04:21:23 +0000418 (" -l Don't follow symbolic links, overwrite\n"));
Chris Allegretta84de5522001-04-12 14:51:48 +0000419#ifndef DISABLE_MOUSE
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000420#ifdef NCURSES_MOUSE_VERSION
421 printf(_(" -m Enable mouse\n"));
422#endif
423#endif
Chris Allegrettabf9a8cc2000-11-17 01:37:39 +0000424 printf(_(" -p Emulate Pico as closely as possible\n"));
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000425 printf(_
426 (" -r [#cols] Set fill cols to (wrap lines at) #cols\n"));
Rocco Corsiaf5c3022001-01-12 07:51:05 +0000427#ifndef DISABLE_SPELLER
Chris Allegrettad55655f2000-12-27 03:36:47 +0000428 printf(_(" -s [prog] Enable alternate speller\n"));
Rocco Corsiaf5c3022001-01-12 07:51:05 +0000429#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000430 printf(_(" -t Auto save on exit, don't prompt\n"));
431 printf(_(" -v View (read only) mode\n"));
Chris Allegrettacef7fbb2001-04-02 05:36:08 +0000432#ifndef DISABLE_WRAPPING
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000433 printf(_(" -w Don't wrap long lines\n"));
Chris Allegrettacef7fbb2001-04-02 05:36:08 +0000434#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000435 printf(_(" -x Don't show help window\n"));
436 printf(_(" -z Enable suspend\n"));
437 printf(_(" +LINE Start at line number LINE\n"));
438#endif
439 exit(0);
440}
441
442void version(void)
443{
Chris Allegrettac46dd812001-02-14 14:28:27 +0000444 printf(_(" GNU nano version %s (compiled %s, %s)\n"),
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000445 VERSION, __TIME__, __DATE__);
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000446 printf(_
Chris Allegretta8a0de3b2000-11-24 20:45:14 +0000447 (" Email: nano@nano-editor.org Web: http://www.nano-editor.org"));
Chris Allegretta8a0de3b2000-11-24 20:45:14 +0000448 printf(_("\n Compiled options:"));
Chris Allegrettaff269f82000-12-01 18:46:01 +0000449
Chris Allegretta8a0de3b2000-11-24 20:45:14 +0000450#ifdef NANO_EXTRA
451 printf(" --enable-extra");
452#endif
Chris Allegrettab881d3e2001-04-18 04:34:43 +0000453#ifdef ENABLE_NANORC
454 printf(" --enable-nanorc");
455#endif
Chris Allegretta8ce24132001-04-30 11:28:46 +0000456#ifdef ENABLE_COLOR
457 printf(" --enable-color");
458#endif
Rocco Corsiaf5c3022001-01-12 07:51:05 +0000459
460#ifdef NANO_SMALL
461 printf(" --enable-tiny");
462#else
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000463#ifdef DISABLE_BROWSER
Chris Allegretta6636dc32001-01-05 05:41:07 +0000464 printf(" --disable-browser");
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000465#endif
466#ifdef DISABLE_TABCOMP
Chris Allegretta8a0de3b2000-11-24 20:45:14 +0000467 printf(" --disable-tabcomp");
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000468#endif
469#ifdef DISABLE_JUSTIFY
Chris Allegrettaff269f82000-12-01 18:46:01 +0000470 printf(" --disable-justify");
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000471#endif
472#ifdef DISABLE_SPELLER
Chris Allegretta7b36c522000-12-06 01:08:10 +0000473 printf(" --disable-speller");
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000474#endif
475#ifdef DISABLE_HELP
Chris Allegrettab7d00ef2000-12-18 05:36:51 +0000476 printf(" --disable-help");
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000477#endif
Chris Allegretta84de5522001-04-12 14:51:48 +0000478#ifdef DISABLE_MOUSE
479 printf(" --disable-mouse");
Chris Allegrettab7d00ef2000-12-18 05:36:51 +0000480#endif
Chris Allegretta84de5522001-04-12 14:51:48 +0000481#endif /* NANO_SMALL */
Rocco Corsiaf5c3022001-01-12 07:51:05 +0000482
Chris Allegrettacef7fbb2001-04-02 05:36:08 +0000483#ifdef DISABLE_WRAPPING
484 printf(" --disable-wrapping");
485#endif
Chris Allegretta8a0de3b2000-11-24 20:45:14 +0000486#ifdef USE_SLANG
487 printf(" --with-slang");
488#endif
489 printf("\n");
490
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000491}
492
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000493filestruct *make_new_node(filestruct * prevnode)
494{
495 filestruct *newnode;
496
497 newnode = nmalloc(sizeof(filestruct));
498 newnode->data = NULL;
499
500 newnode->prev = prevnode;
501 newnode->next = NULL;
502
503 if (prevnode != NULL)
504 newnode->lineno = prevnode->lineno + 1;
505
506 return newnode;
507}
508
Chris Allegretta7975ed82000-07-28 00:58:35 +0000509/* Splice a node into an existing filestruct */
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000510void splice_node(filestruct * begin, filestruct * newnode,
511 filestruct * end)
Chris Allegretta7975ed82000-07-28 00:58:35 +0000512{
Chris Allegrettae3167732001-03-18 16:59:34 +0000513 newnode->next = end;
514 newnode->prev = begin;
515 begin->next = newnode;
Chris Allegretta7975ed82000-07-28 00:58:35 +0000516 if (end != NULL)
Chris Allegrettae3167732001-03-18 16:59:34 +0000517 end->prev = newnode;
Chris Allegretta7975ed82000-07-28 00:58:35 +0000518}
519
Chris Allegrettae3167732001-03-18 16:59:34 +0000520int do_mark(void)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000521{
522#ifdef NANO_SMALL
Rocco Corsiaf5c3022001-01-12 07:51:05 +0000523 nano_disabled_msg();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000524#else
525 if (!ISSET(MARK_ISSET)) {
526 statusbar(_("Mark Set"));
527 SET(MARK_ISSET);
528 mark_beginbuf = current;
529 mark_beginx = current_x;
530 } else {
531 statusbar(_("Mark UNset"));
532 UNSET(MARK_ISSET);
533 mark_beginbuf = NULL;
534 mark_beginx = 0;
535
536 edit_refresh();
537 }
538#endif
539 return 1;
540}
541
542int no_help(void)
543{
544 if ISSET
545 (NO_HELP)
546 return 2;
547 else
548 return 0;
549}
550
Chris Allegretta3bc8c722000-12-10 17:03:25 +0000551#if defined(DISABLE_JUSTIFY) || defined(DISABLE_SPELLER) || defined(DISABLE_HELP)
Chris Allegrettaff269f82000-12-01 18:46:01 +0000552void nano_disabled_msg(void)
553{
554 statusbar("Sorry, support for this function has been disabled");
555}
Chris Allegretta4eb7aa02000-12-01 18:57:11 +0000556#endif
Chris Allegrettaff269f82000-12-01 18:46:01 +0000557
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000558/* The user typed a printable character; add it to the edit buffer */
559void do_char(char ch)
560{
Robert Siemborski63b3d7e2000-07-04 22:15:39 +0000561 /* magic-line: when a character is inserted on the current magic line,
562 * it means we need a new one! */
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000563 if (filebot == current && current->data[0] == '\0') {
Robert Siemborski63b3d7e2000-07-04 22:15:39 +0000564 new_magicline();
Chris Allegretta28a0f892000-07-05 22:47:54 +0000565 fix_editbot();
Robert Siemborski63b3d7e2000-07-04 22:15:39 +0000566 }
567
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000568 /* More dangerousness fun =) */
569 current->data = nrealloc(current->data, strlen(current->data) + 2);
570 memmove(&current->data[current_x + 1],
571 &current->data[current_x],
572 strlen(current->data) - current_x + 1);
573 current->data[current_x] = ch;
574 do_right();
575
Chris Allegrettacef7fbb2001-04-02 05:36:08 +0000576#ifndef DISABLE_WRAPPING
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000577 if (!ISSET(NO_WRAP) && (ch != '\t'))
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000578 check_wrap(current, ch);
Chris Allegrettacef7fbb2001-04-02 05:36:08 +0000579#endif
580
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000581 set_modified();
582 check_statblank();
583 UNSET(KEEP_CUTBUFFER);
584 totsize++;
585
586}
587
588/* Someone hits return *gasp!* */
589int do_enter(filestruct * inptr)
590{
Chris Allegrettae3167732001-03-18 16:59:34 +0000591 filestruct *newnode;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000592 char *tmp, *spc;
593 int extra = 0;
594
Chris Allegrettae3167732001-03-18 16:59:34 +0000595 newnode = make_new_node(inptr);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000596 tmp = &current->data[current_x];
597 current_x = 0;
598
599 /* Do auto-indenting, like the neolithic Turbo Pascal editor */
600 if (ISSET(AUTOINDENT)) {
601 spc = current->data;
602 if (spc) {
603 while ((*spc == ' ') || (*spc == '\t')) {
604 extra++;
605 spc++;
606 current_x++;
Adam Rogoyski1e9183f2001-03-13 18:36:03 +0000607 totsize++;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000608 }
Chris Allegrettae3167732001-03-18 16:59:34 +0000609 newnode->data = nmalloc(strlen(tmp) + extra + 1);
610 strncpy(newnode->data, current->data, extra);
611 strcpy(&newnode->data[extra], tmp);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000612 }
613 } else {
Chris Allegrettae3167732001-03-18 16:59:34 +0000614 newnode->data = nmalloc(strlen(tmp) + 1);
615 strcpy(newnode->data, tmp);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000616 }
617 *tmp = 0;
618
Chris Allegrettada721be2000-07-31 01:26:42 +0000619 if (inptr->next == NULL) {
Chris Allegrettae3167732001-03-18 16:59:34 +0000620 filebot = newnode;
621 editbot = newnode;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000622 }
Chris Allegrettae3167732001-03-18 16:59:34 +0000623 splice_node(inptr, newnode, inptr->next);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000624
625 totsize++;
626 renumber(current);
Chris Allegrettae3167732001-03-18 16:59:34 +0000627 current = newnode;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000628 align(&current->data);
629
Robert Siemborskidd53ec22000-07-04 02:35:19 +0000630 /* The logic here is as follows:
631 * -> If we are at the bottom of the buffer, we want to recenter
632 * (read: rebuild) the screen and forcably move the cursor.
633 * -> otherwise, we want simply to redraw the screen and update
634 * where we think the cursor is.
635 */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000636 if (current_y == editwinrows - 1) {
Chris Allegretta234a34d2000-07-29 04:33:38 +0000637 edit_update(current, CENTER);
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000638 reset_cursor();
Robert Siemborskidd53ec22000-07-04 02:35:19 +0000639 } else {
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000640 current_y++;
Robert Siemborskidd53ec22000-07-04 02:35:19 +0000641 edit_refresh();
642 update_cursor();
643 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000644
645 totlines++;
646 set_modified();
647
Chris Allegrettab0ae3932000-06-15 23:39:14 +0000648 placewewant = xplustabs();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000649 return 1;
650}
651
652int do_enter_void(void)
653{
654 return do_enter(current);
655}
656
657void do_next_word(void)
658{
Chris Allegretta9e2934f2000-12-01 23:49:48 +0000659 filestruct *fileptr, *old;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000660 int i;
661
662 if (current == NULL)
663 return;
664
Chris Allegretta9e2934f2000-12-01 23:49:48 +0000665 old = current;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000666 i = current_x;
667 for (fileptr = current; fileptr != NULL; fileptr = fileptr->next) {
668 if (fileptr == current) {
669 while (isalnum((int) fileptr->data[i])
670 && fileptr->data[i] != 0)
671 i++;
672
673 if (fileptr->data[i] == 0) {
674 i = 0;
675 continue;
676 }
677 }
678 while (!isalnum((int) fileptr->data[i]) && fileptr->data[i] != 0)
679 i++;
680
681 if (fileptr->data[i] != 0)
682 break;
683
684 i = 0;
685 }
686 if (fileptr == NULL)
687 current = filebot;
688 else
689 current = fileptr;
690
691 current_x = i;
692 placewewant = xplustabs();
Chris Allegretta9e2934f2000-12-01 23:49:48 +0000693
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000694 if (current->lineno >= editbot->lineno)
Chris Allegretta234a34d2000-07-29 04:33:38 +0000695 edit_update(current, CENTER);
Chris Allegretta9e2934f2000-12-01 23:49:48 +0000696 else {
697 /* If we've jumped lines, refresh the old line. We can't just use
698 * current->prev here, because we may have skipped over some blank
699 * lines, in which case the previous line is the wrong one.
700 */
701 if (current != old)
702 update_line(old, 0);
703
704 update_line(current, current_x);
705 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000706
707}
708
Chris Allegrettacef7fbb2001-04-02 05:36:08 +0000709#ifndef DISABLE_WRAPPING
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000710void do_wrap(filestruct * inptr, char input_char)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000711{
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000712 int i = 0; /* Index into ->data for line. */
713 int i_tabs = 0; /* Screen position of ->data[i]. */
714 int last_word_end = -1; /* Location of end of last word found. */
715 int current_word_start = -1; /* Location of start of current word. */
716 int current_word_start_t = -1; /* Location of start of current word screen position. */
717 int current_word_end = -1; /* Location of end of current word */
718 int current_word_end_t = -1; /* Location of end of current word screen position. */
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000719 int len = strlen(inptr->data);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000720
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000721 int down = 0;
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000722 int right = 0;
723 struct filestruct *temp = NULL;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000724
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000725 assert(strlenpt(inptr->data) > fill);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000726
Adam Rogoyski0223d6f2000-06-17 20:36:35 +0000727 for (i = 0, i_tabs = 0; i < len; i++, i_tabs++) {
Chris Allegretta9e7efa32000-10-02 03:42:55 +0000728 if (!isspace((int) inptr->data[i])) {
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000729 last_word_end = current_word_end;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000730
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000731 current_word_start = i;
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000732 current_word_start_t = i_tabs;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000733
Chris Allegretta9e7efa32000-10-02 03:42:55 +0000734 while (!isspace((int) inptr->data[i])
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000735 && inptr->data[i]) {
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000736 i++;
737 i_tabs++;
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000738 if (inptr->data[i] < 32)
739 i_tabs++;
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000740 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000741
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000742 if (inptr->data[i]) {
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000743 current_word_end = i;
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000744 current_word_end_t = i_tabs;
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000745 } else {
746 current_word_end = i - 1;
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000747 current_word_end_t = i_tabs - 1;
748 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000749 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000750
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000751 if (inptr->data[i] == NANO_CONTROL_I) {
Chris Allegretta6d690a32000-08-03 22:51:21 +0000752 if (i_tabs % tabsize != 0);
753 i_tabs += tabsize - (i_tabs % tabsize);
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000754 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000755
Adam Rogoyski09f97962000-06-20 02:50:33 +0000756 if (current_word_end_t > fill)
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000757 break;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000758 }
759
Adam Rogoyski3d449b42000-06-19 17:30:14 +0000760 /* There are a few (ever changing) cases of what the line could look like.
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000761 * 1) only one word on the line before wrap point.
Adam Rogoyski0223d6f2000-06-17 20:36:35 +0000762 * a) one word takes up the whole line with no starting spaces.
763 * - do nothing and return.
764 * b) cursor is on word or before word at wrap point and there are spaces at beginning.
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000765 * - word starts new line.
766 * - keep white space on original line up to the cursor.
767 * *) cursor is after word at wrap point
768 * - either it's all white space after word, and this routine isn't called.
769 * - or we are actually in case 2 (2 words).
770 * 2) Two or more words on the line before wrap point.
Adam Rogoyski3d449b42000-06-19 17:30:14 +0000771 * a) cursor is at a word or space before wrap point
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000772 * - word at wrap point starts a new line.
Adam Rogoyski3d449b42000-06-19 17:30:14 +0000773 * - white space at end of original line is cleared, unless
774 * it is all spaces between previous word and next word which appears after fill.
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000775 * b) cursor is at the word at the wrap point.
776 * - word at wrap point starts a new line.
Adam Rogoyski3d449b42000-06-19 17:30:14 +0000777 * 1. pressed a space and at first character of wrap point word.
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000778 * - white space on original line is kept to where cursor was.
Adam Rogoyski3d449b42000-06-19 17:30:14 +0000779 * 2. pressed non space (or space elsewhere).
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000780 * - white space at end of original line is cleared.
781 * c) cursor is past the word at the wrap point.
782 * - word at wrap point starts a new line.
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000783 * - white space at end of original line is cleared
784 */
785
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000786 temp = nmalloc(sizeof(filestruct));
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000787
Adam Rogoyski0223d6f2000-06-17 20:36:35 +0000788 /* Category 1a: one word taking up the whole line with no beginning spaces. */
Chris Allegretta9e7efa32000-10-02 03:42:55 +0000789 if ((last_word_end == -1) && (!isspace((int) inptr->data[0]))) {
Adam Rogoyski0223d6f2000-06-17 20:36:35 +0000790 for (i = current_word_end; i < len; i++) {
Chris Allegretta9e7efa32000-10-02 03:42:55 +0000791 if (!isspace((int) inptr->data[i]) && i < len) {
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000792 current_word_start = i;
Chris Allegretta9e7efa32000-10-02 03:42:55 +0000793 while (!isspace((int) inptr->data[i]) && (i < len)) {
Adam Rogoyski0223d6f2000-06-17 20:36:35 +0000794 i++;
795 }
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000796 last_word_end = current_word_end;
Adam Rogoyski0223d6f2000-06-17 20:36:35 +0000797 current_word_end = i;
798 break;
799 }
800 }
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000801
Adam Rogoyski0223d6f2000-06-17 20:36:35 +0000802 if (last_word_end == -1) {
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000803 free(temp);
Adam Rogoyski0223d6f2000-06-17 20:36:35 +0000804 return;
805 }
806 if (current_x >= last_word_end) {
807 right = (current_x - current_word_start) + 1;
808 current_x = last_word_end;
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000809 down = 1;
Adam Rogoyski0223d6f2000-06-17 20:36:35 +0000810 }
811
812 temp->data = nmalloc(strlen(&inptr->data[current_word_start]) + 1);
813 strcpy(temp->data, &inptr->data[current_word_start]);
814 inptr->data = nrealloc(inptr->data, last_word_end + 2);
815 inptr->data[last_word_end + 1] = 0;
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000816 } else
817 /* Category 1b: one word on the line and word not taking up whole line
818 (i.e. there are spaces at the beginning of the line) */
Adam Rogoyski0223d6f2000-06-17 20:36:35 +0000819 if (last_word_end == -1) {
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000820 temp->data = nmalloc(strlen(&inptr->data[current_word_start]) + 1);
821 strcpy(temp->data, &inptr->data[current_word_start]);
822
823 /* Inside word, remove it from original, and move cursor to right spot. */
824 if (current_x >= current_word_start) {
825 right = current_x - current_word_start;
826 current_x = 0;
Chris Allegretta94a78b82001-03-14 08:28:48 +0000827 if (ISSET(AUTOINDENT)) {
828 int i = 0;
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000829 while ((inptr->next->data[i] == ' '
830 || inptr->next->data[i] == '\t')) {
Chris Allegretta94a78b82001-03-14 08:28:48 +0000831 i++;
832 right++;
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000833 }
Chris Allegretta94a78b82001-03-14 08:28:48 +0000834 }
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000835 down = 1;
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000836 }
837
Chris Allegretta6925bbd2000-07-28 01:41:29 +0000838 null_at(inptr->data, current_x);
Adam Rogoyski0223d6f2000-06-17 20:36:35 +0000839
840 if (ISSET(MARK_ISSET) && (mark_beginbuf == inptr)) {
841 mark_beginbuf = temp;
842 mark_beginx = 0;
843 }
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000844 }
845
846 /* Category 2: two or more words on the line. */
847 else {
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000848 /* Case 2a: cursor before word at wrap point. */
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000849 if (current_x < current_word_start) {
850 temp->data =
851 nmalloc(strlen(&inptr->data[current_word_start]) + 1);
852 strcpy(temp->data, &inptr->data[current_word_start]);
853
Chris Allegretta9e7efa32000-10-02 03:42:55 +0000854 if (!isspace((int) input_char)) {
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000855 i = current_word_start - 1;
Chris Allegretta9e7efa32000-10-02 03:42:55 +0000856 while (isspace((int) inptr->data[i])) {
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000857 i--;
858 assert(i >= 0);
859 }
860 } else if (current_x <= last_word_end)
861 i = last_word_end - 1;
862 else
863 i = current_x;
864
865 inptr->data = nrealloc(inptr->data, i + 2);
866 inptr->data[i + 1] = 0;
867 }
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000868
869
870 /* Case 2b: cursor at word at wrap point. */
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000871 else if ((current_x >= current_word_start)
872 && (current_x <= (current_word_end + 1))) {
873 temp->data =
874 nmalloc(strlen(&inptr->data[current_word_start]) + 1);
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000875 strcpy(temp->data, &inptr->data[current_word_start]);
876
877 down = 1;
878
879 right = current_x - current_word_start;
Chris Allegretta94a78b82001-03-14 08:28:48 +0000880 if (ISSET(AUTOINDENT)) {
881 int i = 0;
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000882 while ((inptr->next->data[i] == ' '
883 || inptr->next->data[i] == '\t')) {
Chris Allegretta94a78b82001-03-14 08:28:48 +0000884 i++;
885 right++;
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000886 }
Chris Allegretta94a78b82001-03-14 08:28:48 +0000887 }
888
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000889 i = current_word_start - 1;
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000890 if (isspace((int) input_char)
891 && (current_x == current_word_start)) {
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000892 current_x = current_word_start;
893
Chris Allegretta6925bbd2000-07-28 01:41:29 +0000894 null_at(inptr->data, current_word_start);
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000895 } else {
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000896
Chris Allegretta9e7efa32000-10-02 03:42:55 +0000897 while (isspace((int) inptr->data[i])) {
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000898 i--;
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000899 assert(i >= 0);
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000900 }
901 inptr->data = nrealloc(inptr->data, i + 2);
902 inptr->data[i + 1] = 0;
903 }
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000904 }
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000905
906
907 /* Case 2c: cursor past word at wrap point. */
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000908 else {
909 temp->data =
910 nmalloc(strlen(&inptr->data[current_word_start]) + 1);
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000911 strcpy(temp->data, &inptr->data[current_word_start]);
912
913 down = 1;
914 right = current_x - current_word_start;
915
916 current_x = current_word_start;
917 i = current_word_start - 1;
918
Chris Allegretta9e7efa32000-10-02 03:42:55 +0000919 while (isspace((int) inptr->data[i])) {
Adam Rogoyski3d449b42000-06-19 17:30:14 +0000920 i--;
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000921 assert(i >= 0);
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000922 inptr->data = nrealloc(inptr->data, i + 2);
923 inptr->data[i + 1] = 0;
924 }
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000925 }
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000926 }
927
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000928 /* We pre-pend wrapped part to next line. */
Adam Rogoyski0223d6f2000-06-17 20:36:35 +0000929 if (ISSET(SAMELINEWRAP) && inptr->next) {
Adam Rogoyski9aeb9da2000-06-16 01:19:31 +0000930 int old_x = current_x, old_y = current_y;
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000931
Chris Allegretta94a78b82001-03-14 08:28:48 +0000932 /* Plus one for the space which concatenates the two lines together plus 1 for \0. */
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000933 char *p =
934 nmalloc((strlen(temp->data) + strlen(inptr->next->data) + 2)
935 * sizeof(char));
Chris Allegretta94a78b82001-03-14 08:28:48 +0000936
937 if (ISSET(AUTOINDENT)) {
938 int non = 0;
939
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000940 /* Grab the beginning of the next line until it's not a
941 space or tab, then null terminate it so we can strcat it
942 to hell */
943 while ((inptr->next->data[non] == ' '
944 || inptr->next->data[non] == '\t'))
945 p[non] = inptr->next->data[non++];
Chris Allegretta94a78b82001-03-14 08:28:48 +0000946
947 p[non] = 0;
948 strcat(p, temp->data);
949 strcat(p, " ");
950
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000951 /* Now tack on the rest of the next line after the spaces and
952 tabs */
Chris Allegretta94a78b82001-03-14 08:28:48 +0000953 strcat(p, &inptr->next->data[non]);
954 } else {
955 strcpy(p, temp->data);
956 strcat(p, " ");
957 strcat(p, inptr->next->data);
958 }
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000959
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000960 free(inptr->next->data);
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000961 inptr->next->data = p;
962
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000963 free(temp->data);
964 free(temp);
Adam Rogoyski9aeb9da2000-06-16 01:19:31 +0000965
Adam Rogoyski9aeb9da2000-06-16 01:19:31 +0000966 current_x = old_x;
967 current_y = old_y;
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000968 }
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000969 /* Else we start a new line. */
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000970 else {
Adam Rogoyski1e9183f2001-03-13 18:36:03 +0000971
Adam Rogoyski77f36de2000-06-07 03:56:54 +0000972 temp->prev = inptr;
973 temp->next = inptr->next;
974
975 if (inptr->next)
976 inptr->next->prev = temp;
977 inptr->next = temp;
978
979 if (!temp->next)
980 filebot = temp;
981
982 SET(SAMELINEWRAP);
Adam Rogoyski1e9183f2001-03-13 18:36:03 +0000983
984 if (ISSET(AUTOINDENT)) {
985 char *spc = inptr->data;
986 char *t = NULL;
987 int extra = 0;
988 if (spc) {
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000989 while ((*spc == ' ') || (*spc == '\t')) {
Adam Rogoyski1e9183f2001-03-13 18:36:03 +0000990 extra++;
991 spc++;
Adam Rogoyski1e9183f2001-03-13 18:36:03 +0000992 totsize++;
993 }
994 t = nmalloc(strlen(temp->data) + extra + 1);
995 strncpy(t, inptr->data, extra);
996 strcpy(t + extra, temp->data);
997 free(temp->data);
998 temp->data = t;
999 }
1000 }
Adam Rogoyski77f36de2000-06-07 03:56:54 +00001001 }
1002
1003
1004 totlines++;
Robert Siemborskia417ddc2000-07-24 23:18:48 +00001005 /* Everything about it makes me want this line here but it causes
1006 * totsize to be high by one for some reason. Sigh. (Rob) */
1007 /* totsize++; */
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001008
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001009 renumber(inptr);
Chris Allegretta234a34d2000-07-29 04:33:38 +00001010 edit_update(edittop, TOP);
Adam Rogoyski0223d6f2000-06-17 20:36:35 +00001011
Adam Rogoyski77f36de2000-06-07 03:56:54 +00001012
1013 /* Move the cursor to the new line if appropriate. */
1014 if (down) {
1015 do_right();
1016 }
1017
1018 /* Move the cursor to the correct spot in the line if appropriate. */
1019 while (right--) {
1020 do_right();
1021 }
1022
Chris Allegretta234a34d2000-07-29 04:33:38 +00001023 edit_update(edittop, TOP);
Adam Rogoyski77f36de2000-06-07 03:56:54 +00001024 reset_cursor();
1025 edit_refresh();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001026}
1027
1028/* Check to see if we've just caused the line to wrap to a new line */
Adam Rogoyski77f36de2000-06-07 03:56:54 +00001029void check_wrap(filestruct * inptr, char ch)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001030{
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001031 int len = strlenpt(inptr->data);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001032#ifdef DEBUG
1033 fprintf(stderr, _("check_wrap called with inptr->data=\"%s\"\n"),
1034 inptr->data);
1035#endif
1036
Adam Rogoyski77f36de2000-06-07 03:56:54 +00001037 if (len <= fill)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001038 return;
Adam Rogoyski77f36de2000-06-07 03:56:54 +00001039 else {
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001040 int i = actual_x(inptr, fill);
Adam Rogoyski77f36de2000-06-07 03:56:54 +00001041
1042 /* Do not wrap if there are no words on or after wrap point. */
Adam Rogoyski09f97962000-06-20 02:50:33 +00001043 int char_found = 0;
Adam Rogoyski77f36de2000-06-07 03:56:54 +00001044
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001045 while (isspace((int) inptr->data[i]) && inptr->data[i])
Adam Rogoyski09f97962000-06-20 02:50:33 +00001046 i++;
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001047
Adam Rogoyski09f97962000-06-20 02:50:33 +00001048 if (!inptr->data[i])
1049 return;
Adam Rogoyski77f36de2000-06-07 03:56:54 +00001050
Adam Rogoyski09f97962000-06-20 02:50:33 +00001051 /* String must be at least 1 character long. */
1052 for (i = strlen(inptr->data) - 1; i >= 0; i--) {
Chris Allegretta9e7efa32000-10-02 03:42:55 +00001053 if (isspace((int) inptr->data[i])) {
Adam Rogoyski09f97962000-06-20 02:50:33 +00001054 if (!char_found)
1055 continue;
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001056 char_found = 2; /* 2 for yes do wrap. */
Adam Rogoyski09f97962000-06-20 02:50:33 +00001057 break;
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001058 } else
1059 char_found = 1; /* 1 for yes found a word, but must check further. */
Adam Rogoyski77f36de2000-06-07 03:56:54 +00001060 }
Adam Rogoyski09f97962000-06-20 02:50:33 +00001061
1062 if (char_found == 2)
1063 do_wrap(inptr, ch);
Adam Rogoyski77f36de2000-06-07 03:56:54 +00001064 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001065}
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001066#endif /* DISABLE_WRAPPING */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001067
1068/* Stuff we do when we abort from programs and want to clean up the
1069 * screen. This doesnt do much right now.
1070 */
1071void do_early_abort(void)
1072{
1073 blank_statusbar_refresh();
1074}
1075
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001076int do_backspace(void)
1077{
1078 filestruct *previous, *tmp;
1079
1080 if (current_x != 0) {
1081 /* Let's get dangerous */
1082 memmove(&current->data[current_x - 1], &current->data[current_x],
1083 strlen(current->data) - current_x + 1);
1084#ifdef DEBUG
1085 fprintf(stderr, _("current->data now = \"%s\"\n"), current->data);
1086#endif
1087 align(&current->data);
1088 do_left();
1089 } else {
1090 if (current == fileage)
1091 return 0; /* Can't delete past top of file */
1092
1093 previous = current->prev;
1094 current_x = strlen(previous->data);
1095 previous->data = nrealloc(previous->data,
1096 strlen(previous->data) +
1097 strlen(current->data) + 1);
1098 strcat(previous->data, current->data);
1099
1100 tmp = current;
1101 unlink_node(current);
1102 delete_node(current);
1103 if (current == edittop) {
1104 if (previous->next)
1105 current = previous->next;
1106 else
1107 current = previous;
Chris Allegrettada721be2000-07-31 01:26:42 +00001108 page_up_center();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001109 } else {
1110 if (previous->next)
1111 current = previous->next;
1112 else
1113 current = previous;
1114 update_line(current, current_x);
1115 }
1116
1117 /* Ooops, sanity check */
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001118 if (tmp == filebot) {
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001119 filebot = current;
1120 editbot = current;
Chris Allegretta28a0f892000-07-05 22:47:54 +00001121
1122 /* Recreate the magic line if we're deleting it AND if the
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001123 line we're on now is NOT blank. if it is blank we
1124 can just use IT for the magic line. This is how Pico
1125 appears to do it, in any case */
Chris Allegretta28a0f892000-07-05 22:47:54 +00001126 if (strcmp(current->data, "")) {
1127 new_magicline();
1128 fix_editbot();
1129 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001130 }
1131
1132 current = previous;
1133 renumber(current);
1134 previous_line();
1135 totlines--;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001136#ifdef DEBUG
1137 fprintf(stderr, _("After, data = \"%s\"\n"), current->data);
1138#endif
1139
1140 }
1141
1142 totsize--;
1143 set_modified();
1144 UNSET(KEEP_CUTBUFFER);
1145 edit_refresh();
1146 return 1;
1147}
1148
1149int do_delete(void)
1150{
1151 filestruct *foo;
1152
1153 if (current_x != strlen(current->data)) {
1154 /* Let's get dangerous */
1155 memmove(&current->data[current_x], &current->data[current_x + 1],
1156 strlen(current->data) - current_x);
1157
1158 align(&current->data);
1159
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001160 /* Now that we have a magic lnie again, we can check for both being
1161 on the line before filebot as well as at filebot */
Chris Allegretta4ed13152001-02-10 17:50:50 +00001162 } else if (current->next != NULL && current->next != filebot) {
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001163 current->data = nrealloc(current->data,
1164 strlen(current->data) +
1165 strlen(current->next->data) + 1);
1166 strcat(current->data, current->next->data);
1167
1168 foo = current->next;
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001169 if (filebot == foo) {
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001170 filebot = current;
1171 editbot = current;
1172 }
1173
1174 unlink_node(foo);
1175 delete_node(foo);
1176 update_line(current, current_x);
1177
Chris Allegretta4ed13152001-02-10 17:50:50 +00001178 /* Please see the comment in do_backspace if you don't understand
Chris Allegretta28a0f892000-07-05 22:47:54 +00001179 this test */
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001180 if (current == filebot && strcmp(current->data, "")) {
Chris Allegretta28a0f892000-07-05 22:47:54 +00001181 new_magicline();
1182 fix_editbot();
Chris Allegretta55373872000-07-06 22:38:37 +00001183 totsize++;
Chris Allegretta28a0f892000-07-05 22:47:54 +00001184 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001185 renumber(current);
1186 totlines--;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001187 } else
1188 return 0;
1189
1190 totsize--;
1191 set_modified();
1192 UNSET(KEEP_CUTBUFFER);
1193 edit_refresh();
1194 return 1;
1195}
1196
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001197void wrap_reset(void)
1198{
1199 UNSET(SAMELINEWRAP);
1200}
1201
Rocco Corsiaf5c3022001-01-12 07:51:05 +00001202#ifndef DISABLE_SPELLER
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001203
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001204int do_int_spell_fix(char *word)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001205{
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001206 char *prevanswer = NULL, *save_search = NULL, *save_replace = NULL;
Chris Allegrettad00e6df2000-11-29 04:33:26 +00001207 filestruct *begin;
1208 int i = 0, j = 0, beginx, beginx_top;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001209
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001210 /* save where we are */
1211 begin = current;
1212 beginx = current_x + 1;
1213
1214 /* save the current search/replace strings */
1215 search_init_globals();
1216 save_search = mallocstrcpy(save_search, last_search);
1217 save_replace = mallocstrcpy(save_replace, last_replace);
1218
1219 /* set search/replace strings to mis-spelt word */
1220 prevanswer = mallocstrcpy(prevanswer, word);
1221 last_search = mallocstrcpy(last_search, word);
1222 last_replace = mallocstrcpy(last_replace, word);
1223
1224 /* start from the top of file */
Chris Allegrettad00e6df2000-11-29 04:33:26 +00001225 current = fileage;
1226 current_x = beginx_top = -1;
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001227
1228 search_last_line = FALSE;
1229
Chris Allegrettad00e6df2000-11-29 04:33:26 +00001230 edit_update(fileage, TOP);
1231
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001232 /* make sure word is still mis-spelt (i.e. when multi-errors) */
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001233 if (findnextstr(TRUE, fileage, beginx_top, prevanswer) != NULL) {
Chris Allegrettad00e6df2000-11-29 04:33:26 +00001234 do_replace_highlight(TRUE, prevanswer);
1235
1236 /* allow replace word to be corrected */
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001237 i = statusq(0, spell_list, SPELL_LIST_LEN, last_replace,
1238 _("Edit a replacement"));
Chris Allegrettad00e6df2000-11-29 04:33:26 +00001239
1240 do_replace_highlight(FALSE, prevanswer);
1241
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001242 /* start from the start of this line again */
Chris Allegrettad00e6df2000-11-29 04:33:26 +00001243 current = fileage;
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001244 current_x = beginx_top;
1245
1246 search_last_line = FALSE;
1247
Chris Allegrettad00e6df2000-11-29 04:33:26 +00001248 j = i;
1249 do_replace_loop(prevanswer, fileage, &beginx_top, TRUE, &j);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001250 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001251
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001252 /* restore the search/replace strings */
1253 last_search = mallocstrcpy(last_search, save_search);
1254 last_replace = mallocstrcpy(last_replace, save_replace);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001255
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001256 /* restore where we were */
1257 current = begin;
1258 current_x = beginx - 1;
1259
1260 edit_update(current, CENTER);
1261
1262 if (i == -1)
1263 return FALSE;
1264
1265 return TRUE;
1266}
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001267
1268/* Integrated spell checking using 'spell' program */
Chris Allegretta271e9722000-11-10 18:15:43 +00001269int do_int_speller(char *tempfile_name)
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001270{
Chris Allegretta271e9722000-11-10 18:15:43 +00001271 char *read_buff, *read_buff_ptr, *read_buff_word;
1272 long pipe_buff_size;
1273 int in_fd[2], tempfile_fd;
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001274 int spell_status;
1275 pid_t pid_spell;
1276 ssize_t bytesread;
1277
Chris Allegretta271e9722000-11-10 18:15:43 +00001278 /* Create a pipe to spell program */
1279
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001280 if (pipe(in_fd) == -1)
1281 return FALSE;
1282
Chris Allegretta271e9722000-11-10 18:15:43 +00001283 /* A new process to run spell in */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001284
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001285 if ((pid_spell = fork()) == 0) {
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001286
1287 /* Child continues, (i.e. future spell process) */
1288
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001289 close(in_fd[0]);
1290
Chris Allegretta271e9722000-11-10 18:15:43 +00001291 /* replace the standard in with the tempfile */
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001292
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001293 if ((tempfile_fd = open(tempfile_name, O_RDONLY)) == -1) {
Chris Allegretta271e9722000-11-10 18:15:43 +00001294
1295 close(in_fd[1]);
1296 exit(1);
1297 }
1298
1299 if (dup2(tempfile_fd, STDIN_FILENO) != STDIN_FILENO) {
1300
1301 close(tempfile_fd);
1302 close(in_fd[1]);
1303 exit(1);
1304 }
1305 close(tempfile_fd);
1306
Chris Allegrettad00e6df2000-11-29 04:33:26 +00001307
Chris Allegretta271e9722000-11-10 18:15:43 +00001308 /* send spell's standard out to the pipe */
1309
1310 if (dup2(in_fd[1], STDOUT_FILENO) != STDOUT_FILENO) {
1311
1312 close(in_fd[1]);
1313 exit(1);
1314 }
1315 close(in_fd[1]);
1316
1317 /* Start spell program, we are using the PATH here!?!? */
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001318 execlp("spell", "spell", NULL);
1319
Chris Allegretta271e9722000-11-10 18:15:43 +00001320 /* Should not be reached, if spell is found!!! */
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001321
Chris Allegretta271e9722000-11-10 18:15:43 +00001322 exit(1);
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001323 }
1324
1325 /* Parent continues here */
1326
Chris Allegretta271e9722000-11-10 18:15:43 +00001327 close(in_fd[1]);
1328
1329 /* Child process was not forked successfully */
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001330
1331 if (pid_spell < 0) {
1332
Chris Allegretta271e9722000-11-10 18:15:43 +00001333 close(in_fd[0]);
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001334 return FALSE;
1335 }
1336
Chris Allegretta271e9722000-11-10 18:15:43 +00001337 /* Get system pipe buffer size */
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001338
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001339 if ((pipe_buff_size = fpathconf(in_fd[0], _PC_PIPE_BUF)) < 1) {
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001340
Chris Allegretta271e9722000-11-10 18:15:43 +00001341 close(in_fd[0]);
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001342 return FALSE;
Chris Allegretta271e9722000-11-10 18:15:43 +00001343 }
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001344
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001345 read_buff = nmalloc(pipe_buff_size + 1);
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001346
Chris Allegretta271e9722000-11-10 18:15:43 +00001347 /* Process the returned spelling errors */
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001348
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001349 while ((bytesread = read(in_fd[0], read_buff, pipe_buff_size)) > 0) {
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001350
Chris Allegretta271e9722000-11-10 18:15:43 +00001351 read_buff[bytesread] = (char) NULL;
1352 read_buff_word = read_buff_ptr = read_buff;
1353
1354 while (*read_buff_ptr != (char) NULL) {
1355
1356 /* Windows version may need to process additional char '\r' */
1357
1358 /* Possible problem here if last word not followed by '\n' */
1359
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001360 if (*read_buff_ptr == '\n') {
Chris Allegretta271e9722000-11-10 18:15:43 +00001361 *read_buff_ptr = (char) NULL;
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001362 if (!do_int_spell_fix(read_buff_word)) {
Chris Allegretta271e9722000-11-10 18:15:43 +00001363
1364 close(in_fd[0]);
1365 free(read_buff);
1366 replace_abort();
1367
1368 return TRUE;
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001369 }
Chris Allegretta271e9722000-11-10 18:15:43 +00001370 read_buff_word = read_buff_ptr;
1371 read_buff_word++;
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001372 }
1373
1374 read_buff_ptr++;
1375 }
1376 }
Chris Allegretta271e9722000-11-10 18:15:43 +00001377
1378 close(in_fd[0]);
1379 free(read_buff);
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001380 replace_abort();
1381
Chris Allegretta271e9722000-11-10 18:15:43 +00001382 /* Process end of spell process */
1383
1384 wait(&spell_status);
1385 if (WIFEXITED(spell_status)) {
1386 if (WEXITSTATUS(spell_status) != 0)
1387 return FALSE;
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001388 } else
Chris Allegretta271e9722000-11-10 18:15:43 +00001389 return FALSE;
1390
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001391 return TRUE;
1392}
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001393
1394/* External spell checking */
Chris Allegretta271e9722000-11-10 18:15:43 +00001395int do_alt_speller(char *file_name)
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001396{
Chris Allegretta271e9722000-11-10 18:15:43 +00001397 int alt_spell_status;
1398 pid_t pid_spell;
Chris Allegretta169ee842001-01-26 01:57:32 +00001399 char *ptr;
Rocco Corsi4dfaf932001-04-20 01:59:55 +00001400 long lineno_cur = current->lineno;
Chris Allegretta169ee842001-01-26 01:57:32 +00001401 static int arglen = 3;
1402 static char **spellargs = (char **) NULL;
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001403
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001404 endwin();
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001405
Chris Allegrettae434b452001-01-27 19:25:00 +00001406 /* Set up an argument list to pass the execvp function */
1407 if (spellargs == NULL) {
1408 spellargs = nmalloc(arglen * sizeof(char *));
Chris Allegretta271e9722000-11-10 18:15:43 +00001409
Chris Allegrettae434b452001-01-27 19:25:00 +00001410 spellargs[0] = strtok(alt_speller, " ");
1411 while ((ptr = strtok(NULL, " ")) != NULL) {
1412 arglen++;
1413 spellargs = nrealloc(spellargs, arglen * sizeof(char *));
1414 spellargs[arglen - 3] = ptr;
Chris Allegretta169ee842001-01-26 01:57:32 +00001415 }
Chris Allegrettae434b452001-01-27 19:25:00 +00001416 spellargs[arglen - 1] = NULL;
1417 }
1418 spellargs[arglen - 2] = file_name;
1419
1420 /* Start a new process for the alternate speller */
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001421 if ((pid_spell = fork()) == 0) {
Chris Allegretta169ee842001-01-26 01:57:32 +00001422
Chris Allegretta271e9722000-11-10 18:15:43 +00001423 /* Start alternate spell program, we are using the PATH here!?!? */
Chris Allegretta169ee842001-01-26 01:57:32 +00001424 execvp(spellargs[0], spellargs);
Chris Allegretta271e9722000-11-10 18:15:43 +00001425
1426 /* Should not be reached, if alternate speller is found!!! */
1427
1428 exit(1);
1429 }
1430
1431 /* Could not fork?? */
1432
1433 if (pid_spell < 0)
1434 return FALSE;
1435
1436 /* Wait for alternate speller to complete */
1437
1438 wait(&alt_spell_status);
1439 if (WIFEXITED(alt_spell_status)) {
1440 if (WEXITSTATUS(alt_spell_status) != 0)
1441 return FALSE;
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001442 } else
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001443 return FALSE;
1444
Chris Allegretta8f6c0692000-07-19 01:16:18 +00001445 refresh();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001446 free_filestruct(fileage);
1447 global_init();
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001448 open_file(file_name, 0, 1);
Rocco Corsi4dfaf932001-04-20 01:59:55 +00001449
1450 do_gotoline(lineno_cur);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001451 set_modified();
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001452
1453 return TRUE;
1454}
1455#endif
1456
1457int do_spell(void)
1458{
1459
Rocco Corsiaf5c3022001-01-12 07:51:05 +00001460#ifdef DISABLE_SPELLER
Chris Allegrettaff269f82000-12-01 18:46:01 +00001461 nano_disabled_msg();
1462 return (TRUE);
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001463#else
Chris Allegretta271e9722000-11-10 18:15:43 +00001464 char *temp;
1465 int spell_res;
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001466
Chris Allegretta271e9722000-11-10 18:15:43 +00001467 if ((temp = tempnam(0, "nano.")) == NULL) {
1468 statusbar(_("Could not create a temporary filename: %s"),
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001469 strerror(errno));
Chris Allegretta271e9722000-11-10 18:15:43 +00001470 return 0;
1471 }
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001472
Chris Allegretta3dbb2782000-12-02 04:36:50 +00001473 if (write_file(temp, 1) == -1) {
1474 statusbar(_("Spell checking failed: unable to write temp file!"));
Chris Allegretta271e9722000-11-10 18:15:43 +00001475 return 0;
Chris Allegretta3dbb2782000-12-02 04:36:50 +00001476 }
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001477
Chris Allegretta271e9722000-11-10 18:15:43 +00001478 if (alt_speller)
1479 spell_res = do_alt_speller(temp);
1480 else
1481 spell_res = do_int_speller(temp);
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001482
Chris Allegretta271e9722000-11-10 18:15:43 +00001483 remove(temp);
Chris Allegretta27eb13f2000-11-05 16:52:21 +00001484
1485 if (spell_res)
1486 statusbar(_("Finished checking spelling"));
1487 else
1488 statusbar(_("Spell checking failed"));
1489
1490 return spell_res;
1491
Chris Allegrettadbc12b22000-07-03 03:10:14 +00001492#endif
Chris Allegretta67105eb2000-07-03 03:18:32 +00001493}
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001494
1495int do_exit(void)
1496{
1497 int i;
1498
1499 if (!ISSET(MODIFIED))
1500 finish(0);
1501
Chris Allegretta30885552000-07-14 01:20:12 +00001502 if (ISSET(TEMP_OPT)) {
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001503 i = 1;
1504 } else {
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001505 i = do_yesno(0, 0,
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001506 _
1507 ("Save modified buffer (ANSWERING \"No\" WILL DESTROY CHANGES) ? "));
1508 }
1509
1510#ifdef DEBUG
1511 dump_buffer(fileage);
1512#endif
1513
1514 if (i == 1) {
Chris Allegrettae1ebaf32001-01-07 05:50:36 +00001515 if (do_writeout(filename, 1) > 0)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001516 finish(0);
1517 } else if (i == 0)
1518 finish(0);
1519 else
1520 statusbar(_("Cancelled"));
1521
1522 display_main_list();
1523 return 1;
1524}
1525
Chris Allegretta84de5522001-04-12 14:51:48 +00001526#ifndef DISABLE_MOUSE
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001527#ifdef NCURSES_MOUSE_VERSION
1528void do_mouse(void)
1529{
1530 MEVENT mevent;
Chris Allegrettae10debd2000-08-22 01:26:42 +00001531 int foo = 0, tab_found = 0;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001532
1533 if (getmouse(&mevent) == ERR)
1534 return;
1535
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001536 /* If mouse not in edit or bottom window, return */
1537 if (wenclose(edit, mevent.y, mevent.x)) {
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001538
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001539 /* Don't let people screw with the marker when they're in a
1540 subfunction */
1541 if (currshortcut != main_list)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001542 return;
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001543
1544 /* Subtract out size of topwin. Perhaps we need a constant somewhere? */
1545 mevent.y -= 2;
1546
1547 /* Selecting where the cursor is sets the mark.
1548 * Selecting beyond the line length with the cursor at the end of the
1549 * line sets the mark as well.
1550 */
1551 if ((mevent.y == current_y) &&
1552 ((mevent.x == current_x) || (current_x == strlen(current->data)
1553 && (mevent.x >
1554 strlen(current->data))))) {
1555 if (ISSET(VIEW_MODE)) {
1556 print_view_warning();
1557 return;
1558 }
1559 do_mark();
1560 } else if (mevent.y > current_y) {
1561 while (mevent.y > current_y) {
1562 if (current->next != NULL)
1563 current = current->next;
1564 else
1565 break;
1566 current_y++;
1567 }
1568 } else if (mevent.y < current_y) {
1569 while (mevent.y < current_y) {
1570 if (current->prev != NULL)
1571 current = current->prev;
1572 else
1573 break;
1574 current_y--;
1575 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001576 }
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001577 current_x = mevent.x;
1578 placewewant = current_x;
1579 while (foo < current_x) {
1580 if (current->data[foo] == NANO_CONTROL_I) {
1581 current_x -= tabsize - (foo % tabsize);
1582 tab_found = 1;
1583 } else if (current->data[foo] & 0x80);
1584 else if (current->data[foo] < 32)
1585 current_x--;
1586 foo++;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001587 }
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001588 /* This is where tab_found comes in. I can't figure out why,
1589 * but without it any line with a tab will place the cursor
1590 * one character behind. Whatever, this fixes it. */
1591 if (tab_found == 1)
1592 current_x++;
1593
1594 if (current_x > strlen(current->data))
1595 current_x = strlen(current->data);
1596
1597 update_cursor();
1598 edit_refresh();
1599 } else if (wenclose(bottomwin, mevent.y, mevent.x) && !ISSET(NO_HELP)) {
1600 int k = COLS / 6, val = 0;
1601
1602 /* Determine what shortcut list was clicked */
1603 mevent.y -= (editwinrows + 3);
1604
1605 if (mevent.y < 0) /* They clicked on the statusbar */
1606 return;
1607
1608 /* Don't select stuff beyond list length */
1609 if (mevent.x / k >= currslen)
1610 return;
1611
1612 val = currshortcut[(mevent.x / k) * 2 + mevent.y].val;
1613
1614 /* And ungetch that value */
1615 ungetch(val);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001616 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001617}
1618#endif
1619#endif
1620
1621/* Handler for SIGHUP */
1622RETSIGTYPE handle_hup(int signal)
1623{
Chris Allegrettae7a58932000-12-02 02:36:22 +00001624 die(_("Received SIGHUP"));
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001625}
1626
Chris Allegretta18f8be02000-09-04 03:20:38 +00001627/* What do we do when we catch the suspend signal */
1628RETSIGTYPE do_suspend(int signal)
1629{
1630
1631 act.sa_handler = SIG_DFL;
1632 sigemptyset(&act.sa_mask);
1633 sigaction(SIGTSTP, &act, NULL);
1634
1635 endwin();
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001636 fprintf(stderr, "\n\n\n\n\nUse \"fg\" to return to nano\n");
Chris Allegretta18f8be02000-09-04 03:20:38 +00001637 raise(SIGTSTP);
1638}
1639
1640/* Restore the suspend handler when we come back into the prog */
1641RETSIGTYPE do_cont(int signal)
1642{
1643
1644 act.sa_handler = do_suspend;
1645 sigemptyset(&act.sa_mask);
1646 sigaction(SIGTSTP, &act, NULL);
1647 initscr();
1648 total_refresh();
1649}
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001650
1651void handle_sigwinch(int s)
1652{
1653#ifndef NANO_SMALL
1654 char *tty = NULL;
1655 int fd = 0;
1656 int result = 0;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001657 struct winsize win;
1658
1659 tty = ttyname(0);
1660 if (!tty)
1661 return;
1662 fd = open(tty, O_RDWR);
1663 if (fd == -1)
1664 return;
1665 result = ioctl(fd, TIOCGWINSZ, &win);
1666 if (result == -1)
1667 return;
1668
1669
1670 COLS = win.ws_col;
1671 LINES = win.ws_row;
1672
Chris Allegrettae61e8302001-01-14 05:18:27 +00001673 if ((editwinrows = LINES - 5 + no_help()) < MIN_EDITOR_ROWS)
1674 die_too_small();
1675
1676 if ((fill = COLS - CHARS_FROM_EOL) < MIN_FILL_LENGTH)
1677 die_too_small();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001678
Chris Allegretta0a06e072001-01-23 02:35:04 +00001679 hblank = nrealloc(hblank, COLS + 1);
1680 memset(hblank, ' ', COLS);
1681 hblank[COLS] = 0;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001682
Chris Allegretta618f5d72001-02-16 04:48:30 +00001683#ifdef HAVE_RESIZETERM
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001684 resizeterm(LINES, COLS);
1685#ifdef HAVE_WRESIZE
1686 if (wresize(topwin, 2, COLS) == ERR)
1687 die(_("Cannot resize top win"));
1688 if (mvwin(topwin, 0, 0) == ERR)
1689 die(_("Cannot move top win"));
1690 if (wresize(edit, editwinrows, COLS) == ERR)
1691 die(_("Cannot resize edit win"));
1692 if (mvwin(edit, 2, 0) == ERR)
1693 die(_("Cannot move edit win"));
1694 if (wresize(bottomwin, 3 - no_help(), COLS) == ERR)
1695 die(_("Cannot resize bottom win"));
1696 if (mvwin(bottomwin, LINES - 3 + no_help(), 0) == ERR)
1697 die(_("Cannot move bottom win"));
1698#endif /* HAVE_WRESIZE */
Chris Allegretta618f5d72001-02-16 04:48:30 +00001699#endif /* HAVE_RESIZETERM */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001700
Robert Siemborskidd53ec22000-07-04 02:35:19 +00001701 fix_editbot();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001702
Chris Allegrettabceb1b22000-06-19 04:22:15 +00001703 if (current_y > editwinrows - 1) {
Chris Allegretta234a34d2000-07-29 04:33:38 +00001704 edit_update(editbot, CENTER);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001705 }
1706 erase();
Chris Allegretta97accc62000-06-19 05:45:52 +00001707
1708 /* Do these b/c width may have changed... */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001709 refresh();
Chris Allegrettaf4b96012001-01-03 07:11:47 +00001710 titlebar(NULL);
Chris Allegretta97accc62000-06-19 05:45:52 +00001711 edit_refresh();
1712 display_main_list();
Chris Allegretta08020882001-01-29 23:37:54 +00001713 blank_statusbar();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001714 total_refresh();
Chris Allegretta08020882001-01-29 23:37:54 +00001715
Chris Allegretta4e90c402001-01-29 23:40:43 +00001716 /* Turn cursor back on for sure */
1717 curs_set(1);
1718
Chris Allegretta08020882001-01-29 23:37:54 +00001719 /* Jump back to mainloop */
1720 siglongjmp(jmpbuf, 1);
1721
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001722#endif
1723}
1724
Chris Allegretta756f2202000-09-01 13:32:47 +00001725void signal_init(void)
1726{
Chris Allegretta756f2202000-09-01 13:32:47 +00001727
1728 /* Trap SIGINT and SIGQUIT cuz we want them to do useful things. */
1729 memset(&act, 0, sizeof(struct sigaction));
1730 act.sa_handler = SIG_IGN;
1731 sigaction(SIGINT, &act, NULL);
Chris Allegretta756f2202000-09-01 13:32:47 +00001732
Chris Allegretta18f8be02000-09-04 03:20:38 +00001733 if (!ISSET(SUSPEND)) {
Chris Allegretta756f2202000-09-01 13:32:47 +00001734 sigaction(SIGTSTP, &act, NULL);
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001735 } else {
Chris Allegretta18f8be02000-09-04 03:20:38 +00001736 act.sa_handler = do_suspend;
1737 sigaction(SIGTSTP, &act, NULL);
1738
1739 act.sa_handler = do_cont;
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001740 sigaction(SIGCONT, &act, NULL);
Chris Allegretta18f8be02000-09-04 03:20:38 +00001741 }
1742
Chris Allegretta756f2202000-09-01 13:32:47 +00001743
1744 /* Trap SIGHUP cuz we want to write the file out. */
1745 act.sa_handler = handle_hup;
1746 sigaction(SIGHUP, &act, NULL);
1747
1748 act.sa_handler = handle_sigwinch;
1749 sigaction(SIGWINCH, &act, NULL);
1750
1751}
1752
Chris Allegretta2a42af12000-09-12 23:02:49 +00001753void window_init(void)
1754{
Chris Allegrettae61e8302001-01-14 05:18:27 +00001755 if ((editwinrows = LINES - 5 + no_help()) < MIN_EDITOR_ROWS)
1756 die_too_small();
Chris Allegretta92c9dd22000-09-13 14:03:27 +00001757
Chris Allegretta2a42af12000-09-12 23:02:49 +00001758 /* Setup up the main text window */
1759 edit = newwin(editwinrows, COLS, 2, 0);
1760
1761 /* And the other windows */
1762 topwin = newwin(2, COLS, 0, 0);
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001763 bottomwin = newwin(3 - no_help(), COLS, LINES - 3 + no_help(), 0);
Chris Allegretta63c8ab92001-01-04 02:33:52 +00001764
Chris Allegretta155d6202001-01-08 01:50:37 +00001765#ifdef PDCURSES
1766 /* Oops, I guess we need this again.
1767 Moved here so the keypad still works after a Meta-X, for example */
1768 keypad(edit, TRUE);
1769 keypad(bottomwin, TRUE);
1770#endif
1771
Chris Allegretta2a42af12000-09-12 23:02:49 +00001772}
1773
Chris Allegretta756f2202000-09-01 13:32:47 +00001774void mouse_init(void)
1775{
Chris Allegretta84de5522001-04-12 14:51:48 +00001776#ifndef DISABLE_MOUSE
Chris Allegretta756f2202000-09-01 13:32:47 +00001777#ifdef NCURSES_MOUSE_VERSION
1778 if (ISSET(USE_MOUSE)) {
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001779 keypad_on(edit, 1);
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001780 keypad_on(bottomwin, 1);
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001781
Chris Allegretta756f2202000-09-01 13:32:47 +00001782 mousemask(BUTTON1_RELEASED, NULL);
1783 mouseinterval(50);
Chris Allegretta0b88ce02000-09-15 15:46:32 +00001784
Chris Allegretta63c8ab92001-01-04 02:33:52 +00001785 } else
Chris Allegretta756f2202000-09-01 13:32:47 +00001786 mousemask(0, NULL);
Chris Allegretta63c8ab92001-01-04 02:33:52 +00001787
Chris Allegretta756f2202000-09-01 13:32:47 +00001788#endif
1789#endif
1790
1791}
1792
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001793int do_tab(void)
1794{
1795 do_char('\t');
1796 return 1;
1797}
1798
Rocco Corsiaf5c3022001-01-12 07:51:05 +00001799#ifndef DISABLE_JUSTIFY
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001800int empty_line(const char *data)
1801{
1802 while (*data) {
Chris Allegretta9e7efa32000-10-02 03:42:55 +00001803 if (!isspace((int) *data))
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001804 return 0;
1805
1806 data++;
1807 }
1808
1809 return 1;
1810}
1811
1812int no_spaces(const char *data)
1813{
1814 while (*data) {
Chris Allegretta9e7efa32000-10-02 03:42:55 +00001815 if (isspace((int) *data))
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001816 return 0;
1817
1818 data++;
1819 }
1820
1821 return 1;
1822}
1823
1824void justify_format(char *data)
1825{
1826 int i = 0;
1827 int len = strlen(data);
1828
1829 /* Skip first character regardless and leading whitespace. */
1830 for (i = 1; i < len; i++) {
Chris Allegretta9e7efa32000-10-02 03:42:55 +00001831 if (!isspace((int) data[i]))
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001832 break;
1833 }
1834
1835 i++; /* (i) is now at least 2. */
1836
1837 /* No double spaces allowed unless following a period. Tabs -> space. No double tabs. */
1838 for (; i < len; i++) {
Chris Allegretta9e7efa32000-10-02 03:42:55 +00001839 if (isspace((int) data[i]) && isspace((int) data[i - 1])
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001840 && (data[i - 2] != '.')) {
1841 memmove(data + i, data + i + 1, len - i);
1842 len--;
1843 i--;
1844 }
1845 }
1846}
1847#endif
1848
1849int do_justify(void)
1850{
Rocco Corsiaf5c3022001-01-12 07:51:05 +00001851#ifdef DISABLE_JUSTIFY
Chris Allegrettaff269f82000-12-01 18:46:01 +00001852 nano_disabled_msg();
1853 return 1;
1854#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001855 int slen = 0; /* length of combined lines on one line. */
Chris Allegretta17dcb722001-01-20 21:40:07 +00001856 int initial_y, kbinput = 0, totbak;
Chris Allegretta9149e612000-11-27 00:23:41 +00001857 filestruct *initial = NULL, *tmpjust = NULL, *cutbak, *tmptop, *tmpbot;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001858
1859 if (empty_line(current->data)) {
1860 /* Justify starting at first non-empty line. */
1861 do {
1862 if (!current->next)
1863 return 1;
1864
1865 current = current->next;
1866 current_y++;
1867 }
1868 while (empty_line(current->data));
1869 } else {
1870 /* Search back for the beginning of the paragraph, where
1871 * Paragraph is 1) A line with leading whitespace
1872 * or 2) A line following an empty line.
1873 */
1874 while (current->prev != NULL) {
Chris Allegretta9e7efa32000-10-02 03:42:55 +00001875 if (isspace((int) current->data[0]) || !current->data[0])
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001876 break;
1877
1878 current = current->prev;
1879 current_y--;
1880 }
1881
1882 /* First line with leading whitespace may be empty. */
1883 if (empty_line(current->data)) {
1884 if (current->next) {
1885 current = current->next;
1886 current_y++;
1887 } else
1888 return 1;
1889 }
1890 }
1891 initial = current;
1892 initial_y = current_y;
1893
1894 set_modified();
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001895 cutbak = cutbuffer; /* Got to like cutbak ;) */
Chris Allegretta17dcb722001-01-20 21:40:07 +00001896 totbak = totsize;
Chris Allegretta9149e612000-11-27 00:23:41 +00001897 cutbuffer = NULL;
1898
1899 tmptop = current;
1900 tmpjust = copy_node(current);
Robert Siemborski60cd6aa2001-01-21 23:23:48 +00001901
1902 /* This is annoying because it mucks with totsize */
Chris Allegretta9149e612000-11-27 00:23:41 +00001903 add_to_cutbuffer(tmpjust);
Robert Siemborski60cd6aa2001-01-21 23:23:48 +00001904
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001905 /* Put the whole paragraph into one big line. */
Chris Allegretta9e7efa32000-10-02 03:42:55 +00001906 while (current->next && !isspace((int) current->next->data[0])
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001907 && current->next->data[0]) {
1908 filestruct *tmpnode = current->next;
1909 int len = strlen(current->data);
1910 int len2 = strlen(current->next->data);
1911
Chris Allegretta9149e612000-11-27 00:23:41 +00001912 tmpjust = NULL;
Chris Allegretta9149e612000-11-27 00:23:41 +00001913 tmpjust = copy_node(current->next);
1914 add_to_cutbuffer(tmpjust);
1915
Robert Siemborski60cd6aa2001-01-21 23:23:48 +00001916 /* Wiping out a newline */
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001917 totsize--;
Robert Siemborski60cd6aa2001-01-21 23:23:48 +00001918
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001919 /* length of both strings plus space between strings and ending \0. */
1920 current->data = nrealloc(current->data, len + len2 + 2);
1921 current->data[len++] = ' ';
1922 current->data[len] = '\0';
1923
1924 strncat(current->data, current->next->data, len2);
1925
1926 unlink_node(tmpnode);
1927 delete_node(tmpnode);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001928 }
1929
1930 justify_format(current->data);
1931
1932 slen = strlen(current->data);
Robert Siemborskia417ddc2000-07-24 23:18:48 +00001933 totsize += slen;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001934
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001935 if ((strlenpt(current->data) > (fill))
1936 && !no_spaces(current->data)) {
Robert Siemborskia417ddc2000-07-24 23:18:48 +00001937 do {
1938 int i = 0;
1939 int len2 = 0;
1940 filestruct *tmpline = nmalloc(sizeof(filestruct));
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001941
Robert Siemborskia417ddc2000-07-24 23:18:48 +00001942 /* Start at fill , unless line isn't that long (but it
1943 * appears at least fill long with tabs.
1944 */
1945 if (slen > fill)
1946 i = fill;
1947 else
1948 i = slen;
Robert Siemborski60cd6aa2001-01-21 23:23:48 +00001949
Robert Siemborskia417ddc2000-07-24 23:18:48 +00001950 for (; i > 0; i--) {
Chris Allegretta9e7efa32000-10-02 03:42:55 +00001951 if (isspace((int) current->data[i]) &&
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001952 ((strlenpt(current->data) - strlen(current->data + i))
1953 <= fill))
1954 break;
Robert Siemborskia417ddc2000-07-24 23:18:48 +00001955 }
Robert Siemborski60cd6aa2001-01-21 23:23:48 +00001956
Robert Siemborskia417ddc2000-07-24 23:18:48 +00001957 if (!i)
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001958 break;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001959
Robert Siemborskia417ddc2000-07-24 23:18:48 +00001960 current->data[i] = '\0';
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001961
Robert Siemborskia417ddc2000-07-24 23:18:48 +00001962 len2 = strlen(current->data + i + 1);
1963 tmpline->data = nmalloc(len2 + 1);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001964
Robert Siemborskia417ddc2000-07-24 23:18:48 +00001965 /* Skip the white space in current. */
1966 memcpy(tmpline->data, current->data + i + 1, len2);
1967 tmpline->data[len2] = '\0';
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001968
Robert Siemborskia417ddc2000-07-24 23:18:48 +00001969 current->data = nrealloc(current->data, i + 1);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001970
Robert Siemborskia417ddc2000-07-24 23:18:48 +00001971 tmpline->prev = current;
1972 tmpline->next = current->next;
1973 if (current->next != NULL)
1974 current->next->prev = tmpline;
1975
1976 current->next = tmpline;
1977 current = tmpline;
1978 slen -= i + 1;
1979 current_y++;
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001980 } while ((strlenpt(current->data) > (fill))
1981 && !no_spaces(current->data));
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001982 }
Chris Allegretta9149e612000-11-27 00:23:41 +00001983 tmpbot = current;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001984
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001985 if (current->next)
1986 current = current->next;
Adam Rogoyski09f97962000-06-20 02:50:33 +00001987 else
1988 filebot = current;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001989 current_x = 0;
1990 placewewant = 0;
1991
Adam Rogoyski09f97962000-06-20 02:50:33 +00001992 renumber(initial);
1993 totlines = filebot->lineno;
1994
1995 werase(edit);
1996
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001997 if ((current_y < 0) || (current_y >= editwinrows - 1)
1998 || (initial_y <= 0)) {
Chris Allegretta234a34d2000-07-29 04:33:38 +00001999 edit_update(current, CENTER);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002000 center_cursor();
2001 } else {
Robert Siemborskidd53ec22000-07-04 02:35:19 +00002002 fix_editbot();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002003 }
2004
Adam Rogoyski09f97962000-06-20 02:50:33 +00002005 edit_refresh();
Chris Allegretta9149e612000-11-27 00:23:41 +00002006 statusbar(_("Can now UnJustify!"));
Chris Allegretta07798352000-11-27 22:58:23 +00002007 /* Change the shortcut list to display the unjustify code */
2008 shortcut_init(1);
2009 display_main_list();
Chris Allegretta9149e612000-11-27 00:23:41 +00002010 reset_cursor();
2011
Chris Allegretta07798352000-11-27 22:58:23 +00002012 /* Now get a keystroke and see if it's unjustify, if not unget the keytroke
Chris Allegretta9149e612000-11-27 00:23:41 +00002013 and return */
Chris Allegretta00ae5df2001-02-05 18:24:33 +00002014 if ((kbinput = wgetch(edit)) != NANO_UNJUSTIFY_KEY) {
Chris Allegretta6b58acd2001-04-12 03:01:53 +00002015 ungetch(kbinput);
Chris Allegretta00ae5df2001-02-05 18:24:33 +00002016 blank_statusbar_refresh();
2017 } else {
Chris Allegretta9149e612000-11-27 00:23:41 +00002018 /* Else restore the justify we just did (ungrateful user!) */
2019 if (tmptop->prev != NULL)
2020 tmptop->prev->next = tmpbot->next;
Chris Allegrettad022eac2000-11-27 02:50:49 +00002021 else
2022 fileage = current;
Chris Allegretta9149e612000-11-27 00:23:41 +00002023 tmpbot->next->prev = tmptop->prev;
Chris Allegretta6b58acd2001-04-12 03:01:53 +00002024 current = tmpbot->next;
Chris Allegretta9149e612000-11-27 00:23:41 +00002025 tmpbot->next = NULL;
2026 do_uncut_text();
Chris Allegrettad022eac2000-11-27 02:50:49 +00002027 if (tmptop->prev == NULL)
2028 edit_refresh();
2029
Chris Allegretta17dcb722001-01-20 21:40:07 +00002030 /* Restore totsize from befure justify */
2031 totsize = totbak;
Chris Allegretta9149e612000-11-27 00:23:41 +00002032 free_filestruct(tmptop);
2033 blank_statusbar_refresh();
2034 }
Chris Allegretta4a9c8582000-11-27 22:59:40 +00002035 shortcut_init(0);
2036 display_main_list();
Chris Allegretta9149e612000-11-27 00:23:41 +00002037 free_filestruct(cutbuffer);
2038 cutbuffer = cutbak;
Chris Allegretta6b58acd2001-04-12 03:01:53 +00002039
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002040 return 1;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002041#endif
2042}
2043
Rocco Corsiaf5c3022001-01-12 07:51:05 +00002044#ifndef DISABLE_HELP
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002045void help_init(void)
2046{
2047 int i, sofar = 0;
2048 long allocsize = 1; /* How much space we're gonna need for the help text */
Chris Allegretta220ba692000-12-18 03:40:00 +00002049 char buf[BUFSIZ] = "";
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002050
2051 /* Compute the space needed for the shortcut lists - we add 15 to
2052 have room for the shortcut abbrev and its possible alternate keys */
Chris Allegretta220ba692000-12-18 03:40:00 +00002053 for (i = 0; i <= MAIN_LIST_LEN - 1; i++)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002054 if (main_list[i].help != NULL)
2055 allocsize += strlen(main_list[i].help) + 15;
2056
Chris Allegretta756f2202000-09-01 13:32:47 +00002057 /* And for the toggle list, we also allocate space for extra text. */
Chris Allegretta423cbfd2000-09-04 16:21:29 +00002058 for (i = 0; i <= TOGGLE_LEN - 1; i++)
Chris Allegretta756f2202000-09-01 13:32:47 +00002059 if (toggles[i].desc != NULL)
2060 allocsize += strlen(toggles[i].desc) + 30;
2061
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002062 allocsize += strlen(help_text_init);
2063
2064 if (help_text != NULL)
2065 free(help_text);
2066
2067 /* Allocate space for the help text */
2068 help_text = nmalloc(allocsize);
2069
2070 /* Now add the text we want */
2071 strcpy(help_text, help_text_init);
2072
2073 /* Now add our shortcut info */
Chris Allegretta220ba692000-12-18 03:40:00 +00002074 for (i = 0; i <= MAIN_LIST_LEN - 1; i++) {
Robert Siemborski6af14312000-07-01 21:34:26 +00002075 sofar = snprintf(buf, BUFSIZ, "^%c ", main_list[i].val + 64);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002076
2077 if (main_list[i].misc1 > KEY_F0 && main_list[i].misc1 <= KEY_F(64))
Robert Siemborski6af14312000-07-01 21:34:26 +00002078 sofar += snprintf(&buf[sofar], BUFSIZ - sofar, "(F%d) ",
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00002079 main_list[i].misc1 - KEY_F0);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002080 else
Robert Siemborski6af14312000-07-01 21:34:26 +00002081 sofar += snprintf(&buf[sofar], BUFSIZ - sofar, " ");
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002082
2083 if (main_list[i].altval > 0)
Chris Allegrettae49f1232000-09-02 07:20:39 +00002084 sofar += snprintf(&buf[sofar], BUFSIZ - sofar, "(M-%c) ",
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00002085 main_list[i].altval - 32);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002086 else
Robert Siemborski6af14312000-07-01 21:34:26 +00002087 sofar += snprintf(&buf[sofar], BUFSIZ - sofar, " ");
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002088
Chris Allegretta756f2202000-09-01 13:32:47 +00002089
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002090 if (main_list[i].help != NULL)
Robert Siemborski976847c2000-07-06 03:43:05 +00002091 snprintf(&buf[sofar], BUFSIZ - sofar, "%s", main_list[i].help);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002092
Chris Allegretta756f2202000-09-01 13:32:47 +00002093
2094 strcat(help_text, buf);
2095 strcat(help_text, "\n");
2096 }
2097
2098 /* And the toggles... */
Chris Allegretta423cbfd2000-09-04 16:21:29 +00002099 for (i = 0; i <= TOGGLE_LEN - 1; i++) {
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00002100 sofar = snprintf(buf, BUFSIZ,
2101 "M-%c ", toggles[i].val - 32);
Chris Allegretta756f2202000-09-01 13:32:47 +00002102
2103 if (toggles[i].desc != NULL)
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00002104 snprintf(&buf[sofar], BUFSIZ - sofar, _("%s enable/disable"),
2105 toggles[i].desc);
Chris Allegretta756f2202000-09-01 13:32:47 +00002106
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002107 strcat(help_text, buf);
Robert Siemborski976847c2000-07-06 03:43:05 +00002108 strcat(help_text, "\n");
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002109 }
2110
2111}
Chris Allegretta3bc8c722000-12-10 17:03:25 +00002112#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002113
Chris Allegretta756f2202000-09-01 13:32:47 +00002114void do_toggle(int which)
2115{
Rocco Corsiaf5c3022001-01-12 07:51:05 +00002116#ifdef NANO_SMALL
2117 nano_disabled_msg();
2118#else
Jordi Mallach2dc0f6b2000-09-07 10:48:00 +00002119 char *enabled = _("enabled");
2120 char *disabled = _("disabled");
Chris Allegrettaf0f63a82000-09-02 18:44:21 +00002121
Chris Allegretta2a42af12000-09-12 23:02:49 +00002122 if (ISSET(toggles[which].flag))
Chris Allegretta756f2202000-09-01 13:32:47 +00002123 UNSET(toggles[which].flag);
Chris Allegretta2a42af12000-09-12 23:02:49 +00002124 else
Chris Allegretta756f2202000-09-01 13:32:47 +00002125 SET(toggles[which].flag);
Chris Allegretta2a42af12000-09-12 23:02:49 +00002126
Chris Allegretta756f2202000-09-01 13:32:47 +00002127 switch (toggles[which].val) {
2128 case TOGGLE_PICOMODE_KEY:
Chris Allegretta07798352000-11-27 22:58:23 +00002129 shortcut_init(0);
Chris Allegretta756f2202000-09-01 13:32:47 +00002130 display_main_list();
2131 break;
2132 case TOGGLE_SUSPEND_KEY:
2133 signal_init();
2134 break;
2135 case TOGGLE_MOUSE_KEY:
2136 mouse_init();
2137 break;
2138 case TOGGLE_NOHELP_KEY:
Chris Allegretta2a42af12000-09-12 23:02:49 +00002139 wclear(bottomwin);
2140 wrefresh(bottomwin);
2141 window_init();
Chris Allegrettaaffeda82000-12-18 04:03:48 +00002142 fix_editbot();
Chris Allegretta2a42af12000-09-12 23:02:49 +00002143 edit_refresh();
2144 display_main_list();
Chris Allegretta756f2202000-09-01 13:32:47 +00002145 break;
2146 }
Chris Allegretta2a42af12000-09-12 23:02:49 +00002147
2148 if (!ISSET(toggles[which].flag)) {
2149 if (toggles[which].val == TOGGLE_NOHELP_KEY ||
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00002150 toggles[which].val == TOGGLE_WRAP_KEY)
Chris Allegretta2a42af12000-09-12 23:02:49 +00002151 statusbar("%s %s", toggles[which].desc, enabled);
2152 else
2153 statusbar("%s %s", toggles[which].desc, disabled);
2154 } else {
2155 if (toggles[which].val == TOGGLE_NOHELP_KEY ||
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00002156 toggles[which].val == TOGGLE_WRAP_KEY)
Chris Allegretta2a42af12000-09-12 23:02:49 +00002157 statusbar("%s %s", toggles[which].desc, disabled);
2158 else
2159 statusbar("%s %s", toggles[which].desc, enabled);
2160 }
Chris Allegretta756f2202000-09-01 13:32:47 +00002161 SET(DISABLE_CURPOS);
2162
2163#endif
2164}
2165
Chris Allegretta201d9bf2001-01-14 03:17:53 +00002166/* If the NumLock key has made the keypad gone awry, print an error
2167 message, hopefully we can address it later. */
2168void print_numlock_warning(void)
2169{
2170 static int didmsg = 0;
2171 if (!didmsg) {
Chris Allegretta6b58acd2001-04-12 03:01:53 +00002172 statusbar(_
2173 ("NumLock glitch detected. Keypad will malfunction with NumLock off"));
Chris Allegretta201d9bf2001-01-14 03:17:53 +00002174 didmsg = 1;
2175 }
2176}
2177
Chris Allegretta1748cd12001-01-13 17:22:54 +00002178/* This function returns the correct keystroke, given the A,B,C or D
2179 input key. This is a common sequence of many terms which send
2180 Esc-O-[A-D] or Esc-[-[A-D]. */
2181int ABCD(int input)
2182{
Chris Allegretta6b58acd2001-04-12 03:01:53 +00002183 switch (input) {
2184 case 'A':
Chris Allegretta316e4d92001-04-28 16:31:19 +00002185 case 'a':
Chris Allegretta6b58acd2001-04-12 03:01:53 +00002186 return (KEY_UP);
2187 case 'B':
Chris Allegretta316e4d92001-04-28 16:31:19 +00002188 case 'b':
Chris Allegretta6b58acd2001-04-12 03:01:53 +00002189 return (KEY_DOWN);
2190 case 'C':
Chris Allegretta316e4d92001-04-28 16:31:19 +00002191 case 'c':
Chris Allegretta6b58acd2001-04-12 03:01:53 +00002192 return (KEY_RIGHT);
2193 case 'D':
Chris Allegretta316e4d92001-04-28 16:31:19 +00002194 case 'd':
Chris Allegretta6b58acd2001-04-12 03:01:53 +00002195 return (KEY_LEFT);
2196 default:
2197 return 0;
Chris Allegretta1748cd12001-01-13 17:22:54 +00002198 }
2199}
2200
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002201int main(int argc, char *argv[])
2202{
2203 int optchr;
2204 int kbinput; /* Input from keyboard */
2205 long startline = 0; /* Line to try and start at */
Chris Allegretta08020882001-01-29 23:37:54 +00002206 int keyhandled; /* Have we handled the keystroke yet? */
2207 int i, modify_control_seq;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002208 char *argv0;
Chris Allegrettaad1dacc2000-09-21 04:25:45 +00002209#ifdef _POSIX_VDISABLE
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002210 struct termios term;
Chris Allegrettaad1dacc2000-09-21 04:25:45 +00002211#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002212
2213#ifdef HAVE_GETOPT_LONG
2214 int option_index = 0;
2215 struct option long_options[] = {
Chris Allegretta805c26d2000-09-06 13:39:17 +00002216#ifdef HAVE_REGEX_H
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00002217 {"regexp", 0, 0, 'R'},
Chris Allegretta47805612000-07-07 02:35:34 +00002218#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002219 {"version", 0, 0, 'V'},
2220 {"const", 0, 0, 'c'},
2221 {"suspend", 0, 0, 'z'},
2222 {"nowrap", 0, 0, 'w'},
2223 {"nohelp", 0, 0, 'x'},
2224 {"help", 0, 0, 'h'},
Chris Allegretta7492cec2000-12-18 04:55:21 +00002225 {"view", 0, 0, 'v'},
Chris Allegrettad19e9912000-07-12 18:14:51 +00002226#ifndef NANO_SMALL
Chris Allegretta627de192000-07-12 02:09:17 +00002227 {"cut", 0, 0, 'k'},
Chris Allegrettad19e9912000-07-12 18:14:51 +00002228#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002229 {"autoindent", 0, 0, 'i'},
2230 {"tempfile", 0, 0, 't'},
Rocco Corsiaf5c3022001-01-12 07:51:05 +00002231#ifndef DISABLE_SPELLER
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002232 {"speller", 1, 0, 's'},
Rocco Corsiaf5c3022001-01-12 07:51:05 +00002233#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002234 {"fill", 1, 0, 'r'},
2235 {"mouse", 0, 0, 'm'},
2236 {"pico", 0, 0, 'p'},
2237 {"nofollow", 0, 0, 'l'},
Chris Allegretta4dbcc3c2000-08-04 15:44:29 +00002238 {"tabsize", 1, 0, 'T'},
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002239 {0, 0, 0, 0}
2240 };
2241#endif
2242
2243 /* Flag inits... */
2244 SET(FOLLOW_SYMLINKS);
2245
2246#ifndef NANO_SMALL
Chris Allegretta8bc03b62001-02-09 02:57:52 +00002247#ifdef ENABLE_NLS
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002248 setlocale(LC_ALL, "");
2249 bindtextdomain(PACKAGE, LOCALEDIR);
2250 textdomain(PACKAGE);
2251#endif
Chris Allegretta8bc03b62001-02-09 02:57:52 +00002252#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002253
Chris Allegretta8d8e0122001-04-18 04:28:54 +00002254#ifdef ENABLE_NANORC
2255 do_rcfile();
2256#endif /* ENABLE_NANORC */
2257
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002258#ifdef HAVE_GETOPT_LONG
Rocco Corsi12f294c2001-04-14 06:50:24 +00002259 while ((optchr = getopt_long(argc, argv, "?T:RVbcefghijklmpr:s:tvwxz",
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002260 long_options, &option_index)) != EOF) {
2261#else
Chris Allegretta6b58acd2001-04-12 03:01:53 +00002262 while ((optchr =
Rocco Corsi12f294c2001-04-14 06:50:24 +00002263 getopt(argc, argv, "h?T:RVbcefgijklmpr:s:tvwxz")) != EOF) {
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002264#endif
2265
2266 switch (optchr) {
Chris Allegretta6724a7e2000-06-19 23:19:07 +00002267 case 'T':
Chris Allegretta99bf73f2000-08-04 00:22:08 +00002268 tabsize = atoi(optarg);
2269 if (tabsize <= 0) {
Chris Allegretta6724a7e2000-06-19 23:19:07 +00002270 usage(); /* To stop bogus data for tab width */
2271 finish(1);
2272 }
2273 break;
Chris Allegretta805c26d2000-09-06 13:39:17 +00002274#ifdef HAVE_REGEX_H
Chris Allegretta9fc8d432000-07-07 01:49:52 +00002275 case 'R':
2276 SET(USE_REGEXP);
2277 break;
Chris Allegretta47805612000-07-07 02:35:34 +00002278#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002279 case 'V':
2280 version();
2281 exit(0);
Chris Allegretta51b3eec2000-12-18 02:23:50 +00002282 case 'b':
2283 case 'e':
2284 case 'f':
Rocco Corsi12f294c2001-04-14 06:50:24 +00002285 case 'g':
2286 case 'j':
Chris Allegretta6b58acd2001-04-12 03:01:53 +00002287 /* Pico compatibility flags */
2288 break;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002289 case 'c':
2290 SET(CONSTUPDATE);
2291 break;
2292 case 'h':
2293 case '?':
2294 usage();
2295 exit(0);
2296 case 'i':
2297 SET(AUTOINDENT);
2298 break;
Chris Allegrettad19e9912000-07-12 18:14:51 +00002299#ifndef NANO_SMALL
Chris Allegretta627de192000-07-12 02:09:17 +00002300 case 'k':
2301 SET(CUT_TO_END);
2302 break;
Chris Allegrettad19e9912000-07-12 18:14:51 +00002303#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002304 case 'l':
2305 UNSET(FOLLOW_SYMLINKS);
2306 break;
2307 case 'm':
2308 SET(USE_MOUSE);
2309 break;
2310 case 'p':
Chris Allegrettabf9a8cc2000-11-17 01:37:39 +00002311 SET(PICO_MODE);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002312 break;
2313 case 'r':
2314 fill = atoi(optarg);
2315 if (fill <= 0) {
2316 usage(); /* To stop bogus data (like a string) */
2317 finish(1);
2318 }
2319 break;
Rocco Corsiaf5c3022001-01-12 07:51:05 +00002320#ifndef DISABLE_SPELLER
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002321 case 's':
2322 alt_speller = nmalloc(strlen(optarg) + 1);
2323 strcpy(alt_speller, optarg);
2324 break;
Rocco Corsiaf5c3022001-01-12 07:51:05 +00002325#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002326 case 't':
Chris Allegretta30885552000-07-14 01:20:12 +00002327 SET(TEMP_OPT);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002328 break;
2329 case 'v':
2330 SET(VIEW_MODE);
2331 break;
2332 case 'w':
Chris Allegrettacef7fbb2001-04-02 05:36:08 +00002333#ifdef DISABLE_WRAPPING
2334 usage();
2335 exit(0);
2336#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002337 SET(NO_WRAP);
2338 break;
Chris Allegretta6b58acd2001-04-12 03:01:53 +00002339#endif /* DISABLE_WRAPPING */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002340 case 'x':
2341 SET(NO_HELP);
2342 break;
2343 case 'z':
2344 SET(SUSPEND);
2345 break;
2346 default:
2347 usage();
Chris Allegretta4da1fc62000-06-21 03:00:43 +00002348 exit(0);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002349 }
2350
2351 }
2352
2353 argv0 = strrchr(argv[0], '/');
2354 if ((argv0 && strstr(argv0, "pico"))
2355 || (!argv0 && strstr(argv[0], "pico")))
Chris Allegrettabf9a8cc2000-11-17 01:37:39 +00002356 SET(PICO_MODE);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002357
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002358 /* See if there's a non-option in argv (first non-option is the
2359 filename, if +LINE is not given) */
2360 if (argc == 1 || argc <= optind)
Chris Allegretta1a6e9042000-12-14 13:56:28 +00002361 clear_filename();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002362 else {
2363 /* Look for the +line flag... */
2364 if (argv[optind][0] == '+') {
2365 startline = atoi(&argv[optind][1]);
2366 optind++;
2367 if (argc == 1 || argc <= optind)
Chris Allegretta1a6e9042000-12-14 13:56:28 +00002368 clear_filename();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002369 else
Chris Allegretta1a6e9042000-12-14 13:56:28 +00002370 filename = mallocstrcpy(filename, argv[optind]);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002371
Chris Allegretta1a6e9042000-12-14 13:56:28 +00002372 } else
2373 filename = mallocstrcpy(filename, argv[optind]);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002374 }
2375
2376
2377 /* First back up the old settings so they can be restored, duh */
Chris Allegretta4da1fc62000-06-21 03:00:43 +00002378 tcgetattr(0, &oldterm);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002379
Chris Allegretta9239d742000-09-06 15:19:18 +00002380#ifdef _POSIX_VDISABLE
Chris Allegretta8f6c0692000-07-19 01:16:18 +00002381 term = oldterm;
2382 term.c_cc[VINTR] = _POSIX_VDISABLE;
2383 term.c_cc[VQUIT] = _POSIX_VDISABLE;
2384 term.c_lflag &= ~IEXTEN;
Chris Allegretta4da1fc62000-06-21 03:00:43 +00002385 tcsetattr(0, TCSANOW, &term);
Chris Allegretta9239d742000-09-06 15:19:18 +00002386#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002387
2388 /* now ncurses init stuff... */
2389 initscr();
2390 savetty();
2391 nonl();
2392 cbreak();
2393 noecho();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002394
2395 /* Set up some global variables */
2396 global_init();
Chris Allegretta07798352000-11-27 22:58:23 +00002397 shortcut_init(0);
Rocco Corsiaf5c3022001-01-12 07:51:05 +00002398#ifndef DISABLE_HELP
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002399 init_help_msg();
2400 help_init();
Chris Allegretta3bc8c722000-12-10 17:03:25 +00002401#endif
Chris Allegretta756f2202000-09-01 13:32:47 +00002402 signal_init();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002403
2404#ifdef DEBUG
2405 fprintf(stderr, _("Main: set up windows\n"));
2406#endif
2407
Chris Allegretta8ce24132001-04-30 11:28:46 +00002408#ifdef ENABLE_COLOR
2409 do_colorinit();
2410#endif /* ENABLE_COLOR */
2411
Chris Allegretta2a42af12000-09-12 23:02:49 +00002412 window_init();
Chris Allegretta756f2202000-09-01 13:32:47 +00002413 mouse_init();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002414
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002415#ifdef DEBUG
2416 fprintf(stderr, _("Main: bottom win\n"));
2417#endif
2418 /* Set up up bottom of window */
2419 display_main_list();
2420
2421#ifdef DEBUG
2422 fprintf(stderr, _("Main: open file\n"));
2423#endif
2424
Chris Allegrettaf4b96012001-01-03 07:11:47 +00002425 titlebar(NULL);
Chris Allegretta31c76662000-11-21 06:20:20 +00002426
2427 /* Now we check to see if argv[optind] is non-null to determine if
2428 we're dealing with a new file or not, not argc == 1... */
2429 if (argv[optind] == NULL)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002430 new_file();
2431 else
2432 open_file(filename, 0, 0);
2433
2434 if (startline > 0)
2435 do_gotoline(startline);
2436 else
Chris Allegretta234a34d2000-07-29 04:33:38 +00002437 edit_update(fileage, CENTER);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002438
Chris Allegretta08020882001-01-29 23:37:54 +00002439 /* return here after a sigwinch */
Chris Allegretta6b58acd2001-04-12 03:01:53 +00002440 sigsetjmp(jmpbuf, 1);
Chris Allegretta08020882001-01-29 23:37:54 +00002441
2442 /* Fix clobber-age */
2443 kbinput = 0;
2444 keyhandled = 0;
2445 modify_control_seq = 0;
2446
Robert Siemborski6967eec2000-07-08 14:23:32 +00002447 edit_refresh();
2448 reset_cursor();
2449
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002450 while (1) {
Chris Allegretta9239d742000-09-06 15:19:18 +00002451
Chris Allegretta6b58acd2001-04-12 03:01:53 +00002452 currshortcut = main_list;
2453 currslen = MAIN_VISIBLE;
2454
Chris Allegretta9239d742000-09-06 15:19:18 +00002455#ifndef _POSIX_VDISABLE
2456 /* We're going to have to do it the old way, i.e. on cygwin */
2457 raw();
2458#endif
2459
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002460 kbinput = wgetch(edit);
Chris Allegrettac08f50d2001-01-06 18:12:43 +00002461#ifdef DEBUG
2462 fprintf(stderr, "AHA! %c (%d)\n", kbinput, kbinput);
2463#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002464 if (kbinput == 27) { /* Grab Alt-key stuff first */
2465 switch (kbinput = wgetch(edit)) {
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00002466 /* Alt-O, suddenly very important ;) */
Chris Allegretta16e41682000-09-11 22:33:54 +00002467 case 79:
2468 kbinput = wgetch(edit);
Chris Allegretta316e4d92001-04-28 16:31:19 +00002469 if ((kbinput <= 'D' && kbinput >= 'A') ||
2470 (kbinput <= 'd' && kbinput >= 'a'))
Chris Allegretta6b58acd2001-04-12 03:01:53 +00002471 kbinput = ABCD(kbinput);
Chris Allegretta201d9bf2001-01-14 03:17:53 +00002472 else if (kbinput <= 'z' && kbinput >= 'j')
2473 print_numlock_warning();
2474 else if (kbinput <= 'S' && kbinput >= 'P')
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00002475 kbinput = KEY_F(kbinput - 79);
Chris Allegretta16e41682000-09-11 22:33:54 +00002476#ifdef DEBUG
2477 else {
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00002478 fprintf(stderr, _("I got Alt-O-%c! (%d)\n"),
2479 kbinput, kbinput);
2480 break;
Chris Allegretta16e41682000-09-11 22:33:54 +00002481 }
2482#endif
2483 break;
Chris Allegretta51b3eec2000-12-18 02:23:50 +00002484 case 27:
2485 /* If we get Alt-Alt, the next keystroke should be the same as a
2486 control sequence */
2487 modify_control_seq = 1;
2488 keyhandled = 1;
2489 break;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002490 case 91:
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002491 switch (kbinput = wgetch(edit)) {
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00002492 case '1': /* Alt-[-1-[0-5,7-9] = F1-F8 in X at least */
Chris Allegretta16e41682000-09-11 22:33:54 +00002493 kbinput = wgetch(edit);
2494 if (kbinput >= '1' && kbinput <= '5') {
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00002495 kbinput = KEY_F(kbinput - 48);
2496 wgetch(edit);
2497 } else if (kbinput >= '7' && kbinput <= '9') {
2498 kbinput = KEY_F(kbinput - 49);
2499 wgetch(edit);
2500 } else if (kbinput == 126)
2501 kbinput = KEY_HOME;
Chris Allegretta16e41682000-09-11 22:33:54 +00002502
2503#ifdef DEBUG
2504 else {
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00002505 fprintf(stderr, _("I got Alt-[-1-%c! (%d)\n"),
2506 kbinput, kbinput);
2507 break;
Chris Allegretta16e41682000-09-11 22:33:54 +00002508 }
2509#endif
2510
2511 break;
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00002512 case '2': /* Alt-[-2-[0,1,3,4] = F9-F12 in many terms */
Chris Allegretta16e41682000-09-11 22:33:54 +00002513 kbinput = wgetch(edit);
Chris Allegretta16e41682000-09-11 22:33:54 +00002514 switch (kbinput) {
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00002515 case '0':
2516 kbinput = KEY_F(9);
2517 wgetch(edit);
2518 break;
2519 case '1':
2520 kbinput = KEY_F(10);
2521 wgetch(edit);
2522 break;
2523 case '3':
2524 kbinput = KEY_F(11);
2525 wgetch(edit);
2526 break;
2527 case '4':
2528 kbinput = KEY_F(12);
2529 wgetch(edit);
2530 break;
2531 case 126: /* Hack, make insert key do something
2532 usefile, like insert file */
2533 do_insertfile();
2534 keyhandled = 1;
2535 break;
Chris Allegretta16e41682000-09-11 22:33:54 +00002536#ifdef DEBUG
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00002537 default:
2538 fprintf(stderr, _("I got Alt-[-2-%c! (%d)\n"),
2539 kbinput, kbinput);
2540 break;
Chris Allegretta16e41682000-09-11 22:33:54 +00002541#endif
2542
2543 }
2544 break;
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00002545 case '3': /* Alt-[-3 = Delete? */
Chris Allegretta16e41682000-09-11 22:33:54 +00002546 kbinput = NANO_DELETE_KEY;
2547 wgetch(edit);
2548 break;
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00002549 case '4': /* Alt-[-4 = End? */
Chris Allegretta16e41682000-09-11 22:33:54 +00002550 kbinput = NANO_END_KEY;
2551 wgetch(edit);
2552 break;
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00002553 case '5': /* Alt-[-5 = Page Up */
Chris Allegretta16e41682000-09-11 22:33:54 +00002554 kbinput = KEY_PPAGE;
2555 wgetch(edit);
2556 break;
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00002557 case '6': /* Alt-[-6 = Page Down */
Chris Allegretta16e41682000-09-11 22:33:54 +00002558 kbinput = KEY_NPAGE;
2559 wgetch(edit);
2560 break;
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00002561 case '[': /* Alt-[-[-[A-E], F1-F5 in linux console */
Chris Allegretta16e41682000-09-11 22:33:54 +00002562 kbinput = wgetch(edit);
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00002563 if (kbinput >= 'A' && kbinput <= 'E')
2564 kbinput = KEY_F(kbinput - 64);
Chris Allegretta16e41682000-09-11 22:33:54 +00002565 break;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002566 case 'A':
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002567 case 'B':
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002568 case 'C':
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002569 case 'D':
Chris Allegretta316e4d92001-04-28 16:31:19 +00002570 case 'a':
2571 case 'b':
2572 case 'c':
2573 case 'd':
Chris Allegretta1748cd12001-01-13 17:22:54 +00002574 kbinput = ABCD(kbinput);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002575 break;
2576 case 'H':
2577 kbinput = KEY_HOME;
2578 break;
2579 case 'F':
2580 kbinput = KEY_END;
2581 break;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002582 default:
2583#ifdef DEBUG
2584 fprintf(stderr, _("I got Alt-[-%c! (%d)\n"),
2585 kbinput, kbinput);
2586#endif
2587 break;
2588 }
2589 break;
2590 default:
2591
2592 /* Check for the altkey defs.... */
2593 for (i = 0; i <= MAIN_LIST_LEN - 1; i++)
2594 if (kbinput == main_list[i].altval ||
2595 kbinput == main_list[i].altval - 32) {
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00002596 kbinput = main_list[i].val;
2597 break;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002598 }
Chris Allegretta756f2202000-09-01 13:32:47 +00002599#ifndef NANO_SMALL
2600 /* And for toggle switches */
2601 for (i = 0; i <= TOGGLE_LEN - 1 && !keyhandled; i++)
2602 if (kbinput == toggles[i].val ||
2603 kbinput == toggles[i].val - 32) {
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00002604 do_toggle(i);
2605 keyhandled = 1;
2606 break;
Chris Allegretta756f2202000-09-01 13:32:47 +00002607 }
2608#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002609#ifdef DEBUG
2610 fprintf(stderr, _("I got Alt-%c! (%d)\n"), kbinput,
2611 kbinput);
2612#endif
2613 break;
2614 }
2615 }
Chris Allegretta51b3eec2000-12-18 02:23:50 +00002616 /* If the modify_control_seq is set, we received an Alt-Alt
2617 sequence before this, so we make this key a control sequence
2618 by subtracting 64 or 96, depending on its value. */
2619 if (!keyhandled && modify_control_seq) {
2620 if (kbinput >= 'A' && kbinput < 'a')
2621 kbinput -= 64;
2622 else if (kbinput >= 'a' && kbinput <= 'z')
2623 kbinput -= 96;
2624
2625 modify_control_seq = 0;
2626 }
2627
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002628 /* Look through the main shortcut list to see if we've hit a
2629 shortcut key */
Chris Allegretta756f2202000-09-01 13:32:47 +00002630 for (i = 0; i < MAIN_LIST_LEN && !keyhandled; i++) {
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002631 if (kbinput == main_list[i].val ||
2632 (main_list[i].misc1 && kbinput == main_list[i].misc1) ||
2633 (main_list[i].misc2 && kbinput == main_list[i].misc2)) {
2634 if (ISSET(VIEW_MODE) && !main_list[i].viewok)
2635 print_view_warning();
2636 else
2637 main_list[i].func();
2638 keyhandled = 1;
2639 }
2640 }
Chris Allegretta51b3eec2000-12-18 02:23:50 +00002641 /* If we're in raw mode or using Alt-Alt-x, we have to catch
2642 Control-S and Control-Q */
Chris Allegretta9239d742000-09-06 15:19:18 +00002643 if (kbinput == 17 || kbinput == 19)
2644 keyhandled = 1;
2645
Chris Allegretta51b3eec2000-12-18 02:23:50 +00002646 /* Catch ^Z by hand when triggered also */
Chris Allegretta9239d742000-09-06 15:19:18 +00002647 if (kbinput == 26) {
2648 if (ISSET(SUSPEND))
2649 do_suspend(0);
2650 keyhandled = 1;
2651 }
Chris Allegretta9239d742000-09-06 15:19:18 +00002652
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002653 /* Last gasp, stuff that's not in the main lists */
2654 if (!keyhandled)
2655 switch (kbinput) {
Chris Allegretta84de5522001-04-12 14:51:48 +00002656#ifndef DISABLE_MOUSE
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002657#ifdef NCURSES_MOUSE_VERSION
2658 case KEY_MOUSE:
2659 do_mouse();
2660 break;
2661#endif
2662#endif
2663 case 0: /* Erg */
2664 do_next_word();
2665 break;
Chris Allegrettaf4f7e042001-01-04 16:56:15 +00002666
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002667 case 331: /* Stuff that we don't want to do squat */
2668 case -1:
2669 case 410: /* Must ignore this, it gets sent when we resize */
Chris Allegrettaad1dacc2000-09-21 04:25:45 +00002670#ifdef PDCURSES
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00002671 case 541: /* ???? */
2672 case 542: /* Control and alt in Windows *shrug* */
Chris Allegretta72623582000-11-29 23:43:28 +00002673 case 543: /* Right ctrl key */
Chris Allegrettaad1dacc2000-09-21 04:25:45 +00002674 case 544:
Chris Allegretta72623582000-11-29 23:43:28 +00002675 case 545: /* Right alt key */
Chris Allegrettaad1dacc2000-09-21 04:25:45 +00002676#endif
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00002677
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002678 break;
2679 default:
2680#ifdef DEBUG
2681 fprintf(stderr, "I got %c (%d)!\n", kbinput, kbinput);
2682#endif
2683 /* We no longer stop unhandled sequences so that people with
2684 odd character sets can type... */
2685
2686 if (ISSET(VIEW_MODE)) {
2687 print_view_warning();
2688 break;
2689 }
2690 do_char(kbinput);
2691 }
Chris Allegretta756f2202000-09-01 13:32:47 +00002692 if (ISSET(CONSTUPDATE)) {
2693 if (ISSET(DISABLE_CURPOS))
2694 UNSET(DISABLE_CURPOS);
2695 else
2696 do_cursorpos();
2697 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002698
2699 reset_cursor();
2700 wrefresh(edit);
2701 keyhandled = 0;
2702 }
2703
2704 getchar();
2705 finish(0);
2706
2707}