blob: 73cb0877cb1433a76c84c9a2f26c40b670fa33c3 [file] [log] [blame]
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001/**************************************************************************
Benno Schulenberg514cd9a2016-08-29 17:10:49 +02002 * nano.c -- This file is part of GNU nano. *
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00003 * *
Chris Allegretta8a07a962009-12-02 03:36:22 +00004 * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
Benno Schulenberg7a9f4a42014-04-30 20:18:26 +00005 * 2008, 2009, 2010, 2011, 2013, 2014 Free Software Foundation, Inc. *
Benno Schulenberg406e5242016-08-29 15:14:18 +02006 * Copyright (C) 2014, 2015, 2016 Benno Schulenberg *
7 * *
Benno Schulenberg514cd9a2016-08-29 17:10:49 +02008 * GNU nano is free software: you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published *
10 * by the Free Software Foundation, either version 3 of the License, *
11 * or (at your option) any later version. *
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000012 * *
Benno Schulenberg514cd9a2016-08-29 17:10:49 +020013 * GNU nano is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty *
15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
16 * See the GNU General Public License for more details. *
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000017 * *
18 * You should have received a copy of the GNU General Public License *
Benno Schulenberg514cd9a2016-08-29 17:10:49 +020019 * along with this program. If not, see http://www.gnu.org/licenses/. *
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000020 * *
21 **************************************************************************/
22
David Lawrence Ramsey034b9942005-12-08 02:47:10 +000023#include "proto.h"
Benno Schulenberg2ae490c2016-05-20 12:59:57 +020024#include "revision.h"
Chris Allegretta6efda542001-04-28 18:03:52 +000025
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000026#include <stdio.h>
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000027#include <stdarg.h>
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000028#include <unistd.h>
29#include <string.h>
30#include <fcntl.h>
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000031#include <errno.h>
32#include <ctype.h>
33#include <locale.h>
Chris Allegrettab8576782008-07-12 02:32:19 +000034#ifdef ENABLE_UTF8
David Lawrence Ramseya78b4352007-05-25 14:39:40 +000035#include <langinfo.h>
Chris Allegrettab8576782008-07-12 02:32:19 +000036#endif
David Lawrence Ramseyce029f22005-12-28 05:01:00 +000037#include <termios.h>
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000038#ifdef HAVE_GETOPT_H
39#include <getopt.h>
40#endif
David Lawrence Ramsey82697f22006-07-12 18:57:04 +000041#ifndef NANO_TINY
42#include <sys/ioctl.h>
43#endif
44
David Lawrence Ramsey9bd537f2007-12-04 20:49:09 +000045#ifndef DISABLE_MOUSE
46static int oldinterval = -1;
47 /* Used to store the user's original mouse click interval. */
48#endif
Benno Schulenbergeea09082014-04-13 20:50:20 +000049#ifndef DISABLE_NANORC
David Lawrence Ramsey18dae622006-04-24 18:54:29 +000050static bool no_rcfiles = FALSE;
51 /* Should we ignore all rcfiles? */
52#endif
David Lawrence Ramsey6d6a36c2005-12-08 07:09:08 +000053static struct termios oldterm;
54 /* The user's original terminal settings. */
55static struct sigaction act;
David Lawrence Ramsey6335fb52007-01-01 05:15:32 +000056 /* Used to set up all our fun signal handlers. */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000057
David Lawrence Ramseya1b69972006-08-29 21:18:24 +000058/* Create a new filestruct node. Note that we do not set prevnode->next
59 * to the new line. */
David Lawrence Ramsey90573292005-07-08 02:47:05 +000060filestruct *make_new_node(filestruct *prevnode)
61{
62 filestruct *newnode = (filestruct *)nmalloc(sizeof(filestruct));
63
64 newnode->data = NULL;
65 newnode->prev = prevnode;
66 newnode->next = NULL;
67 newnode->lineno = (prevnode != NULL) ? prevnode->lineno + 1 : 1;
68
Benno Schulenberg00389922014-04-04 11:59:03 +000069#ifndef DISABLE_COLOR
Chris Allegretta364763f2009-02-03 05:05:58 +000070 newnode->multidata = NULL;
Chris Allegrettaa1171632009-01-19 19:10:39 +000071#endif
72
David Lawrence Ramsey90573292005-07-08 02:47:05 +000073 return newnode;
74}
75
76/* Make a copy of a filestruct node. */
77filestruct *copy_node(const filestruct *src)
78{
79 filestruct *dst;
80
David Lawrence Ramsey90573292005-07-08 02:47:05 +000081 dst = (filestruct *)nmalloc(sizeof(filestruct));
82
83 dst->data = mallocstrcpy(NULL, src->data);
84 dst->next = src->next;
85 dst->prev = src->prev;
86 dst->lineno = src->lineno;
Benno Schulenberg00389922014-04-04 11:59:03 +000087#ifndef DISABLE_COLOR
Chris Allegretta364763f2009-02-03 05:05:58 +000088 dst->multidata = NULL;
Chris Allegrettad47d8cd2009-01-25 07:25:17 +000089#endif
David Lawrence Ramsey90573292005-07-08 02:47:05 +000090
91 return dst;
92}
93
Benno Schulenberge0d0ca42015-11-24 13:28:32 +000094/* Splice a new node into an existing linked list of filestructs. */
95void splice_node(filestruct *afterthis, filestruct *newnode)
David Lawrence Ramsey90573292005-07-08 02:47:05 +000096{
Benno Schulenberge0d0ca42015-11-24 13:28:32 +000097 newnode->next = afterthis->next;
98 newnode->prev = afterthis;
99 if (afterthis->next != NULL)
100 afterthis->next->prev = newnode;
101 afterthis->next = newnode;
Benno Schulenberg77c03572015-12-08 15:29:56 +0000102
103 /* Update filebot when inserting a node at the end of file. */
104 if (openfile && openfile->filebot == afterthis)
105 openfile->filebot = newnode;
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000106}
107
Benno Schulenberga64bfbe2015-12-08 16:02:05 +0000108/* Disconnect a node from a linked list of filestructs and delete it. */
Benno Schulenberg72caa542015-11-22 16:14:42 +0000109void unlink_node(filestruct *fileptr)
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000110{
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000111 if (fileptr->prev != NULL)
112 fileptr->prev->next = fileptr->next;
113 if (fileptr->next != NULL)
114 fileptr->next->prev = fileptr->prev;
Benno Schulenberg72caa542015-11-22 16:14:42 +0000115
Benno Schulenberga64bfbe2015-12-08 16:02:05 +0000116 /* Update filebot when removing a node at the end of file. */
117 if (openfile && openfile->filebot == fileptr)
118 openfile->filebot = fileptr->prev;
119
Benno Schulenberg72caa542015-11-22 16:14:42 +0000120 delete_node(fileptr);
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000121}
122
Benno Schulenberga64bfbe2015-12-08 16:02:05 +0000123/* Free the data structures in the given node. */
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000124void delete_node(filestruct *fileptr)
125{
Benno Schulenbergc32a58a2015-06-14 19:14:41 +0000126 free(fileptr->data);
Benno Schulenberg00389922014-04-04 11:59:03 +0000127#ifndef DISABLE_COLOR
Benno Schulenbergc32a58a2015-06-14 19:14:41 +0000128 free(fileptr->multidata);
Chris Allegrettad47d8cd2009-01-25 07:25:17 +0000129#endif
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000130 free(fileptr);
131}
132
133/* Duplicate a whole filestruct. */
134filestruct *copy_filestruct(const filestruct *src)
135{
136 filestruct *head, *copy;
137
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000138 copy = copy_node(src);
139 copy->prev = NULL;
140 head = copy;
141 src = src->next;
142
143 while (src != NULL) {
144 copy->next = copy_node(src);
145 copy->next->prev = copy;
146 copy = copy->next;
147
148 src = src->next;
149 }
David Lawrence Ramsey826fbea2005-07-19 04:50:55 +0000150
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000151 copy->next = NULL;
152
153 return head;
154}
155
Benno Schulenberg97039342016-02-18 19:58:18 +0000156/* Free a whole linked list of filestructs. */
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000157void free_filestruct(filestruct *src)
158{
Benno Schulenberg97039342016-02-18 19:58:18 +0000159 if (src == NULL)
160 return;
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000161
162 while (src->next != NULL) {
163 src = src->next;
164 delete_node(src->prev);
165 }
David Lawrence Ramsey826fbea2005-07-19 04:50:55 +0000166
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000167 delete_node(src);
168}
169
David Lawrence Ramseyc104ef12005-07-17 01:44:35 +0000170/* Renumber all entries in a filestruct, starting with fileptr. */
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000171void renumber(filestruct *fileptr)
172{
David Lawrence Ramseydbcaa3b2005-07-08 20:59:24 +0000173 ssize_t line;
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000174
Benno Schulenberg4d9b5e92015-03-14 15:59:01 +0000175 if (fileptr == NULL)
176 return;
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000177
David Lawrence Ramsey26ee7592005-07-15 00:08:23 +0000178 line = (fileptr->prev == NULL) ? 0 : fileptr->prev->lineno;
David Lawrence Ramseydbcaa3b2005-07-08 20:59:24 +0000179
180 assert(fileptr != fileptr->next);
181
182 for (; fileptr != NULL; fileptr = fileptr->next)
David Lawrence Ramsey05322962005-07-14 23:51:52 +0000183 fileptr->lineno = ++line;
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000184}
185
David Lawrence Ramseye44cd2d2007-01-11 22:54:55 +0000186/* Partition a filestruct so that it begins at (top, top_x) and ends at
187 * (bot, bot_x). */
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000188partition *partition_filestruct(filestruct *top, size_t top_x,
189 filestruct *bot, size_t bot_x)
190{
191 partition *p;
192
David Lawrence Ramsey6ad59cd2005-07-08 20:09:16 +0000193 assert(top != NULL && bot != NULL && openfile->fileage != NULL && openfile->filebot != NULL);
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000194
195 /* Initialize the partition. */
196 p = (partition *)nmalloc(sizeof(partition));
197
198 /* If the top and bottom of the partition are different from the top
199 * and bottom of the filestruct, save the latter and then set them
200 * to top and bot. */
David Lawrence Ramsey6ad59cd2005-07-08 20:09:16 +0000201 if (top != openfile->fileage) {
202 p->fileage = openfile->fileage;
203 openfile->fileage = top;
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000204 } else
205 p->fileage = NULL;
David Lawrence Ramsey6ad59cd2005-07-08 20:09:16 +0000206 if (bot != openfile->filebot) {
207 p->filebot = openfile->filebot;
208 openfile->filebot = bot;
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000209 } else
210 p->filebot = NULL;
211
Benno Schulenberg95f417f2016-06-14 11:06:04 +0200212 /* Remember which line is above the top of the partition, detach the
213 * top of the partition from it, and save the text before top_x. */
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000214 p->top_prev = top->prev;
215 top->prev = NULL;
216 p->top_data = mallocstrncpy(NULL, top->data, top_x + 1);
217 p->top_data[top_x] = '\0';
218
Benno Schulenberg95f417f2016-06-14 11:06:04 +0200219 /* Remember which line is below the bottom of the partition, detach the
220 * bottom of the partition from it, and save the text after bot_x. */
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000221 p->bot_next = bot->next;
222 bot->next = NULL;
223 p->bot_data = mallocstrcpy(NULL, bot->data + bot_x);
224
225 /* Remove all text after bot_x at the bottom of the partition. */
226 null_at(&bot->data, bot_x);
227
228 /* Remove all text before top_x at the top of the partition. */
Benno Schulenberg95f417f2016-06-14 11:06:04 +0200229 charmove(top->data, top->data + top_x, strlen(top->data) - top_x + 1);
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000230
231 /* Return the partition. */
232 return p;
233}
234
David Lawrence Ramseye44cd2d2007-01-11 22:54:55 +0000235/* Unpartition a filestruct so that it begins at (fileage, 0) and ends
236 * at (filebot, strlen(filebot->data)) again. */
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000237void unpartition_filestruct(partition **p)
238{
David Lawrence Ramsey6ad59cd2005-07-08 20:09:16 +0000239 assert(p != NULL && openfile->fileage != NULL && openfile->filebot != NULL);
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000240
241 /* Reattach the line above the top of the partition, and restore the
242 * text before top_x from top_data. Free top_data when we're done
243 * with it. */
David Lawrence Ramsey6ad59cd2005-07-08 20:09:16 +0000244 openfile->fileage->prev = (*p)->top_prev;
245 if (openfile->fileage->prev != NULL)
246 openfile->fileage->prev->next = openfile->fileage;
247 openfile->fileage->data = charealloc(openfile->fileage->data,
Benno Schulenberg95f417f2016-06-14 11:06:04 +0200248 strlen((*p)->top_data) + strlen(openfile->fileage->data) + 1);
Benno Schulenberg80552ae2016-06-14 12:06:58 +0200249 charmove(openfile->fileage->data + strlen((*p)->top_data),
250 openfile->fileage->data, strlen(openfile->fileage->data) + 1);
251 strncpy(openfile->fileage->data, (*p)->top_data, strlen((*p)->top_data));
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000252 free((*p)->top_data);
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000253
254 /* Reattach the line below the bottom of the partition, and restore
255 * the text after bot_x from bot_data. Free bot_data when we're
256 * done with it. */
David Lawrence Ramsey6ad59cd2005-07-08 20:09:16 +0000257 openfile->filebot->next = (*p)->bot_next;
258 if (openfile->filebot->next != NULL)
259 openfile->filebot->next->prev = openfile->filebot;
260 openfile->filebot->data = charealloc(openfile->filebot->data,
Benno Schulenberg95f417f2016-06-14 11:06:04 +0200261 strlen(openfile->filebot->data) + strlen((*p)->bot_data) + 1);
David Lawrence Ramsey6ad59cd2005-07-08 20:09:16 +0000262 strcat(openfile->filebot->data, (*p)->bot_data);
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000263 free((*p)->bot_data);
264
265 /* Restore the top and bottom of the filestruct, if they were
266 * different from the top and bottom of the partition. */
267 if ((*p)->fileage != NULL)
David Lawrence Ramsey6ad59cd2005-07-08 20:09:16 +0000268 openfile->fileage = (*p)->fileage;
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000269 if ((*p)->filebot != NULL)
David Lawrence Ramsey6ad59cd2005-07-08 20:09:16 +0000270 openfile->filebot = (*p)->filebot;
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000271
272 /* Uninitialize the partition. */
273 free(*p);
274 *p = NULL;
275}
276
277/* Move all the text between (top, top_x) and (bot, bot_x) in the
278 * current filestruct to a filestruct beginning with file_top and ending
279 * with file_bot. If no text is between (top, top_x) and (bot, bot_x),
280 * don't do anything. */
David Lawrence Ramsey1cb945f2017-02-14 21:35:01 -0600281void extract_buffer(filestruct **file_top, filestruct **file_bot,
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000282 filestruct *top, size_t top_x, filestruct *bot, size_t bot_x)
283{
284 filestruct *top_save;
David Lawrence Ramseye4e61732005-09-02 04:35:58 +0000285 bool edittop_inside;
David Lawrence Ramseyebe34252005-11-15 03:17:35 +0000286#ifndef NANO_TINY
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000287 bool mark_inside = FALSE;
Benno Schulenberg72495072014-02-22 16:46:27 +0000288 bool same_line = FALSE;
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000289#endif
290
291 assert(file_top != NULL && file_bot != NULL && top != NULL && bot != NULL);
292
293 /* If (top, top_x)-(bot, bot_x) doesn't cover any text, get out. */
294 if (top == bot && top_x == bot_x)
295 return;
296
297 /* Partition the filestruct so that it contains only the text from
298 * (top, top_x) to (bot, bot_x), keep track of whether the top of
David Lawrence Ramseye4e61732005-09-02 04:35:58 +0000299 * the edit window is inside the partition, and keep track of
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000300 * whether the mark begins inside the partition. */
301 filepart = partition_filestruct(top, top_x, bot, bot_x);
Benno Schulenberg95f417f2016-06-14 11:06:04 +0200302 edittop_inside = (openfile->edittop->lineno >= openfile->fileage->lineno &&
303 openfile->edittop->lineno <= openfile->filebot->lineno);
David Lawrence Ramseyebe34252005-11-15 03:17:35 +0000304#ifndef NANO_TINY
Benno Schulenberg72495072014-02-22 16:46:27 +0000305 if (openfile->mark_set) {
David Lawrence Ramsey5128de82005-07-12 17:40:16 +0000306 mark_inside = (openfile->mark_begin->lineno >=
David Lawrence Ramsey6ad59cd2005-07-08 20:09:16 +0000307 openfile->fileage->lineno &&
David Lawrence Ramsey5128de82005-07-12 17:40:16 +0000308 openfile->mark_begin->lineno <=
David Lawrence Ramsey6ad59cd2005-07-08 20:09:16 +0000309 openfile->filebot->lineno &&
David Lawrence Ramsey5128de82005-07-12 17:40:16 +0000310 (openfile->mark_begin != openfile->fileage ||
311 openfile->mark_begin_x >= top_x) &&
312 (openfile->mark_begin != openfile->filebot ||
313 openfile->mark_begin_x <= bot_x));
Benno Schulenberg72495072014-02-22 16:46:27 +0000314 same_line = (openfile->mark_begin == openfile->fileage);
315 }
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000316#endif
317
Benno Schulenberg95f417f2016-06-14 11:06:04 +0200318 /* Subtract the number of characters in the text from the file size. */
David Lawrence Ramseyc104ef12005-07-17 01:44:35 +0000319 openfile->totsize -= get_totsize(top, bot);
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000320
321 if (*file_top == NULL) {
322 /* If file_top is empty, just move all the text directly into
323 * it. This is equivalent to tacking the text in top onto the
324 * (lack of) text at the end of file_top. */
David Lawrence Ramsey6ad59cd2005-07-08 20:09:16 +0000325 *file_top = openfile->fileage;
326 *file_bot = openfile->filebot;
David Lawrence Ramseyc104ef12005-07-17 01:44:35 +0000327
Benno Schulenberg95f417f2016-06-14 11:06:04 +0200328 /* Renumber, starting with file_top. */
David Lawrence Ramseyc104ef12005-07-17 01:44:35 +0000329 renumber(*file_top);
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000330 } else {
David Lawrence Ramseyc104ef12005-07-17 01:44:35 +0000331 filestruct *file_bot_save = *file_bot;
332
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000333 /* Otherwise, tack the text in top onto the text at the end of
334 * file_bot. */
335 (*file_bot)->data = charealloc((*file_bot)->data,
David Lawrence Ramsey6ad59cd2005-07-08 20:09:16 +0000336 strlen((*file_bot)->data) +
337 strlen(openfile->fileage->data) + 1);
338 strcat((*file_bot)->data, openfile->fileage->data);
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000339
340 /* Attach the line after top to the line after file_bot. Then,
341 * if there's more than one line after top, move file_bot down
342 * to bot. */
David Lawrence Ramsey6ad59cd2005-07-08 20:09:16 +0000343 (*file_bot)->next = openfile->fileage->next;
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000344 if ((*file_bot)->next != NULL) {
345 (*file_bot)->next->prev = *file_bot;
David Lawrence Ramsey6ad59cd2005-07-08 20:09:16 +0000346 *file_bot = openfile->filebot;
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000347 }
David Lawrence Ramseyc104ef12005-07-17 01:44:35 +0000348
Benno Schulenberg97039342016-02-18 19:58:18 +0000349 delete_node(openfile->fileage);
Benno Schulenberg2394e522014-07-16 08:46:42 +0000350
Benno Schulenberg95f417f2016-06-14 11:06:04 +0200351 /* Renumber, starting with the line after the original file_bot. */
Benno Schulenberg4d9b5e92015-03-14 15:59:01 +0000352 renumber(file_bot_save->next);
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000353 }
354
Benno Schulenberg95f417f2016-06-14 11:06:04 +0200355 /* Since the text has now been saved, remove it from the filestruct. */
David Lawrence Ramsey17f5c052017-02-09 16:00:07 -0600356 openfile->fileage = make_new_node(NULL);
David Lawrence Ramsey6ad59cd2005-07-08 20:09:16 +0000357 openfile->fileage->data = mallocstrcpy(NULL, "");
358 openfile->filebot = openfile->fileage;
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000359
David Lawrence Ramsey884ca532007-08-07 19:55:06 +0000360 /* Restore the current line and cursor position. If the mark begins
361 * inside the partition, set the beginning of the mark to where the
362 * saved text used to start. */
David Lawrence Ramsey6ad59cd2005-07-08 20:09:16 +0000363 openfile->current = openfile->fileage;
364 openfile->current_x = top_x;
David Lawrence Ramsey884ca532007-08-07 19:55:06 +0000365#ifndef NANO_TINY
366 if (mark_inside) {
367 openfile->mark_begin = openfile->current;
368 openfile->mark_begin_x = openfile->current_x;
Benno Schulenberg72495072014-02-22 16:46:27 +0000369 } else if (same_line)
Benno Schulenberg6007d622015-11-22 16:08:28 +0000370 /* Update the pointer to this partially cut line. */
Benno Schulenberg72495072014-02-22 16:46:27 +0000371 openfile->mark_begin = openfile->current;
David Lawrence Ramsey884ca532007-08-07 19:55:06 +0000372#endif
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000373
David Lawrence Ramsey6ad59cd2005-07-08 20:09:16 +0000374 top_save = openfile->fileage;
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000375
376 /* Unpartition the filestruct so that it contains all the text
377 * again, minus the saved text. */
378 unpartition_filestruct(&filepart);
379
David Lawrence Ramseye4e61732005-09-02 04:35:58 +0000380 /* If the top of the edit window was inside the old partition, put
381 * it in range of current. */
Benno Schulenbergb97c36c2016-04-25 20:05:21 +0200382 if (edittop_inside) {
Benno Schulenberg01bbf7e2016-10-20 21:11:11 +0200383 adjust_viewport(STATIONARY);
Benno Schulenberg53f4a9f2016-04-25 21:14:18 +0200384 refresh_needed = TRUE;
Benno Schulenbergb97c36c2016-04-25 20:05:21 +0200385 }
David Lawrence Ramseye4e61732005-09-02 04:35:58 +0000386
Benno Schulenberg95f417f2016-06-14 11:06:04 +0200387 /* Renumber, starting with the beginning line of the old partition. */
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000388 renumber(top_save);
389
Benno Schulenberg95f417f2016-06-14 11:06:04 +0200390 /* If the text doesn't end with a magicline, and it should, add one. */
David Lawrence Ramseya0168ca2005-11-05 17:35:44 +0000391 if (!ISSET(NO_NEWLINES) && openfile->filebot->data[0] != '\0')
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000392 new_magicline();
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000393}
394
David Lawrence Ramseya847d372017-02-10 00:17:33 -0600395/* Meld the given buffer into the current file buffer
Benno Schulenbergc8fbc7d2014-04-14 09:14:39 +0000396 * at the current cursor position. */
David Lawrence Ramseya847d372017-02-10 00:17:33 -0600397void ingraft_buffer(filestruct *somebuffer)
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000398{
399 filestruct *top_save;
David Lawrence Ramseyee894182007-08-16 03:23:30 +0000400 size_t current_x_save = openfile->current_x;
David Lawrence Ramseye4e61732005-09-02 04:35:58 +0000401 bool edittop_inside;
David Lawrence Ramseyd1ab89a2007-08-07 20:21:39 +0000402#ifndef NANO_TINY
David Lawrence Ramsey64b8f422007-08-16 14:45:17 +0000403 bool right_side_up = FALSE, single_line = FALSE;
David Lawrence Ramseyd1ab89a2007-08-07 20:21:39 +0000404#endif
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000405
Benno Schulenbergc8fbc7d2014-04-14 09:14:39 +0000406 assert(somebuffer != NULL);
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000407
David Lawrence Ramsey64b8f422007-08-16 14:45:17 +0000408#ifndef NANO_TINY
409 /* Keep track of whether the mark begins inside the partition and
410 * will need adjustment. */
411 if (openfile->mark_set) {
412 filestruct *top, *bot;
413 size_t top_x, bot_x;
414
415 mark_order((const filestruct **)&top, &top_x,
Benno Schulenberg95f417f2016-06-14 11:06:04 +0200416 (const filestruct **)&bot, &bot_x, &right_side_up);
David Lawrence Ramsey64b8f422007-08-16 14:45:17 +0000417
418 single_line = (top == bot);
419 }
420#endif
421
Benno Schulenberg95f417f2016-06-14 11:06:04 +0200422 /* Partition the filestruct so that it contains no text, and remember
Benno Schulenberg17fb6df2016-06-16 11:54:11 +0200423 * whether the current line is at the top of the edit window. */
Benno Schulenberg95f417f2016-06-14 11:06:04 +0200424 filepart = partition_filestruct(openfile->current, openfile->current_x,
425 openfile->current, openfile->current_x);
David Lawrence Ramseyd5a98002007-08-08 00:05:49 +0000426 edittop_inside = (openfile->edittop == openfile->fileage);
Benno Schulenberg17fb6df2016-06-16 11:54:11 +0200427 free_filestruct(openfile->fileage);
David Lawrence Ramseyd1ab89a2007-08-07 20:21:39 +0000428
Benno Schulenbergc8fbc7d2014-04-14 09:14:39 +0000429 /* Put the top and bottom of the current filestruct at the top and
David Lawrence Ramseya847d372017-02-10 00:17:33 -0600430 * bottom of the passed buffer. */
431 openfile->fileage = somebuffer;
David Lawrence Ramsey6ad59cd2005-07-08 20:09:16 +0000432 openfile->filebot = openfile->fileage;
433 while (openfile->filebot->next != NULL)
434 openfile->filebot = openfile->filebot->next;
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000435
Benno Schulenbergdf80bfd2015-10-31 20:17:09 +0000436 /* Put the cursor at the end of the pasted text. */
David Lawrence Ramsey6ad59cd2005-07-08 20:09:16 +0000437 openfile->current = openfile->filebot;
438 openfile->current_x = strlen(openfile->filebot->data);
Benno Schulenbergdf80bfd2015-10-31 20:17:09 +0000439
440 /* Refresh the mark's pointer, and compensate the mark's
441 * x coordinate for the change in the current line. */
David Lawrence Ramseyd1ab89a2007-08-07 20:21:39 +0000442 if (openfile->fileage == openfile->filebot) {
443#ifndef NANO_TINY
Benno Schulenberg4a1835f2015-10-31 19:03:53 +0000444 if (openfile->mark_set && single_line) {
David Lawrence Ramseyd1ab89a2007-08-07 20:21:39 +0000445 openfile->mark_begin = openfile->current;
David Lawrence Ramsey64b8f422007-08-16 14:45:17 +0000446 if (!right_side_up)
David Lawrence Ramseyd1ab89a2007-08-07 20:21:39 +0000447 openfile->mark_begin_x += openfile->current_x;
448 }
449#endif
Benno Schulenbergdf80bfd2015-10-31 20:17:09 +0000450 /* When the pasted stuff contains no newline, adjust the cursor's
451 * x coordinate for the text that is before the pasted stuff. */
David Lawrence Ramseyee894182007-08-16 03:23:30 +0000452 openfile->current_x += current_x_save;
David Lawrence Ramseyd1ab89a2007-08-07 20:21:39 +0000453 }
David Lawrence Ramseyee894182007-08-16 03:23:30 +0000454#ifndef NANO_TINY
Benno Schulenbergdf80bfd2015-10-31 20:17:09 +0000455 else if (openfile->mark_set && single_line) {
456 if (right_side_up)
457 openfile->mark_begin = openfile->fileage;
458 else {
459 openfile->mark_begin = openfile->current;
460 openfile->mark_begin_x += openfile->current_x - current_x_save;
David Lawrence Ramsey64b8f422007-08-16 14:45:17 +0000461 }
462 }
David Lawrence Ramseyee894182007-08-16 03:23:30 +0000463#endif
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000464
Benno Schulenberg95f417f2016-06-14 11:06:04 +0200465 /* Add the number of characters in the copied text to the file size. */
466 openfile->totsize += get_totsize(openfile->fileage, openfile->filebot);
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000467
Benno Schulenberg17fb6df2016-06-16 11:54:11 +0200468 /* If we pasted onto the first line of the edit window, the corresponding
469 * struct has been freed, so... point at the start of the copied text. */
David Lawrence Ramseye4e61732005-09-02 04:35:58 +0000470 if (edittop_inside)
471 openfile->edittop = openfile->fileage;
472
Benno Schulenberg17fb6df2016-06-16 11:54:11 +0200473 top_save = openfile->fileage;
474
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000475 /* Unpartition the filestruct so that it contains all the text
David Lawrence Ramseye4e61732005-09-02 04:35:58 +0000476 * again, plus the copied text. */
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000477 unpartition_filestruct(&filepart);
478
Benno Schulenberg95f417f2016-06-14 11:06:04 +0200479 /* Renumber, starting with the beginning line of the old partition. */
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000480 renumber(top_save);
481
Benno Schulenberg95f417f2016-06-14 11:06:04 +0200482 /* If the text doesn't end with a magicline, and it should, add one. */
David Lawrence Ramseya0168ca2005-11-05 17:35:44 +0000483 if (!ISSET(NO_NEWLINES) && openfile->filebot->data[0] != '\0')
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000484 new_magicline();
David Lawrence Ramsey90573292005-07-08 02:47:05 +0000485}
486
David Lawrence Ramseya847d372017-02-10 00:17:33 -0600487/* Meld a copy of the given buffer into the current file buffer. */
488void copy_from_buffer(filestruct *somebuffer)
489{
490 filestruct *the_copy = copy_filestruct(somebuffer);
491
492 ingraft_buffer(the_copy);
493}
494
David Lawrence Ramseye99494f2005-07-20 21:08:38 +0000495/* Create a new openfilestruct node. */
496openfilestruct *make_new_opennode(void)
497{
Benno Schulenberg8925eab2015-08-16 15:21:32 +0000498 return (openfilestruct *)nmalloc(sizeof(openfilestruct));
David Lawrence Ramseye99494f2005-07-20 21:08:38 +0000499}
500
David Lawrence Ramseye99494f2005-07-20 21:08:38 +0000501/* Unlink a node from the rest of the openfilestruct, and delete it. */
502void unlink_opennode(openfilestruct *fileptr)
503{
Benno Schulenberg0562d272016-12-15 20:26:47 +0100504 assert(fileptr != fileptr->prev && fileptr != fileptr->next);
David Lawrence Ramseye99494f2005-07-20 21:08:38 +0000505
506 fileptr->prev->next = fileptr->next;
507 fileptr->next->prev = fileptr->prev;
508
509 delete_opennode(fileptr);
510}
511
Benno Schulenbergf4f99542016-02-22 09:02:58 +0000512/* Free all the memory in the given open-file node. */
David Lawrence Ramseye99494f2005-07-20 21:08:38 +0000513void delete_opennode(openfilestruct *fileptr)
514{
David Lawrence Ramseye99494f2005-07-20 21:08:38 +0000515 free(fileptr->filename);
516 free_filestruct(fileptr->fileage);
David Lawrence Ramseyebe34252005-11-15 03:17:35 +0000517#ifndef NANO_TINY
Benno Schulenbergc32a58a2015-06-14 19:14:41 +0000518 free(fileptr->current_stat);
Benno Schulenberg9fcde232015-07-10 15:54:06 +0000519 free(fileptr->lock_filename);
Benno Schulenbergf8459382016-01-15 16:44:50 +0000520 /* Free the undo stack. */
521 discard_until(NULL, fileptr);
David Lawrence Ramseye99494f2005-07-20 21:08:38 +0000522#endif
David Lawrence Ramseye99494f2005-07-20 21:08:38 +0000523 free(fileptr);
524}
525
David Lawrence Ramsey6d6a36c2005-12-08 07:09:08 +0000526/* Display a warning about a key disabled in view mode. */
David Lawrence Ramsey50406662005-01-19 19:52:42 +0000527void print_view_warning(void)
528{
Benno Schulenberg68476162015-07-30 18:10:16 +0000529 statusbar(_("Key is invalid in view mode"));
David Lawrence Ramsey50406662005-01-19 19:52:42 +0000530}
531
Benno Schulenberg68476162015-07-30 18:10:16 +0000532/* Indicate that something is disabled in restricted mode. */
533void show_restricted_warning(void)
534{
535 statusbar(_("This function is disabled in restricted mode"));
536 beep();
537}
538
539#ifdef DISABLE_HELP
540/* Indicate that help texts are unavailable. */
541void say_there_is_no_help(void)
542{
Benno Schulenbergf5234e52015-08-09 18:12:32 +0000543 statusbar(_("Help is not available"));
Benno Schulenberg68476162015-07-30 18:10:16 +0000544}
545#endif
546
David Lawrence Ramseycb04b562007-01-09 22:56:56 +0000547/* Make nano exit gracefully. */
David Lawrence Ramseyda141062004-05-25 19:41:11 +0000548void finish(void)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000549{
Benno Schulenbergea2b51a2015-08-09 18:10:13 +0000550 /* Blank the statusbar and (if applicable) the shortcut list,
551 * and move the cursor to the last line of the screen. */
552 blank_statusbar();
553 blank_bottombars();
David Lawrence Ramsey3f4520b2005-07-29 03:28:09 +0000554 wrefresh(bottomwin);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000555 endwin();
556
David Lawrence Ramseyd7fd2002004-05-18 01:20:36 +0000557 /* Restore the old terminal settings. */
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000558 tcsetattr(0, TCSANOW, &oldterm);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000559
Benno Schulenbergb341f292014-06-19 20:05:24 +0000560#ifndef DISABLE_HISTORIES
Benno Schulenbergfcb4c3f2014-06-19 15:09:23 +0000561 if (ISSET(HISTORYLOG))
Chris Allegrettad8451932003-03-11 03:50:40 +0000562 save_history();
Benno Schulenbergfcb4c3f2014-06-19 15:09:23 +0000563 if (ISSET(POS_HISTORY)) {
Benno Schulenberg1de337d2014-06-04 16:02:51 +0000564 update_poshistory(openfile->filename, openfile->current->lineno, xplustabs() + 1);
Chris Allegretta9bfda912011-02-16 06:52:30 +0000565 save_poshistory();
Chris Allegretta8e2a9302011-02-18 07:30:57 +0000566 }
Chris Allegrettad8451932003-03-11 03:50:40 +0000567#endif
568
Chris Allegretta6232d662002-05-12 19:52:15 +0000569#ifdef DEBUG
Chris Allegrettaf5de33a2002-02-27 04:14:16 +0000570 thanks_for_all_the_fish();
Chris Allegretta6232d662002-05-12 19:52:15 +0000571#endif
Chris Allegrettaf5de33a2002-02-27 04:14:16 +0000572
David Lawrence Ramseycb04b562007-01-09 22:56:56 +0000573 /* Get out. */
David Lawrence Ramseyda141062004-05-25 19:41:11 +0000574 exit(0);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000575}
576
David Lawrence Ramseycb04b562007-01-09 22:56:56 +0000577/* Make nano die gracefully. */
Chris Allegretta6df90f52002-07-19 01:08:59 +0000578void die(const char *msg, ...)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000579{
580 va_list ap;
581
Chris Allegrettaa0d89972003-02-03 03:32:08 +0000582 endwin();
Chris Allegrettaa0d89972003-02-03 03:32:08 +0000583
David Lawrence Ramseyd7fd2002004-05-18 01:20:36 +0000584 /* Restore the old terminal settings. */
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000585 tcsetattr(0, TCSANOW, &oldterm);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000586
Chris Allegretta6df90f52002-07-19 01:08:59 +0000587 va_start(ap, msg);
588 vfprintf(stderr, msg, ap);
589 va_end(ap);
Chris Allegretta2d7893d2001-07-11 02:08:33 +0000590
Benno Schulenberga7ae1762016-08-02 17:11:50 +0200591#ifndef NANO_TINY
592 /* If the current buffer has a lockfile, remove it. */
Benno Schulenberg68010d92016-08-16 16:56:25 +0200593 if (openfile && ISSET(LOCKING) && openfile->lock_filename)
Benno Schulenberga7ae1762016-08-02 17:11:50 +0200594 delete_lockfile(openfile->lock_filename);
595#endif
596
Benno Schulenbergf6dd0ad2016-08-02 17:26:25 +0200597 /* If the current file buffer was modified, save it. */
Chris Allegrettae67bf802008-05-31 22:23:16 +0000598 if (openfile && openfile->modified) {
Benno Schulenbergf6dd0ad2016-08-02 17:26:25 +0200599 /* If the filestruct is partitioned, unpartition it first. */
David Lawrence Ramseyf4595bb2005-06-06 16:27:18 +0000600 if (filepart != NULL)
601 unpartition_filestruct(&filepart);
602
Benno Schulenbergf6dd0ad2016-08-02 17:26:25 +0200603 die_save_file(openfile->filename, openfile->current_stat);
David Lawrence Ramseyf4595bb2005-06-06 16:27:18 +0000604 }
Chris Allegretta2d7893d2001-07-11 02:08:33 +0000605
Benno Schulenberg0636d7b2014-04-03 20:23:07 +0000606#ifndef DISABLE_MULTIBUFFER
David Lawrence Ramsey3ece0b92004-12-01 15:11:27 +0000607 /* Save all of the other modified file buffers, if any. */
David Lawrence Ramsey64661ac2005-07-08 19:57:25 +0000608 if (openfile != NULL) {
Benno Schulenbergf6dd0ad2016-08-02 17:26:25 +0200609 openfilestruct *firstone = openfile;
Chris Allegretta2d7893d2001-07-11 02:08:33 +0000610
Benno Schulenbergf6dd0ad2016-08-02 17:26:25 +0200611 while (openfile->next != firstone) {
David Lawrence Ramsey64661ac2005-07-08 19:57:25 +0000612 openfile = openfile->next;
Chris Allegretta2d7893d2001-07-11 02:08:33 +0000613
Benno Schulenberga7ae1762016-08-02 17:11:50 +0200614#ifndef NANO_TINY
615 if (ISSET(LOCKING) && openfile->lock_filename)
616 delete_lockfile(openfile->lock_filename);
617#endif
David Lawrence Ramsey6ad59cd2005-07-08 20:09:16 +0000618 if (openfile->modified)
Benno Schulenbergf6dd0ad2016-08-02 17:26:25 +0200619 die_save_file(openfile->filename, openfile->current_stat);
Chris Allegretta2d7893d2001-07-11 02:08:33 +0000620 }
Chris Allegretta2d7893d2001-07-11 02:08:33 +0000621 }
622#endif
623
Benno Schulenbergf6dd0ad2016-08-02 17:26:25 +0200624 /* Abandon the building. */
David Lawrence Ramsey3ece0b92004-12-01 15:11:27 +0000625 exit(1);
Chris Allegretta2d7893d2001-07-11 02:08:33 +0000626}
627
Benno Schulenberg3129ff62016-05-27 21:43:39 +0200628/* Save the current file under the name specified in die_filename, which
David Lawrence Ramsey6d6a36c2005-12-08 07:09:08 +0000629 * is modified to be unique if necessary. */
Benno Schulenbergf6dd0ad2016-08-02 17:26:25 +0200630void die_save_file(const char *die_filename, struct stat *die_stat)
Chris Allegretta2d7893d2001-07-11 02:08:33 +0000631{
Benno Schulenberg3129ff62016-05-27 21:43:39 +0200632 char *targetname;
David Lawrence Ramseyce62e822004-08-05 22:10:22 +0000633 bool failed = TRUE;
Chris Allegretta2d7893d2001-07-11 02:08:33 +0000634
David Lawrence Ramsey32e3b882004-05-29 01:20:17 +0000635 /* If we're using restricted mode, don't write any emergency backup
636 * files, since that would allow reading from or writing to files
637 * not specified on the command line. */
David Lawrence Ramseyd893fa92004-04-30 04:49:02 +0000638 if (ISSET(RESTRICTED))
639 return;
640
David Lawrence Ramseycb04b562007-01-09 22:56:56 +0000641 /* If we can't save, we have really bad problems, but we might as
642 * well try. */
David Lawrence Ramsey1904f512007-07-01 21:33:17 +0000643 if (*die_filename == '\0')
David Lawrence Ramsey049e4a52004-08-10 23:05:59 +0000644 die_filename = "nano";
Chris Allegretta6df90f52002-07-19 01:08:59 +0000645
Benno Schulenberg3129ff62016-05-27 21:43:39 +0200646 targetname = get_next_filename(die_filename, ".save");
647
648 if (*targetname != '\0')
649 failed = !write_file(targetname, NULL, TRUE, OVERWRITE, TRUE);
Chris Allegretta2d7893d2001-07-11 02:08:33 +0000650
David Lawrence Ramseyce62e822004-08-05 22:10:22 +0000651 if (!failed)
Benno Schulenberg3129ff62016-05-27 21:43:39 +0200652 fprintf(stderr, _("\nBuffer written to %s\n"), targetname);
653 else if (*targetname != '\0')
654 fprintf(stderr, _("\nBuffer not written to %s: %s\n"), targetname,
David Lawrence Ramseydac3bca2005-06-01 04:23:52 +0000655 strerror(errno));
656 else
657 fprintf(stderr, _("\nBuffer not written: %s\n"),
David Lawrence Ramsey54b74ce2005-05-29 23:03:28 +0000658 _("Too many backup files?"));
Chris Allegretta48b06702002-02-22 04:30:50 +0000659
Chris Allegretta8b6f6fc2009-11-22 21:35:56 +0000660#ifndef NANO_TINY
Benno Schulenberg0b6d6f42015-03-27 13:46:50 +0000661 /* Try and chmod/chown the save file to the values of the original file,
662 * but don't worry if it fails because we're supposed to be bailing as
663 * fast as possible. */
Chris Allegretta123110c2009-11-20 05:09:12 +0000664 if (die_stat) {
Benno Schulenberge3e3f652016-05-27 21:48:38 +0200665 IGNORE_CALL_RESULT(chmod(targetname, die_stat->st_mode));
666 IGNORE_CALL_RESULT(chown(targetname, die_stat->st_uid,
667 die_stat->st_gid));
Chris Allegretta123110c2009-11-20 05:09:12 +0000668 }
Chris Allegretta8b6f6fc2009-11-22 21:35:56 +0000669#endif
Chris Allegretta123110c2009-11-20 05:09:12 +0000670
Benno Schulenberg3129ff62016-05-27 21:43:39 +0200671 free(targetname);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000672}
673
David Lawrence Ramsey6d6a36c2005-12-08 07:09:08 +0000674/* Initialize the three window portions nano uses. */
David Lawrence Ramsey3f12ada2005-07-25 22:54:16 +0000675void window_init(void)
Chris Allegrettae61e8302001-01-14 05:18:27 +0000676{
Benno Schulenberg97eb0e52016-08-15 14:55:59 +0200677 /* First delete existing windows, in case of resizing. */
678 delwin(topwin);
Benno Schulenberg76a960d2016-08-15 19:44:49 +0200679 topwin = NULL;
Benno Schulenberg97eb0e52016-08-15 14:55:59 +0200680 delwin(edit);
681 delwin(bottomwin);
682
Benno Schulenberg76a960d2016-08-15 19:44:49 +0200683 /* If the terminal is very flat, don't set up a titlebar. */
684 if (LINES < 3) {
685 editwinrows = 1;
686 /* Set up two subwindows. If the terminal is just one line,
687 * edit window and statusbar window will cover each other. */
688 edit = newwin(1, COLS, 0, 0);
689 bottomwin = newwin(1, COLS, LINES - 1, 0);
690 } else {
691 int toprows = (ISSET(MORE_SPACE) ? 1 : (LINES < 6) ? 1 : 2);
692 int bottomrows = (ISSET(NO_HELP) ? 1 : (LINES < 5) ? 1 : 3);
Benno Schulenberg0dd2a552016-08-15 12:55:03 +0200693
Benno Schulenberg76a960d2016-08-15 19:44:49 +0200694 editwinrows = LINES - toprows - bottomrows;
David Lawrence Ramseyb386a902005-07-10 02:37:38 +0000695
Benno Schulenberg76a960d2016-08-15 19:44:49 +0200696 /* Set up the normal three subwindows. */
697 topwin = newwin(toprows, COLS, 0, 0);
698 edit = newwin(editwinrows, COLS, toprows, 0);
699 bottomwin = newwin(bottomrows, COLS, toprows + editwinrows, 0);
700 }
701
702 /* In case the terminal shrunk, make sure the status line is clear. */
703 blank_statusbar();
704 wnoutrefresh(bottomwin);
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +0000705
David Lawrence Ramsey31de1052005-08-14 19:25:16 +0000706 /* Turn the keypad on for the windows, if necessary. */
David Lawrence Ramsey057edf72005-08-10 21:22:15 +0000707 if (!ISSET(REBIND_KEYPAD)) {
David Lawrence Ramsey31de1052005-08-14 19:25:16 +0000708 keypad(topwin, TRUE);
David Lawrence Ramsey057edf72005-08-10 21:22:15 +0000709 keypad(edit, TRUE);
710 keypad(bottomwin, TRUE);
711 }
Benno Schulenberg97eb0e52016-08-15 14:55:59 +0200712
713#ifndef DISABLE_WRAPJUSTIFY
714 /* Set up the wrapping point, accounting for screen width when negative. */
715 fill = wrap_at;
716 if (fill <= 0)
717 fill += COLS;
718 if (fill < 0)
719 fill = 0;
720#endif
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +0000721}
722
David Lawrence Ramseyf5b256b2003-10-03 20:26:25 +0000723#ifndef DISABLE_MOUSE
David Lawrence Ramsey503bad02006-06-09 18:24:37 +0000724/* Disable mouse support. */
725void disable_mouse_support(void)
726{
727 mousemask(0, NULL);
David Lawrence Ramsey9bd537f2007-12-04 20:49:09 +0000728 mouseinterval(oldinterval);
David Lawrence Ramsey503bad02006-06-09 18:24:37 +0000729}
730
731/* Enable mouse support. */
732void enable_mouse_support(void)
733{
David Lawrence Ramsey98e4d4f2006-06-28 21:54:55 +0000734 mousemask(ALL_MOUSE_EVENTS, NULL);
David Lawrence Ramsey9bd537f2007-12-04 20:49:09 +0000735 oldinterval = mouseinterval(50);
David Lawrence Ramsey503bad02006-06-09 18:24:37 +0000736}
737
738/* Initialize mouse support. Enable it if the USE_MOUSE flag is set,
739 * and disable it otherwise. */
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +0000740void mouse_init(void)
741{
David Lawrence Ramsey503bad02006-06-09 18:24:37 +0000742 if (ISSET(USE_MOUSE))
743 enable_mouse_support();
744 else
745 disable_mouse_support();
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +0000746}
David Lawrence Ramsey503bad02006-06-09 18:24:37 +0000747#endif /* !DISABLE_MOUSE */
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +0000748
David Lawrence Ramseybc6a36e2005-03-22 20:17:38 +0000749#ifdef HAVE_GETOPT_LONG
David Lawrence Ramsey660e05b2006-05-12 19:30:28 +0000750#define print_opt(shortflag, longflag, desc) print_opt_full(shortflag, longflag, desc)
David Lawrence Ramseybc6a36e2005-03-22 20:17:38 +0000751#else
David Lawrence Ramsey660e05b2006-05-12 19:30:28 +0000752#define print_opt(shortflag, longflag, desc) print_opt_full(shortflag, desc)
David Lawrence Ramseybc6a36e2005-03-22 20:17:38 +0000753#endif
754
David Lawrence Ramsey22fac782004-08-05 15:16:19 +0000755/* Print one usage string to the screen. This cuts down on duplicate
David Lawrence Ramsey39e8ce62005-03-21 07:24:47 +0000756 * strings to translate, and leaves out the parts that shouldn't be
David Lawrence Ramseycb04b562007-01-09 22:56:56 +0000757 * translatable (i.e. the flag names). */
David Lawrence Ramsey660e05b2006-05-12 19:30:28 +0000758void print_opt_full(const char *shortflag
David Lawrence Ramsey39e8ce62005-03-21 07:24:47 +0000759#ifdef HAVE_GETOPT_LONG
760 , const char *longflag
761#endif
762 , const char *desc)
Chris Allegretta3fc5d572002-03-09 18:51:58 +0000763{
764 printf(" %s\t", shortflag);
David Lawrence Ramsey3fb62b82007-12-18 22:00:17 +0000765 if (strlenpt(shortflag) < 8)
Chris Allegretta3fc5d572002-03-09 18:51:58 +0000766 printf("\t");
767
768#ifdef HAVE_GETOPT_LONG
769 printf("%s\t", longflag);
David Lawrence Ramsey3fb62b82007-12-18 22:00:17 +0000770 if (strlenpt(longflag) < 8)
Chris Allegretta3fc5d572002-03-09 18:51:58 +0000771 printf("\t\t");
David Lawrence Ramsey3fb62b82007-12-18 22:00:17 +0000772 else if (strlenpt(longflag) < 16)
Chris Allegretta3fc5d572002-03-09 18:51:58 +0000773 printf("\t");
774#endif
775
David Lawrence Ramseyc2b07472005-04-14 03:13:49 +0000776 if (desc != NULL)
777 printf("%s", _(desc));
778 printf("\n");
Chris Allegretta3fc5d572002-03-09 18:51:58 +0000779}
780
Benno Schulenberg62de3302014-05-28 15:44:11 +0000781/* Explain how to properly use nano and its command-line options. */
David Lawrence Ramsey0341b582002-08-21 16:10:37 +0000782void usage(void)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000783{
David Lawrence Ramsey74d8ebc2006-06-26 04:39:31 +0000784 printf(_("Usage: nano [OPTIONS] [[+LINE,COLUMN] FILE]...\n\n"));
David Lawrence Ramsey560e83f2006-05-08 19:55:18 +0000785#ifdef HAVE_GETOPT_LONG
Benno Schulenbergffeb0f92016-10-23 22:00:45 +0200786 printf(_("Option\t\tGNU long option\t\tMeaning\n"));
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000787#else
Benno Schulenbergffeb0f92016-10-23 22:00:45 +0200788 printf(_("Option\t\tMeaning\n"));
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +0000789#endif
David Lawrence Ramsey74d8ebc2006-06-26 04:39:31 +0000790 print_opt(_("+LINE,COLUMN"), "",
Benno Schulenberg62de3302014-05-28 15:44:11 +0000791 /* TRANSLATORS: The next forty or so strings are option descriptions
792 * for the --help output. Try to keep them at most 40 characters. */
David Lawrence Ramsey86ce3902005-05-21 17:15:46 +0000793 N_("Start at line LINE, column COLUMN"));
David Lawrence Ramseyebe34252005-11-15 03:17:35 +0000794#ifndef NANO_TINY
David Lawrence Ramsey660e05b2006-05-12 19:30:28 +0000795 print_opt("-A", "--smarthome", N_("Enable smart home key"));
Benno Schulenberg5885e342015-07-29 19:31:50 +0000796 if (!ISSET(RESTRICTED)) {
Benno Schulenberg104ea6b2015-07-30 11:29:45 +0000797 print_opt("-B", "--backup", N_("Save backups of existing files"));
798 print_opt(_("-C <dir>"), _("--backupdir=<dir>"),
799 N_("Directory for saving unique backup files"));
Benno Schulenberg5885e342015-07-29 19:31:50 +0000800 }
David Lawrence Ramsey9dbd0d22006-05-13 13:02:14 +0000801#endif
Benno Schulenberga3387982015-05-03 13:56:51 +0000802 print_opt("-D", "--boldtext", N_("Use bold instead of reverse video text"));
David Lawrence Ramsey9dbd0d22006-05-13 13:02:14 +0000803#ifndef NANO_TINY
Benno Schulenberga3387982015-05-03 13:56:51 +0000804 print_opt("-E", "--tabstospaces", N_("Convert typed tabs to spaces"));
Chris Allegretta7004c282001-09-22 00:42:10 +0000805#endif
Benno Schulenberg0636d7b2014-04-03 20:23:07 +0000806#ifndef DISABLE_MULTIBUFFER
Benno Schulenberg5885e342015-07-29 19:31:50 +0000807 if (!ISSET(RESTRICTED))
Benno Schulenberg104ea6b2015-07-30 11:29:45 +0000808 print_opt("-F", "--multibuffer",
809 N_("Read a file into a new buffer by default"));
Chris Allegretta355fbe52001-07-14 19:32:47 +0000810#endif
David Lawrence Ramseyebe34252005-11-15 03:17:35 +0000811#ifndef NANO_TINY
Benno Schulenberga3387982015-05-03 13:56:51 +0000812 print_opt("-G", "--locking", N_("Use (vim-style) lock files"));
Benno Schulenbergb341f292014-06-19 20:05:24 +0000813#endif
814#ifndef DISABLE_HISTORIES
Benno Schulenberg5885e342015-07-29 19:31:50 +0000815 if (!ISSET(RESTRICTED))
Benno Schulenberg104ea6b2015-07-30 11:29:45 +0000816 print_opt("-H", "--historylog",
817 N_("Log & read search/replace string history"));
Benno Schulenberg85ddc712014-07-02 19:57:23 +0000818#endif
819#ifndef DISABLE_NANORC
Benno Schulenberg5885e342015-07-29 19:31:50 +0000820 if (!ISSET(RESTRICTED))
Benno Schulenberg104ea6b2015-07-30 11:29:45 +0000821 print_opt("-I", "--ignorercfiles", N_("Don't look at nanorc files"));
Chris Allegretta6df90f52002-07-19 01:08:59 +0000822#endif
David Lawrence Ramsey660e05b2006-05-12 19:30:28 +0000823 print_opt("-K", "--rebindkeypad",
David Lawrence Ramsey057edf72005-08-10 21:22:15 +0000824 N_("Fix numeric keypad key confusion problem"));
David Lawrence Ramsey660e05b2006-05-12 19:30:28 +0000825 print_opt("-L", "--nonewlines",
David Lawrence Ramseya0168ca2005-11-05 17:35:44 +0000826 N_("Don't add newlines to the ends of files"));
David Lawrence Ramseyebe34252005-11-15 03:17:35 +0000827#ifndef NANO_TINY
David Lawrence Ramsey660e05b2006-05-12 19:30:28 +0000828 print_opt("-N", "--noconvert",
David Lawrence Ramsey86ce3902005-05-21 17:15:46 +0000829 N_("Don't convert files from DOS/Mac format"));
Chris Allegretta8fa1e282001-09-22 04:20:25 +0000830#endif
David Lawrence Ramsey7b0531a2006-07-31 01:30:31 +0000831 print_opt("-O", "--morespace", N_("Use one more line for editing"));
Benno Schulenbergb341f292014-06-19 20:05:24 +0000832#ifndef DISABLE_HISTORIES
Benno Schulenberg5885e342015-07-29 19:31:50 +0000833 if (!ISSET(RESTRICTED))
Benno Schulenberg104ea6b2015-07-30 11:29:45 +0000834 print_opt("-P", "--positionlog",
835 N_("Log & read location of cursor position"));
Chris Allegretta9bfda912011-02-16 06:52:30 +0000836#endif
Chris Allegrettae4f940d2002-03-03 22:36:36 +0000837#ifndef DISABLE_JUSTIFY
Benno Schulenberga3387982015-05-03 13:56:51 +0000838 print_opt(_("-Q <str>"), _("--quotestr=<str>"), N_("Quoting string"));
Chris Allegrettae4f940d2002-03-03 22:36:36 +0000839#endif
Benno Schulenberg5885e342015-07-29 19:31:50 +0000840 if (!ISSET(RESTRICTED))
Benno Schulenberg104ea6b2015-07-30 11:29:45 +0000841 print_opt("-R", "--restricted", N_("Restricted mode"));
David Lawrence Ramseyebe34252005-11-15 03:17:35 +0000842#ifndef NANO_TINY
Benno Schulenberga3387982015-05-03 13:56:51 +0000843 print_opt("-S", "--smooth", N_("Scroll by line instead of half-screen"));
Chris Allegretta3e3ae942001-09-22 19:02:04 +0000844#endif
David Lawrence Ramseye77ebfa2006-05-14 15:19:38 +0000845 print_opt(_("-T <#cols>"), _("--tabsize=<#cols>"),
David Lawrence Ramsey7b0531a2006-07-31 01:30:31 +0000846 N_("Set width of a tab to #cols columns"));
David Lawrence Ramseyebe34252005-11-15 03:17:35 +0000847#ifndef NANO_TINY
David Lawrence Ramsey660e05b2006-05-12 19:30:28 +0000848 print_opt("-U", "--quickblank", N_("Do quick statusbar blanking"));
David Lawrence Ramsey66357b52005-06-17 19:09:18 +0000849#endif
Benno Schulenberga3387982015-05-03 13:56:51 +0000850 print_opt("-V", "--version", N_("Print version information and exit"));
David Lawrence Ramseyebe34252005-11-15 03:17:35 +0000851#ifndef NANO_TINY
David Lawrence Ramsey660e05b2006-05-12 19:30:28 +0000852 print_opt("-W", "--wordbounds",
David Lawrence Ramsey4f03daf2005-08-10 22:12:28 +0000853 N_("Detect word boundaries more accurately"));
Benno Schulenberg0a387d92016-08-07 17:02:02 +0200854 print_opt(_("-X <str>"), _("--wordchars=<str>"),
Benno Schulenberg6f129922016-06-30 18:02:45 +0200855 N_("Which other characters are word parts"));
David Lawrence Ramsey4f03daf2005-08-10 22:12:28 +0000856#endif
Benno Schulenberg00389922014-04-04 11:59:03 +0000857#ifndef DISABLE_COLOR
Benno Schulenberg5885e342015-07-29 19:31:50 +0000858 if (!ISSET(RESTRICTED))
Benno Schulenberg104ea6b2015-07-30 11:29:45 +0000859 print_opt(_("-Y <str>"), _("--syntax=<str>"),
860 N_("Syntax definition to use for coloring"));
Chris Allegretta09900ff2002-05-04 04:23:30 +0000861#endif
Benno Schulenberg79526152015-07-15 19:40:37 +0000862 print_opt("-c", "--constantshow", N_("Constantly show cursor position"));
David Lawrence Ramsey660e05b2006-05-12 19:30:28 +0000863 print_opt("-d", "--rebinddelete",
David Lawrence Ramsey86ce3902005-05-21 17:15:46 +0000864 N_("Fix Backspace/Delete confusion problem"));
Benno Schulenbergace15172015-08-01 08:47:38 +0000865 print_opt("-h", "--help", N_("Show this help text and exit"));
Benno Schulenbergb341f292014-06-19 20:05:24 +0000866#ifndef NANO_TINY
Benno Schulenberga3387982015-05-03 13:56:51 +0000867 print_opt("-i", "--autoindent", N_("Automatically indent new lines"));
David Lawrence Ramsey660e05b2006-05-12 19:30:28 +0000868 print_opt("-k", "--cut", N_("Cut from cursor to end of line"));
David Lawrence Ramseyb80d49f2005-03-26 22:49:46 +0000869#endif
Faissal Bensefiade95ca62016-10-20 09:44:29 +0100870#ifdef ENABLE_LINENUMBERS
871 print_opt("-l", "--linenumbers", N_("Show line numbers in front of the text"));
872#endif
David Lawrence Ramseyf5b256b2003-10-03 20:26:25 +0000873#ifndef DISABLE_MOUSE
David Lawrence Ramsey69e1ce52006-06-08 02:37:45 +0000874 print_opt("-m", "--mouse", N_("Enable the use of the mouse"));
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000875#endif
Benno Schulenbergdb7064b2014-04-08 18:59:30 +0000876 print_opt("-n", "--noread", N_("Do not read the file (only write it)"));
Chris Allegrettae1f14522001-09-19 03:19:43 +0000877#ifndef DISABLE_OPERATINGDIR
David Lawrence Ramseye77ebfa2006-05-14 15:19:38 +0000878 print_opt(_("-o <dir>"), _("--operatingdir=<dir>"),
David Lawrence Ramsey86ce3902005-05-21 17:15:46 +0000879 N_("Set operating directory"));
Chris Allegrettae1f14522001-09-19 03:19:43 +0000880#endif
Benno Schulenberga3387982015-05-03 13:56:51 +0000881 print_opt("-p", "--preserve", N_("Preserve XON (^Q) and XOFF (^S) keys"));
Benno Schulenberg85ddc712014-07-02 19:57:23 +0000882#ifndef DISABLE_NANORC
Benno Schulenberg5885e342015-07-29 19:31:50 +0000883 if (!ISSET(RESTRICTED))
Benno Schulenberg104ea6b2015-07-30 11:29:45 +0000884 print_opt("-q", "--quiet",
885 N_("Silently ignore startup issues like rc file errors"));
Benno Schulenberg85ddc712014-07-02 19:57:23 +0000886#endif
Chris Allegretta6fe61492001-05-21 12:56:25 +0000887#ifndef DISABLE_WRAPJUSTIFY
David Lawrence Ramseye77ebfa2006-05-14 15:19:38 +0000888 print_opt(_("-r <#cols>"), _("--fill=<#cols>"),
Benno Schulenberg00db9942014-04-23 20:42:55 +0000889 N_("Set hard-wrapping point at column #cols"));
Chris Allegretta6fe61492001-05-21 12:56:25 +0000890#endif
Rocco Corsiaf5c3022001-01-12 07:51:05 +0000891#ifndef DISABLE_SPELLER
Benno Schulenberg5885e342015-07-29 19:31:50 +0000892 if (!ISSET(RESTRICTED))
Benno Schulenberg104ea6b2015-07-30 11:29:45 +0000893 print_opt(_("-s <prog>"), _("--speller=<prog>"),
894 N_("Enable alternate speller"));
Rocco Corsiaf5c3022001-01-12 07:51:05 +0000895#endif
Benno Schulenberga3387982015-05-03 13:56:51 +0000896 print_opt("-t", "--tempfile", N_("Auto save on exit, don't prompt"));
Benno Schulenbergeac04462015-08-09 16:31:01 +0000897#ifndef NANO_TINY
898 print_opt("-u", "--unix", N_("Save a file by default in Unix format"));
899#endif
David Lawrence Ramsey7b0531a2006-07-31 01:30:31 +0000900 print_opt("-v", "--view", N_("View mode (read-only)"));
Chris Allegrettacef7fbb2001-04-02 05:36:08 +0000901#ifndef DISABLE_WRAPPING
Benno Schulenberg00db9942014-04-23 20:42:55 +0000902 print_opt("-w", "--nowrap", N_("Don't hard-wrap long lines"));
Chris Allegrettacef7fbb2001-04-02 05:36:08 +0000903#endif
David Lawrence Ramsey69e1ce52006-06-08 02:37:45 +0000904 print_opt("-x", "--nohelp", N_("Don't show the two help lines"));
Benno Schulenberg5885e342015-07-29 19:31:50 +0000905 if (!ISSET(RESTRICTED))
Benno Schulenberg104ea6b2015-07-30 11:29:45 +0000906 print_opt("-z", "--suspend", N_("Enable suspension"));
Benno Schulenbergc347ce42014-03-03 21:30:50 +0000907#ifndef NANO_TINY
Chris Allegretta05417a22009-08-17 07:52:10 +0000908 print_opt("-$", "--softwrap", N_("Enable soft line wrapping"));
Benno Schulenbergc347ce42014-03-03 21:30:50 +0000909#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000910}
911
David Lawrence Ramsey6d6a36c2005-12-08 07:09:08 +0000912/* Display the current version of nano, the date and time it was
913 * compiled, contact information for it, and the configuration options
914 * it was compiled with. */
David Lawrence Ramsey0341b582002-08-21 16:10:37 +0000915void version(void)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000916{
Benno Schulenbergec295f52016-04-08 10:22:09 +0200917#ifdef REVISION
Benno Schulenberg49fc5282016-08-14 21:18:00 +0200918 printf(" GNU nano from git, %s\n", REVISION);
Benno Schulenbergec295f52016-04-08 10:22:09 +0200919#else
Benno Schulenberg49fc5282016-08-14 21:18:00 +0200920 printf(_(" GNU nano, version %s\n"), VERSION);
Benno Schulenbergec295f52016-04-08 10:22:09 +0200921#endif
Benno Schulenberg1b293ff2016-01-10 16:18:43 +0000922 printf(" (C) 1999..2016 Free Software Foundation, Inc.\n");
Benno Schulenbergc1183972017-02-21 20:27:49 +0100923 printf(_(" (C) 2014..%s the contributors to nano\n"), "2017");
David Lawrence Ramseyb1d9b412005-03-11 04:22:34 +0000924 printf(
Jordi Mallachc2b199e2016-06-20 19:44:56 +0200925 _(" Email: nano@nano-editor.org Web: https://nano-editor.org/"));
Chris Allegretta8a0de3b2000-11-24 20:45:14 +0000926 printf(_("\n Compiled options:"));
Chris Allegrettaff269f82000-12-01 18:46:01 +0000927
Benno Schulenberg2d83e8d2014-04-05 19:57:17 +0000928#ifdef NANO_TINY
929 printf(" --enable-tiny");
930#ifndef DISABLE_BROWSER
931 printf(" --enable-browser");
932#endif
933#ifndef DISABLE_COLOR
934 printf(" --enable-color");
935#endif
936#ifndef DISABLE_EXTRA
937 printf(" --enable-extra");
938#endif
939#ifndef DISABLE_HELP
940 printf(" --enable-help");
941#endif
Benno Schulenbergb341f292014-06-19 20:05:24 +0000942#ifndef DISABLE_HISTORIES
943 printf(" --enable-histories");
944#endif
Benno Schulenberg2d83e8d2014-04-05 19:57:17 +0000945#ifndef DISABLE_JUSTIFY
946 printf(" --enable-justify");
947#endif
Benno Schulenbergb9881322014-04-13 19:54:47 +0000948#ifdef HAVE_LIBMAGIC
949 printf(" --enable-libmagic");
950#endif
Faissal Bensefiade95ca62016-10-20 09:44:29 +0100951#ifdef ENABLE_LINENUMBERS
952 printf(" --enable-linenumbers");
953#endif
Benno Schulenberg2d83e8d2014-04-05 19:57:17 +0000954#ifndef DISABLE_MOUSE
955 printf(" --enable-mouse");
956#endif
Benno Schulenbergeea09082014-04-13 20:50:20 +0000957#ifndef DISABLE_NANORC
958 printf(" --enable-nanorc");
959#endif
Benno Schulenberg2d83e8d2014-04-05 19:57:17 +0000960#ifndef DISABLE_MULTIBUFFER
961 printf(" --enable-multibuffer");
962#endif
963#ifndef DISABLE_OPERATINGDIR
964 printf(" --enable-operatingdir");
965#endif
966#ifndef DISABLE_SPELLER
967 printf(" --enable-speller");
968#endif
969#ifndef DISABLE_TABCOMP
970 printf(" --enable-tabcomp");
971#endif
972#ifndef DISABLE_WRAPPING
973 printf(" --enable-wrapping");
974#endif
975#else /* !NANO_TINY */
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000976#ifdef DISABLE_BROWSER
Chris Allegretta6636dc32001-01-05 05:41:07 +0000977 printf(" --disable-browser");
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000978#endif
Benno Schulenberg2d83e8d2014-04-05 19:57:17 +0000979#ifdef DISABLE_COLOR
980 printf(" --disable-color");
981#endif
Mike Scalora6a2032f2016-05-25 22:13:50 +0200982#ifndef ENABLE_COMMENT
983 printf(" --disable-comment");
984#endif
Benno Schulenbergd17438b2014-04-03 20:57:44 +0000985#ifdef DISABLE_EXTRA
986 printf(" --disable-extra");
987#endif
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +0000988#ifdef DISABLE_HELP
989 printf(" --disable-help");
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000990#endif
Benno Schulenbergb341f292014-06-19 20:05:24 +0000991#ifdef DISABLE_HISTORIES
992 printf(" --disable-histories");
993#endif
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000994#ifdef DISABLE_JUSTIFY
Chris Allegrettaff269f82000-12-01 18:46:01 +0000995 printf(" --disable-justify");
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000996#endif
Benno Schulenbergb9881322014-04-13 19:54:47 +0000997#ifndef HAVE_LIBMAGIC
998 printf(" --disable-libmagic");
999#endif
Faissal Bensefiade95ca62016-10-20 09:44:29 +01001000#ifndef ENABLE_LINENUMBERS
1001 printf(" --disable-linenumbers");
1002#endif
David Lawrence Ramseyf5b256b2003-10-03 20:26:25 +00001003#ifdef DISABLE_MOUSE
Chris Allegretta84de5522001-04-12 14:51:48 +00001004 printf(" --disable-mouse");
Chris Allegrettab7d00ef2000-12-18 05:36:51 +00001005#endif
Benno Schulenberg0636d7b2014-04-03 20:23:07 +00001006#ifdef DISABLE_MULTIBUFFER
1007 printf(" --disable-multibuffer");
1008#endif
Benno Schulenbergeea09082014-04-13 20:50:20 +00001009#ifdef DISABLE_NANORC
1010 printf(" --disable-nanorc");
1011#endif
Chris Allegrettae1f14522001-09-19 03:19:43 +00001012#ifdef DISABLE_OPERATINGDIR
1013 printf(" --disable-operatingdir");
1014#endif
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001015#ifdef DISABLE_SPELLER
1016 printf(" --disable-speller");
1017#endif
1018#ifdef DISABLE_TABCOMP
1019 printf(" --disable-tabcomp");
1020#endif
Benno Schulenberg1df41152016-12-15 12:38:47 +01001021#ifndef ENABLE_WORDCOMPLETION
1022 printf(" --disable-wordcomp");
1023#endif
Chris Allegrettacef7fbb2001-04-02 05:36:08 +00001024#ifdef DISABLE_WRAPPING
1025 printf(" --disable-wrapping");
1026#endif
Benno Schulenberg2d83e8d2014-04-05 19:57:17 +00001027#endif /* !NANO_TINY */
1028
David Lawrence Ramseye53e1252006-07-19 15:50:19 +00001029#ifdef DISABLE_ROOTWRAPPING
David Lawrence Ramseydc60b722002-10-25 16:08:53 +00001030 printf(" --disable-wrapping-as-root");
1031#endif
David Lawrence Ramsey85c0b3c2005-06-29 17:10:58 +00001032#ifdef DEBUG
1033 printf(" --enable-debug");
1034#endif
Benno Schulenberg2d83e8d2014-04-05 19:57:17 +00001035#ifndef ENABLE_NLS
1036 printf(" --disable-nls");
David Lawrence Ramsey85c0b3c2005-06-29 17:10:58 +00001037#endif
David Lawrence Ramsey7eb30a82005-07-17 02:40:07 +00001038#ifdef ENABLE_UTF8
David Lawrence Ramsey85c0b3c2005-06-29 17:10:58 +00001039 printf(" --enable-utf8");
Benno Schulenberg2d83e8d2014-04-05 19:57:17 +00001040#else
1041 printf(" --disable-utf8");
David Lawrence Ramsey85c0b3c2005-06-29 17:10:58 +00001042#endif
David Lawrence Ramseyf78bc852007-12-18 15:55:48 +00001043#ifdef USE_SLANG
1044 printf(" --with-slang");
1045#endif
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001046 printf("\n");
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001047}
1048
David Lawrence Ramseycb04b562007-01-09 22:56:56 +00001049/* If the current file buffer has been modified, and the TEMP_FILE flag
1050 * isn't set, ask whether or not to save the file buffer. If the
Benno Schulenberg4f3f9762014-06-16 20:44:34 +00001051 * TEMP_FILE flag is set and the current file has a name, save it
1052 * unconditionally. Then, if more than one file buffer is open, close
1053 * the current file buffer and switch to the next one. If only one file
1054 * buffer is open, exit from nano. */
David Lawrence Ramsey72e51ab2004-07-02 14:31:03 +00001055void do_exit(void)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001056{
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001057 int i;
Chris Allegretta13fd44b2002-01-02 13:59:11 +00001058
David Lawrence Ramsey6d6a36c2005-12-08 07:09:08 +00001059 /* If the file hasn't been modified, pretend the user chose not to
1060 * save. */
David Lawrence Ramsey6ad59cd2005-07-08 20:09:16 +00001061 if (!openfile->modified)
David Lawrence Ramseye19449e2005-11-07 21:45:44 +00001062 i = 0;
Benno Schulenberg4f3f9762014-06-16 20:44:34 +00001063 /* If the TEMP_FILE flag is set and the current file has a name,
1064 * pretend the user chose to save. */
1065 else if (openfile->filename[0] != '\0' && ISSET(TEMP_FILE))
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001066 i = 1;
David Lawrence Ramsey6d6a36c2005-12-08 07:09:08 +00001067 /* Otherwise, ask the user whether or not to save. */
Benno Schulenberg4f3f9762014-06-16 20:44:34 +00001068 else {
1069 /* If the TEMP_FILE flag is set, and the current file doesn't
Benno Schulenberg0d9397e2015-10-29 10:36:07 +00001070 * have a name, warn the user before prompting for a name. */
1071 if (ISSET(TEMP_FILE))
David Lawrence Ramseye4d45242016-11-27 15:01:54 -06001072 warn_and_shortly_pause(_("No file name"));
Benno Schulenberg4f3f9762014-06-16 20:44:34 +00001073
Benno Schulenberg17cf8332016-05-30 09:09:36 +02001074 i = do_yesno_prompt(FALSE, _("Save modified buffer? "
1075 "(Answering \"No\" will DISCARD changes.) "));
Benno Schulenberg4f3f9762014-06-16 20:44:34 +00001076 }
David Lawrence Ramsey72e51ab2004-07-02 14:31:03 +00001077
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001078#ifdef DEBUG
David Lawrence Ramsey6ad59cd2005-07-08 20:09:16 +00001079 dump_filestruct(openfile->fileage);
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001080#endif
1081
David Lawrence Ramsey6d6a36c2005-12-08 07:09:08 +00001082 /* If the user chose not to save, or if the user chose to save and
1083 * the save succeeded, we're ready to exit. */
Benno Schulenberg8cc63082015-12-23 16:34:44 +00001084 if (i == 0 || (i == 1 && do_writeout(TRUE)))
1085 close_and_go();
1086 else if (i != 1)
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001087 statusbar(_("Cancelled"));
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001088}
1089
Benno Schulenberg8cc63082015-12-23 16:34:44 +00001090/* Close the current buffer, and terminate nano if it was the last. */
1091void close_and_go(void)
1092{
1093#ifndef NANO_TINY
1094 /* If there is a lockfile, remove it. */
1095 if (ISSET(LOCKING) && openfile->lock_filename)
1096 delete_lockfile(openfile->lock_filename);
1097#endif
1098#ifndef DISABLE_MULTIBUFFER
1099 /* If there are no more open file buffers, jump off a cliff. */
Benno Schulenberg906ada82016-05-17 13:37:53 +02001100 if (!close_buffer())
Benno Schulenberg8cc63082015-12-23 16:34:44 +00001101#endif
1102 finish();
1103}
1104
Benno Schulenbergd19be5a2014-04-08 18:38:45 +00001105/* Another placeholder for function mapping. */
Chris Allegretta637daa82011-02-07 14:45:56 +00001106void do_cancel(void)
1107{
1108 ;
1109}
Chris Allegrettab0f0b7f2009-01-30 17:37:44 +00001110
Benno Schulenberga3387982015-05-03 13:56:51 +00001111static struct sigaction pager_oldaction, pager_newaction;
1112 /* Original and temporary handlers for SIGINT. */
1113static bool pager_sig_failed = FALSE;
1114 /* Did sigaction() fail without changing the signal handlers? */
1115static bool pager_input_aborted = FALSE;
1116 /* Did someone invoke the pager and abort it via ^C? */
Chris Allegretta35b59762010-03-21 05:31:43 +00001117
Chris Allegrettab0f0b7f2009-01-30 17:37:44 +00001118/* Things which need to be run regardless of whether
Benno Schulenberg499c6de2014-03-24 21:48:23 +00001119 * we finished the stdin pipe correctly or not. */
Chris Allegrettab0f0b7f2009-01-30 17:37:44 +00001120void finish_stdin_pager(void)
1121{
1122 FILE *f;
1123 int ttystdin;
1124
Benno Schulenberg499c6de2014-03-24 21:48:23 +00001125 /* Read whatever we did get from stdin. */
Chris Allegrettab0f0b7f2009-01-30 17:37:44 +00001126 f = fopen("/dev/stdin", "rb");
Benno Schulenberg3345e342015-03-20 11:18:22 +00001127 if (f == NULL)
1128 nperror("fopen");
Chris Allegrettab0f0b7f2009-01-30 17:37:44 +00001129
Chris Allegretta2c7b5062009-12-09 16:51:43 +00001130 read_file(f, 0, "stdin", TRUE, FALSE);
Benno Schulenberg907ba3a2016-04-25 15:44:52 +02001131 openfile->edittop = openfile->fileage;
1132
Chris Allegrettab0f0b7f2009-01-30 17:37:44 +00001133 ttystdin = open("/dev/tty", O_RDONLY);
1134 if (!ttystdin)
Benno Schulenberg3345e342015-03-20 11:18:22 +00001135 die(_("Couldn't reopen stdin from keyboard, sorry\n"));
Chris Allegrettab0f0b7f2009-01-30 17:37:44 +00001136
1137 dup2(ttystdin,0);
1138 close(ttystdin);
Chris Allegretta35b59762010-03-21 05:31:43 +00001139 if (!pager_input_aborted)
1140 tcgetattr(0, &oldterm);
Chris Allegrettab0f0b7f2009-01-30 17:37:44 +00001141 if (!pager_sig_failed && sigaction(SIGINT, &pager_oldaction, NULL) == -1)
Benno Schulenberg3345e342015-03-20 11:18:22 +00001142 nperror("sigaction");
Chris Allegrettab0f0b7f2009-01-30 17:37:44 +00001143 terminal_init();
1144 doupdate();
1145}
1146
Benno Schulenberg499c6de2014-03-24 21:48:23 +00001147/* Cancel reading from stdin like a pager. */
Chris Allegrettab0f0b7f2009-01-30 17:37:44 +00001148RETSIGTYPE cancel_stdin_pager(int signal)
1149{
Chris Allegretta35b59762010-03-21 05:31:43 +00001150 pager_input_aborted = TRUE;
Chris Allegrettab0f0b7f2009-01-30 17:37:44 +00001151}
1152
Benno Schulenberg499c6de2014-03-24 21:48:23 +00001153/* Let nano read stdin for the first file at least. */
Chris Allegrettab0f0b7f2009-01-30 17:37:44 +00001154void stdin_pager(void)
1155{
1156 endwin();
Chris Allegretta35b59762010-03-21 05:31:43 +00001157 if (!pager_input_aborted)
1158 tcsetattr(0, TCSANOW, &oldterm);
Chris Allegrettab0f0b7f2009-01-30 17:37:44 +00001159 fprintf(stderr, _("Reading from stdin, ^C to abort\n"));
1160
Benno Schulenberg57d17552016-09-03 12:14:08 +02001161#ifndef NANO_TINY
Benno Schulenberg499c6de2014-03-24 21:48:23 +00001162 /* Enable interpretation of the special control keys so that
1163 * we get SIGINT when Ctrl-C is pressed. */
Chris Allegrettab0f0b7f2009-01-30 17:37:44 +00001164 enable_signals();
Chris Allegrettaecc245c2009-02-01 00:04:42 +00001165#endif
Chris Allegrettab0f0b7f2009-01-30 17:37:44 +00001166
Benno Schulenberg3345e342015-03-20 11:18:22 +00001167 /* Set things up so that SIGINT will cancel the new process. */
Chris Allegrettab0f0b7f2009-01-30 17:37:44 +00001168 if (sigaction(SIGINT, NULL, &pager_newaction) == -1) {
1169 pager_sig_failed = TRUE;
1170 nperror("sigaction");
1171 } else {
1172 pager_newaction.sa_handler = cancel_stdin_pager;
1173 if (sigaction(SIGINT, &pager_newaction, &pager_oldaction) == -1) {
1174 pager_sig_failed = TRUE;
1175 nperror("sigaction");
1176 }
1177 }
Chris Allegretta35b59762010-03-21 05:31:43 +00001178
Chris Allegrettab0f0b7f2009-01-30 17:37:44 +00001179 open_buffer("", FALSE);
1180 finish_stdin_pager();
1181}
1182
David Lawrence Ramsey6d6a36c2005-12-08 07:09:08 +00001183/* Initialize the signal handlers. */
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001184void signal_init(void)
1185{
Benno Schulenberga3387982015-05-03 13:56:51 +00001186 /* Trap SIGINT and SIGQUIT because we want them to do useful things. */
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001187 memset(&act, 0, sizeof(struct sigaction));
1188 act.sa_handler = SIG_IGN;
1189 sigaction(SIGINT, &act, NULL);
David Lawrence Ramsey2897d2b2004-01-26 20:56:20 +00001190 sigaction(SIGQUIT, &act, NULL);
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001191
David Lawrence Ramsey5520e852004-04-07 00:44:35 +00001192 /* Trap SIGHUP and SIGTERM because we want to write the file out. */
David Lawrence Ramsey2ab03f62002-10-17 02:19:31 +00001193 act.sa_handler = handle_hupterm;
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001194 sigaction(SIGHUP, &act, NULL);
David Lawrence Ramsey2ab03f62002-10-17 02:19:31 +00001195 sigaction(SIGTERM, &act, NULL);
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001196
David Lawrence Ramseyebe34252005-11-15 03:17:35 +00001197#ifndef NANO_TINY
David Lawrence Ramsey5520e852004-04-07 00:44:35 +00001198 /* Trap SIGWINCH because we want to handle window resizes. */
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001199 act.sa_handler = handle_sigwinch;
1200 sigaction(SIGWINCH, &act, NULL);
1201#endif
1202
David Lawrence Ramseyd7fd2002004-05-18 01:20:36 +00001203 /* Trap normal suspend (^Z) so we can handle it ourselves. */
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001204 if (!ISSET(SUSPEND)) {
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001205 act.sa_handler = SIG_IGN;
1206 sigaction(SIGTSTP, &act, NULL);
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001207 } else {
David Lawrence Ramsey5520e852004-04-07 00:44:35 +00001208 /* Block all other signals in the suspend and continue handlers.
1209 * If we don't do this, other stuff interrupts them! */
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001210 sigfillset(&act.sa_mask);
1211
1212 act.sa_handler = do_suspend;
1213 sigaction(SIGTSTP, &act, NULL);
1214
David Lawrence Ramsey8befda62005-12-06 19:39:56 +00001215 act.sa_handler = do_continue;
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001216 sigaction(SIGCONT, &act, NULL);
1217 }
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001218}
1219
David Lawrence Ramseyd7fd2002004-05-18 01:20:36 +00001220/* Handler for SIGHUP (hangup) and SIGTERM (terminate). */
David Lawrence Ramsey8befda62005-12-06 19:39:56 +00001221RETSIGTYPE handle_hupterm(int signal)
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001222{
Chris Allegrettaa0d89972003-02-03 03:32:08 +00001223 die(_("Received SIGHUP or SIGTERM\n"));
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001224}
1225
David Lawrence Ramseyd7fd2002004-05-18 01:20:36 +00001226/* Handler for SIGTSTP (suspend). */
David Lawrence Ramsey8befda62005-12-06 19:39:56 +00001227RETSIGTYPE do_suspend(int signal)
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001228{
David Lawrence Ramsey503bad02006-06-09 18:24:37 +00001229#ifndef DISABLE_MOUSE
1230 /* Turn mouse support off. */
1231 disable_mouse_support();
1232#endif
1233
Chris Allegrettab43f6912009-11-29 06:24:10 +00001234 /* Move the cursor to the last line of the screen. */
David Lawrence Ramsey85c775a2006-06-09 16:04:19 +00001235 move(LINES - 1, 0);
Chris Allegrettadaaf4682009-11-28 03:01:30 +00001236 endwin();
David Lawrence Ramseyf70f67b2006-06-03 17:31:52 +00001237
David Lawrence Ramsey85c775a2006-06-09 16:04:19 +00001238 /* Display our helpful message. */
1239 printf(_("Use \"fg\" to return to nano.\n"));
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001240 fflush(stdout);
1241
David Lawrence Ramseyd7fd2002004-05-18 01:20:36 +00001242 /* Restore the old terminal settings. */
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001243 tcsetattr(0, TCSANOW, &oldterm);
1244
David Lawrence Ramsey99bede32003-09-29 07:21:11 +00001245 /* Trap SIGHUP and SIGTERM so we can properly deal with them while
David Lawrence Ramseyd7fd2002004-05-18 01:20:36 +00001246 * suspended. */
David Lawrence Ramsey99bede32003-09-29 07:21:11 +00001247 act.sa_handler = handle_hupterm;
1248 sigaction(SIGHUP, &act, NULL);
1249 sigaction(SIGTERM, &act, NULL);
1250
David Lawrence Ramseyd7fd2002004-05-18 01:20:36 +00001251 /* Do what mutt does: send ourselves a SIGSTOP. */
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001252 kill(0, SIGSTOP);
1253}
1254
Benno Schulenberga3387982015-05-03 13:56:51 +00001255/* The version of above function that is bound to a key. */
Chris Allegrettaab538642010-11-12 06:22:12 +00001256void do_suspend_void(void)
Chris Allegretta0018d8e2008-03-13 08:23:52 +00001257{
1258 if (ISSET(SUSPEND))
1259 do_suspend(0);
Benno Schulenberg20ba5592015-07-30 20:15:01 +00001260 else {
1261 statusbar(_("Suspension is not enabled"));
1262 beep();
1263 }
Chris Allegretta0018d8e2008-03-13 08:23:52 +00001264}
1265
David Lawrence Ramseyd7fd2002004-05-18 01:20:36 +00001266/* Handler for SIGCONT (continue after suspend). */
David Lawrence Ramsey8befda62005-12-06 19:39:56 +00001267RETSIGTYPE do_continue(int signal)
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001268{
David Lawrence Ramsey503bad02006-06-09 18:24:37 +00001269#ifndef DISABLE_MOUSE
1270 /* Turn mouse support back on if it was on before. */
1271 if (ISSET(USE_MOUSE))
1272 enable_mouse_support();
1273#endif
1274
David Lawrence Ramseyebe34252005-11-15 03:17:35 +00001275#ifndef NANO_TINY
Benno Schulenberg07a39e82016-06-29 15:55:38 +02001276 /* Perhaps the user resized the window while we slept. So act as if,
1277 * and restore the terminal to its previous state in the process. */
1278 regenerate_screen();
David Lawrence Ramsey5520e852004-04-07 00:44:35 +00001279#else
Benno Schulenbergbfcce572016-12-04 12:27:12 +01001280 /* Restore the state of the terminal and redraw the whole screen. */
David Lawrence Ramsey85c775a2006-06-09 16:04:19 +00001281 terminal_init();
David Lawrence Ramsey85c775a2006-06-09 16:04:19 +00001282 total_refresh();
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001283#endif
1284}
1285
David Lawrence Ramseyebe34252005-11-15 03:17:35 +00001286#ifndef NANO_TINY
David Lawrence Ramsey6d6a36c2005-12-08 07:09:08 +00001287/* Handler for SIGWINCH (window size change). */
David Lawrence Ramsey8befda62005-12-06 19:39:56 +00001288RETSIGTYPE handle_sigwinch(int signal)
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001289{
Benno Schulenberg75d64e62015-05-28 13:02:29 +00001290 /* Let the input routine know that a SIGWINCH has occurred. */
Benno Schulenbergb77e6bd2016-12-14 20:37:03 +01001291 the_window_resized = TRUE;
Benno Schulenberg75d64e62015-05-28 13:02:29 +00001292}
1293
1294/* Reinitialize and redraw the screen completely. */
1295void regenerate_screen(void)
1296{
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001297 const char *tty = ttyname(0);
David Lawrence Ramsey9d691692005-03-08 16:41:53 +00001298 int fd, result = 0;
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001299 struct winsize win;
1300
Benno Schulenbergb77e6bd2016-12-14 20:37:03 +01001301 /* Reset the trigger. */
1302 the_window_resized = FALSE;
1303
David Lawrence Ramsey9b13ff32002-12-22 16:30:00 +00001304 if (tty == NULL)
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001305 return;
1306 fd = open(tty, O_RDWR);
1307 if (fd == -1)
1308 return;
1309 result = ioctl(fd, TIOCGWINSZ, &win);
1310 close(fd);
1311 if (result == -1)
1312 return;
1313
David Lawrence Ramsey9b33d512006-03-20 04:46:48 +00001314 /* We could check whether the COLS or LINES changed, and return
1315 * otherwise. However, COLS and LINES are curses global variables,
1316 * and in some cases curses has already updated them. But not in
1317 * all cases. Argh. */
Benno Schulenberg90ea21f2014-03-26 10:45:07 +00001318#ifdef REDEFINING_MACROS_OK
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001319 COLS = win.ws_col;
1320 LINES = win.ws_row;
Chris Allegretta42bd8712010-03-07 19:35:46 +00001321#endif
Faissal Bensefiade95ca62016-10-20 09:44:29 +01001322 editwincols = COLS - margin;
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001323
David Lawrence Ramseyf78bc852007-12-18 15:55:48 +00001324#ifdef USE_SLANG
1325 /* Slang curses emulation brain damage, part 1: If we just do what
1326 * curses does here, it'll only work properly if the resize made the
1327 * window smaller. Do what mutt does: Leave and immediately reenter
1328 * Slang screen management mode. */
1329 SLsmg_reset_smg();
1330 SLsmg_init_smg();
1331#else
David Lawrence Ramseyd7fd2002004-05-18 01:20:36 +00001332 /* Do the equivalent of what Minimum Profit does: Leave and
1333 * immediately reenter curses mode. */
1334 endwin();
David Lawrence Ramsey84fdb902005-08-14 20:08:49 +00001335 doupdate();
David Lawrence Ramseyf78bc852007-12-18 15:55:48 +00001336#endif
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001337
David Lawrence Ramsey8aaf0302004-07-27 16:46:35 +00001338 /* Restore the terminal to its previous state. */
1339 terminal_init();
1340
David Lawrence Ramseyd7fd2002004-05-18 01:20:36 +00001341 /* Do the equivalent of what both mutt and Minimum Profit do:
1342 * Reinitialize all the windows based on the new screen
1343 * dimensions. */
1344 window_init();
1345
David Lawrence Ramsey907725f2004-11-12 00:09:20 +00001346 /* Redraw the contents of the windows that need it. */
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001347 total_refresh();
David Lawrence Ramseyad40fdb2002-09-06 20:35:28 +00001348}
David Lawrence Ramsey369732f2004-02-16 20:32:40 +00001349
Benno Schulenberg9e6b9a22016-01-04 10:37:11 +00001350/* If allow is FALSE, block any SIGWINCH signal. If allow is TRUE,
1351 * unblock SIGWINCH so any pending ones can be dealt with. */
1352void allow_sigwinch(bool allow)
David Lawrence Ramsey369732f2004-02-16 20:32:40 +00001353{
1354 sigset_t winch;
Benno Schulenbergbff6a902015-07-28 19:39:34 +00001355
David Lawrence Ramsey369732f2004-02-16 20:32:40 +00001356 sigemptyset(&winch);
1357 sigaddset(&winch, SIGWINCH);
David Lawrence Ramsey9c3249c2005-07-01 22:58:47 +00001358 sigprocmask(allow ? SIG_UNBLOCK : SIG_BLOCK, &winch, NULL);
David Lawrence Ramsey369732f2004-02-16 20:32:40 +00001359}
David Lawrence Ramseyebe34252005-11-15 03:17:35 +00001360#endif /* !NANO_TINY */
David Lawrence Ramseyc5967552002-06-21 03:20:06 +00001361
David Lawrence Ramseyebe34252005-11-15 03:17:35 +00001362#ifndef NANO_TINY
Benno Schulenberg499c6de2014-03-24 21:48:23 +00001363/* Handle the global toggle specified in flag. */
Chris Allegretta79a33bb2008-03-05 07:34:01 +00001364void do_toggle(int flag)
Chris Allegretta756f2202000-09-01 13:32:47 +00001365{
David Lawrence Ramseyce62e822004-08-05 22:10:22 +00001366 bool enabled;
Chris Allegrettaf0f63a82000-09-02 18:44:21 +00001367
Benno Schulenbergefbf7b62015-07-29 20:21:45 +00001368 if (ISSET(RESTRICTED) && (flag == SUSPEND || flag == MULTIBUFFER ||
1369 flag == BACKUP_FILE || flag == NO_COLOR_SYNTAX)) {
Benno Schulenberg68476162015-07-30 18:10:16 +00001370 show_restricted_warning();
Benno Schulenbergefbf7b62015-07-29 20:21:45 +00001371 return;
1372 }
1373
Chris Allegretta79a33bb2008-03-05 07:34:01 +00001374 TOGGLE(flag);
Chris Allegretta2a42af12000-09-12 23:02:49 +00001375
Chris Allegretta79a33bb2008-03-05 07:34:01 +00001376 switch (flag) {
David Lawrence Ramseyf5b256b2003-10-03 20:26:25 +00001377#ifndef DISABLE_MOUSE
Chris Allegretta79a33bb2008-03-05 07:34:01 +00001378 case USE_MOUSE:
David Lawrence Ramsey62a217d2004-11-27 16:54:00 +00001379 mouse_init();
1380 break;
David Lawrence Ramsey9b13ff32002-12-22 16:30:00 +00001381#endif
Chris Allegretta79a33bb2008-03-05 07:34:01 +00001382 case MORE_SPACE:
1383 case NO_HELP:
David Lawrence Ramsey62a217d2004-11-27 16:54:00 +00001384 window_init();
David Lawrence Ramsey637b8bb2005-01-17 05:06:55 +00001385 total_refresh();
David Lawrence Ramsey62a217d2004-11-27 16:54:00 +00001386 break;
Chris Allegretta79a33bb2008-03-05 07:34:01 +00001387 case SUSPEND:
David Lawrence Ramsey637b8bb2005-01-17 05:06:55 +00001388 signal_init();
David Lawrence Ramsey62a217d2004-11-27 16:54:00 +00001389 break;
Chris Allegretta79a33bb2008-03-05 07:34:01 +00001390 case WHITESPACE_DISPLAY:
Benno Schulenbergf920e0d2016-12-03 17:00:28 +01001391 titlebar(NULL); /* Fall through. */
Benno Schulenberg00389922014-04-04 11:59:03 +00001392#ifndef DISABLE_COLOR
Chris Allegretta79a33bb2008-03-05 07:34:01 +00001393 case NO_COLOR_SYNTAX:
David Lawrence Ramsey637b8bb2005-01-17 05:06:55 +00001394#endif
Chris Allegretta05417a22009-08-17 07:52:10 +00001395 case SOFTWRAP:
Benno Schulenberg2789bb02016-10-21 13:52:40 +02001396 refresh_needed = TRUE;
Chris Allegretta05417a22009-08-17 07:52:10 +00001397 break;
Chris Allegretta756f2202000-09-01 13:32:47 +00001398 }
Chris Allegretta2a42af12000-09-12 23:02:49 +00001399
Chris Allegretta79a33bb2008-03-05 07:34:01 +00001400 enabled = ISSET(flag);
David Lawrence Ramsey53aca712005-06-09 04:00:03 +00001401
Benno Schulenberg4eac6992016-12-03 20:25:16 +01001402 if (flag == NO_HELP || flag == NO_WRAP || flag == NO_COLOR_SYNTAX)
Chris Allegretta6df90f52002-07-19 01:08:59 +00001403 enabled = !enabled;
David Lawrence Ramsey53aca712005-06-09 04:00:03 +00001404
Benno Schulenberg2535f512016-04-30 17:31:43 +02001405 statusline(HUSH, "%s %s", _(flagtostr(flag)),
1406 enabled ? _("enabled") : _("disabled"));
Chris Allegretta756f2202000-09-01 13:32:47 +00001407}
Chris Allegretta637daa82011-02-07 14:45:56 +00001408
Benno Schulenbergd19be5a2014-04-08 18:38:45 +00001409/* Bleh. */
Chris Allegretta637daa82011-02-07 14:45:56 +00001410void do_toggle_void(void)
1411{
Benno Schulenbergd19be5a2014-04-08 18:38:45 +00001412 ;
Chris Allegretta637daa82011-02-07 14:45:56 +00001413}
Benno Schulenberg7b7d2bf2016-09-01 09:36:47 +02001414#endif /* !NANO_TINY */
Chris Allegretta756f2202000-09-01 13:32:47 +00001415
David Lawrence Ramsey6d6a36c2005-12-08 07:09:08 +00001416/* Disable extended input and output processing in our terminal
1417 * settings. */
David Lawrence Ramsey8bcac8a2005-06-09 04:02:57 +00001418void disable_extended_io(void)
David Lawrence Ramsey013344c2004-09-22 22:45:08 +00001419{
1420 struct termios term;
1421
1422 tcgetattr(0, &term);
1423 term.c_lflag &= ~IEXTEN;
David Lawrence Ramsey8bcac8a2005-06-09 04:02:57 +00001424 term.c_oflag &= ~OPOST;
David Lawrence Ramsey013344c2004-09-22 22:45:08 +00001425 tcsetattr(0, TCSANOW, &term);
1426}
1427
David Lawrence Ramseyf78bc852007-12-18 15:55:48 +00001428/* Disable interpretation of the special control keys in our terminal
1429 * settings. */
1430void disable_signals(void)
1431{
1432 struct termios term;
1433
1434 tcgetattr(0, &term);
1435 term.c_lflag &= ~ISIG;
1436 tcsetattr(0, TCSANOW, &term);
1437}
David Lawrence Ramseyf78bc852007-12-18 15:55:48 +00001438
David Lawrence Ramseyebe34252005-11-15 03:17:35 +00001439#ifndef NANO_TINY
David Lawrence Ramsey6d6a36c2005-12-08 07:09:08 +00001440/* Enable interpretation of the special control keys in our terminal
1441 * settings. */
David Lawrence Ramseyd7fd2002004-05-18 01:20:36 +00001442void enable_signals(void)
1443{
1444 struct termios term;
1445
1446 tcgetattr(0, &term);
1447 term.c_lflag |= ISIG;
1448 tcsetattr(0, TCSANOW, &term);
1449}
1450#endif
1451
David Lawrence Ramsey6d6a36c2005-12-08 07:09:08 +00001452/* Disable interpretation of the flow control characters in our terminal
1453 * settings. */
David Lawrence Ramseyd7fd2002004-05-18 01:20:36 +00001454void disable_flow_control(void)
1455{
1456 struct termios term;
1457
1458 tcgetattr(0, &term);
David Lawrence Ramsey5e50e2f2005-06-23 22:28:56 +00001459 term.c_iflag &= ~IXON;
David Lawrence Ramseyd7fd2002004-05-18 01:20:36 +00001460 tcsetattr(0, TCSANOW, &term);
1461}
1462
David Lawrence Ramsey6d6a36c2005-12-08 07:09:08 +00001463/* Enable interpretation of the flow control characters in our terminal
1464 * settings. */
David Lawrence Ramseyd7fd2002004-05-18 01:20:36 +00001465void enable_flow_control(void)
1466{
1467 struct termios term;
1468
1469 tcgetattr(0, &term);
David Lawrence Ramsey5e50e2f2005-06-23 22:28:56 +00001470 term.c_iflag |= IXON;
David Lawrence Ramseyd7fd2002004-05-18 01:20:36 +00001471 tcsetattr(0, TCSANOW, &term);
1472}
1473
David Lawrence Ramsey7f6f5a62007-12-18 02:03:00 +00001474/* Set up the terminal state. Put the terminal in raw mode (read one
1475 * character at a time, disable the special control keys, and disable
1476 * the flow control characters), disable translation of carriage return
1477 * (^M) into newline (^J) so that we can tell the difference between the
1478 * Enter key and Ctrl-J, and disable echoing of characters as they're
1479 * typed. Finally, disable extended input and output processing, and,
1480 * if we're not in preserve mode, reenable interpretation of the flow
1481 * control characters. */
David Lawrence Ramsey8aaf0302004-07-27 16:46:35 +00001482void terminal_init(void)
1483{
David Lawrence Ramseyf78bc852007-12-18 15:55:48 +00001484#ifdef USE_SLANG
1485 /* Slang curses emulation brain damage, part 2: Slang doesn't
1486 * implement raw(), nonl(), or noecho() properly, so there's no way
1487 * to properly reinitialize the terminal using them. We have to
David Lawrence Ramseybc668262007-12-18 16:51:48 +00001488 * disable the special control keys and interpretation of the flow
1489 * control characters using termios, save the terminal state after
1490 * the first call, and restore it on subsequent calls. */
David Lawrence Ramseyf78bc852007-12-18 15:55:48 +00001491 static struct termios newterm;
1492 static bool newterm_set = FALSE;
1493
1494 if (!newterm_set) {
1495#endif
1496
1497 raw();
1498 nonl();
1499 noecho();
1500 disable_extended_io();
1501 if (ISSET(PRESERVE))
1502 enable_flow_control();
1503
David Lawrence Ramseyf78bc852007-12-18 15:55:48 +00001504 disable_signals();
Chris Allegrettae137f122008-09-06 06:52:47 +00001505#ifdef USE_SLANG
David Lawrence Ramsey27be74c2007-12-18 16:47:06 +00001506 if (!ISSET(PRESERVE))
1507 disable_flow_control();
David Lawrence Ramseyf78bc852007-12-18 15:55:48 +00001508
1509 tcgetattr(0, &newterm);
1510 newterm_set = TRUE;
1511 } else
1512 tcsetattr(0, TCSANOW, &newterm);
1513#endif
David Lawrence Ramsey8aaf0302004-07-27 16:46:35 +00001514}
1515
Benno Schulenbergc6615062016-08-16 10:49:55 +02001516/* Ask ncurses for a keycode, or assign a default one. */
1517int get_keycode(const char *keyname, const int standard)
1518{
Benno Schulenbergf2c72bf2016-11-17 17:32:28 +01001519#ifdef HAVE_KEY_DEFINED
Benno Schulenbergc6615062016-08-16 10:49:55 +02001520 const char *keyvalue = tigetstr(keyname);
1521
Benno Schulenbergf2c72bf2016-11-17 17:32:28 +01001522 if (keyvalue != 0 && keyvalue != (char *)-1)
Benno Schulenbergc6615062016-08-16 10:49:55 +02001523 return key_defined(keyvalue);
Benno Schulenbergf2c72bf2016-11-17 17:32:28 +01001524 else
Benno Schulenbergc6615062016-08-16 10:49:55 +02001525#endif
Benno Schulenbergf2c72bf2016-11-17 17:32:28 +01001526 return standard;
1527}
Benno Schulenbergc6615062016-08-16 10:49:55 +02001528
Benno Schulenberge0c4f9c2016-04-27 14:37:31 +02001529/* Say that an unbound key was struck, and if possible which one. */
1530void unbound_key(int code)
1531{
Benno Schulenbergcb10b2b2016-07-13 16:22:56 +02001532 if (!is_byte(code))
Benno Schulenberg2535f512016-04-30 17:31:43 +02001533 statusline(ALERT, _("Unbound key"));
Benno Schulenberge0c4f9c2016-04-27 14:37:31 +02001534 else if (meta_key) {
Benno Schulenbergb3fbb7c2016-07-14 22:01:55 +02001535 if (code == '[')
1536 statusline(ALERT, _("Unbindable key: M-["));
1537 else
1538 statusline(ALERT, _("Unbound key: M-%c"), toupper(code));
Benno Schulenberge0c4f9c2016-04-27 14:37:31 +02001539 } else if (code < 0x20)
Benno Schulenberg2535f512016-04-30 17:31:43 +02001540 statusline(ALERT, _("Unbound key: ^%c"), code + 0x40);
Benno Schulenberge0c4f9c2016-04-27 14:37:31 +02001541 else
Benno Schulenberg2535f512016-04-30 17:31:43 +02001542 statusline(ALERT, _("Unbound key: %c"), code);
Benno Schulenberge0c4f9c2016-04-27 14:37:31 +02001543}
1544
Benno Schulenbergddd9c7a2016-06-24 22:45:41 +02001545/* Read in a keystroke. Act on the keystroke if it is a shortcut or a toggle;
1546 * otherwise, insert it into the edit buffer. If allow_funcs is FALSE, don't
1547 * do anything with the keystroke -- just return it. */
Benno Schulenberg7e5324d2014-06-30 18:04:33 +00001548int do_input(bool allow_funcs)
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001549{
1550 int input;
Benno Schulenbergddd9c7a2016-06-24 22:45:41 +02001551 /* The keystroke we read in: a character or a shortcut. */
Benno Schulenberg067b0a32016-06-26 14:08:05 +02001552 static char *puddle = NULL;
Benno Schulenbergddd9c7a2016-06-24 22:45:41 +02001553 /* The input buffer for actual characters. */
1554 static size_t depth = 0;
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001555 /* The length of the input buffer. */
Benno Schulenberg3af22aa2014-06-13 12:28:33 +00001556 bool preserve = FALSE;
Benno Schulenbergddd9c7a2016-06-24 22:45:41 +02001557 /* Whether to preserve the contents of the cutbuffer. */
Chris Allegretta79a33bb2008-03-05 07:34:01 +00001558 const sc *s;
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001559 bool have_shortcut;
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001560
Benno Schulenbergddd9c7a2016-06-24 22:45:41 +02001561 /* Read in a keystroke. */
Benno Schulenberg7e5324d2014-06-30 18:04:33 +00001562 input = get_kbinput(edit);
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001563
Benno Schulenberg75d64e62015-05-28 13:02:29 +00001564#ifndef NANO_TINY
1565 if (input == KEY_WINCH)
1566 return KEY_WINCH;
1567#endif
1568
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001569#ifndef DISABLE_MOUSE
Benno Schulenbergcb10b2b2016-07-13 16:22:56 +02001570 if (input == KEY_MOUSE) {
Benno Schulenberg454563c2014-06-13 12:07:18 +00001571 /* We received a mouse click. */
Benno Schulenberg99a649d2014-06-16 12:30:35 +00001572 if (do_mouse() == 1)
Benno Schulenberg454563c2014-06-13 12:07:18 +00001573 /* The click was on a shortcut -- read in the character
1574 * that it was converted into. */
Benno Schulenberg7e5324d2014-06-30 18:04:33 +00001575 input = get_kbinput(edit);
Benno Schulenberg99a649d2014-06-16 12:30:35 +00001576 else
1577 /* The click was invalid or has been handled -- get out. */
Benno Schulenbergfc35e202014-06-11 18:23:29 +00001578 return ERR;
David Lawrence Ramsey8992d0a2006-05-10 12:48:47 +00001579 }
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001580#endif
1581
1582 /* Check for a shortcut in the main list. */
Benno Schulenberg49816fe2014-07-01 10:41:10 +00001583 s = get_shortcut(&input);
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001584
1585 /* If we got a shortcut from the main list, or a "universal"
1586 * edit window shortcut, set have_shortcut to TRUE. */
Chris Allegretta0018d8e2008-03-13 08:23:52 +00001587 have_shortcut = (s != NULL);
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001588
David Lawrence Ramseyd6eb1752006-05-25 21:39:25 +00001589 /* If we got a non-high-bit control key, a meta key sequence, or a
1590 * function key, and it's not a shortcut or toggle, throw it out. */
Chris Allegretta79a33bb2008-03-05 07:34:01 +00001591 if (!have_shortcut) {
Benno Schulenbergcb10b2b2016-07-13 16:22:56 +02001592 if (is_ascii_cntrl_char(input) || meta_key || !is_byte(input)) {
Benno Schulenberge0c4f9c2016-04-27 14:37:31 +02001593 unbound_key(input);
David Lawrence Ramsey305d8892006-05-24 19:48:03 +00001594 input = ERR;
David Lawrence Ramsey8e341e12006-05-24 17:36:00 +00001595 }
1596 }
1597
Benno Schulenberge7f39bc2016-08-28 21:00:13 +02001598 if (!allow_funcs)
1599 return input;
1600
Benno Schulenberg5ad26f82016-08-28 21:18:34 +02001601 /* If the keystroke isn't a shortcut nor a toggle, it's a normal text
1602 * character: add the character to the input buffer -- or display a
1603 * warning when we're in view mode. */
1604 if (input != ERR && !have_shortcut) {
1605 if (ISSET(VIEW_MODE))
1606 print_view_warning();
1607 else {
1608 /* Store the byte, and leave room for a terminating zero. */
1609 puddle = charealloc(puddle, depth + 2);
1610 puddle[depth++] = (char)input;
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001611 }
Benno Schulenberg96fbdfb2016-08-30 10:41:28 +02001612#ifndef NANO_TINY
1613 if (openfile->mark_set && openfile->kind_of_mark == SOFTMARK) {
1614 openfile->mark_set = FALSE;
1615 refresh_needed = TRUE;
1616 }
1617#endif
Benno Schulenberg5ad26f82016-08-28 21:18:34 +02001618 }
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001619
Benno Schulenberg5ad26f82016-08-28 21:18:34 +02001620 /* If we got a shortcut or toggle, or if there aren't any other
1621 * characters waiting after the one we read in, we need to output
1622 * all available characters in the input puddle. Note that this
1623 * puddle will be empty if we're in view mode. */
1624 if (have_shortcut || get_key_buffer_len() == 0) {
David Lawrence Ramsey9133cbe2006-05-22 15:45:24 +00001625#ifndef DISABLE_WRAPPING
Benno Schulenberg5ad26f82016-08-28 21:18:34 +02001626 /* If we got a shortcut or toggle, and it's not the shortcut
1627 * for verbatim input, turn off prepending of wrapped text. */
1628 if (have_shortcut && s->scfunc != do_verbatim_input)
1629 wrap_reset();
David Lawrence Ramsey9133cbe2006-05-22 15:45:24 +00001630#endif
David Lawrence Ramseyef0d5a72006-05-22 02:08:49 +00001631
Benno Schulenberg5ad26f82016-08-28 21:18:34 +02001632 if (puddle != NULL) {
1633 /* Insert all bytes in the input buffer into the edit buffer
1634 * at once, filtering out any low control codes. */
1635 puddle[depth] = '\0';
1636 do_output(puddle, depth, FALSE);
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001637
Benno Schulenberg5ad26f82016-08-28 21:18:34 +02001638 /* Empty the input buffer. */
1639 free(puddle);
1640 puddle = NULL;
1641 depth = 0;
1642 }
1643 }
1644
Benno Schulenberg68a03142016-12-07 13:10:40 +01001645 if (!have_shortcut)
1646 pletion_line = NULL;
1647 else {
Benno Schulenberg5ad26f82016-08-28 21:18:34 +02001648 const subnfunc *f = sctofunc(s);
1649
1650 if (ISSET(VIEW_MODE) && f && !f->viewok) {
1651 print_view_warning();
1652 return ERR;
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001653 }
1654
Benno Schulenberg5ad26f82016-08-28 21:18:34 +02001655 /* If the function associated with this shortcut is
1656 * cutting or copying text, remember this. */
1657 if (s->scfunc == do_cut_text_void
David Lawrence Ramseyc87e0c02006-04-25 02:23:28 +00001658#ifndef NANO_TINY
Benno Schulenberg95e77a92014-06-30 20:39:27 +00001659 || s->scfunc == do_copy_text || s->scfunc == do_cut_till_eof
David Lawrence Ramseyc87e0c02006-04-25 02:23:28 +00001660#endif
Benno Schulenberg8cc8b082014-06-11 18:34:35 +00001661 )
Benno Schulenberg5ad26f82016-08-28 21:18:34 +02001662 preserve = TRUE;
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001663
Benno Schulenberg68a03142016-12-07 13:10:40 +01001664#ifdef ENABLE_WORDCOMPLETION
Sumedh Pendurkardca4ab52016-12-07 09:43:47 +05301665 if (s->scfunc != complete_a_word)
1666 pletion_line = NULL;
Benno Schulenberg68a03142016-12-07 13:10:40 +01001667#endif
1668#ifndef NANO_TINY
Benno Schulenberg5ad26f82016-08-28 21:18:34 +02001669 if (s->scfunc == do_toggle_void) {
1670 do_toggle(s->toggle);
1671 if (s->toggle != CUT_TO_END)
1672 preserve = TRUE;
1673 } else
Chris Allegretta79a33bb2008-03-05 07:34:01 +00001674#endif
Benno Schulenberg5ad26f82016-08-28 21:18:34 +02001675 {
Benno Schulenberg382c9d72016-04-24 11:28:28 +02001676#ifndef NANO_TINY
Benno Schulenberg5ad26f82016-08-28 21:18:34 +02001677 /* If Shifted movement occurs, set the mark. */
1678 if (shift_held && !openfile->mark_set) {
1679 openfile->mark_set = TRUE;
1680 openfile->mark_begin = openfile->current;
1681 openfile->mark_begin_x = openfile->current_x;
1682 openfile->kind_of_mark = SOFTMARK;
1683 }
Benno Schulenberg382c9d72016-04-24 11:28:28 +02001684#endif
Benno Schulenberg5ad26f82016-08-28 21:18:34 +02001685 /* Execute the function of the shortcut. */
1686 s->scfunc();
Benno Schulenberg382c9d72016-04-24 11:28:28 +02001687#ifndef NANO_TINY
Benno Schulenberg5ad26f82016-08-28 21:18:34 +02001688 /* If Shiftless movement occurred, discard a soft mark. */
1689 if (openfile->mark_set && !shift_held &&
Benno Schulenberg382c9d72016-04-24 11:28:28 +02001690 openfile->kind_of_mark == SOFTMARK) {
Benno Schulenberg5ad26f82016-08-28 21:18:34 +02001691 openfile->mark_set = FALSE;
1692 openfile->mark_begin = NULL;
1693 refresh_needed = TRUE;
1694 }
Benno Schulenberg382c9d72016-04-24 11:28:28 +02001695#endif
Benno Schulenberg00389922014-04-04 11:59:03 +00001696#ifndef DISABLE_COLOR
Benno Schulenberg5ad26f82016-08-28 21:18:34 +02001697 if (f && !f->viewok)
Benno Schulenberg9ec546d2017-02-13 19:11:04 +01001698 check_the_multis(openfile->current);
Chris Allegretta8b6f6fc2009-11-22 21:35:56 +00001699#endif
Benno Schulenberg2789bb02016-10-21 13:52:40 +02001700 if (!refresh_needed && (s->scfunc == do_delete || s->scfunc == do_backspace))
Benno Schulenberg5ad26f82016-08-28 21:18:34 +02001701 update_line(openfile->current, openfile->current_x);
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001702 }
Benno Schulenberg5ad26f82016-08-28 21:18:34 +02001703 }
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001704
Benno Schulenberg3af22aa2014-06-13 12:28:33 +00001705 /* If we aren't cutting or copying text, and the key wasn't a toggle,
1706 * blow away the text in the cutbuffer upon the next cutting action. */
1707 if (!preserve)
David Lawrence Ramsey41b89722006-05-21 20:03:43 +00001708 cutbuffer_reset();
1709
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001710 return input;
1711}
1712
Chris Allegretta79a33bb2008-03-05 07:34:01 +00001713void xon_complaint(void)
1714{
1715 statusbar(_("XON ignored, mumble mumble"));
1716}
1717
1718void xoff_complaint(void)
1719{
1720 statusbar(_("XOFF ignored, mumble mumble"));
1721}
1722
1723
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001724#ifndef DISABLE_MOUSE
David Lawrence Ramsey6d6a36c2005-12-08 07:09:08 +00001725/* Handle a mouse click on the edit window or the shortcut list. */
David Lawrence Ramsey3a5eaeb2007-05-20 23:41:56 +00001726int do_mouse(void)
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001727{
David Lawrence Ramsey3e222402017-02-01 21:10:49 -06001728 int mouse_col, mouse_row;
1729 int retval = get_mouseinput(&mouse_col, &mouse_row, TRUE);
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001730
Benno Schulenberg13176792017-01-03 15:04:22 +01001731 /* If the click is wrong or already handled, we're done. */
Benno Schulenberg1d064552014-06-13 12:19:44 +00001732 if (retval != 0)
Benno Schulenberg1d064552014-06-13 12:19:44 +00001733 return retval;
1734
Benno Schulenberg13176792017-01-03 15:04:22 +01001735 /* If the click was in the edit window, put the cursor in that spot. */
David Lawrence Ramsey3e222402017-02-01 21:10:49 -06001736 if (wmouse_trafo(edit, &mouse_row, &mouse_col, FALSE)) {
1737 bool sameline = (mouse_row == openfile->current_y);
1738 /* Whether the click was on the row where the cursor is. */
Chris Allegrettad47d8cd2009-01-25 07:25:17 +00001739 filestruct *current_save = openfile->current;
Benno Schulenberg8611e472014-04-04 16:06:27 +00001740#ifndef NANO_TINY
David Lawrence Ramseyebc38fd2007-06-28 16:00:50 +00001741 size_t current_x_save = openfile->current_x;
Benno Schulenberg8611e472014-04-04 16:06:27 +00001742#endif
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001743
Chris Allegrettaf55ada72009-11-13 20:38:32 +00001744#ifdef DEBUG
David Lawrence Ramsey3e222402017-02-01 21:10:49 -06001745 fprintf(stderr, "mouse_row = %d, current_y = %ld\n", mouse_row, (long)openfile->current_y);
Chris Allegrettaf55ada72009-11-13 20:38:32 +00001746#endif
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001747
Benno Schulenberg1102aaa2014-06-09 20:26:54 +00001748#ifndef NANO_TINY
Benno Schulenberga65ef422014-03-17 21:36:37 +00001749 if (ISSET(SOFTWRAP)) {
Benno Schulenberg13176792017-01-03 15:04:22 +01001750 ssize_t current_row = 0;
Benno Schulenberg30591c52016-12-10 21:18:10 +01001751
1752 openfile->current = openfile->edittop;
1753
David Lawrence Ramsey3e222402017-02-01 21:10:49 -06001754 while (openfile->current->next != NULL && current_row < mouse_row) {
Benno Schulenberg13176792017-01-03 15:04:22 +01001755 current_row += strlenpt(openfile->current->data) / editwincols + 1;
Benno Schulenberg30591c52016-12-10 21:18:10 +01001756 openfile->current = openfile->current->next;
Chris Allegrettaf55ada72009-11-13 20:38:32 +00001757 }
Chris Allegrettaf55ada72009-11-13 20:38:32 +00001758
David Lawrence Ramsey3e222402017-02-01 21:10:49 -06001759 if (current_row > mouse_row) {
Chris Allegrettaf55ada72009-11-13 20:38:32 +00001760 openfile->current = openfile->current->prev;
Benno Schulenberg13176792017-01-03 15:04:22 +01001761 current_row -= strlenpt(openfile->current->data) / editwincols + 1;
Benno Schulenberge9fde7d2016-12-10 19:38:03 +01001762 openfile->current_x = actual_x(openfile->current->data,
David Lawrence Ramsey3e222402017-02-01 21:10:49 -06001763 ((mouse_row - current_row) * editwincols) + mouse_col);
Benno Schulenberg30591c52016-12-10 21:18:10 +01001764 } else
David Lawrence Ramsey3e222402017-02-01 21:10:49 -06001765 openfile->current_x = actual_x(openfile->current->data, mouse_col);
Benno Schulenberg8d692a82017-01-03 15:26:05 +01001766
1767 openfile->current_y = current_row;
1768 ensure_line_is_visible();
1769 refresh_needed = TRUE;
Benno Schulenberg1930e812014-06-20 18:06:22 +00001770 } else
1771#endif /* NANO_TINY */
1772 {
David Lawrence Ramseyd7fbc702017-01-02 13:41:27 -06001773 ssize_t current_row = openfile->current_y;
1774
Chris Allegrettaf55ada72009-11-13 20:38:32 +00001775 /* Move to where the click occurred. */
David Lawrence Ramsey3e222402017-02-01 21:10:49 -06001776 while (current_row < mouse_row && openfile->current->next != NULL) {
Chris Allegrettaf55ada72009-11-13 20:38:32 +00001777 openfile->current = openfile->current->next;
Benno Schulenberg13176792017-01-03 15:04:22 +01001778 current_row++;
1779 }
David Lawrence Ramsey3e222402017-02-01 21:10:49 -06001780 while (current_row > mouse_row && openfile->current->prev != NULL) {
Chris Allegrettaf55ada72009-11-13 20:38:32 +00001781 openfile->current = openfile->current->prev;
Benno Schulenberg13176792017-01-03 15:04:22 +01001782 current_row--;
1783 }
Chris Allegrettaf55ada72009-11-13 20:38:32 +00001784
1785 openfile->current_x = actual_x(openfile->current->data,
David Lawrence Ramsey3e222402017-02-01 21:10:49 -06001786 get_page_start(xplustabs()) + mouse_col);
Chris Allegrettaf55ada72009-11-13 20:38:32 +00001787 }
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001788
David Lawrence Ramseyebe34252005-11-15 03:17:35 +00001789#ifndef NANO_TINY
Benno Schulenberg13176792017-01-03 15:04:22 +01001790 /* Clicking where the cursor is toggles the mark, as does clicking
1791 * beyond the line length with the cursor at the end of the line. */
David Lawrence Ramseyebc38fd2007-06-28 16:00:50 +00001792 if (sameline && openfile->current_x == current_x_save)
1793 do_mark();
Benno Schulenberg99a649d2014-06-16 12:30:35 +00001794 else
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001795#endif
Benno Schulenberg99a649d2014-06-16 12:30:35 +00001796 /* The cursor moved; clean the cutbuffer on the next cut. */
1797 cutbuffer_reset();
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001798
Benno Schulenberg8d692a82017-01-03 15:26:05 +01001799 if (!ISSET(SOFTWRAP))
1800 edit_redraw(current_save);
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001801 }
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001802
Benno Schulenberg99a649d2014-06-16 12:30:35 +00001803 /* No more handling is needed. */
Benno Schulenberg1d064552014-06-13 12:19:44 +00001804 return 2;
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001805}
1806#endif /* !DISABLE_MOUSE */
1807
David Lawrence Ramseyef0d5a72006-05-22 02:08:49 +00001808/* The user typed output_len multibyte characters. Add them to the edit
David Lawrence Ramsey6fb66892006-05-27 17:39:19 +00001809 * buffer, filtering out all ASCII control characters if allow_cntrls is
David Lawrence Ramseyefec6412005-03-17 03:52:08 +00001810 * TRUE. */
1811void do_output(char *output, size_t output_len, bool allow_cntrls)
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001812{
Benno Schulenberg1102aaa2014-06-09 20:26:54 +00001813 size_t current_len, i = 0;
1814#ifndef NANO_TINY
David Lawrence Ramsey83ff6442017-01-19 19:58:37 -06001815 size_t orig_rows = 0;
Benno Schulenberg1102aaa2014-06-09 20:26:54 +00001816#endif
David Lawrence Ramseyb54155c2005-01-12 03:25:57 +00001817 char *char_buf = charalloc(mb_cur_max());
Benno Schulenberg79a4bf82016-12-19 19:58:15 +01001818 int char_len;
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001819
David Lawrence Ramsey6ad59cd2005-07-08 20:09:16 +00001820 current_len = strlen(openfile->current->data);
Benno Schulenberg1102aaa2014-06-09 20:26:54 +00001821
1822#ifndef NANO_TINY
Chris Allegrettaa8bc4922009-12-12 22:21:20 +00001823 if (ISSET(SOFTWRAP))
David Lawrence Ramsey83ff6442017-01-19 19:58:37 -06001824 orig_rows = strlenpt(openfile->current->data) / editwincols;
Benno Schulenberg1102aaa2014-06-09 20:26:54 +00001825#endif
David Lawrence Ramsey31b159c2005-05-26 05:17:13 +00001826
David Lawrence Ramseyb54155c2005-01-12 03:25:57 +00001827 while (i < output_len) {
Benno Schulenberg908663e2016-12-27 12:20:20 +01001828 /* Encode an embedded NUL byte as 0x0A. */
1829 if (output[i] == '\0')
1830 output[i] = '\n';
David Lawrence Ramseyabc94232004-12-08 23:24:31 +00001831
Benno Schulenberg95f417f2016-06-14 11:06:04 +02001832 /* Get the next multibyte character. */
Benno Schulenberg79a4bf82016-12-19 19:58:15 +01001833 char_len = parse_mbchar(output + i, char_buf, NULL);
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001834
Benno Schulenberg79a4bf82016-12-19 19:58:15 +01001835 i += char_len;
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001836
Benno Schulenberg95f417f2016-06-14 11:06:04 +02001837 /* If controls are not allowed, ignore an ASCII control character. */
Benno Schulenberg79a4bf82016-12-19 19:58:15 +01001838 if (!allow_cntrls && is_ascii_cntrl_char(*(output + i - char_len)))
David Lawrence Ramseyefec6412005-03-17 03:52:08 +00001839 continue;
1840
Benno Schulenberg95f417f2016-06-14 11:06:04 +02001841 /* If we're adding to the magicline, create a new magicline. */
Benno Schulenbergae648772016-10-21 15:59:16 +02001842 if (!ISSET(NO_NEWLINES) && openfile->filebot == openfile->current) {
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001843 new_magicline();
Benno Schulenbergae648772016-10-21 15:59:16 +02001844 if (margin > 0)
1845 refresh_needed = TRUE;
1846 }
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001847
David Lawrence Ramsey6ad59cd2005-07-08 20:09:16 +00001848 assert(openfile->current_x <= current_len);
David Lawrence Ramsey3e819142004-12-31 04:10:28 +00001849
Benno Schulenberg95f417f2016-06-14 11:06:04 +02001850 /* Make room for the new character and copy it into the line. */
1851 openfile->current->data = charealloc(openfile->current->data,
Benno Schulenberg79a4bf82016-12-19 19:58:15 +01001852 current_len + char_len + 1);
1853 charmove(openfile->current->data + openfile->current_x + char_len,
Benno Schulenbergf2da4662015-12-04 21:11:10 +00001854 openfile->current->data + openfile->current_x,
Benno Schulenberg7165bd52016-06-14 14:39:56 +02001855 current_len - openfile->current_x + 1);
David Lawrence Ramsey4eeff482005-11-05 04:59:00 +00001856 strncpy(openfile->current->data + openfile->current_x, char_buf,
Benno Schulenberg79a4bf82016-12-19 19:58:15 +01001857 char_len);
1858 current_len += char_len;
David Lawrence Ramsey6ad59cd2005-07-08 20:09:16 +00001859 openfile->totsize++;
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001860 set_modified();
1861
David Lawrence Ramseyebe34252005-11-15 03:17:35 +00001862#ifndef NANO_TINY
Benno Schulenberg60815462014-05-15 20:00:46 +00001863 add_undo(ADD);
Chris Allegretta07fcc4c2008-07-10 20:13:04 +00001864
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001865 /* Note that current_x has not yet been incremented. */
Benno Schulenbergf2da4662015-12-04 21:11:10 +00001866 if (openfile->mark_set && openfile->current == openfile->mark_begin &&
1867 openfile->current_x < openfile->mark_begin_x)
Benno Schulenberg79a4bf82016-12-19 19:58:15 +01001868 openfile->mark_begin_x += char_len;
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001869#endif
1870
Benno Schulenberg79a4bf82016-12-19 19:58:15 +01001871 openfile->current_x += char_len;
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001872
Benno Schulenberg60815462014-05-15 20:00:46 +00001873#ifndef NANO_TINY
1874 update_undo(ADD);
1875#endif
1876
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001877#ifndef DISABLE_WRAPPING
Benno Schulenberg0f3e3032016-12-02 17:37:11 +01001878 /* If text gets wrapped, the edit window needs a refresh. */
1879 if (!ISSET(NO_WRAP) && do_wrap(openfile->current))
1880 refresh_needed = TRUE;
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001881#endif
Benno Schulenberg438cb112015-11-25 09:10:02 +00001882 }
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001883
Benno Schulenberg1102aaa2014-06-09 20:26:54 +00001884#ifndef NANO_TINY
Benno Schulenberg43f35fc2016-10-18 13:03:01 +02001885 ensure_line_is_visible();
1886
Benno Schulenberg7598b772016-11-12 15:57:42 +01001887 /* If the number of screen rows that a softwrapped line occupies
1888 * has changed, we need a full refresh. */
Benno Schulenberg53f4a9f2016-04-25 21:14:18 +02001889 if (ISSET(SOFTWRAP) && refresh_needed == FALSE)
David Lawrence Ramsey83ff6442017-01-19 19:58:37 -06001890 if ((strlenpt(openfile->current->data) / editwincols) != orig_rows)
Benno Schulenberg53f4a9f2016-04-25 21:14:18 +02001891 refresh_needed = TRUE;
Benno Schulenberg1102aaa2014-06-09 20:26:54 +00001892#endif
Chris Allegrettaa8bc4922009-12-12 22:21:20 +00001893
David Lawrence Ramseyb54155c2005-01-12 03:25:57 +00001894 free(char_buf);
David Lawrence Ramsey78ea5e42004-12-12 19:04:56 +00001895
David Lawrence Ramsey157ce912005-07-16 23:36:10 +00001896 openfile->placewewant = xplustabs();
1897
Benno Schulenberg00389922014-04-04 11:59:03 +00001898#ifndef DISABLE_COLOR
Benno Schulenberg9ec546d2017-02-13 19:11:04 +01001899 check_the_multis(openfile->current);
Chris Allegretta019998a2009-01-26 07:55:01 +00001900#endif
Benno Schulenberg37712fb2016-01-03 16:21:04 +00001901
Benno Schulenberg2789bb02016-10-21 13:52:40 +02001902 if (!refresh_needed)
David Lawrence Ramsey6ad59cd2005-07-08 20:09:16 +00001903 update_line(openfile->current, openfile->current_x);
David Lawrence Ramsey74835712004-12-04 17:41:52 +00001904}
1905
David Lawrence Ramseya27bd652004-08-17 05:23:38 +00001906int main(int argc, char **argv)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001907{
1908 int optchr;
Benno Schulenberg3060ce32014-06-20 19:10:24 +00001909 ssize_t startline = 0, startcol = 0;
1910 /* Target line and column when specified on the command line. */
David Lawrence Ramseydf13e3b2004-08-12 19:48:21 +00001911#ifndef DISABLE_WRAPJUSTIFY
David Lawrence Ramsey3f12ada2005-07-25 22:54:16 +00001912 bool fill_used = FALSE;
Benno Schulenberg1f027a82015-11-21 19:44:27 +00001913 /* Was the fill option used on the command line? */
Benno Schulenberg04a230f2016-05-15 15:18:47 +02001914#ifndef DISABLE_WRAPPING
Benno Schulenberg1f027a82015-11-21 19:44:27 +00001915 bool forced_wrapping = FALSE;
1916 /* Should long lines be automatically hard wrapped? */
David Lawrence Ramseydf13e3b2004-08-12 19:48:21 +00001917#endif
Benno Schulenberg04a230f2016-05-15 15:18:47 +02001918#endif
Benno Schulenberg0636d7b2014-04-03 20:23:07 +00001919#ifndef DISABLE_MULTIBUFFER
David Lawrence Ramsey02517e02004-09-05 21:40:31 +00001920 bool old_multibuffer;
1921 /* The old value of the multibuffer option, restored after we
1922 * load all files on the command line. */
1923#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001924#ifdef HAVE_GETOPT_LONG
David Lawrence Ramsey9b13ff32002-12-22 16:30:00 +00001925 const struct option long_options[] = {
David Lawrence Ramsey4d72de72006-04-12 15:27:40 +00001926 {"boldtext", 0, NULL, 'D'},
Benno Schulenberg0636d7b2014-04-03 20:23:07 +00001927#ifndef DISABLE_MULTIBUFFER
David Lawrence Ramseyfe605242005-03-26 22:49:08 +00001928 {"multibuffer", 0, NULL, 'F'},
David Lawrence Ramsey5db0cdc2002-06-28 22:45:14 +00001929#endif
Benno Schulenbergeea09082014-04-13 20:50:20 +00001930#ifndef DISABLE_NANORC
David Lawrence Ramseyfe605242005-03-26 22:49:08 +00001931 {"ignorercfiles", 0, NULL, 'I'},
Chris Allegretta6df90f52002-07-19 01:08:59 +00001932#endif
David Lawrence Ramsey057edf72005-08-10 21:22:15 +00001933 {"rebindkeypad", 0, NULL, 'K'},
David Lawrence Ramseya0168ca2005-11-05 17:35:44 +00001934 {"nonewlines", 0, NULL, 'L'},
David Lawrence Ramseyfe605242005-03-26 22:49:08 +00001935 {"morespace", 0, NULL, 'O'},
David Lawrence Ramsey5db0cdc2002-06-28 22:45:14 +00001936#ifndef DISABLE_JUSTIFY
David Lawrence Ramseyfe605242005-03-26 22:49:08 +00001937 {"quotestr", 1, NULL, 'Q'},
David Lawrence Ramsey5db0cdc2002-06-28 22:45:14 +00001938#endif
David Lawrence Ramsey84635cd2005-06-17 22:53:41 +00001939 {"restricted", 0, NULL, 'R'},
David Lawrence Ramseyfe605242005-03-26 22:49:08 +00001940 {"tabsize", 1, NULL, 'T'},
1941 {"version", 0, NULL, 'V'},
Benno Schulenberg00389922014-04-04 11:59:03 +00001942#ifndef DISABLE_COLOR
David Lawrence Ramseyfe605242005-03-26 22:49:08 +00001943 {"syntax", 1, NULL, 'Y'},
David Lawrence Ramsey5db0cdc2002-06-28 22:45:14 +00001944#endif
Benno Schulenberg79526152015-07-15 19:40:37 +00001945 {"constantshow", 0, NULL, 'c'},
David Lawrence Ramseyfe605242005-03-26 22:49:08 +00001946 {"rebinddelete", 0, NULL, 'd'},
Benno Schulenberg10c90932016-10-23 12:56:47 +02001947#ifndef DISABLE_BROWSER
1948 {"showcursor", 0, NULL, 'g'},
1949#endif
Benno Schulenberg44995202015-06-20 18:48:43 +00001950 {"help", 0, NULL, 'h'},
Faissal Bensefiade95ca62016-10-20 09:44:29 +01001951#ifdef ENABLE_LINENUMBERS
1952 {"linenumbers", 0, NULL, 'l'},
1953#endif
David Lawrence Ramseyf5b256b2003-10-03 20:26:25 +00001954#ifndef DISABLE_MOUSE
David Lawrence Ramseyfe605242005-03-26 22:49:08 +00001955 {"mouse", 0, NULL, 'm'},
David Lawrence Ramsey9b13ff32002-12-22 16:30:00 +00001956#endif
Benno Schulenbergdb7064b2014-04-08 18:59:30 +00001957 {"noread", 0, NULL, 'n'},
Chris Allegrettae1f14522001-09-19 03:19:43 +00001958#ifndef DISABLE_OPERATINGDIR
David Lawrence Ramseyfe605242005-03-26 22:49:08 +00001959 {"operatingdir", 1, NULL, 'o'},
Chris Allegrettae1f14522001-09-19 03:19:43 +00001960#endif
David Lawrence Ramseyfe605242005-03-26 22:49:08 +00001961 {"preserve", 0, NULL, 'p'},
Chris Allegrettaa30eb782009-02-09 04:03:20 +00001962 {"quiet", 0, NULL, 'q'},
David Lawrence Ramsey5db0cdc2002-06-28 22:45:14 +00001963#ifndef DISABLE_WRAPJUSTIFY
David Lawrence Ramseyfe605242005-03-26 22:49:08 +00001964 {"fill", 1, NULL, 'r'},
Chris Allegretta2d7893d2001-07-11 02:08:33 +00001965#endif
David Lawrence Ramsey5db0cdc2002-06-28 22:45:14 +00001966#ifndef DISABLE_SPELLER
David Lawrence Ramseyfe605242005-03-26 22:49:08 +00001967 {"speller", 1, NULL, 's'},
David Lawrence Ramsey5db0cdc2002-06-28 22:45:14 +00001968#endif
David Lawrence Ramseyfe605242005-03-26 22:49:08 +00001969 {"tempfile", 0, NULL, 't'},
1970 {"view", 0, NULL, 'v'},
David Lawrence Ramsey2ab03f62002-10-17 02:19:31 +00001971#ifndef DISABLE_WRAPPING
David Lawrence Ramseyfe605242005-03-26 22:49:08 +00001972 {"nowrap", 0, NULL, 'w'},
David Lawrence Ramsey2ab03f62002-10-17 02:19:31 +00001973#endif
David Lawrence Ramseyfe605242005-03-26 22:49:08 +00001974 {"nohelp", 0, NULL, 'x'},
1975 {"suspend", 0, NULL, 'z'},
David Lawrence Ramseyebe34252005-11-15 03:17:35 +00001976#ifndef NANO_TINY
David Lawrence Ramseyfe605242005-03-26 22:49:08 +00001977 {"smarthome", 0, NULL, 'A'},
1978 {"backup", 0, NULL, 'B'},
David Lawrence Ramsey6f143c82005-06-15 23:20:56 +00001979 {"backupdir", 1, NULL, 'C'},
1980 {"tabstospaces", 0, NULL, 'E'},
Chris Allegrettabf88d272013-01-01 03:24:39 +00001981 {"locking", 0, NULL, 'G'},
David Lawrence Ramsey18a89a62005-06-17 17:37:46 +00001982 {"historylog", 0, NULL, 'H'},
David Lawrence Ramseyfe605242005-03-26 22:49:08 +00001983 {"noconvert", 0, NULL, 'N'},
Benno Schulenbergcadb4f32015-07-15 19:50:55 +00001984 {"poslog", 0, NULL, 'P'}, /* deprecated form, remove in 2018 */
1985 {"positionlog", 0, NULL, 'P'},
David Lawrence Ramseyfe605242005-03-26 22:49:08 +00001986 {"smooth", 0, NULL, 'S'},
David Lawrence Ramseye29111f2005-06-17 19:06:25 +00001987 {"quickblank", 0, NULL, 'U'},
David Lawrence Ramsey4f03daf2005-08-10 22:12:28 +00001988 {"wordbounds", 0, NULL, 'W'},
Benno Schulenberg6f129922016-06-30 18:02:45 +02001989 {"wordchars", 1, NULL, 'X'},
David Lawrence Ramseyfe605242005-03-26 22:49:08 +00001990 {"autoindent", 0, NULL, 'i'},
1991 {"cut", 0, NULL, 'k'},
Benno Schulenbergeac04462015-08-09 16:31:01 +00001992 {"unix", 0, NULL, 'u'},
Chris Allegretta05417a22009-08-17 07:52:10 +00001993 {"softwrap", 0, NULL, '$'},
Chris Allegretta3e3ae942001-09-22 19:02:04 +00001994#endif
David Lawrence Ramseyfe605242005-03-26 22:49:08 +00001995 {NULL, 0, NULL, 0}
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001996 };
1997#endif
1998
Benno Schulenbergaa09abe2016-06-12 11:13:45 +02001999 /* Back up the terminal settings so that they can be restored. */
2000 tcgetattr(0, &oldterm);
2001
David Lawrence Ramsey7eb30a82005-07-17 02:40:07 +00002002#ifdef ENABLE_UTF8
David Lawrence Ramseyfc693212004-12-23 17:43:27 +00002003 {
David Lawrence Ramseya78b4352007-05-25 14:39:40 +00002004 /* If the locale set exists and uses UTF-8, we should use
2005 * UTF-8. */
David Lawrence Ramseyfc693212004-12-23 17:43:27 +00002006 char *locale = setlocale(LC_ALL, "");
2007
David Lawrence Ramseya78b4352007-05-25 14:39:40 +00002008 if (locale != NULL && (strcmp(nl_langinfo(CODESET),
2009 "UTF-8") == 0)) {
David Lawrence Ramseyd15de732005-01-28 19:37:23 +00002010#ifdef USE_SLANG
David Lawrence Ramsey4ac129c2006-07-19 19:40:54 +00002011 SLutf8_enable(1);
David Lawrence Ramseyd15de732005-01-28 19:37:23 +00002012#endif
David Lawrence Ramsey4d72de72006-04-12 15:27:40 +00002013 utf8_init();
David Lawrence Ramsey7a4aaa52005-06-16 02:09:57 +00002014 }
David Lawrence Ramseyfc693212004-12-23 17:43:27 +00002015 }
2016#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002017 setlocale(LC_ALL, "");
David Lawrence Ramseyfc693212004-12-23 17:43:27 +00002018#endif
2019
David Lawrence Ramseyad1fd0d2004-07-27 15:46:58 +00002020#ifdef ENABLE_NLS
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002021 bindtextdomain(PACKAGE, LOCALEDIR);
2022 textdomain(PACKAGE);
2023#endif
2024
Benno Schulenbergeea09082014-04-13 20:50:20 +00002025#if defined(DISABLE_NANORC) && defined(DISABLE_ROOTWRAPPING)
Benno Schulenberg6f6ee842014-04-07 20:05:05 +00002026 /* If we don't have rcfile support, --disable-wrapping-as-root is
2027 * used, and we're root, turn wrapping off. */
David Lawrence Ramseya619ae62004-03-04 06:33:52 +00002028 if (geteuid() == NANO_ROOT_UID)
David Lawrence Ramseydc60b722002-10-25 16:08:53 +00002029 SET(NO_WRAP);
2030#endif
Chris Allegretta6df90f52002-07-19 01:08:59 +00002031
Benno Schulenbergeb5968f2016-11-17 18:05:09 +01002032 /* If the executable's name starts with 'r', activate restricted mode. */
2033 if (*(tail(argv[0])) == 'r')
2034 SET(RESTRICTED);
2035
Chris Allegretta6df90f52002-07-19 01:08:59 +00002036 while ((optchr =
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002037#ifdef HAVE_GETOPT_LONG
David Lawrence Ramsey068edf42005-06-12 16:13:44 +00002038 getopt_long(argc, argv,
Benno Schulenberg6f129922016-06-30 18:02:45 +02002039 "ABC:DEFGHIKLNOPQ:RST:UVWX:Y:abcdefghijklmno:pqr:s:tuvwxz$",
David Lawrence Ramsey068edf42005-06-12 16:13:44 +00002040 long_options, NULL)
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002041#else
David Lawrence Ramsey068edf42005-06-12 16:13:44 +00002042 getopt(argc, argv,
Benno Schulenberg6f129922016-06-30 18:02:45 +02002043 "ABC:DEFGHIKLNOPQ:RST:UVWX:Y:abcdefghijklmno:pqr:s:tuvwxz$")
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002044#endif
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002045 ) != -1) {
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002046 switch (optchr) {
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002047 case 'a':
2048 case 'b':
2049 case 'e':
2050 case 'f':
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002051 case 'j':
2052 /* Pico compatibility flags. */
2053 break;
David Lawrence Ramseyebe34252005-11-15 03:17:35 +00002054#ifndef NANO_TINY
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002055 case 'A':
2056 SET(SMART_HOME);
2057 break;
2058 case 'B':
2059 SET(BACKUP_FILE);
2060 break;
David Lawrence Ramsey6f143c82005-06-15 23:20:56 +00002061 case 'C':
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002062 backup_dir = mallocstrcpy(backup_dir, optarg);
2063 break;
David Lawrence Ramsey4d72de72006-04-12 15:27:40 +00002064#endif
2065 case 'D':
2066 SET(BOLD_TEXT);
2067 break;
2068#ifndef NANO_TINY
David Lawrence Ramsey6f143c82005-06-15 23:20:56 +00002069 case 'E':
2070 SET(TABS_TO_SPACES);
2071 break;
Chris Allegretta7004c282001-09-22 00:42:10 +00002072#endif
Benno Schulenberg0636d7b2014-04-03 20:23:07 +00002073#ifndef DISABLE_MULTIBUFFER
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002074 case 'F':
2075 SET(MULTIBUFFER);
2076 break;
Chris Allegretta2d7893d2001-07-11 02:08:33 +00002077#endif
David Lawrence Ramseyebe34252005-11-15 03:17:35 +00002078#ifndef NANO_TINY
Chris Allegrettabf88d272013-01-01 03:24:39 +00002079 case 'G':
2080 SET(LOCKING);
2081 break;
Benno Schulenbergb341f292014-06-19 20:05:24 +00002082#endif
2083#ifndef DISABLE_HISTORIES
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002084 case 'H':
2085 SET(HISTORYLOG);
2086 break;
David Lawrence Ramsey417b03a2003-09-06 21:44:37 +00002087#endif
Benno Schulenbergb341f292014-06-19 20:05:24 +00002088#ifndef DISABLE_NANORC
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002089 case 'I':
David Lawrence Ramsey18dae622006-04-24 18:54:29 +00002090 no_rcfiles = TRUE;
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002091 break;
Chris Allegretta6df90f52002-07-19 01:08:59 +00002092#endif
David Lawrence Ramsey057edf72005-08-10 21:22:15 +00002093 case 'K':
2094 SET(REBIND_KEYPAD);
2095 break;
David Lawrence Ramseya0168ca2005-11-05 17:35:44 +00002096 case 'L':
2097 SET(NO_NEWLINES);
2098 break;
David Lawrence Ramseyebe34252005-11-15 03:17:35 +00002099#ifndef NANO_TINY
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002100 case 'N':
2101 SET(NO_CONVERT);
2102 break;
Chris Allegrettaa8c22572002-02-15 19:17:02 +00002103#endif
David Lawrence Ramsey637b8bb2005-01-17 05:06:55 +00002104 case 'O':
2105 SET(MORE_SPACE);
2106 break;
Benno Schulenbergb341f292014-06-19 20:05:24 +00002107#ifndef DISABLE_HISTORIES
Chris Allegretta9bfda912011-02-16 06:52:30 +00002108 case 'P':
2109 SET(POS_HISTORY);
2110 break;
2111#endif
Chris Allegrettae4f940d2002-03-03 22:36:36 +00002112#ifndef DISABLE_JUSTIFY
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002113 case 'Q':
2114 quotestr = mallocstrcpy(quotestr, optarg);
2115 break;
Chris Allegrettae4f940d2002-03-03 22:36:36 +00002116#endif
David Lawrence Ramsey84635cd2005-06-17 22:53:41 +00002117 case 'R':
2118 SET(RESTRICTED);
2119 break;
David Lawrence Ramseyebe34252005-11-15 03:17:35 +00002120#ifndef NANO_TINY
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002121 case 'S':
David Lawrence Ramseyb2b69762005-06-16 02:13:10 +00002122 SET(SMOOTH_SCROLL);
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002123 break;
Chris Allegretta3e3ae942001-09-22 19:02:04 +00002124#endif
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002125 case 'T':
2126 if (!parse_num(optarg, &tabsize) || tabsize <= 0) {
David Lawrence Ramseyfed01952006-06-08 02:54:20 +00002127 fprintf(stderr, _("Requested tab size \"%s\" is invalid"), optarg);
David Lawrence Ramsey6420d442004-08-11 05:13:08 +00002128 fprintf(stderr, "\n");
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002129 exit(1);
2130 }
2131 break;
David Lawrence Ramseyebe34252005-11-15 03:17:35 +00002132#ifndef NANO_TINY
David Lawrence Ramseye29111f2005-06-17 19:06:25 +00002133 case 'U':
2134 SET(QUICK_BLANK);
2135 break;
2136#endif
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002137 case 'V':
2138 version();
2139 exit(0);
David Lawrence Ramseyebe34252005-11-15 03:17:35 +00002140#ifndef NANO_TINY
David Lawrence Ramsey4f03daf2005-08-10 22:12:28 +00002141 case 'W':
2142 SET(WORD_BOUNDS);
2143 break;
Benno Schulenberg6f129922016-06-30 18:02:45 +02002144 case 'X':
2145 word_chars = mallocstrcpy(word_chars, optarg);
2146 break;
David Lawrence Ramsey4f03daf2005-08-10 22:12:28 +00002147#endif
Benno Schulenberg00389922014-04-04 11:59:03 +00002148#ifndef DISABLE_COLOR
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002149 case 'Y':
2150 syntaxstr = mallocstrcpy(syntaxstr, optarg);
2151 break;
Chris Allegretta09900ff2002-05-04 04:23:30 +00002152#endif
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002153 case 'c':
David Lawrence Ramsey3435a0f2005-06-17 21:08:13 +00002154 SET(CONST_UPDATE);
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002155 break;
2156 case 'd':
2157 SET(REBIND_DELETE);
2158 break;
Benno Schulenberg10c90932016-10-23 12:56:47 +02002159 case 'g':
2160 SET(SHOW_CURSOR);
2161 break;
David Lawrence Ramseyebe34252005-11-15 03:17:35 +00002162#ifndef NANO_TINY
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002163 case 'i':
2164 SET(AUTOINDENT);
2165 break;
2166 case 'k':
2167 SET(CUT_TO_END);
2168 break;
Chris Allegrettad19e9912000-07-12 18:14:51 +00002169#endif
David Lawrence Ramseyf5b256b2003-10-03 20:26:25 +00002170#ifndef DISABLE_MOUSE
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002171 case 'm':
2172 SET(USE_MOUSE);
2173 break;
David Lawrence Ramsey9b13ff32002-12-22 16:30:00 +00002174#endif
Benno Schulenbergdb7064b2014-04-08 18:59:30 +00002175 case 'n':
2176 SET(NOREAD_MODE);
2177 break;
Chris Allegrettae1f14522001-09-19 03:19:43 +00002178#ifndef DISABLE_OPERATINGDIR
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002179 case 'o':
2180 operating_dir = mallocstrcpy(operating_dir, optarg);
2181 break;
Chris Allegrettae1f14522001-09-19 03:19:43 +00002182#endif
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002183 case 'p':
2184 SET(PRESERVE);
2185 break;
Benno Schulenberg85ddc712014-07-02 19:57:23 +00002186#ifndef DISABLE_NANORC
Chris Allegrettaa30eb782009-02-09 04:03:20 +00002187 case 'q':
2188 SET(QUIET);
2189 break;
Benno Schulenberg85ddc712014-07-02 19:57:23 +00002190#endif
Chris Allegretta6fe61492001-05-21 12:56:25 +00002191#ifndef DISABLE_WRAPJUSTIFY
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002192 case 'r':
2193 if (!parse_num(optarg, &wrap_at)) {
David Lawrence Ramseyfed01952006-06-08 02:54:20 +00002194 fprintf(stderr, _("Requested fill size \"%s\" is invalid"), optarg);
David Lawrence Ramsey6420d442004-08-11 05:13:08 +00002195 fprintf(stderr, "\n");
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002196 exit(1);
2197 }
David Lawrence Ramsey3f12ada2005-07-25 22:54:16 +00002198 fill_used = TRUE;
Benno Schulenberg04a230f2016-05-15 15:18:47 +02002199#ifndef DISABLE_WRAPPING
Benno Schulenberg1f027a82015-11-21 19:44:27 +00002200 forced_wrapping = TRUE;
Benno Schulenberg04a230f2016-05-15 15:18:47 +02002201#endif
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002202 break;
Chris Allegretta6fe61492001-05-21 12:56:25 +00002203#endif
Rocco Corsiaf5c3022001-01-12 07:51:05 +00002204#ifndef DISABLE_SPELLER
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002205 case 's':
2206 alt_speller = mallocstrcpy(alt_speller, optarg);
2207 break;
Rocco Corsiaf5c3022001-01-12 07:51:05 +00002208#endif
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002209 case 't':
2210 SET(TEMP_FILE);
2211 break;
Benno Schulenbergeac04462015-08-09 16:31:01 +00002212#ifndef NANO_TINY
Benno Schulenberg70cbbda2015-08-04 18:49:57 +00002213 case 'u':
2214 SET(MAKE_IT_UNIX);
2215 break;
Benno Schulenbergeac04462015-08-09 16:31:01 +00002216#endif
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002217 case 'v':
2218 SET(VIEW_MODE);
2219 break;
David Lawrence Ramsey95e0cf52003-01-02 16:32:20 +00002220#ifndef DISABLE_WRAPPING
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002221 case 'w':
2222 SET(NO_WRAP);
Benno Schulenberg499c6de2014-03-24 21:48:23 +00002223 /* If both --fill and --nowrap are given on the
2224 * command line, the last given option wins. */
Benno Schulenberg1f027a82015-11-21 19:44:27 +00002225 forced_wrapping = FALSE;
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002226 break;
David Lawrence Ramsey9b13ff32002-12-22 16:30:00 +00002227#endif
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002228 case 'x':
2229 SET(NO_HELP);
2230 break;
2231 case 'z':
2232 SET(SUSPEND);
2233 break;
Chris Allegretta05417a22009-08-17 07:52:10 +00002234#ifndef NANO_TINY
2235 case '$':
2236 SET(SOFTWRAP);
2237 break;
2238#endif
Faissal Bensefiade95ca62016-10-20 09:44:29 +01002239#ifdef ENABLE_LINENUMBERS
2240 case 'l':
2241 SET(LINE_NUMBERS);
2242 break;
2243#endif
Benno Schulenberg43019182014-04-27 12:13:26 +00002244 case 'h':
David Lawrence Ramseyc7b6ac52004-08-07 22:00:02 +00002245 usage();
Benno Schulenberg43019182014-04-27 12:13:26 +00002246 exit(0);
2247 default:
2248 printf(_("Type '%s -h' for a list of available options.\n"), argv[0]);
2249 exit(1);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002250 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002251 }
2252
Benno Schulenbergfcb4c3f2014-06-19 15:09:23 +00002253 /* If we're using restricted mode, disable suspending, backups,
2254 * rcfiles, and history files, since they all would allow reading
2255 * from or writing to files not specified on the command line. */
David Lawrence Ramseyd893fa92004-04-30 04:49:02 +00002256 if (ISSET(RESTRICTED)) {
2257 UNSET(SUSPEND);
2258 UNSET(BACKUP_FILE);
Benno Schulenbergeea09082014-04-13 20:50:20 +00002259#ifndef DISABLE_NANORC
David Lawrence Ramsey18dae622006-04-24 18:54:29 +00002260 no_rcfiles = TRUE;
Benno Schulenbergfcb4c3f2014-06-19 15:09:23 +00002261 UNSET(HISTORYLOG);
2262 UNSET(POS_HISTORY);
David Lawrence Ramsey9adc4452006-04-24 20:17:50 +00002263#endif
David Lawrence Ramseyd893fa92004-04-30 04:49:02 +00002264 }
2265
Benno Schulenberga2dcd6e2014-04-07 09:24:10 +00002266 /* Set up the function and shortcut lists. This needs to be done
2267 * before reading the rcfile, to be able to rebind/unbind keys. */
2268 shortcut_init();
Chris Allegretta79a33bb2008-03-05 07:34:01 +00002269
Chris Allegretta7662c862003-01-13 01:35:15 +00002270/* We've read through the command line options. Now back up the flags
David Lawrence Ramsey02517e02004-09-05 21:40:31 +00002271 * and values that are set, and read the rcfile(s). If the values
2272 * haven't changed afterward, restore the backed-up values. */
Benno Schulenbergeea09082014-04-13 20:50:20 +00002273#ifndef DISABLE_NANORC
David Lawrence Ramsey18dae622006-04-24 18:54:29 +00002274 if (!no_rcfiles) {
David Lawrence Ramseye21adfa2002-09-13 18:14:04 +00002275#ifndef DISABLE_OPERATINGDIR
Chris Allegretta7662c862003-01-13 01:35:15 +00002276 char *operating_dir_cpy = operating_dir;
2277#endif
David Lawrence Ramsey7e8dd192004-08-12 20:06:20 +00002278#ifndef DISABLE_WRAPJUSTIFY
David Lawrence Ramsey49c3f242004-07-12 16:07:14 +00002279 ssize_t wrap_at_cpy = wrap_at;
Chris Allegretta7662c862003-01-13 01:35:15 +00002280#endif
David Lawrence Ramseyebe34252005-11-15 03:17:35 +00002281#ifndef NANO_TINY
David Lawrence Ramsey04e42a62004-02-28 16:24:31 +00002282 char *backup_dir_cpy = backup_dir;
Benno Schulenberg6f129922016-06-30 18:02:45 +02002283 char *word_chars_cpy = word_chars;
David Lawrence Ramsey04e42a62004-02-28 16:24:31 +00002284#endif
Chris Allegretta7662c862003-01-13 01:35:15 +00002285#ifndef DISABLE_JUSTIFY
2286 char *quotestr_cpy = quotestr;
2287#endif
2288#ifndef DISABLE_SPELLER
2289 char *alt_speller_cpy = alt_speller;
2290#endif
David Lawrence Ramsey49c3f242004-07-12 16:07:14 +00002291 ssize_t tabsize_cpy = tabsize;
Chris Allegrettaa48507d2009-08-14 03:18:29 +00002292 unsigned flags_cpy[sizeof(flags) / sizeof(flags[0])];
2293 size_t i;
2294
2295 memcpy(flags_cpy, flags, sizeof(flags_cpy));
Chris Allegretta7662c862003-01-13 01:35:15 +00002296
Chris Allegretta5ec68622003-02-05 02:39:34 +00002297#ifndef DISABLE_OPERATINGDIR
Chris Allegretta7662c862003-01-13 01:35:15 +00002298 operating_dir = NULL;
Chris Allegretta5ec68622003-02-05 02:39:34 +00002299#endif
David Lawrence Ramseyebe34252005-11-15 03:17:35 +00002300#ifndef NANO_TINY
David Lawrence Ramsey04e42a62004-02-28 16:24:31 +00002301 backup_dir = NULL;
Benno Schulenberg6f129922016-06-30 18:02:45 +02002302 word_chars = NULL;
David Lawrence Ramsey04e42a62004-02-28 16:24:31 +00002303#endif
Chris Allegretta5ec68622003-02-05 02:39:34 +00002304#ifndef DISABLE_JUSTIFY
Chris Allegretta7662c862003-01-13 01:35:15 +00002305 quotestr = NULL;
Chris Allegretta5ec68622003-02-05 02:39:34 +00002306#endif
2307#ifndef DISABLE_SPELLER
Chris Allegretta7662c862003-01-13 01:35:15 +00002308 alt_speller = NULL;
Chris Allegretta5ec68622003-02-05 02:39:34 +00002309#endif
Chris Allegretta7662c862003-01-13 01:35:15 +00002310
Benno Schulenbergc1a48422016-11-27 18:21:04 +01002311 do_rcfiles();
Chris Allegretta7662c862003-01-13 01:35:15 +00002312
Chris Allegretta79a33bb2008-03-05 07:34:01 +00002313#ifdef DEBUG
Benno Schulenberg0b6d6f42015-03-27 13:46:50 +00002314 fprintf(stderr, "After rebinding keys...\n");
2315 print_sclist();
Chris Allegretta79a33bb2008-03-05 07:34:01 +00002316#endif
2317
Chris Allegretta7662c862003-01-13 01:35:15 +00002318#ifndef DISABLE_OPERATINGDIR
2319 if (operating_dir_cpy != NULL) {
2320 free(operating_dir);
2321 operating_dir = operating_dir_cpy;
2322 }
2323#endif
David Lawrence Ramseydf13e3b2004-08-12 19:48:21 +00002324#ifndef DISABLE_WRAPJUSTIFY
David Lawrence Ramsey3f12ada2005-07-25 22:54:16 +00002325 if (fill_used)
Chris Allegretta7662c862003-01-13 01:35:15 +00002326 wrap_at = wrap_at_cpy;
2327#endif
David Lawrence Ramseyebe34252005-11-15 03:17:35 +00002328#ifndef NANO_TINY
David Lawrence Ramsey04e42a62004-02-28 16:24:31 +00002329 if (backup_dir_cpy != NULL) {
2330 free(backup_dir);
2331 backup_dir = backup_dir_cpy;
2332 }
Benno Schulenberg6f129922016-06-30 18:02:45 +02002333 if (word_chars_cpy != NULL) {
2334 free(word_chars);
2335 word_chars = word_chars_cpy;
2336 }
David Lawrence Ramseye68748a2007-12-10 17:59:26 +00002337#endif
Chris Allegretta7662c862003-01-13 01:35:15 +00002338#ifndef DISABLE_JUSTIFY
2339 if (quotestr_cpy != NULL) {
2340 free(quotestr);
2341 quotestr = quotestr_cpy;
2342 }
2343#endif
2344#ifndef DISABLE_SPELLER
2345 if (alt_speller_cpy != NULL) {
2346 free(alt_speller);
2347 alt_speller = alt_speller_cpy;
2348 }
2349#endif
David Lawrence Ramsey04419b92004-07-18 18:13:54 +00002350 if (tabsize_cpy != -1)
Chris Allegretta7662c862003-01-13 01:35:15 +00002351 tabsize = tabsize_cpy;
Chris Allegrettaa48507d2009-08-14 03:18:29 +00002352
2353 for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++)
2354 flags[i] |= flags_cpy[i];
Chris Allegretta7662c862003-01-13 01:35:15 +00002355 }
Benno Schulenberg6f6ee842014-04-07 20:05:05 +00002356#ifdef DISABLE_ROOTWRAPPING
2357 /* If we don't have any rcfiles, --disable-wrapping-as-root is used,
2358 * and we're root, turn wrapping off. */
2359 else if (geteuid() == NANO_ROOT_UID)
2360 SET(NO_WRAP);
2361#endif
Benno Schulenbergeea09082014-04-13 20:50:20 +00002362#endif /* !DISABLE_NANORC */
Chris Allegretta7662c862003-01-13 01:35:15 +00002363
Chris Allegretta8b6f6fc2009-11-22 21:35:56 +00002364#ifndef DISABLE_WRAPPING
Benno Schulenberg1f027a82015-11-21 19:44:27 +00002365 /* Override a "set nowrap" in an rcfile (or a --disable-wrapping-as-root)
2366 * if --fill was given on the command line and not undone by --nowrap. */
2367 if (forced_wrapping)
Chris Allegretta16e07d52009-11-18 12:39:47 +00002368 UNSET(NO_WRAP);
Chris Allegretta8b6f6fc2009-11-22 21:35:56 +00002369#endif
Chris Allegretta16e07d52009-11-18 12:39:47 +00002370
David Lawrence Ramsey4d72de72006-04-12 15:27:40 +00002371 /* If we're using bold text instead of reverse video text, set it up
2372 * now. */
2373 if (ISSET(BOLD_TEXT))
Benno Schulenbergc9700352014-05-04 08:53:06 +00002374 hilite_attribute = A_BOLD;
David Lawrence Ramsey4d72de72006-04-12 15:27:40 +00002375
Benno Schulenbergb341f292014-06-19 20:05:24 +00002376#ifndef DISABLE_HISTORIES
David Lawrence Ramsey4d72de72006-04-12 15:27:40 +00002377 /* Set up the search/replace history. */
Chris Allegrettad8451932003-03-11 03:50:40 +00002378 history_init();
Benno Schulenbergb341f292014-06-19 20:05:24 +00002379 /* Verify that the home directory and ~/.nano subdir exist. */
Benno Schulenbergfcb4c3f2014-06-19 15:09:23 +00002380 if (ISSET(HISTORYLOG) || ISSET(POS_HISTORY)) {
2381 get_homedir();
2382 if (homedir == NULL || check_dotnano() == 0) {
2383 UNSET(HISTORYLOG);
2384 UNSET(POS_HISTORY);
Chris Allegretta9bfda912011-02-16 06:52:30 +00002385 }
Chris Allegretta9bfda912011-02-16 06:52:30 +00002386 }
Benno Schulenbergfcb4c3f2014-06-19 15:09:23 +00002387 if (ISSET(HISTORYLOG))
2388 load_history();
2389 if (ISSET(POS_HISTORY))
2390 load_poshistory();
Benno Schulenbergb341f292014-06-19 20:05:24 +00002391#endif /* !DISABLE_HISTORIES */
Chris Allegrettad8451932003-03-11 03:50:40 +00002392
Benno Schulenbergb341f292014-06-19 20:05:24 +00002393#ifndef NANO_TINY
David Lawrence Ramseydd7cc722004-05-28 23:45:25 +00002394 /* Set up the backup directory (unless we're using restricted mode,
David Lawrence Ramsey32e3b882004-05-29 01:20:17 +00002395 * in which case backups are disabled, since they would allow
2396 * reading from or writing to files not specified on the command
2397 * line). This entails making sure it exists and is a directory, so
2398 * that backup files will be saved there. */
David Lawrence Ramseydd7cc722004-05-28 23:45:25 +00002399 if (!ISSET(RESTRICTED))
2400 init_backup_dir();
Benno Schulenbergb341f292014-06-19 20:05:24 +00002401#endif
David Lawrence Ramsey04e42a62004-02-28 16:24:31 +00002402
Benno Schulenbergaa09abe2016-06-12 11:13:45 +02002403#ifndef DISABLE_OPERATINGDIR
2404 /* Set up the operating directory. This entails chdir()ing there,
2405 * so that file reads and writes will be based there. */
2406 init_operating_dir();
2407#endif
2408
Chris Allegretta7662c862003-01-13 01:35:15 +00002409#ifndef DISABLE_JUSTIFY
David Lawrence Ramseyd89617f2006-01-06 21:51:10 +00002410 /* If punct wasn't specified, set its default value. */
David Lawrence Ramsey2c62b072004-05-29 16:38:57 +00002411 if (punct == NULL)
David Lawrence Ramsey5329f232006-01-03 04:53:41 +00002412 punct = mallocstrcpy(NULL, "!.?");
David Lawrence Ramsey2c62b072004-05-29 16:38:57 +00002413
David Lawrence Ramseyd89617f2006-01-06 21:51:10 +00002414 /* If brackets wasn't specified, set its default value. */
David Lawrence Ramsey2c62b072004-05-29 16:38:57 +00002415 if (brackets == NULL)
David Lawrence Ramsey5329f232006-01-03 04:53:41 +00002416 brackets = mallocstrcpy(NULL, "\"')>]}");
David Lawrence Ramsey2c62b072004-05-29 16:38:57 +00002417
David Lawrence Ramseyd89617f2006-01-06 21:51:10 +00002418 /* If quotestr wasn't specified, set its default value. */
Chris Allegretta7662c862003-01-13 01:35:15 +00002419 if (quotestr == NULL)
David Lawrence Ramsey74af3a72004-06-12 21:03:14 +00002420 quotestr = mallocstrcpy(NULL,
Chris Allegretta7662c862003-01-13 01:35:15 +00002421#ifdef HAVE_REGEX_H
David Lawrence Ramsey5329f232006-01-03 04:53:41 +00002422 "^([ \t]*[#:>|}])+"
Chris Allegretta7662c862003-01-13 01:35:15 +00002423#else
David Lawrence Ramsey74af3a72004-06-12 21:03:14 +00002424 "> "
Chris Allegretta7662c862003-01-13 01:35:15 +00002425#endif
David Lawrence Ramsey74af3a72004-06-12 21:03:14 +00002426 );
David Lawrence Ramsey819c7f02004-07-30 03:54:34 +00002427#ifdef HAVE_REGEX_H
Benno Schulenberg2f817a62016-03-22 10:42:28 +00002428 quoterc = regcomp(&quotereg, quotestr, NANO_REG_EXTENDED);
David Lawrence Ramsey819c7f02004-07-30 03:54:34 +00002429
2430 if (quoterc == 0) {
2431 /* We no longer need quotestr, just quotereg. */
2432 free(quotestr);
2433 quotestr = NULL;
2434 } else {
2435 size_t size = regerror(quoterc, &quotereg, NULL, 0);
2436
2437 quoteerr = charalloc(size);
2438 regerror(quoterc, &quotereg, quoteerr, size);
2439 }
2440#else
2441 quotelen = strlen(quotestr);
2442#endif /* !HAVE_REGEX_H */
Chris Allegretta7662c862003-01-13 01:35:15 +00002443#endif /* !DISABLE_JUSTIFY */
David Lawrence Ramsey04e42a62004-02-28 16:24:31 +00002444
David Lawrence Ramsey3aedb362004-05-28 22:42:41 +00002445#ifndef DISABLE_SPELLER
2446 /* If we don't have an alternative spell checker after reading the
David Lawrence Ramsey32e3b882004-05-29 01:20:17 +00002447 * command line and/or rcfile(s), check $SPELL for one, as Pico
David Lawrence Ramseydd7cc722004-05-28 23:45:25 +00002448 * does (unless we're using restricted mode, in which case spell
David Lawrence Ramsey32e3b882004-05-29 01:20:17 +00002449 * checking is disabled, since it would allow reading from or
2450 * writing to files not specified on the command line). */
David Lawrence Ramseydd7cc722004-05-28 23:45:25 +00002451 if (!ISSET(RESTRICTED) && alt_speller == NULL) {
David Lawrence Ramsey3aedb362004-05-28 22:42:41 +00002452 char *spellenv = getenv("SPELL");
2453 if (spellenv != NULL)
2454 alt_speller = mallocstrcpy(NULL, spellenv);
2455 }
2456#endif
2457
David Lawrence Ramseyd89617f2006-01-06 21:51:10 +00002458#ifndef NANO_TINY
2459 /* If matchbrackets wasn't specified, set its default value. */
2460 if (matchbrackets == NULL)
2461 matchbrackets = mallocstrcpy(NULL, "(<[{)>]}");
David Lawrence Ramseyd89617f2006-01-06 21:51:10 +00002462
Benno Schulenberg91c740e2014-04-08 12:24:52 +00002463 /* If whitespace wasn't specified, set its default value. If we're
2464 * using UTF-8, it's Unicode 00BB (Right-Pointing Double Angle
2465 * Quotation Mark) and Unicode 00B7 (Middle Dot). Otherwise, it's
2466 * ">" and ".". */
Benno Schulenberg55a0d762014-03-24 13:35:50 +00002467 if (whitespace == NULL) {
Benno Schulenbergcf715782014-03-27 11:06:16 +00002468#ifdef ENABLE_UTF8
Benno Schulenbergc85dc052014-03-16 13:19:41 +00002469 if (using_utf8()) {
Benno Schulenberg91c740e2014-04-08 12:24:52 +00002470 whitespace = mallocstrcpy(NULL, "\xC2\xBB\xC2\xB7");
Benno Schulenbergc85dc052014-03-16 13:19:41 +00002471 whitespace_len[0] = 2;
2472 whitespace_len[1] = 2;
Benno Schulenbergcf715782014-03-27 11:06:16 +00002473 } else
2474#endif
2475 {
Benno Schulenbergc85dc052014-03-16 13:19:41 +00002476 whitespace = mallocstrcpy(NULL, ">.");
2477 whitespace_len[0] = 1;
2478 whitespace_len[1] = 1;
2479 }
Benno Schulenberg55a0d762014-03-24 13:35:50 +00002480 }
Benno Schulenberg70b2d082014-04-05 20:28:29 +00002481#endif /* !NANO_TINY */
David Lawrence Ramsey483ea322004-05-29 16:25:30 +00002482
Benno Schulenberg51743232016-03-28 19:14:33 +00002483 /* Initialize the search string. */
Benno Schulenberg1cf22d42015-04-21 18:42:11 +00002484 last_search = mallocstrcpy(NULL, "");
Benno Schulenberg1cf22d42015-04-21 18:42:11 +00002485
David Lawrence Ramsey02517e02004-09-05 21:40:31 +00002486 /* If tabsize wasn't specified, set its default value. */
Chris Allegretta7662c862003-01-13 01:35:15 +00002487 if (tabsize == -1)
David Lawrence Ramsey02517e02004-09-05 21:40:31 +00002488 tabsize = WIDTH_OF_TAB;
David Lawrence Ramseyf21cd102002-06-13 00:40:19 +00002489
David Lawrence Ramseye68748a2007-12-10 17:59:26 +00002490 /* Initialize curses mode. If this fails, get out. */
2491 if (initscr() == NULL)
2492 exit(1);
David Lawrence Ramseyb386a902005-07-10 02:37:38 +00002493
2494 /* Set up the terminal state. */
David Lawrence Ramsey8aaf0302004-07-27 16:46:35 +00002495 terminal_init();
David Lawrence Ramseyc53a92d2004-01-12 03:28:06 +00002496
Benno Schulenberg08cd1972016-09-08 21:00:51 +02002497#ifdef __linux__
Benno Schulenberg290d2782016-07-29 09:15:07 +02002498 /* Check whether we're running on a Linux console. */
2499 console = (getenv("DISPLAY") == NULL);
Benno Schulenberg928a24c2016-08-11 12:37:11 +02002500#endif
Benno Schulenberge7f39bc2016-08-28 21:00:13 +02002501
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002502#ifdef DEBUG
Jordi Mallachf9390af2003-08-05 19:31:12 +00002503 fprintf(stderr, "Main: set up windows\n");
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002504#endif
2505
David Lawrence Ramsey3f12ada2005-07-25 22:54:16 +00002506 /* Initialize all the windows based on the current screen
2507 * dimensions. */
Chris Allegretta2a42af12000-09-12 23:02:49 +00002508 window_init();
David Lawrence Ramsey3f12ada2005-07-25 22:54:16 +00002509
Benno Schulenberg9c2e2702016-10-28 10:50:06 +02002510 editwincols = COLS;
2511
David Lawrence Ramsey3f12ada2005-07-25 22:54:16 +00002512 /* Set up the signal handlers. */
2513 signal_init();
2514
David Lawrence Ramseyf5b256b2003-10-03 20:26:25 +00002515#ifndef DISABLE_MOUSE
David Lawrence Ramsey503bad02006-06-09 18:24:37 +00002516 /* Initialize mouse support. */
Chris Allegretta756f2202000-09-01 13:32:47 +00002517 mouse_init();
David Lawrence Ramsey9b13ff32002-12-22 16:30:00 +00002518#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002519
Benno Schulenberg16639942014-05-03 18:24:45 +00002520#ifndef DISABLE_COLOR
2521 set_colorpairs();
2522#else
Benno Schulenberg960e8482016-07-12 09:35:48 +02002523 interface_color_pair[TITLE_BAR] = hilite_attribute;
Benno Schulenbergde2aa4f2016-10-20 10:07:48 +02002524 interface_color_pair[LINE_NUMBER] = hilite_attribute;
Benno Schulenberg960e8482016-07-12 09:35:48 +02002525 interface_color_pair[STATUS_BAR] = hilite_attribute;
2526 interface_color_pair[KEY_COMBO] = hilite_attribute;
2527 interface_color_pair[FUNCTION_TAG] = A_NORMAL;
Benno Schulenberg16639942014-05-03 18:24:45 +00002528#endif
2529
Benno Schulenbergc6dbcf92016-06-25 15:16:52 +02002530 /* Ask ncurses for the key codes for Control+Left/Right/Up/Down. */
Benno Schulenbergc6615062016-08-16 10:49:55 +02002531 controlleft = get_keycode("kLFT5", CONTROL_LEFT);
2532 controlright = get_keycode("kRIT5", CONTROL_RIGHT);
2533 controlup = get_keycode("kUP5", CONTROL_UP);
2534 controldown = get_keycode("kDN5", CONTROL_DOWN);
Benno Schulenbergf2c72bf2016-11-17 17:32:28 +01002535#ifndef NANO_TINY
Benno Schulenberg382c9d72016-04-24 11:28:28 +02002536 /* Ask for the codes for Shift+Control+Left/Right/Up/Down. */
2537 shiftcontrolleft = get_keycode("kLFT6", SHIFT_CONTROL_LEFT);
2538 shiftcontrolright = get_keycode("kRIT6", SHIFT_CONTROL_RIGHT);
2539 shiftcontrolup = get_keycode("kUP6", SHIFT_CONTROL_UP);
2540 shiftcontroldown = get_keycode("kDN6", SHIFT_CONTROL_DOWN);
2541 /* Ask for the codes for Shift+Alt+Left/Right/Up/Down. */
2542 shiftaltleft = get_keycode("kLFT4", SHIFT_ALT_LEFT);
2543 shiftaltright = get_keycode("kRIT4", SHIFT_ALT_RIGHT);
2544 shiftaltup = get_keycode("kUP4", SHIFT_ALT_UP);
2545 shiftaltdown = get_keycode("kDN4", SHIFT_ALT_DOWN);
Benno Schulenbergf08d79d2015-11-23 08:52:23 +00002546#endif
2547
Benno Schulenbergf2150d32016-07-11 14:21:38 +02002548#ifndef USE_SLANG
2549 /* Tell ncurses to pass the Esc key quickly. */
2550 set_escdelay(50);
2551#endif
2552
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002553#ifdef DEBUG
Jordi Mallachf9390af2003-08-05 19:31:12 +00002554 fprintf(stderr, "Main: open file\n");
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002555#endif
David Lawrence Ramsey02517e02004-09-05 21:40:31 +00002556
David Lawrence Ramsey775eeba2005-05-16 18:38:16 +00002557 /* If there's a +LINE or +LINE,COLUMN flag here, it is the first
2558 * non-option argument, and it is followed by at least one other
2559 * argument, the filename it applies to. */
David Lawrence Ramseybf1346f2004-10-22 20:25:56 +00002560 if (0 < optind && optind < argc - 1 && argv[optind][0] == '+') {
Benno Schulenberge8c7cf22017-01-17 14:17:42 +01002561 if (!parse_line_column(&argv[optind][1], &startline, &startcol))
2562 statusline(ALERT, _("Invalid line or column number"));
David Lawrence Ramseybf1346f2004-10-22 20:25:56 +00002563 optind++;
2564 }
2565
Benno Schulenberge7f39bc2016-08-28 21:00:13 +02002566 /* If one of the arguments is a dash, read text from standard input. */
Chris Allegretta25d459a2009-01-30 08:34:27 +00002567 if (optind < argc && !strcmp(argv[optind], "-")) {
Chris Allegrettab0f0b7f2009-01-30 17:37:44 +00002568 stdin_pager();
Chris Allegretta25d459a2009-01-30 08:34:27 +00002569 set_modified();
2570 optind++;
2571 }
2572
Benno Schulenberg0636d7b2014-04-03 20:23:07 +00002573#ifndef DISABLE_MULTIBUFFER
David Lawrence Ramsey02517e02004-09-05 21:40:31 +00002574 old_multibuffer = ISSET(MULTIBUFFER);
2575 SET(MULTIBUFFER);
2576
2577 /* Read all the files after the first one on the command line into
2578 * new buffers. */
2579 {
David Lawrence Ramsey2cf6d712005-06-28 06:25:34 +00002580 int i = optind + 1;
Benno Schulenberg3060ce32014-06-20 19:10:24 +00002581 ssize_t iline = 0, icol = 0;
David Lawrence Ramsey775eeba2005-05-16 18:38:16 +00002582
David Lawrence Ramseybf1346f2004-10-22 20:25:56 +00002583 for (; i < argc; i++) {
Benno Schulenbergd52f1082015-07-19 09:25:25 +00002584 /* If there's a +LINE or +LINE,COLUMN flag here, it is followed
2585 * by at least one other argument: the filename it applies to. */
Benno Schulenberge8c7cf22017-01-17 14:17:42 +01002586 if (i < argc - 1 && argv[i][0] == '+') {
2587 if (!parse_line_column(&argv[i][1], &iline, &icol))
2588 statusline(ALERT, _("Invalid line or column number"));
2589 } else {
Benno Schulenberg37d8ad82015-12-30 10:11:20 +00002590 /* If opening fails, don't try to position the cursor. */
2591 if (!open_buffer(argv[i], FALSE))
2592 continue;
David Lawrence Ramsey775eeba2005-05-16 18:38:16 +00002593
Benno Schulenbergd52f1082015-07-19 09:25:25 +00002594 /* If a position was given on the command line, go there. */
Benno Schulenberg3060ce32014-06-20 19:10:24 +00002595 if (iline > 0 || icol > 0) {
Benno Schulenberg46db6382015-12-31 19:20:40 +00002596 do_gotolinecolumn(iline, icol, FALSE, FALSE);
Benno Schulenberg9dc544a2015-07-19 09:01:59 +00002597 iline = 0;
2598 icol = 0;
David Lawrence Ramseybf1346f2004-10-22 20:25:56 +00002599 }
Benno Schulenbergb341f292014-06-19 20:05:24 +00002600#ifndef DISABLE_HISTORIES
Benno Schulenbergf8ed6bb2016-01-29 16:20:28 +00002601 else if (ISSET(POS_HISTORY)) {
Chris Allegretta9bfda912011-02-16 06:52:30 +00002602 ssize_t savedposline, savedposcol;
Benno Schulenbergd52f1082015-07-19 09:25:25 +00002603 /* If edited before, restore the last cursor position. */
Benno Schulenbergdc187462016-12-23 13:49:14 +01002604 if (has_old_position(argv[i], &savedposline, &savedposcol))
Benno Schulenberg1592ca02015-12-31 17:20:46 +00002605 do_gotolinecolumn(savedposline, savedposcol,
Benno Schulenberg46db6382015-12-31 19:20:40 +00002606 FALSE, FALSE);
Chris Allegretta9bfda912011-02-16 06:52:30 +00002607 }
Benno Schulenbergd6e39722014-02-22 16:26:30 +00002608#endif
David Lawrence Ramseybf1346f2004-10-22 20:25:56 +00002609 }
2610 }
Chris Allegretta7662c862003-01-13 01:35:15 +00002611 }
Benno Schulenberg70b2d082014-04-05 20:28:29 +00002612#endif /* !DISABLE_MULTIBUFFER */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002613
Benno Schulenbergd52f1082015-07-19 09:25:25 +00002614 /* Now read the first file on the command line into a new buffer. */
David Lawrence Ramsey02517e02004-09-05 21:40:31 +00002615 if (optind < argc)
Chris Allegretta14c86202008-08-03 04:48:05 +00002616 open_buffer(argv[optind], FALSE);
David Lawrence Ramsey02517e02004-09-05 21:40:31 +00002617
Benno Schulenbergd52f1082015-07-19 09:25:25 +00002618 /* If all the command-line arguments were invalid files like directories,
2619 * or if there were no filenames given, we didn't open any file. In this
2620 * case, load a blank buffer. Also, unset view mode to allow editing. */
David Lawrence Ramsey6ad59cd2005-07-08 20:09:16 +00002621 if (openfile == NULL) {
Chris Allegretta14c86202008-08-03 04:48:05 +00002622 open_buffer("", FALSE);
David Lawrence Ramsey02517e02004-09-05 21:40:31 +00002623 UNSET(VIEW_MODE);
David Lawrence Ramsey02517e02004-09-05 21:40:31 +00002624 }
2625
Benno Schulenberg0636d7b2014-04-03 20:23:07 +00002626#ifndef DISABLE_MULTIBUFFER
David Lawrence Ramsey02517e02004-09-05 21:40:31 +00002627 if (!old_multibuffer)
2628 UNSET(MULTIBUFFER);
2629#endif
2630
Benno Schulenbergd52f1082015-07-19 09:25:25 +00002631 /* If a starting position was given on the command line, go there. */
Benno Schulenberg3060ce32014-06-20 19:10:24 +00002632 if (startline > 0 || startcol > 0)
Benno Schulenberg46db6382015-12-31 19:20:40 +00002633 do_gotolinecolumn(startline, startcol, FALSE, FALSE);
Benno Schulenbergb341f292014-06-19 20:05:24 +00002634#ifndef DISABLE_HISTORIES
Benno Schulenberg98e72f52016-01-29 17:18:27 +00002635 else if (ISSET(POS_HISTORY)) {
Chris Allegretta9bfda912011-02-16 06:52:30 +00002636 ssize_t savedposline, savedposcol;
Benno Schulenbergd52f1082015-07-19 09:25:25 +00002637 /* If the file was edited before, restore the last cursor position. */
Benno Schulenbergdc187462016-12-23 13:49:14 +01002638 if (has_old_position(argv[optind], &savedposline, &savedposcol))
Benno Schulenberg46db6382015-12-31 19:20:40 +00002639 do_gotolinecolumn(savedposline, savedposcol, FALSE, FALSE);
Chris Allegretta9bfda912011-02-16 06:52:30 +00002640 }
Benno Schulenbergd6e39722014-02-22 16:26:30 +00002641#endif
David Lawrence Ramsey775eeba2005-05-16 18:38:16 +00002642
Benno Schulenbergf5eb3162016-02-23 12:37:10 +00002643#ifdef DEBUG
Benno Schulenberge7f39bc2016-08-28 21:00:13 +02002644 fprintf(stderr, "Main: show buffer contents, and enter main loop\n");
Benno Schulenbergf5eb3162016-02-23 12:37:10 +00002645#endif
2646
David Lawrence Ramseyf3318a92007-12-03 18:40:33 +00002647 display_buffer();
Robert Siemborski6967eec2000-07-08 14:23:32 +00002648
David Lawrence Ramsey6aec4b82004-03-15 20:26:30 +00002649 while (TRUE) {
Benno Schulenberg023edff2016-10-21 14:31:37 +02002650#ifdef ENABLE_LINENUMBERS
2651 int needed_margin = digits(openfile->filebot->lineno) + 1;
2652
2653 /* Only enable line numbers when there is enough room for them. */
David Lawrence Ramseyc24545f2017-02-09 10:20:04 -06002654 if (!ISSET(LINE_NUMBERS) || needed_margin > COLS - 4)
2655 needed_margin = 0;
2656
2657 if (needed_margin != margin) {
2658 margin = needed_margin;
2659 editwincols = COLS - margin;
2660 /* The margin has changed -- schedule a full refresh. */
2661 refresh_needed = TRUE;
Benno Schulenberg023edff2016-10-21 14:31:37 +02002662 }
David Lawrence Ramseyc24545f2017-02-09 10:20:04 -06002663#endif
Benno Schulenbergb38cbfe2016-10-24 17:38:24 +02002664
Benno Schulenberg9106cc82016-05-08 12:01:33 +02002665 if (currmenu != MMAIN)
2666 display_main_list();
2667
Benno Schulenberged165822016-11-13 20:00:31 +01002668 lastmessage = HUSH;
Benno Schulenbergeef7d102016-12-20 19:27:41 +01002669 as_an_at = TRUE;
Benno Schulenberged165822016-11-13 20:00:31 +01002670
2671 /* Update the displayed current cursor position only when there
2672 * are no keys waiting in the input buffer. */
2673 if (ISSET(CONST_UPDATE) && get_key_buffer_len() == 0)
2674 do_cursorpos(TRUE);
2675
Benno Schulenberg372bd0f2016-12-03 17:47:37 +01002676 /* Refresh just the cursor position or the entire edit window. */
Benno Schulenberga4132e22016-11-12 17:59:28 +01002677 if (!refresh_needed) {
2678 reset_cursor();
Benno Schulenberga4132e22016-11-12 17:59:28 +01002679 wnoutrefresh(edit);
2680 } else
2681 edit_refresh();
2682
Benno Schulenberg372bd0f2016-12-03 17:47:37 +01002683 /* Make sure the cursor is visible. */
2684 curs_set(1);
2685
Benno Schulenberg318ed6b2016-04-12 10:24:57 +02002686 focusing = TRUE;
Chris Allegrettad26ab912003-01-28 01:16:47 +00002687
Benno Schulenberg34a20f82016-04-17 15:24:05 +02002688 /* Forget any earlier statusbar x position. */
2689 reinit_statusbar_x();
2690
Benno Schulenbergddd9c7a2016-06-24 22:45:41 +02002691 /* Read in and interpret keystrokes. */
Benno Schulenberg7e5324d2014-06-30 18:04:33 +00002692 do_input(TRUE);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002693 }
David Lawrence Ramsey5f9acfe2005-03-04 17:09:41 +00002694
David Lawrence Ramsey6d6a36c2005-12-08 07:09:08 +00002695 /* We should never get here. */
David Lawrence Ramseyfd1768a2004-03-19 21:57:56 +00002696 assert(FALSE);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002697}