2000-06-06 05:53:49 +00:00
|
|
|
/**************************************************************************
|
2016-08-29 15:10:49 +00:00
|
|
|
* nano.c -- This file is part of GNU nano. *
|
2000-06-06 05:53:49 +00:00
|
|
|
* *
|
2021-01-11 13:21:03 +00:00
|
|
|
* Copyright (C) 1999-2011, 2013-2021 Free Software Foundation, Inc. *
|
2020-03-11 10:52:15 +00:00
|
|
|
* Copyright (C) 2014-2020 Benno Schulenberg *
|
2016-08-29 13:14:18 +00:00
|
|
|
* *
|
2016-08-29 15:10:49 +00:00
|
|
|
* GNU nano is free software: you can redistribute it and/or modify *
|
|
|
|
* it under the terms of the GNU General Public License as published *
|
|
|
|
* by the Free Software Foundation, either version 3 of the License, *
|
|
|
|
* or (at your option) any later version. *
|
2000-06-06 05:53:49 +00:00
|
|
|
* *
|
2016-08-29 15:10:49 +00:00
|
|
|
* GNU nano is distributed in the hope that it will be useful, *
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty *
|
|
|
|
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
|
|
|
* See the GNU General Public License for more details. *
|
2000-06-06 05:53:49 +00:00
|
|
|
* *
|
|
|
|
* You should have received a copy of the GNU General Public License *
|
2016-08-29 15:10:49 +00:00
|
|
|
* along with this program. If not, see http://www.gnu.org/licenses/. *
|
2000-06-06 05:53:49 +00:00
|
|
|
* *
|
|
|
|
**************************************************************************/
|
|
|
|
|
2020-06-20 10:09:31 +00:00
|
|
|
#include "prototypes.h"
|
2016-05-20 10:59:57 +00:00
|
|
|
#include "revision.h"
|
2001-04-28 18:03:52 +00:00
|
|
|
|
2000-06-06 05:53:49 +00:00
|
|
|
#include <ctype.h>
|
2017-08-06 11:32:44 +00:00
|
|
|
#include <errno.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <getopt.h>
|
2018-01-31 11:35:21 +00:00
|
|
|
#if defined(__linux__) || !defined(NANO_TINY)
|
2017-08-06 11:32:44 +00:00
|
|
|
#include <sys/ioctl.h>
|
|
|
|
#endif
|
2008-07-12 02:32:19 +00:00
|
|
|
#ifdef ENABLE_UTF8
|
2007-05-25 14:39:40 +00:00
|
|
|
#include <langinfo.h>
|
2008-07-12 02:32:19 +00:00
|
|
|
#endif
|
2017-08-06 17:32:55 +00:00
|
|
|
#include <locale.h>
|
2017-08-06 11:32:44 +00:00
|
|
|
#include <string.h>
|
2017-02-21 22:04:48 +00:00
|
|
|
#ifdef HAVE_TERMIOS_H
|
2005-12-28 05:01:00 +00:00
|
|
|
#include <termios.h>
|
2017-02-21 22:04:48 +00:00
|
|
|
#endif
|
2017-08-06 11:32:44 +00:00
|
|
|
#include <unistd.h>
|
2018-01-31 11:35:21 +00:00
|
|
|
#ifdef __linux__
|
|
|
|
#include <sys/vt.h>
|
|
|
|
#endif
|
2006-07-12 18:57:04 +00:00
|
|
|
|
2018-03-21 10:40:15 +00:00
|
|
|
#ifdef ENABLE_MULTIBUFFER
|
2020-05-29 16:45:14 +00:00
|
|
|
#define read_them_all TRUE
|
2018-03-21 10:40:15 +00:00
|
|
|
#else
|
2020-05-29 16:45:14 +00:00
|
|
|
#define read_them_all FALSE
|
2018-03-21 10:40:15 +00:00
|
|
|
#endif
|
|
|
|
|
2017-05-01 18:45:07 +00:00
|
|
|
#ifdef ENABLE_MOUSE
|
2007-12-04 20:49:09 +00:00
|
|
|
static int oldinterval = -1;
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Used to store the user's original mouse click interval. */
|
2007-12-04 20:49:09 +00:00
|
|
|
#endif
|
2017-02-21 22:04:48 +00:00
|
|
|
#ifdef HAVE_TERMIOS_H
|
2019-09-06 17:38:14 +00:00
|
|
|
static struct termios original_state;
|
|
|
|
/* The original settings of the user's terminal. */
|
2017-02-21 22:04:48 +00:00
|
|
|
#else
|
|
|
|
# define tcsetattr(...)
|
|
|
|
# define tcgetattr(...)
|
|
|
|
#endif
|
2019-05-27 17:30:29 +00:00
|
|
|
|
2019-05-26 11:10:47 +00:00
|
|
|
static struct sigaction oldaction, newaction;
|
|
|
|
/* Containers for the original and the temporary handler for SIGINT. */
|
2017-06-23 07:27:29 +00:00
|
|
|
|
2018-03-22 18:54:20 +00:00
|
|
|
/* Create a new linestruct node. Note that we do not set prevnode->next. */
|
2019-03-21 16:08:52 +00:00
|
|
|
linestruct *make_new_node(linestruct *prevnode)
|
2005-01-19 19:52:42 +00:00
|
|
|
{
|
2019-03-21 16:08:52 +00:00
|
|
|
linestruct *newnode = nmalloc(sizeof(linestruct));
|
2005-07-08 02:47:05 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
newnode->prev = prevnode;
|
|
|
|
newnode->next = NULL;
|
2020-01-29 11:31:52 +00:00
|
|
|
newnode->data = NULL;
|
2017-11-01 18:45:33 +00:00
|
|
|
#ifdef ENABLE_COLOR
|
2017-12-29 18:27:33 +00:00
|
|
|
newnode->multidata = NULL;
|
2009-01-19 19:10:39 +00:00
|
|
|
#endif
|
2020-01-29 11:31:52 +00:00
|
|
|
newnode->lineno = (prevnode) ? prevnode->lineno + 1 : 1;
|
new feature: bindable functions for toggling and jumping to "bookmarks"
With the 'bookmark' function, the user can place a bookmark on any
line in the buffer. Multiple lines can be bookmarked in this way.
With 'prevbookmark' and 'nextbookmark', the user can then easily
return to the bookmarked lines. The search for a bookmark wraps
around, as if start and end of buffer are connected.
[However, in this implementation, when a bookmarked line is deleted,
the bookmark is deleted too. This is undesirable. Also, when such
a deleted line is pasted elsewhere, the bookmark reappears with it,
and when pasted multiple times, the bookmark will be there as many
times. This is thoroughly undesirable. These behaviors will be
changed in a later commit.]
A bookmark is not yet visible in any way.
This fulfills https://savannah.gnu.org/bugs/?57577.
Requested-by: Ken Tyler <kent@werple.net.au>
Signed-off-by: Marco Diego Aurélio Mesquita <marcodiegomesquita@gmail.com>
Signed-off-by: Benno Schulenberg <bensberg@telfort.nl>
2018-11-12 20:30:47 +00:00
|
|
|
#ifndef NANO_TINY
|
2020-04-06 15:42:29 +00:00
|
|
|
newnode->has_anchor = FALSE;
|
new feature: bindable functions for toggling and jumping to "bookmarks"
With the 'bookmark' function, the user can place a bookmark on any
line in the buffer. Multiple lines can be bookmarked in this way.
With 'prevbookmark' and 'nextbookmark', the user can then easily
return to the bookmarked lines. The search for a bookmark wraps
around, as if start and end of buffer are connected.
[However, in this implementation, when a bookmarked line is deleted,
the bookmark is deleted too. This is undesirable. Also, when such
a deleted line is pasted elsewhere, the bookmark reappears with it,
and when pasted multiple times, the bookmark will be there as many
times. This is thoroughly undesirable. These behaviors will be
changed in a later commit.]
A bookmark is not yet visible in any way.
This fulfills https://savannah.gnu.org/bugs/?57577.
Requested-by: Ken Tyler <kent@werple.net.au>
Signed-off-by: Marco Diego Aurélio Mesquita <marcodiegomesquita@gmail.com>
Signed-off-by: Benno Schulenberg <bensberg@telfort.nl>
2018-11-12 20:30:47 +00:00
|
|
|
#endif
|
2009-01-19 19:10:39 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
return newnode;
|
2005-01-19 19:52:42 +00:00
|
|
|
}
|
|
|
|
|
2017-04-19 15:38:34 +00:00
|
|
|
/* Splice a new node into an existing linked list of linestructs. */
|
2019-03-21 16:08:52 +00:00
|
|
|
void splice_node(linestruct *afterthis, linestruct *newnode)
|
2000-06-06 05:53:49 +00:00
|
|
|
{
|
2017-12-29 18:27:33 +00:00
|
|
|
newnode->next = afterthis->next;
|
|
|
|
newnode->prev = afterthis;
|
|
|
|
if (afterthis->next != NULL)
|
|
|
|
afterthis->next->prev = newnode;
|
|
|
|
afterthis->next = newnode;
|
|
|
|
|
|
|
|
/* Update filebot when inserting a node at the end of file. */
|
|
|
|
if (openfile && openfile->filebot == afterthis)
|
|
|
|
openfile->filebot = newnode;
|
2005-07-08 02:47:05 +00:00
|
|
|
}
|
2001-07-11 02:08:33 +00:00
|
|
|
|
2015-12-08 16:02:05 +00:00
|
|
|
/* Free the data structures in the given node. */
|
2019-10-16 09:04:26 +00:00
|
|
|
void delete_node(linestruct *line)
|
2005-07-08 02:47:05 +00:00
|
|
|
{
|
editing: prevent the pointer for the top row from becoming dangling
When undoing several actions, it is possible for the line at the top
of the screen to be removed, leaving 'edittop' pointing to a structure
that has been freed. Soon after, 'edittop' is referenced to determine
whether the cursor is offscreen... Prevent this invalid reference by
stepping 'edittop' one line back in that special case. This changes
the normal centering behavior of Undo when the cursor goes offscreen,
but... so be it.
When a single node is deleted, it is always possible to step one line
back, because a buffer contains always at least one line (even though
maybe empty), so if the current line could be deleted, there must be
one before it (when at the top of the screen).
This fixes https://savannah.gnu.org/bugs/?60436.
Bug existed since version 2.3.3, commit 60815461,
since undoing does not always center the cursor.
2021-04-22 17:28:34 +00:00
|
|
|
/* If the first line on the screen gets deleted, step one back. */
|
|
|
|
if (line == openfile->edittop)
|
|
|
|
openfile->edittop = line->prev;
|
2019-04-21 15:31:29 +00:00
|
|
|
#ifdef ENABLE_WRAPPING
|
|
|
|
/* If the spill-over line for hard-wrapping is deleted... */
|
2019-10-16 09:04:26 +00:00
|
|
|
if (line == openfile->spillage_line)
|
2019-04-21 15:31:29 +00:00
|
|
|
openfile->spillage_line = NULL;
|
|
|
|
#endif
|
2019-10-16 09:04:26 +00:00
|
|
|
free(line->data);
|
2017-11-01 18:45:33 +00:00
|
|
|
#ifdef ENABLE_COLOR
|
2019-10-16 09:04:26 +00:00
|
|
|
free(line->multidata);
|
2009-01-25 07:25:17 +00:00
|
|
|
#endif
|
2019-10-16 09:04:26 +00:00
|
|
|
free(line);
|
2001-07-11 02:08:33 +00:00
|
|
|
}
|
|
|
|
|
2020-01-29 09:54:30 +00:00
|
|
|
/* Disconnect a node from a linked list of linestructs and delete it. */
|
|
|
|
void unlink_node(linestruct *line)
|
|
|
|
{
|
|
|
|
if (line->prev != NULL)
|
|
|
|
line->prev->next = line->next;
|
|
|
|
if (line->next != NULL)
|
|
|
|
line->next->prev = line->prev;
|
|
|
|
|
|
|
|
/* Update filebot when removing a node at the end of file. */
|
|
|
|
if (openfile && openfile->filebot == line)
|
|
|
|
openfile->filebot = line->prev;
|
|
|
|
|
|
|
|
delete_node(line);
|
|
|
|
}
|
|
|
|
|
2020-01-29 09:56:03 +00:00
|
|
|
/* Free an entire linked list of linestructs. */
|
|
|
|
void free_lines(linestruct *src)
|
|
|
|
{
|
|
|
|
if (src == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
while (src->next != NULL) {
|
|
|
|
src = src->next;
|
|
|
|
delete_node(src->prev);
|
|
|
|
}
|
|
|
|
|
|
|
|
delete_node(src);
|
|
|
|
}
|
|
|
|
|
2020-01-29 09:53:05 +00:00
|
|
|
/* Make a copy of a linestruct node. */
|
|
|
|
linestruct *copy_node(const linestruct *src)
|
|
|
|
{
|
|
|
|
linestruct *dst = nmalloc(sizeof(linestruct));
|
|
|
|
|
|
|
|
dst->data = copy_of(src->data);
|
|
|
|
#ifdef ENABLE_COLOR
|
|
|
|
dst->multidata = NULL;
|
|
|
|
#endif
|
|
|
|
dst->lineno = src->lineno;
|
new feature: bindable functions for toggling and jumping to "bookmarks"
With the 'bookmark' function, the user can place a bookmark on any
line in the buffer. Multiple lines can be bookmarked in this way.
With 'prevbookmark' and 'nextbookmark', the user can then easily
return to the bookmarked lines. The search for a bookmark wraps
around, as if start and end of buffer are connected.
[However, in this implementation, when a bookmarked line is deleted,
the bookmark is deleted too. This is undesirable. Also, when such
a deleted line is pasted elsewhere, the bookmark reappears with it,
and when pasted multiple times, the bookmark will be there as many
times. This is thoroughly undesirable. These behaviors will be
changed in a later commit.]
A bookmark is not yet visible in any way.
This fulfills https://savannah.gnu.org/bugs/?57577.
Requested-by: Ken Tyler <kent@werple.net.au>
Signed-off-by: Marco Diego Aurélio Mesquita <marcodiegomesquita@gmail.com>
Signed-off-by: Benno Schulenberg <bensberg@telfort.nl>
2018-11-12 20:30:47 +00:00
|
|
|
#ifndef NANO_TINY
|
2020-04-06 15:42:29 +00:00
|
|
|
dst->has_anchor = FALSE;
|
new feature: bindable functions for toggling and jumping to "bookmarks"
With the 'bookmark' function, the user can place a bookmark on any
line in the buffer. Multiple lines can be bookmarked in this way.
With 'prevbookmark' and 'nextbookmark', the user can then easily
return to the bookmarked lines. The search for a bookmark wraps
around, as if start and end of buffer are connected.
[However, in this implementation, when a bookmarked line is deleted,
the bookmark is deleted too. This is undesirable. Also, when such
a deleted line is pasted elsewhere, the bookmark reappears with it,
and when pasted multiple times, the bookmark will be there as many
times. This is thoroughly undesirable. These behaviors will be
changed in a later commit.]
A bookmark is not yet visible in any way.
This fulfills https://savannah.gnu.org/bugs/?57577.
Requested-by: Ken Tyler <kent@werple.net.au>
Signed-off-by: Marco Diego Aurélio Mesquita <marcodiegomesquita@gmail.com>
Signed-off-by: Benno Schulenberg <bensberg@telfort.nl>
2018-11-12 20:30:47 +00:00
|
|
|
#endif
|
2020-01-29 09:53:05 +00:00
|
|
|
|
|
|
|
return dst;
|
|
|
|
}
|
|
|
|
|
2017-04-19 15:38:34 +00:00
|
|
|
/* Duplicate an entire linked list of linestructs. */
|
2019-03-21 16:18:50 +00:00
|
|
|
linestruct *copy_buffer(const linestruct *src)
|
2001-07-11 02:08:33 +00:00
|
|
|
{
|
2020-01-29 09:47:09 +00:00
|
|
|
linestruct *head, *item;
|
|
|
|
|
|
|
|
head = copy_node(src);
|
|
|
|
head->prev = NULL;
|
2001-07-11 02:08:33 +00:00
|
|
|
|
2020-01-29 09:47:09 +00:00
|
|
|
item = head;
|
2017-12-29 18:27:33 +00:00
|
|
|
src = src->next;
|
2004-08-10 23:05:59 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
while (src != NULL) {
|
2020-01-29 09:47:09 +00:00
|
|
|
item->next = copy_node(src);
|
|
|
|
item->next->prev = item;
|
2000-06-06 05:53:49 +00:00
|
|
|
|
2020-01-29 09:47:09 +00:00
|
|
|
item = item->next;
|
2017-12-29 18:27:33 +00:00
|
|
|
src = src->next;
|
|
|
|
}
|
2005-07-19 04:50:55 +00:00
|
|
|
|
2020-01-29 09:47:09 +00:00
|
|
|
item->next = NULL;
|
2002-02-22 04:30:50 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
return head;
|
2000-06-06 05:53:49 +00:00
|
|
|
}
|
|
|
|
|
2019-04-30 08:27:10 +00:00
|
|
|
/* Renumber the lines in a buffer, from the given line onwards. */
|
|
|
|
void renumber_from(linestruct *line)
|
2000-06-06 05:53:49 +00:00
|
|
|
{
|
2019-04-03 13:11:18 +00:00
|
|
|
ssize_t number = (line->prev == NULL) ? 0 : line->prev->lineno;
|
2001-01-14 05:18:27 +00:00
|
|
|
|
2018-03-04 11:55:15 +00:00
|
|
|
while (line != NULL) {
|
2018-03-04 11:52:45 +00:00
|
|
|
line->lineno = ++number;
|
2018-03-04 11:55:15 +00:00
|
|
|
line = line->next;
|
|
|
|
}
|
2000-06-06 05:53:49 +00:00
|
|
|
}
|
|
|
|
|
2005-12-08 07:09:08 +00:00
|
|
|
/* Display a warning about a key disabled in view mode. */
|
2005-07-08 02:47:05 +00:00
|
|
|
void print_view_warning(void)
|
2002-09-06 20:35:28 +00:00
|
|
|
{
|
2020-12-08 16:09:07 +00:00
|
|
|
statusline(AHEM, _("Key is invalid in view mode"));
|
2002-09-06 20:35:28 +00:00
|
|
|
}
|
|
|
|
|
2019-10-09 16:58:30 +00:00
|
|
|
/* When in restricted mode, show a warning and return TRUE. */
|
|
|
|
bool in_restricted_mode(void)
|
2015-07-30 18:10:16 +00:00
|
|
|
{
|
2019-10-09 16:58:30 +00:00
|
|
|
if (ISSET(RESTRICTED)) {
|
2020-12-08 16:09:07 +00:00
|
|
|
statusline(AHEM, _("This function is disabled in restricted mode"));
|
2019-10-09 16:58:30 +00:00
|
|
|
beep();
|
|
|
|
return TRUE;
|
|
|
|
} else
|
|
|
|
return FALSE;
|
2015-07-30 18:10:16 +00:00
|
|
|
}
|
|
|
|
|
2020-01-22 11:45:15 +00:00
|
|
|
/* Make sure the cursor is visible, then exit from curses mode, disable
|
|
|
|
* bracketed-paste mode, and restore the original terminal settings. */
|
|
|
|
void restore_terminal(void)
|
2020-01-03 23:52:21 +00:00
|
|
|
{
|
2020-01-22 11:45:15 +00:00
|
|
|
curs_set(1);
|
|
|
|
endwin();
|
2020-01-22 11:55:32 +00:00
|
|
|
#ifndef NANO_TINY
|
2020-07-22 07:07:14 +00:00
|
|
|
printf("\x1B[?2004l");
|
2020-01-03 23:52:21 +00:00
|
|
|
fflush(stdout);
|
2020-01-22 11:55:32 +00:00
|
|
|
#endif
|
2020-10-10 09:43:55 +00:00
|
|
|
tcsetattr(STDIN_FILENO, TCSANOW, &original_state);
|
2020-01-03 23:52:21 +00:00
|
|
|
}
|
|
|
|
|
2020-06-05 17:05:29 +00:00
|
|
|
/* Exit normally: restore terminal state and report any startup errors. */
|
2005-07-08 02:47:05 +00:00
|
|
|
void finish(void)
|
2000-06-06 05:53:49 +00:00
|
|
|
{
|
2020-01-16 15:16:31 +00:00
|
|
|
/* Blank the status bar and (if applicable) the shortcut list. */
|
2017-12-29 18:27:33 +00:00
|
|
|
blank_statusbar();
|
|
|
|
blank_bottombars();
|
|
|
|
wrefresh(bottomwin);
|
2018-05-10 15:30:06 +00:00
|
|
|
|
2018-05-10 16:00:05 +00:00
|
|
|
#ifndef NANO_TINY
|
|
|
|
/* Deallocate the two or three subwindows. */
|
|
|
|
if (topwin != NULL)
|
|
|
|
delwin(topwin);
|
|
|
|
delwin(edit);
|
|
|
|
delwin(bottomwin);
|
|
|
|
#endif
|
2020-01-22 11:45:15 +00:00
|
|
|
/* Switch the cursor on, exit from curses, and restore terminal settings. */
|
|
|
|
restore_terminal();
|
2005-03-04 17:09:41 +00:00
|
|
|
|
2019-11-25 18:17:41 +00:00
|
|
|
#if defined(ENABLE_NANORC) || defined(ENABLE_HISTORIES)
|
2019-05-13 23:43:53 +00:00
|
|
|
display_rcfile_errors();
|
|
|
|
#endif
|
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Get out. */
|
|
|
|
exit(0);
|
2002-04-10 02:31:20 +00:00
|
|
|
}
|
|
|
|
|
2020-06-05 17:05:29 +00:00
|
|
|
/* Close the current buffer, and terminate nano if it is the only buffer. */
|
|
|
|
void close_and_go(void)
|
|
|
|
{
|
|
|
|
#ifndef NANO_TINY
|
|
|
|
if (openfile->lock_filename)
|
|
|
|
delete_lockfile(openfile->lock_filename);
|
|
|
|
#endif
|
|
|
|
#ifdef ENABLE_HISTORIES
|
|
|
|
if (ISSET(POSITIONLOG))
|
|
|
|
update_poshistory();
|
|
|
|
#endif
|
|
|
|
#ifdef ENABLE_MULTIBUFFER
|
|
|
|
/* If there is another buffer, close this one; otherwise just terminate. */
|
|
|
|
if (openfile != openfile->next) {
|
|
|
|
switch_to_next_buffer();
|
|
|
|
openfile = openfile->prev;
|
|
|
|
close_buffer();
|
|
|
|
openfile = openfile->next;
|
|
|
|
/* Adjust the count in the top bar. */
|
|
|
|
titlebar(NULL);
|
|
|
|
} else
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
#ifdef ENABLE_HISTORIES
|
|
|
|
if (ISSET(HISTORYLOG))
|
|
|
|
save_history();
|
|
|
|
#endif
|
|
|
|
finish();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Close the current buffer if it is unmodified; otherwise (when not doing
|
|
|
|
* automatic saving), ask the user whether to save it, then close it and
|
|
|
|
* exit, or return when the user cancelled. */
|
|
|
|
void do_exit(void)
|
|
|
|
{
|
|
|
|
int choice;
|
|
|
|
|
|
|
|
/* When unmodified, simply close. Else, when doing automatic saving
|
|
|
|
* and the file has a name, simply save. Otherwise, ask the user. */
|
|
|
|
if (!openfile->modified)
|
|
|
|
choice = 0;
|
|
|
|
else if (ISSET(SAVE_ON_EXIT) && openfile->filename[0] != '\0')
|
|
|
|
choice = 1;
|
|
|
|
else {
|
|
|
|
if (ISSET(SAVE_ON_EXIT))
|
|
|
|
warn_and_briefly_pause(_("No file name"));
|
|
|
|
|
|
|
|
choice = do_yesno_prompt(FALSE, _("Save modified buffer? "));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* When not saving, or the save succeeds, close the buffer. */
|
|
|
|
if (choice == 0 || (choice == 1 && do_writeout(TRUE, TRUE) > 0))
|
|
|
|
close_and_go();
|
|
|
|
else if (choice != 1)
|
|
|
|
statusbar(_("Cancelled"));
|
|
|
|
}
|
|
|
|
|
2020-06-05 15:08:04 +00:00
|
|
|
/* Save the current buffer under the given name (or under the name "nano"
|
|
|
|
* for a nameless buffer). If needed, the name is modified to be unique. */
|
2020-06-05 15:23:52 +00:00
|
|
|
void emergency_save(const char *plainname)
|
2020-06-05 15:08:04 +00:00
|
|
|
{
|
|
|
|
bool failed = TRUE;
|
|
|
|
char *targetname;
|
|
|
|
|
2020-06-05 15:23:52 +00:00
|
|
|
if (*plainname == '\0')
|
|
|
|
plainname = "nano";
|
2020-06-05 15:08:04 +00:00
|
|
|
|
2020-06-05 15:23:52 +00:00
|
|
|
targetname = get_next_filename(plainname, ".save");
|
2020-06-05 15:08:04 +00:00
|
|
|
|
|
|
|
if (*targetname != '\0')
|
|
|
|
failed = !write_file(targetname, NULL, TRUE, OVERWRITE, FALSE);
|
|
|
|
|
|
|
|
if (!failed)
|
|
|
|
fprintf(stderr, _("\nBuffer written to %s\n"), targetname);
|
|
|
|
else if (*targetname != '\0')
|
|
|
|
fprintf(stderr, _("\nBuffer not written to %s: %s\n"),
|
|
|
|
targetname, strerror(errno));
|
|
|
|
else
|
|
|
|
fprintf(stderr, _("\nToo many .save files"));
|
|
|
|
|
|
|
|
#ifndef NANO_TINY
|
|
|
|
/* Try to chmod/chown the saved file to the values of the original file,
|
|
|
|
* but ignore any failure as we are in a hurry to get out. */
|
2020-06-05 15:23:52 +00:00
|
|
|
if (openfile->statinfo) {
|
|
|
|
IGNORE_CALL_RESULT(chmod(targetname, openfile->statinfo->st_mode));
|
|
|
|
IGNORE_CALL_RESULT(chown(targetname, openfile->statinfo->st_uid,
|
|
|
|
openfile->statinfo->st_gid));
|
2020-06-05 15:08:04 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
free(targetname);
|
|
|
|
}
|
|
|
|
|
2018-05-10 15:30:06 +00:00
|
|
|
/* Die gracefully -- by restoring the terminal state and saving any buffers
|
|
|
|
* that were modified. */
|
2005-07-08 02:47:05 +00:00
|
|
|
void die(const char *msg, ...)
|
2000-06-06 05:53:49 +00:00
|
|
|
{
|
2017-12-29 18:27:33 +00:00
|
|
|
va_list ap;
|
2018-03-23 16:12:55 +00:00
|
|
|
openfilestruct *firstone = openfile;
|
2000-06-06 05:53:49 +00:00
|
|
|
|
2020-01-22 11:45:15 +00:00
|
|
|
restore_terminal();
|
2005-05-14 20:52:20 +00:00
|
|
|
|
2019-05-13 23:43:53 +00:00
|
|
|
#ifdef ENABLE_NANORC
|
|
|
|
display_rcfile_errors();
|
|
|
|
#endif
|
|
|
|
|
2018-03-23 16:54:06 +00:00
|
|
|
/* Display the dying message. */
|
2017-12-29 18:27:33 +00:00
|
|
|
va_start(ap, msg);
|
|
|
|
vfprintf(stderr, msg, ap);
|
|
|
|
va_end(ap);
|
2000-06-06 05:53:49 +00:00
|
|
|
|
2018-03-23 16:12:55 +00:00
|
|
|
while (openfile) {
|
2016-08-02 15:11:50 +00:00
|
|
|
#ifndef NANO_TINY
|
2018-03-23 16:12:55 +00:00
|
|
|
/* If the current buffer has a lockfile, remove it. */
|
2020-05-08 09:06:43 +00:00
|
|
|
if (openfile->lock_filename)
|
2018-03-23 16:12:55 +00:00
|
|
|
delete_lockfile(openfile->lock_filename);
|
2016-08-02 15:11:50 +00:00
|
|
|
#endif
|
2020-04-09 10:12:04 +00:00
|
|
|
/* When modified, save the current buffer. But not when in restricted
|
|
|
|
* mode, as it would write a file not mentioned on the command line. */
|
|
|
|
if (openfile->modified && !ISSET(RESTRICTED))
|
2020-06-05 15:23:52 +00:00
|
|
|
emergency_save(openfile->filename);
|
2000-06-06 05:53:49 +00:00
|
|
|
|
2018-03-23 18:14:56 +00:00
|
|
|
#ifdef ENABLE_MULTIBUFFER
|
2018-03-23 16:12:55 +00:00
|
|
|
openfile = openfile->next;
|
2018-03-23 18:14:56 +00:00
|
|
|
#endif
|
2018-03-23 16:12:55 +00:00
|
|
|
if (openfile == firstone)
|
|
|
|
break;
|
2005-07-08 02:47:05 +00:00
|
|
|
}
|
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Abandon the building. */
|
|
|
|
exit(1);
|
2002-04-10 02:31:20 +00:00
|
|
|
}
|
|
|
|
|
2005-12-08 07:09:08 +00:00
|
|
|
/* Initialize the three window portions nano uses. */
|
2005-07-25 22:54:16 +00:00
|
|
|
void window_init(void)
|
2005-07-08 02:47:05 +00:00
|
|
|
{
|
2017-12-29 18:27:33 +00:00
|
|
|
/* When resizing, first delete the existing windows. */
|
|
|
|
if (edit != NULL) {
|
|
|
|
if (topwin != NULL)
|
|
|
|
delwin(topwin);
|
|
|
|
delwin(edit);
|
|
|
|
delwin(bottomwin);
|
|
|
|
}
|
|
|
|
|
2020-08-15 15:32:31 +00:00
|
|
|
topwin = NULL;
|
|
|
|
|
2020-01-16 15:16:31 +00:00
|
|
|
/* If the terminal is very flat, don't set up a title bar. */
|
2017-12-29 18:27:33 +00:00
|
|
|
if (LINES < 3) {
|
|
|
|
editwinrows = 1;
|
|
|
|
/* Set up two subwindows. If the terminal is just one line,
|
2020-01-16 15:16:31 +00:00
|
|
|
* edit window and status-bar window will cover each other. */
|
2017-12-29 18:27:33 +00:00
|
|
|
edit = newwin(1, COLS, 0, 0);
|
|
|
|
bottomwin = newwin(1, COLS, LINES - 1, 0);
|
|
|
|
} else {
|
2020-12-04 15:27:34 +00:00
|
|
|
int toprows = ((ISSET(EMPTY_LINE) && LINES > 5) ? 2 : 1);
|
|
|
|
int bottomrows = ((ISSET(NO_HELP) || LINES < 5) ? 1 : 3);
|
2017-12-29 18:27:33 +00:00
|
|
|
|
2020-08-15 15:32:31 +00:00
|
|
|
#ifndef NANO_TINY
|
2020-12-29 12:21:07 +00:00
|
|
|
if (ISSET(MINIBAR))
|
2020-08-15 15:32:31 +00:00
|
|
|
toprows = 0;
|
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
editwinrows = LINES - toprows - bottomrows;
|
|
|
|
|
|
|
|
/* Set up the normal three subwindows. */
|
2020-08-15 15:32:31 +00:00
|
|
|
if (toprows > 0)
|
|
|
|
topwin = newwin(toprows, COLS, 0, 0);
|
2017-12-29 18:27:33 +00:00
|
|
|
edit = newwin(editwinrows, COLS, toprows, 0);
|
|
|
|
bottomwin = newwin(bottomrows, COLS, toprows + editwinrows, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* In case the terminal shrunk, make sure the status line is clear. */
|
|
|
|
wipe_statusbar();
|
|
|
|
|
2018-12-28 16:47:03 +00:00
|
|
|
/* When not disabled, turn escape-sequence translation on. */
|
|
|
|
if (!ISSET(RAW_SEQUENCES)) {
|
2017-12-29 18:27:33 +00:00
|
|
|
keypad(edit, TRUE);
|
|
|
|
keypad(bottomwin, TRUE);
|
|
|
|
}
|
2016-08-15 12:55:59 +00:00
|
|
|
|
2017-10-31 16:39:30 +00:00
|
|
|
#ifdef ENABLED_WRAPORJUSTIFY
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Set up the wrapping point, accounting for screen width when negative. */
|
2019-09-30 17:30:54 +00:00
|
|
|
if (COLS + fill < 0)
|
2018-10-22 23:01:23 +00:00
|
|
|
wrap_at = 0;
|
2019-09-30 17:30:54 +00:00
|
|
|
else if (fill <= 0)
|
|
|
|
wrap_at = COLS + fill;
|
|
|
|
else
|
|
|
|
wrap_at = fill;
|
2016-08-15 12:55:59 +00:00
|
|
|
#endif
|
2004-11-03 22:03:41 +00:00
|
|
|
}
|
|
|
|
|
2017-05-01 18:45:07 +00:00
|
|
|
#ifdef ENABLE_MOUSE
|
2006-06-09 18:24:37 +00:00
|
|
|
void disable_mouse_support(void)
|
|
|
|
{
|
2017-12-29 18:27:33 +00:00
|
|
|
mousemask(0, NULL);
|
|
|
|
mouseinterval(oldinterval);
|
2006-06-09 18:24:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void enable_mouse_support(void)
|
|
|
|
{
|
2017-12-29 18:27:33 +00:00
|
|
|
mousemask(ALL_MOUSE_EVENTS, NULL);
|
|
|
|
oldinterval = mouseinterval(50);
|
2006-06-09 18:24:37 +00:00
|
|
|
}
|
|
|
|
|
2017-05-01 18:45:07 +00:00
|
|
|
/* Switch mouse support on or off, as needed. */
|
2005-07-08 02:47:05 +00:00
|
|
|
void mouse_init(void)
|
2004-11-23 04:08:28 +00:00
|
|
|
{
|
2017-12-29 18:27:33 +00:00
|
|
|
if (ISSET(USE_MOUSE))
|
|
|
|
enable_mouse_support();
|
|
|
|
else
|
|
|
|
disable_mouse_support();
|
2005-07-08 02:47:05 +00:00
|
|
|
}
|
2017-05-01 18:45:07 +00:00
|
|
|
#endif /* ENABLE_MOUSE */
|
2004-11-23 04:08:28 +00:00
|
|
|
|
2018-05-22 16:01:15 +00:00
|
|
|
/* Print the usage line for the given option to the screen. */
|
2017-02-21 22:04:40 +00:00
|
|
|
void print_opt(const char *shortflag, const char *longflag, const char *desc)
|
2002-03-09 18:51:58 +00:00
|
|
|
{
|
2019-09-21 17:23:52 +00:00
|
|
|
int firstwidth = breadth(shortflag);
|
|
|
|
int secondwidth = breadth(longflag);
|
|
|
|
|
|
|
|
printf(" %s", shortflag);
|
|
|
|
if (firstwidth < 14)
|
|
|
|
printf("%*s", 14 - firstwidth, " ");
|
|
|
|
|
|
|
|
printf(" %s", longflag);
|
|
|
|
if (secondwidth < 24)
|
|
|
|
printf("%*s", 24 - secondwidth, " ");
|
|
|
|
|
|
|
|
printf("%s\n", _(desc));
|
2002-03-09 18:51:58 +00:00
|
|
|
}
|
|
|
|
|
2014-05-28 15:44:11 +00:00
|
|
|
/* Explain how to properly use nano and its command-line options. */
|
2002-08-21 16:10:37 +00:00
|
|
|
void usage(void)
|
2000-06-06 05:53:49 +00:00
|
|
|
{
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(_("Usage: nano [OPTIONS] [[+LINE[,COLUMN]] FILE]...\n\n"));
|
2020-09-12 09:40:08 +00:00
|
|
|
#ifndef NANO_TINY
|
2017-12-29 18:27:33 +00:00
|
|
|
/* TRANSLATORS: The next two strings are part of the --help output.
|
|
|
|
* It's best to keep its lines within 80 characters. */
|
|
|
|
printf(_("To place the cursor on a specific line of a file, put the line number with\n"
|
|
|
|
"a '+' before the filename. The column number can be added after a comma.\n"));
|
|
|
|
printf(_("When a filename is '-', nano reads data from standard input.\n\n"));
|
2019-05-22 17:55:25 +00:00
|
|
|
/* TRANSLATORS: The next three are column headers of the --help output. */
|
2019-09-21 17:23:52 +00:00
|
|
|
print_opt(_("Option"), _("Long option"), N_("Meaning"));
|
2018-05-22 16:07:50 +00:00
|
|
|
/* TRANSLATORS: The next forty or so strings are option descriptions
|
|
|
|
* for the --help output. Try to keep them at most 40 characters. */
|
|
|
|
print_opt("-A", "--smarthome", N_("Enable smart home key"));
|
2017-12-29 18:27:33 +00:00
|
|
|
if (!ISSET(RESTRICTED)) {
|
|
|
|
print_opt("-B", "--backup", N_("Save backups of existing files"));
|
|
|
|
print_opt(_("-C <dir>"), _("--backupdir=<dir>"),
|
2018-05-22 16:07:50 +00:00
|
|
|
N_("Directory for saving unique backup files"));
|
2017-12-29 18:27:33 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
print_opt("-D", "--boldtext", N_("Use bold instead of reverse video text"));
|
2006-05-13 13:02:14 +00:00
|
|
|
#ifndef NANO_TINY
|
2017-12-29 18:27:33 +00:00
|
|
|
print_opt("-E", "--tabstospaces", N_("Convert typed tabs to spaces"));
|
2001-09-22 00:42:10 +00:00
|
|
|
#endif
|
2017-05-01 18:20:34 +00:00
|
|
|
#ifdef ENABLE_MULTIBUFFER
|
2017-12-29 18:27:33 +00:00
|
|
|
if (!ISSET(RESTRICTED))
|
|
|
|
print_opt("-F", "--multibuffer",
|
2018-05-22 16:07:50 +00:00
|
|
|
N_("Read a file into a new buffer by default"));
|
2002-07-19 01:08:59 +00:00
|
|
|
#endif
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2017-12-29 18:27:33 +00:00
|
|
|
print_opt("-G", "--locking", N_("Use (vim-style) lock files"));
|
2014-06-19 20:05:24 +00:00
|
|
|
#endif
|
2017-10-29 18:42:12 +00:00
|
|
|
#ifdef ENABLE_HISTORIES
|
2017-12-29 18:27:33 +00:00
|
|
|
if (!ISSET(RESTRICTED))
|
|
|
|
print_opt("-H", "--historylog",
|
2018-05-22 16:07:50 +00:00
|
|
|
N_("Log & read search/replace string history"));
|
2014-07-02 19:57:23 +00:00
|
|
|
#endif
|
2017-05-08 17:42:44 +00:00
|
|
|
#ifdef ENABLE_NANORC
|
2018-09-30 11:20:43 +00:00
|
|
|
print_opt("-I", "--ignorercfiles", N_("Don't look at nanorc files"));
|
2018-12-17 18:57:30 +00:00
|
|
|
#endif
|
|
|
|
#ifndef NANO_TINY
|
2019-09-21 17:48:11 +00:00
|
|
|
print_opt(_("-J <number>"), _("--guidestripe=<number>"),
|
2018-12-17 18:57:30 +00:00
|
|
|
N_("Show a guiding bar at this column"));
|
2001-09-22 04:20:25 +00:00
|
|
|
#endif
|
2018-12-31 17:34:28 +00:00
|
|
|
print_opt("-K", "--rawsequences",
|
2018-05-22 16:07:50 +00:00
|
|
|
N_("Fix numeric keypad key confusion problem"));
|
2019-03-10 18:17:52 +00:00
|
|
|
#ifndef NANO_TINY
|
2017-12-29 18:27:33 +00:00
|
|
|
print_opt("-L", "--nonewlines",
|
2019-04-07 07:01:52 +00:00
|
|
|
N_("Don't add an automatic newline"));
|
2019-03-10 18:17:52 +00:00
|
|
|
#endif
|
2018-01-24 08:56:03 +00:00
|
|
|
#ifdef ENABLED_WRAPORJUSTIFY
|
2018-01-23 12:44:03 +00:00
|
|
|
print_opt("-M", "--trimblanks",
|
2018-05-22 16:07:50 +00:00
|
|
|
N_("Trim tail spaces when hard-wrapping"));
|
2018-01-24 08:56:03 +00:00
|
|
|
#endif
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2017-12-29 18:27:33 +00:00
|
|
|
print_opt("-N", "--noconvert",
|
2018-05-22 16:07:50 +00:00
|
|
|
N_("Don't convert files from DOS/Mac format"));
|
2019-12-18 16:19:04 +00:00
|
|
|
print_opt("-O", "--bookstyle",
|
|
|
|
N_("Leading whitespace means new paragraph"));
|
2002-03-03 22:36:36 +00:00
|
|
|
#endif
|
2017-10-29 18:42:12 +00:00
|
|
|
#ifdef ENABLE_HISTORIES
|
2017-12-29 18:27:33 +00:00
|
|
|
if (!ISSET(RESTRICTED))
|
|
|
|
print_opt("-P", "--positionlog",
|
2018-05-22 16:07:50 +00:00
|
|
|
N_("Log & read location of cursor position"));
|
2011-02-16 06:52:30 +00:00
|
|
|
#endif
|
2017-10-31 16:34:07 +00:00
|
|
|
#ifdef ENABLE_JUSTIFY
|
2018-05-22 16:25:59 +00:00
|
|
|
print_opt(_("-Q <regex>"), _("--quotestr=<regex>"),
|
2019-09-22 15:30:22 +00:00
|
|
|
/* TRANSLATORS: This refers to email quoting,
|
|
|
|
* like the > in: > quoted text. */
|
|
|
|
N_("Regular expression to match quoting"));
|
2001-07-14 19:32:47 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
if (!ISSET(RESTRICTED))
|
2020-01-28 09:01:02 +00:00
|
|
|
print_opt("-R", "--restricted", N_("Restrict access to the filesystem"));
|
2020-03-27 15:57:25 +00:00
|
|
|
#ifndef NANO_TINY
|
|
|
|
print_opt("-S", "--softwrap", N_("Display overlong lines on multiple rows"));
|
2020-05-14 15:27:15 +00:00
|
|
|
print_opt(_("-T <number>"), _("--tabsize=<number>"),
|
|
|
|
N_("Make a tab this number of columns wide"));
|
2020-10-03 09:21:18 +00:00
|
|
|
#endif
|
2020-01-28 09:01:02 +00:00
|
|
|
print_opt("-U", "--quickblank", N_("Wipe status bar upon next keystroke"));
|
2017-12-29 18:27:33 +00:00
|
|
|
print_opt("-V", "--version", N_("Print version information and exit"));
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2017-12-29 18:27:33 +00:00
|
|
|
print_opt("-W", "--wordbounds",
|
2018-05-22 16:07:50 +00:00
|
|
|
N_("Detect word boundaries more accurately"));
|
2020-05-14 15:27:15 +00:00
|
|
|
print_opt(_("-X <string>"), _("--wordchars=<string>"),
|
2018-05-22 16:07:50 +00:00
|
|
|
N_("Which other characters are word parts"));
|
2005-08-10 22:12:28 +00:00
|
|
|
#endif
|
2017-11-01 18:45:33 +00:00
|
|
|
#ifdef ENABLE_COLOR
|
2017-12-29 18:27:33 +00:00
|
|
|
if (!ISSET(RESTRICTED))
|
|
|
|
print_opt(_("-Y <name>"), _("--syntax=<name>"),
|
2018-05-22 16:07:50 +00:00
|
|
|
N_("Syntax definition to use for coloring"));
|
2017-06-28 14:57:46 +00:00
|
|
|
#endif
|
|
|
|
#ifndef NANO_TINY
|
2018-10-24 09:02:08 +00:00
|
|
|
print_opt("-Z", "--zap", N_("Let Bsp and Del erase a marked region"));
|
2017-12-29 18:27:33 +00:00
|
|
|
print_opt("-a", "--atblanks", N_("When soft-wrapping, do it at whitespace"));
|
2019-01-25 13:40:30 +00:00
|
|
|
#endif
|
|
|
|
#ifdef ENABLE_WRAPPING
|
|
|
|
print_opt("-b", "--breaklonglines", N_("Automatically hard-wrap overlong lines"));
|
2002-05-04 04:23:30 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
print_opt("-c", "--constantshow", N_("Constantly show cursor position"));
|
|
|
|
print_opt("-d", "--rebinddelete",
|
2018-05-22 16:07:50 +00:00
|
|
|
N_("Fix Backspace/Delete confusion problem"));
|
2020-09-21 15:04:10 +00:00
|
|
|
#ifndef NANO_TINY
|
2019-01-25 15:31:36 +00:00
|
|
|
print_opt("-e", "--emptyline", N_("Keep the line below the title bar empty"));
|
2020-09-21 15:04:10 +00:00
|
|
|
#endif
|
2020-01-14 11:41:22 +00:00
|
|
|
#ifdef ENABLE_NANORC
|
|
|
|
print_opt(_("-f <file>"), _("--rcfile=<file>"),
|
|
|
|
N_("Use only this file for configuring nano"));
|
|
|
|
#endif
|
2020-01-28 10:46:04 +00:00
|
|
|
#if defined(ENABLE_BROWSER) || defined(ENABLE_HELP)
|
|
|
|
print_opt("-g", "--showcursor", N_("Show cursor in file browser & help text"));
|
2017-03-04 18:04:15 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
print_opt("-h", "--help", N_("Show this help text and exit"));
|
2014-06-19 20:05:24 +00:00
|
|
|
#ifndef NANO_TINY
|
2017-12-29 18:27:33 +00:00
|
|
|
print_opt("-i", "--autoindent", N_("Automatically indent new lines"));
|
2019-01-25 14:44:52 +00:00
|
|
|
print_opt("-j", "--jumpyscrolling", N_("Scroll per half-screen, not per line"));
|
2017-12-29 18:27:33 +00:00
|
|
|
print_opt("-k", "--cutfromcursor", N_("Cut from cursor to end of line"));
|
2005-03-26 22:49:46 +00:00
|
|
|
#endif
|
2016-10-20 08:44:29 +00:00
|
|
|
#ifdef ENABLE_LINENUMBERS
|
2017-12-29 18:27:33 +00:00
|
|
|
print_opt("-l", "--linenumbers", N_("Show line numbers in front of the text"));
|
2016-10-20 08:44:29 +00:00
|
|
|
#endif
|
2017-05-01 18:45:07 +00:00
|
|
|
#ifdef ENABLE_MOUSE
|
2017-12-29 18:27:33 +00:00
|
|
|
print_opt("-m", "--mouse", N_("Enable the use of the mouse"));
|
2000-06-06 05:53:49 +00:00
|
|
|
#endif
|
2020-09-21 15:04:10 +00:00
|
|
|
#ifndef NANO_TINY
|
2017-12-29 18:27:33 +00:00
|
|
|
print_opt("-n", "--noread", N_("Do not read the file (only write it)"));
|
2020-09-21 15:04:10 +00:00
|
|
|
#endif
|
2017-10-29 20:08:07 +00:00
|
|
|
#ifdef ENABLE_OPERATINGDIR
|
2017-12-29 18:27:33 +00:00
|
|
|
print_opt(_("-o <dir>"), _("--operatingdir=<dir>"),
|
2018-05-22 16:07:50 +00:00
|
|
|
N_("Set operating directory"));
|
2000-06-06 05:53:49 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
print_opt("-p", "--preserve", N_("Preserve XON (^Q) and XOFF (^S) keys"));
|
2020-05-26 17:07:42 +00:00
|
|
|
#ifndef NANO_TINY
|
|
|
|
print_opt("-q", "--indicator", N_("Show a position+portion indicator"));
|
|
|
|
#endif
|
2017-10-31 16:39:30 +00:00
|
|
|
#ifdef ENABLED_WRAPORJUSTIFY
|
2020-05-14 15:27:15 +00:00
|
|
|
print_opt(_("-r <number>"), _("--fill=<number>"),
|
2019-01-25 18:25:39 +00:00
|
|
|
N_("Set width for hard-wrap and justify"));
|
2001-05-21 12:56:25 +00:00
|
|
|
#endif
|
2017-10-31 18:32:42 +00:00
|
|
|
#ifdef ENABLE_SPELLER
|
2017-12-29 18:27:33 +00:00
|
|
|
if (!ISSET(RESTRICTED))
|
2020-05-14 15:27:15 +00:00
|
|
|
print_opt(_("-s <program>"), _("--speller=<program>"),
|
|
|
|
N_("Use this alternative spell checker"));
|
2001-01-12 07:51:05 +00:00
|
|
|
#endif
|
2020-04-30 15:25:48 +00:00
|
|
|
print_opt("-t", "--saveonexit", N_("Save changes on exit, don't prompt"));
|
2015-08-09 16:31:01 +00:00
|
|
|
#ifndef NANO_TINY
|
2017-12-29 18:27:33 +00:00
|
|
|
print_opt("-u", "--unix", N_("Save a file by default in Unix format"));
|
2015-08-09 16:31:01 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
print_opt("-v", "--view", N_("View mode (read-only)"));
|
2017-10-29 20:00:09 +00:00
|
|
|
#ifdef ENABLE_WRAPPING
|
2019-01-25 13:40:30 +00:00
|
|
|
print_opt("-w", "--nowrap", N_("Don't hard-wrap long lines [default]"));
|
2000-06-06 05:53:49 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
print_opt("-x", "--nohelp", N_("Don't show the two help lines"));
|
2018-04-30 20:10:27 +00:00
|
|
|
#ifndef NANO_TINY
|
|
|
|
print_opt("-y", "--afterends", N_("Make Ctrl+Right stop at word ends"));
|
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
if (!ISSET(RESTRICTED))
|
2020-03-13 14:54:24 +00:00
|
|
|
print_opt("-z", "--suspendable", N_("Enable suspension"));
|
2020-10-01 09:18:45 +00:00
|
|
|
#ifndef NANO_TINY
|
2021-01-07 13:14:35 +00:00
|
|
|
print_opt("-%", "--stateflags", N_("Show some states on the title bar"));
|
2021-01-07 13:09:57 +00:00
|
|
|
print_opt("-_", "--minibar", N_("Show a feedback bar at the bottom"));
|
2020-10-01 09:18:45 +00:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_LIBMAGIC
|
|
|
|
print_opt("-!", "--magic", N_("Also try magic to determine syntax"));
|
|
|
|
#endif
|
2000-06-06 05:53:49 +00:00
|
|
|
}
|
|
|
|
|
2020-09-12 10:21:24 +00:00
|
|
|
/* Display the version number of this nano, a copyright notice, some contact
|
|
|
|
* information, and the configuration options this nano was compiled with. */
|
2002-08-21 16:10:37 +00:00
|
|
|
void version(void)
|
2000-06-06 05:53:49 +00:00
|
|
|
{
|
2016-04-08 08:22:09 +00:00
|
|
|
#ifdef REVISION
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" GNU nano from git, %s\n", REVISION);
|
2016-04-08 08:22:09 +00:00
|
|
|
#else
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(_(" GNU nano, version %s\n"), VERSION);
|
2016-04-08 08:22:09 +00:00
|
|
|
#endif
|
2020-10-01 08:40:25 +00:00
|
|
|
#ifndef NANO_TINY
|
2021-01-11 13:21:03 +00:00
|
|
|
printf(" (C) 1999-2011, 2013-2021 Free Software Foundation, Inc.\n");
|
|
|
|
printf(_(" (C) 2014-%s the contributors to nano\n"), "2021");
|
2020-10-01 08:40:25 +00:00
|
|
|
#endif
|
|
|
|
printf(_(" Compiled options:"));
|
2000-12-01 18:46:01 +00:00
|
|
|
|
2014-04-05 19:57:17 +00:00
|
|
|
#ifdef NANO_TINY
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --enable-tiny");
|
2017-05-08 17:08:23 +00:00
|
|
|
#ifdef ENABLE_BROWSER
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --enable-browser");
|
2014-04-05 19:57:17 +00:00
|
|
|
#endif
|
2017-11-01 18:45:33 +00:00
|
|
|
#ifdef ENABLE_COLOR
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --enable-color");
|
2014-04-05 19:57:17 +00:00
|
|
|
#endif
|
2017-11-01 19:33:14 +00:00
|
|
|
#ifdef ENABLE_EXTRA
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --enable-extra");
|
2014-04-05 19:57:17 +00:00
|
|
|
#endif
|
2017-04-25 15:51:45 +00:00
|
|
|
#ifdef ENABLE_HELP
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --enable-help");
|
2014-04-05 19:57:17 +00:00
|
|
|
#endif
|
2017-10-29 18:42:12 +00:00
|
|
|
#ifdef ENABLE_HISTORIES
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --enable-histories");
|
2014-06-19 20:05:24 +00:00
|
|
|
#endif
|
2017-10-31 16:34:07 +00:00
|
|
|
#ifdef ENABLE_JUSTIFY
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --enable-justify");
|
2014-04-05 19:57:17 +00:00
|
|
|
#endif
|
2014-04-13 19:54:47 +00:00
|
|
|
#ifdef HAVE_LIBMAGIC
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --enable-libmagic");
|
2014-04-13 19:54:47 +00:00
|
|
|
#endif
|
2016-10-20 08:44:29 +00:00
|
|
|
#ifdef ENABLE_LINENUMBERS
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --enable-linenumbers");
|
2016-10-20 08:44:29 +00:00
|
|
|
#endif
|
2017-05-01 18:45:07 +00:00
|
|
|
#ifdef ENABLE_MOUSE
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --enable-mouse");
|
2014-04-05 19:57:17 +00:00
|
|
|
#endif
|
2017-05-08 17:42:44 +00:00
|
|
|
#ifdef ENABLE_NANORC
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --enable-nanorc");
|
2014-04-13 20:50:20 +00:00
|
|
|
#endif
|
2017-05-01 18:20:34 +00:00
|
|
|
#ifdef ENABLE_MULTIBUFFER
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --enable-multibuffer");
|
2014-04-05 19:57:17 +00:00
|
|
|
#endif
|
2017-10-29 20:08:07 +00:00
|
|
|
#ifdef ENABLE_OPERATINGDIR
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --enable-operatingdir");
|
2014-04-05 19:57:17 +00:00
|
|
|
#endif
|
2017-10-31 18:32:42 +00:00
|
|
|
#ifdef ENABLE_SPELLER
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --enable-speller");
|
2014-04-05 19:57:17 +00:00
|
|
|
#endif
|
2017-05-08 17:15:51 +00:00
|
|
|
#ifdef ENABLE_TABCOMP
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --enable-tabcomp");
|
2014-04-05 19:57:17 +00:00
|
|
|
#endif
|
2017-10-29 20:00:09 +00:00
|
|
|
#ifdef ENABLE_WRAPPING
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --enable-wrapping");
|
2014-04-05 19:57:17 +00:00
|
|
|
#endif
|
|
|
|
#else /* !NANO_TINY */
|
2017-05-08 17:08:23 +00:00
|
|
|
#ifndef ENABLE_BROWSER
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --disable-browser");
|
2001-04-12 03:01:53 +00:00
|
|
|
#endif
|
2017-11-01 18:45:33 +00:00
|
|
|
#ifndef ENABLE_COLOR
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --disable-color");
|
2014-04-05 19:57:17 +00:00
|
|
|
#endif
|
2016-05-25 20:13:50 +00:00
|
|
|
#ifndef ENABLE_COMMENT
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --disable-comment");
|
2016-05-25 20:13:50 +00:00
|
|
|
#endif
|
2017-11-01 19:33:14 +00:00
|
|
|
#ifndef ENABLE_EXTRA
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --disable-extra");
|
2014-04-03 20:57:44 +00:00
|
|
|
#endif
|
2017-04-25 15:51:45 +00:00
|
|
|
#ifndef ENABLE_HELP
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --disable-help");
|
2001-04-12 03:01:53 +00:00
|
|
|
#endif
|
2017-10-29 18:42:12 +00:00
|
|
|
#ifndef ENABLE_HISTORIES
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --disable-histories");
|
2014-06-19 20:05:24 +00:00
|
|
|
#endif
|
2017-10-31 16:34:07 +00:00
|
|
|
#ifndef ENABLE_JUSTIFY
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --disable-justify");
|
2001-04-12 03:01:53 +00:00
|
|
|
#endif
|
2014-04-13 19:54:47 +00:00
|
|
|
#ifndef HAVE_LIBMAGIC
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --disable-libmagic");
|
2014-04-13 19:54:47 +00:00
|
|
|
#endif
|
2016-10-20 08:44:29 +00:00
|
|
|
#ifndef ENABLE_LINENUMBERS
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --disable-linenumbers");
|
2016-10-20 08:44:29 +00:00
|
|
|
#endif
|
2017-05-01 18:45:07 +00:00
|
|
|
#ifndef ENABLE_MOUSE
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --disable-mouse");
|
2000-12-18 05:36:51 +00:00
|
|
|
#endif
|
2017-05-01 18:20:34 +00:00
|
|
|
#ifndef ENABLE_MULTIBUFFER
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --disable-multibuffer");
|
2014-04-03 20:23:07 +00:00
|
|
|
#endif
|
2017-05-08 17:42:44 +00:00
|
|
|
#ifndef ENABLE_NANORC
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --disable-nanorc");
|
2014-04-13 20:50:20 +00:00
|
|
|
#endif
|
2017-10-29 20:08:07 +00:00
|
|
|
#ifndef ENABLE_OPERATINGDIR
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --disable-operatingdir");
|
2001-09-19 03:19:43 +00:00
|
|
|
#endif
|
2017-10-31 18:32:42 +00:00
|
|
|
#ifndef ENABLE_SPELLER
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --disable-speller");
|
2002-09-06 20:35:28 +00:00
|
|
|
#endif
|
2017-05-08 17:15:51 +00:00
|
|
|
#ifndef ENABLE_TABCOMP
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --disable-tabcomp");
|
2002-09-06 20:35:28 +00:00
|
|
|
#endif
|
2016-12-15 11:38:47 +00:00
|
|
|
#ifndef ENABLE_WORDCOMPLETION
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --disable-wordcomp");
|
2016-12-15 11:38:47 +00:00
|
|
|
#endif
|
2017-10-29 20:00:09 +00:00
|
|
|
#ifndef ENABLE_WRAPPING
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --disable-wrapping");
|
2002-09-06 20:35:28 +00:00
|
|
|
#endif
|
2014-04-05 19:57:17 +00:00
|
|
|
#endif /* !NANO_TINY */
|
|
|
|
|
2005-06-29 17:10:58 +00:00
|
|
|
#ifdef DEBUG
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --enable-debug");
|
2005-06-29 17:10:58 +00:00
|
|
|
#endif
|
2014-04-05 19:57:17 +00:00
|
|
|
#ifndef ENABLE_NLS
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --disable-nls");
|
2005-06-29 17:10:58 +00:00
|
|
|
#endif
|
2005-07-17 02:40:07 +00:00
|
|
|
#ifdef ENABLE_UTF8
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --enable-utf8");
|
2014-04-05 19:57:17 +00:00
|
|
|
#else
|
2017-12-29 18:27:33 +00:00
|
|
|
printf(" --disable-utf8");
|
2000-11-24 20:45:14 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
printf("\n");
|
2000-06-06 05:53:49 +00:00
|
|
|
}
|
|
|
|
|
2020-05-08 09:06:43 +00:00
|
|
|
/* Register that Ctrl+C was pressed during some system call. */
|
2020-09-16 10:11:09 +00:00
|
|
|
void make_a_note(int signal)
|
2009-01-30 17:37:44 +00:00
|
|
|
{
|
2019-05-26 11:10:47 +00:00
|
|
|
control_C_was_pressed = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make ^C interrupt a system call and set a flag. */
|
|
|
|
void install_handler_for_Ctrl_C(void)
|
|
|
|
{
|
|
|
|
/* Enable the generation of a SIGINT when ^C is pressed. */
|
2019-05-27 15:24:35 +00:00
|
|
|
enable_kb_interrupt();
|
2019-05-26 11:10:47 +00:00
|
|
|
|
|
|
|
/* Set up a signal handler so that pressing ^C will set a flag. */
|
|
|
|
newaction.sa_handler = make_a_note;
|
|
|
|
newaction.sa_flags = 0;
|
|
|
|
sigaction(SIGINT, &newaction, &oldaction);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Go back to ignoring ^C. */
|
|
|
|
void restore_handler_for_Ctrl_C(void)
|
|
|
|
{
|
|
|
|
sigaction(SIGINT, &oldaction, NULL);
|
2019-05-27 15:24:35 +00:00
|
|
|
disable_kb_interrupt();
|
2009-01-30 17:37:44 +00:00
|
|
|
}
|
|
|
|
|
2020-09-12 09:40:08 +00:00
|
|
|
#ifndef NANO_TINY
|
2019-05-28 09:06:42 +00:00
|
|
|
/* Reconnect standard input to the tty, and store its state. */
|
|
|
|
void reconnect_and_store_state(void)
|
|
|
|
{
|
|
|
|
int thetty = open("/dev/tty", O_RDONLY);
|
|
|
|
|
2020-10-10 09:43:55 +00:00
|
|
|
if (thetty < 0 || dup2(thetty, STDIN_FILENO) < 0)
|
2019-05-28 09:06:42 +00:00
|
|
|
die(_("Could not reconnect stdin to keyboard\n"));
|
|
|
|
|
|
|
|
close(thetty);
|
|
|
|
|
2019-05-28 10:19:49 +00:00
|
|
|
/* If input was not cut short, store the current state of the terminal. */
|
|
|
|
if (!control_C_was_pressed)
|
2020-10-10 09:43:55 +00:00
|
|
|
tcgetattr(STDIN_FILENO, &original_state);
|
2019-05-28 09:06:42 +00:00
|
|
|
}
|
|
|
|
|
2017-06-23 06:27:06 +00:00
|
|
|
/* Read whatever comes from standard input into a new buffer. */
|
|
|
|
bool scoop_stdin(void)
|
2009-01-30 17:37:44 +00:00
|
|
|
{
|
2017-12-29 18:27:33 +00:00
|
|
|
FILE *stream;
|
2017-06-07 13:42:05 +00:00
|
|
|
|
2020-01-22 11:45:15 +00:00
|
|
|
restore_terminal();
|
2020-01-03 23:52:21 +00:00
|
|
|
|
2019-05-19 17:44:27 +00:00
|
|
|
/* When input comes from a terminal, show a helpful message. */
|
2020-10-10 09:43:55 +00:00
|
|
|
if (isatty(STDIN_FILENO))
|
2019-05-19 17:44:27 +00:00
|
|
|
fprintf(stderr, _("Reading data from keyboard; "
|
|
|
|
"type ^D or ^D^D to finish.\n"));
|
2019-05-26 10:24:44 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Open standard input. */
|
|
|
|
stream = fopen("/dev/stdin", "rb");
|
|
|
|
if (stream == NULL) {
|
|
|
|
int errnumber = errno;
|
2017-06-08 08:40:19 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
terminal_init();
|
|
|
|
doupdate();
|
|
|
|
statusline(ALERT, _("Failed to open stdin: %s"), strerror(errnumber));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2019-05-24 08:04:59 +00:00
|
|
|
/* Set up a signal handler so that ^C will stop the reading. */
|
2019-05-26 11:10:47 +00:00
|
|
|
install_handler_for_Ctrl_C();
|
2019-05-24 08:04:59 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Read the input into a new buffer. */
|
2019-05-19 15:48:08 +00:00
|
|
|
make_new_buffer();
|
2018-03-22 09:41:39 +00:00
|
|
|
read_file(stream, 0, "stdin", TRUE);
|
2019-05-19 15:48:08 +00:00
|
|
|
#ifdef ENABLE_COLOR
|
2020-04-28 14:32:04 +00:00
|
|
|
find_and_prime_applicable_syntax();
|
2019-05-19 15:48:08 +00:00
|
|
|
#endif
|
2019-05-27 17:30:29 +00:00
|
|
|
|
2019-05-28 09:06:42 +00:00
|
|
|
/* Restore the original ^C handler. */
|
2019-05-26 11:10:47 +00:00
|
|
|
restore_handler_for_Ctrl_C();
|
2017-12-29 18:27:33 +00:00
|
|
|
|
|
|
|
if (!ISSET(VIEW_MODE) && openfile->totsize > 0)
|
|
|
|
set_modified();
|
|
|
|
|
|
|
|
return TRUE;
|
2009-01-30 17:37:44 +00:00
|
|
|
}
|
2020-09-12 09:40:08 +00:00
|
|
|
#endif
|
2009-01-30 17:37:44 +00:00
|
|
|
|
2017-06-06 15:57:15 +00:00
|
|
|
/* Register half a dozen signal handlers. */
|
2002-09-06 20:35:28 +00:00
|
|
|
void signal_init(void)
|
|
|
|
{
|
2019-05-28 12:09:54 +00:00
|
|
|
struct sigaction deed = {{0}};
|
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Trap SIGINT and SIGQUIT because we want them to do useful things. */
|
2019-05-28 12:09:54 +00:00
|
|
|
deed.sa_handler = SIG_IGN;
|
|
|
|
sigaction(SIGINT, &deed, NULL);
|
2017-02-21 22:04:47 +00:00
|
|
|
#ifdef SIGQUIT
|
2019-05-28 12:09:54 +00:00
|
|
|
sigaction(SIGQUIT, &deed, NULL);
|
2017-02-21 22:04:47 +00:00
|
|
|
#endif
|
2002-09-06 20:35:28 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Trap SIGHUP and SIGTERM because we want to write the file out. */
|
2019-05-28 12:09:54 +00:00
|
|
|
deed.sa_handler = handle_hupterm;
|
2017-02-21 22:04:47 +00:00
|
|
|
#ifdef SIGHUP
|
2019-05-28 12:09:54 +00:00
|
|
|
sigaction(SIGHUP, &deed, NULL);
|
2017-02-21 22:04:47 +00:00
|
|
|
#endif
|
2019-05-28 12:09:54 +00:00
|
|
|
sigaction(SIGTERM, &deed, NULL);
|
2002-09-06 20:35:28 +00:00
|
|
|
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Trap SIGWINCH because we want to handle window resizes. */
|
2019-05-28 12:09:54 +00:00
|
|
|
deed.sa_handler = handle_sigwinch;
|
|
|
|
sigaction(SIGWINCH, &deed, NULL);
|
2002-03-21 05:07:28 +00:00
|
|
|
#endif
|
2000-06-06 05:53:49 +00:00
|
|
|
|
2020-09-07 09:44:29 +00:00
|
|
|
/* In the suspend and continue handlers, block all other signals.
|
|
|
|
* If we don't do this, other stuff interrupts them! */
|
|
|
|
sigfillset(&deed.sa_mask);
|
2017-02-21 22:04:47 +00:00
|
|
|
#ifdef SIGTSTP
|
2020-09-07 09:44:29 +00:00
|
|
|
deed.sa_handler = do_suspend;
|
|
|
|
sigaction(SIGTSTP, &deed, NULL);
|
2017-02-21 22:04:47 +00:00
|
|
|
#endif
|
|
|
|
#ifdef SIGCONT
|
2020-09-07 09:44:29 +00:00
|
|
|
deed.sa_handler = do_continue;
|
|
|
|
sigaction(SIGCONT, &deed, NULL);
|
2017-05-24 08:20:23 +00:00
|
|
|
#endif
|
2018-04-29 11:51:52 +00:00
|
|
|
|
2018-05-10 10:21:53 +00:00
|
|
|
#if !defined(NANO_TINY) && !defined(DEBUG)
|
2018-05-06 14:46:41 +00:00
|
|
|
if (getenv("NANO_NOCATCH") == NULL) {
|
2018-05-06 18:01:53 +00:00
|
|
|
/* Trap SIGSEGV and SIGABRT to save any changed buffers and reset
|
|
|
|
* the terminal to a usable state. Reset these handlers to their
|
|
|
|
* defaults as soon as their signal fires. */
|
2019-05-28 12:09:54 +00:00
|
|
|
deed.sa_handler = handle_crash;
|
|
|
|
deed.sa_flags |= SA_RESETHAND;
|
|
|
|
sigaction(SIGSEGV, &deed, NULL);
|
|
|
|
sigaction(SIGABRT, &deed, NULL);
|
2018-05-06 14:46:41 +00:00
|
|
|
}
|
2018-04-29 11:51:52 +00:00
|
|
|
#endif
|
2002-09-06 20:35:28 +00:00
|
|
|
}
|
2000-09-01 13:32:47 +00:00
|
|
|
|
2004-05-18 01:20:36 +00:00
|
|
|
/* Handler for SIGHUP (hangup) and SIGTERM (terminate). */
|
2020-09-16 10:11:09 +00:00
|
|
|
void handle_hupterm(int signal)
|
2002-09-06 20:35:28 +00:00
|
|
|
{
|
2017-12-29 18:27:33 +00:00
|
|
|
die(_("Received SIGHUP or SIGTERM\n"));
|
2002-09-06 20:35:28 +00:00
|
|
|
}
|
2002-06-21 03:20:06 +00:00
|
|
|
|
2018-05-10 10:21:53 +00:00
|
|
|
#if !defined(NANO_TINY) && !defined(DEBUG)
|
2018-04-29 11:51:52 +00:00
|
|
|
/* Handler for SIGSEGV (segfault) and SIGABRT (abort). */
|
2020-09-16 10:11:09 +00:00
|
|
|
void handle_crash(int signal)
|
2018-04-29 11:51:52 +00:00
|
|
|
{
|
|
|
|
die(_("Sorry! Nano crashed! Code: %d. Please report a bug.\n"), signal);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2004-05-18 01:20:36 +00:00
|
|
|
/* Handler for SIGTSTP (suspend). */
|
2020-09-16 10:11:09 +00:00
|
|
|
void do_suspend(int signal)
|
2002-09-06 20:35:28 +00:00
|
|
|
{
|
2017-05-01 18:45:07 +00:00
|
|
|
#ifdef ENABLE_MOUSE
|
2017-12-29 18:27:33 +00:00
|
|
|
disable_mouse_support();
|
2006-06-09 18:24:37 +00:00
|
|
|
#endif
|
2020-01-22 11:45:15 +00:00
|
|
|
restore_terminal();
|
2020-01-03 23:52:21 +00:00
|
|
|
|
2020-01-07 12:31:08 +00:00
|
|
|
printf("\n\n");
|
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Display our helpful message. */
|
|
|
|
printf(_("Use \"fg\" to return to nano.\n"));
|
|
|
|
fflush(stdout);
|
2000-09-01 13:32:47 +00:00
|
|
|
|
2018-09-12 14:04:11 +00:00
|
|
|
/* The suspend keystroke must not elicit cursor-position display. */
|
2020-07-03 07:32:25 +00:00
|
|
|
lastmessage = HUSH;
|
2018-09-12 14:04:11 +00:00
|
|
|
|
2017-02-21 22:04:47 +00:00
|
|
|
#ifdef SIGSTOP
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Do what mutt does: send ourselves a SIGSTOP. */
|
|
|
|
kill(0, SIGSTOP);
|
2017-02-21 22:04:47 +00:00
|
|
|
#endif
|
2002-09-06 20:35:28 +00:00
|
|
|
}
|
2002-06-21 03:20:06 +00:00
|
|
|
|
2017-06-06 15:57:15 +00:00
|
|
|
/* Put nano to sleep (if suspension is enabled). */
|
2010-11-12 06:22:12 +00:00
|
|
|
void do_suspend_void(void)
|
2008-03-13 08:23:52 +00:00
|
|
|
{
|
2020-12-05 11:12:11 +00:00
|
|
|
if (!ISSET(SUSPENDABLE)) {
|
2020-12-08 16:09:07 +00:00
|
|
|
statusline(AHEM, _("Suspension is not enabled"));
|
2017-12-29 18:27:33 +00:00
|
|
|
beep();
|
2020-12-05 11:12:11 +00:00
|
|
|
} else
|
|
|
|
do_suspend(0);
|
2020-05-28 10:09:56 +00:00
|
|
|
|
|
|
|
ran_a_tool = TRUE;
|
2008-03-13 08:23:52 +00:00
|
|
|
}
|
|
|
|
|
2004-05-18 01:20:36 +00:00
|
|
|
/* Handler for SIGCONT (continue after suspend). */
|
2020-09-16 10:11:09 +00:00
|
|
|
void do_continue(int signal)
|
2002-09-06 20:35:28 +00:00
|
|
|
{
|
2017-05-01 18:45:07 +00:00
|
|
|
#ifdef ENABLE_MOUSE
|
2017-12-29 18:27:33 +00:00
|
|
|
if (ISSET(USE_MOUSE))
|
|
|
|
enable_mouse_support();
|
2006-06-09 18:24:37 +00:00
|
|
|
#endif
|
|
|
|
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Perhaps the user resized the window while we slept. */
|
|
|
|
the_window_resized = TRUE;
|
2004-04-07 00:44:35 +00:00
|
|
|
#else
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Put the terminal in the desired state again. */
|
|
|
|
terminal_init();
|
2002-09-06 20:35:28 +00:00
|
|
|
#endif
|
2020-12-05 10:57:08 +00:00
|
|
|
|
2020-09-08 10:07:22 +00:00
|
|
|
/* Insert a fake keystroke, to neutralize a key-eating issue. */
|
2017-12-29 18:27:33 +00:00
|
|
|
ungetch(KEY_FLUSH);
|
2002-09-06 20:35:28 +00:00
|
|
|
}
|
|
|
|
|
2020-06-22 12:00:23 +00:00
|
|
|
#if !defined(NANO_TINY) || defined(ENABLE_SPELLER) || defined(ENABLE_COLOR)
|
2019-03-30 18:23:15 +00:00
|
|
|
/* Block or unblock the SIGWINCH signal, depending on the blockit parameter. */
|
|
|
|
void block_sigwinch(bool blockit)
|
|
|
|
{
|
|
|
|
sigset_t winch;
|
|
|
|
|
|
|
|
sigemptyset(&winch);
|
|
|
|
sigaddset(&winch, SIGWINCH);
|
|
|
|
sigprocmask(blockit ? SIG_BLOCK : SIG_UNBLOCK, &winch, NULL);
|
2019-03-31 23:17:45 +00:00
|
|
|
|
|
|
|
#ifndef NANO_TINY
|
|
|
|
if (the_window_resized)
|
|
|
|
regenerate_screen();
|
|
|
|
#endif
|
2019-03-30 18:23:15 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2005-12-08 07:09:08 +00:00
|
|
|
/* Handler for SIGWINCH (window size change). */
|
2020-09-16 10:11:09 +00:00
|
|
|
void handle_sigwinch(int signal)
|
2015-05-28 13:02:29 +00:00
|
|
|
{
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Let the input routine know that a SIGWINCH has occurred. */
|
|
|
|
the_window_resized = TRUE;
|
2015-05-28 13:02:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Reinitialize and redraw the screen completely. */
|
|
|
|
void regenerate_screen(void)
|
2002-09-06 20:35:28 +00:00
|
|
|
{
|
2017-12-29 18:27:33 +00:00
|
|
|
const char *tty = ttyname(0);
|
|
|
|
int fd, result = 0;
|
|
|
|
struct winsize win;
|
|
|
|
|
|
|
|
/* Reset the trigger. */
|
|
|
|
the_window_resized = FALSE;
|
|
|
|
|
|
|
|
if (tty == NULL)
|
|
|
|
return;
|
|
|
|
fd = open(tty, O_RDWR);
|
|
|
|
if (fd == -1)
|
|
|
|
return;
|
|
|
|
result = ioctl(fd, TIOCGWINSZ, &win);
|
|
|
|
close(fd);
|
|
|
|
if (result == -1)
|
|
|
|
return;
|
|
|
|
|
2019-05-27 15:19:21 +00:00
|
|
|
/* We could check whether COLS or LINES changed, and return otherwise,
|
|
|
|
* but it seems curses does not always update these global variables. */
|
2020-01-03 11:00:06 +00:00
|
|
|
#ifdef REDEFINING_MACROS_OK
|
2017-12-29 18:27:33 +00:00
|
|
|
COLS = win.ws_col;
|
|
|
|
LINES = win.ws_row;
|
2010-03-07 19:35:46 +00:00
|
|
|
#endif
|
2020-05-26 17:07:42 +00:00
|
|
|
thebar = (ISSET(INDICATOR) && LINES > 5 && COLS > 9) ? 1 : 0;
|
2020-04-25 15:19:03 +00:00
|
|
|
bardata = nrealloc(bardata, LINES * sizeof(int));
|
|
|
|
|
|
|
|
editwincols = COLS - margin - thebar;
|
2002-09-06 20:35:28 +00:00
|
|
|
|
2020-01-07 19:25:31 +00:00
|
|
|
/* Do as the website suggests: leave and immediately reenter curses mode. */
|
2017-12-29 18:27:33 +00:00
|
|
|
endwin();
|
|
|
|
doupdate();
|
2002-09-06 20:35:28 +00:00
|
|
|
|
2020-05-21 07:12:33 +00:00
|
|
|
/* Put the terminal in the desired state again, and
|
|
|
|
* recreate the subwindows with their (new) sizes. */
|
2017-12-29 18:27:33 +00:00
|
|
|
terminal_init();
|
|
|
|
window_init();
|
2020-05-21 07:12:33 +00:00
|
|
|
|
|
|
|
/* If we have an open buffer, redraw the contents of the subwindows. */
|
|
|
|
if (openfile) {
|
|
|
|
ensure_firstcolumn_is_aligned();
|
2020-05-31 14:14:43 +00:00
|
|
|
draw_all_subwindows();
|
2020-05-21 07:12:33 +00:00
|
|
|
}
|
2002-09-06 20:35:28 +00:00
|
|
|
}
|
2004-02-16 20:32:40 +00:00
|
|
|
|
2014-03-24 21:48:23 +00:00
|
|
|
/* Handle the global toggle specified in flag. */
|
2008-03-05 07:34:01 +00:00
|
|
|
void do_toggle(int flag)
|
2000-09-01 13:32:47 +00:00
|
|
|
{
|
2020-03-13 15:17:10 +00:00
|
|
|
if (flag == SUSPENDABLE && in_restricted_mode())
|
2017-12-29 18:27:33 +00:00
|
|
|
return;
|
2015-07-29 20:21:45 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
TOGGLE(flag);
|
2019-05-16 14:04:12 +00:00
|
|
|
focusing = FALSE;
|
2000-09-12 23:02:49 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
switch (flag) {
|
2019-05-16 14:04:12 +00:00
|
|
|
case NO_HELP:
|
|
|
|
window_init();
|
2020-05-31 14:14:43 +00:00
|
|
|
draw_all_subwindows();
|
2019-05-16 14:04:12 +00:00
|
|
|
break;
|
2017-05-01 18:45:07 +00:00
|
|
|
#ifdef ENABLE_MOUSE
|
2017-12-29 18:27:33 +00:00
|
|
|
case USE_MOUSE:
|
|
|
|
mouse_init();
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
case SOFTWRAP:
|
2021-04-21 14:27:36 +00:00
|
|
|
if (!ISSET(SOFTWRAP))
|
2017-12-29 18:27:33 +00:00
|
|
|
openfile->firstcolumn = 0;
|
|
|
|
refresh_needed = TRUE;
|
|
|
|
break;
|
|
|
|
case WHITESPACE_DISPLAY:
|
2019-05-16 14:04:12 +00:00
|
|
|
titlebar(NULL);
|
|
|
|
refresh_needed = TRUE;
|
|
|
|
break;
|
2017-11-01 18:45:33 +00:00
|
|
|
#ifdef ENABLE_COLOR
|
2020-05-01 11:25:15 +00:00
|
|
|
case NO_SYNTAX:
|
2020-05-01 12:08:55 +00:00
|
|
|
precalc_multicolorinfo();
|
2017-12-29 18:27:33 +00:00
|
|
|
refresh_needed = TRUE;
|
|
|
|
break;
|
2019-05-16 14:04:12 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
}
|
2000-09-12 23:02:49 +00:00
|
|
|
|
2021-02-08 11:32:39 +00:00
|
|
|
if (!ISSET(MINIBAR) && ISSET(STATEFLAGS))
|
|
|
|
if (flag == AUTOINDENT || flag == BREAK_LONG_LINES || flag == SOFTWRAP)
|
|
|
|
titlebar(NULL);
|
2005-06-09 04:00:03 +00:00
|
|
|
|
2021-02-08 11:32:39 +00:00
|
|
|
if (ISSET(MINIBAR) && (flag == NO_HELP || flag == LINE_NUMBERS ))
|
|
|
|
return;
|
2005-06-09 04:00:03 +00:00
|
|
|
|
2021-02-08 09:18:22 +00:00
|
|
|
if (flag == CONSTANT_SHOW)
|
|
|
|
wipe_statusbar();
|
2021-02-08 11:32:39 +00:00
|
|
|
else if (!ISSET(MINIBAR) || !ISSET(STATEFLAGS) || flag == SMART_HOME ||
|
|
|
|
flag == NO_SYNTAX || flag == WHITESPACE_DISPLAY ||
|
|
|
|
flag == CUT_FROM_CURSOR || flag == TABS_TO_SPACES ||
|
|
|
|
flag == USE_MOUSE || flag == SUSPENDABLE) {
|
|
|
|
bool enabled = ISSET(flag);
|
|
|
|
|
|
|
|
if (flag == NO_HELP || flag == NO_SYNTAX)
|
|
|
|
enabled = !enabled;
|
|
|
|
|
2020-12-08 16:09:07 +00:00
|
|
|
statusline(REMARK, "%s %s", _(flagtostr(flag)),
|
2021-02-08 11:32:39 +00:00
|
|
|
enabled ? _("enabled") : _("disabled"));
|
|
|
|
}
|
2000-06-06 05:53:49 +00:00
|
|
|
}
|
2016-09-01 07:36:47 +00:00
|
|
|
#endif /* !NANO_TINY */
|
2000-06-06 05:53:49 +00:00
|
|
|
|
2020-01-08 09:25:46 +00:00
|
|
|
/* Disable extended input and output processing in our terminal settings. */
|
2005-06-09 04:02:57 +00:00
|
|
|
void disable_extended_io(void)
|
2004-09-22 22:45:08 +00:00
|
|
|
{
|
2017-02-21 22:04:48 +00:00
|
|
|
#ifdef HAVE_TERMIOS_H
|
2019-09-06 17:38:14 +00:00
|
|
|
struct termios settings = {0};
|
2004-09-22 22:45:08 +00:00
|
|
|
|
2019-09-06 17:38:14 +00:00
|
|
|
tcgetattr(0, &settings);
|
|
|
|
settings.c_lflag &= ~IEXTEN;
|
|
|
|
settings.c_oflag &= ~OPOST;
|
|
|
|
tcsetattr(0, TCSANOW, &settings);
|
2017-02-21 22:04:48 +00:00
|
|
|
#endif
|
2004-09-22 22:45:08 +00:00
|
|
|
}
|
|
|
|
|
2019-05-26 10:24:44 +00:00
|
|
|
/* Stop ^C from generating a SIGINT. */
|
2019-05-27 15:24:35 +00:00
|
|
|
void disable_kb_interrupt(void)
|
2007-12-18 15:55:48 +00:00
|
|
|
{
|
2017-02-21 22:04:48 +00:00
|
|
|
#ifdef HAVE_TERMIOS_H
|
2019-09-06 17:38:14 +00:00
|
|
|
struct termios settings = {0};
|
2007-12-18 15:55:48 +00:00
|
|
|
|
2019-09-06 17:38:14 +00:00
|
|
|
tcgetattr(0, &settings);
|
|
|
|
settings.c_lflag &= ~ISIG;
|
|
|
|
tcsetattr(0, TCSANOW, &settings);
|
2017-02-21 22:04:48 +00:00
|
|
|
#endif
|
2007-12-18 15:55:48 +00:00
|
|
|
}
|
|
|
|
|
2019-05-26 10:24:44 +00:00
|
|
|
/* Make ^C generate a SIGINT. */
|
2019-05-27 15:24:35 +00:00
|
|
|
void enable_kb_interrupt(void)
|
2004-05-18 01:20:36 +00:00
|
|
|
{
|
2017-02-21 22:04:48 +00:00
|
|
|
#ifdef HAVE_TERMIOS_H
|
2019-09-06 17:38:14 +00:00
|
|
|
struct termios settings = {0};
|
2004-05-18 01:20:36 +00:00
|
|
|
|
2019-09-06 17:38:14 +00:00
|
|
|
tcgetattr(0, &settings);
|
|
|
|
settings.c_lflag |= ISIG;
|
|
|
|
tcsetattr(0, TCSANOW, &settings);
|
2017-02-21 22:04:48 +00:00
|
|
|
#endif
|
2004-05-18 01:20:36 +00:00
|
|
|
}
|
|
|
|
|
2019-05-27 15:19:21 +00:00
|
|
|
/* Disable the terminal's XON/XOFF flow-control characters. */
|
2004-05-18 01:20:36 +00:00
|
|
|
void disable_flow_control(void)
|
|
|
|
{
|
2017-02-21 22:04:48 +00:00
|
|
|
#ifdef HAVE_TERMIOS_H
|
2019-09-06 17:38:14 +00:00
|
|
|
struct termios settings;
|
2004-05-18 01:20:36 +00:00
|
|
|
|
2019-09-06 17:38:14 +00:00
|
|
|
tcgetattr(0, &settings);
|
|
|
|
settings.c_iflag &= ~IXON;
|
|
|
|
tcsetattr(0, TCSANOW, &settings);
|
2017-02-21 22:04:48 +00:00
|
|
|
#endif
|
2004-05-18 01:20:36 +00:00
|
|
|
}
|
|
|
|
|
2019-05-27 15:19:21 +00:00
|
|
|
/* Enable the terminal's XON/XOFF flow-control characters. */
|
2004-05-18 01:20:36 +00:00
|
|
|
void enable_flow_control(void)
|
|
|
|
{
|
2017-02-21 22:04:48 +00:00
|
|
|
#ifdef HAVE_TERMIOS_H
|
2019-09-06 17:38:14 +00:00
|
|
|
struct termios settings;
|
2004-05-18 01:20:36 +00:00
|
|
|
|
2019-09-06 17:38:14 +00:00
|
|
|
tcgetattr(0, &settings);
|
|
|
|
settings.c_iflag |= IXON;
|
|
|
|
tcsetattr(0, TCSANOW, &settings);
|
2017-02-21 22:04:48 +00:00
|
|
|
#endif
|
2004-05-18 01:20:36 +00:00
|
|
|
}
|
|
|
|
|
2007-12-18 02:03:00 +00:00
|
|
|
/* Set up the terminal state. Put the terminal in raw mode (read one
|
|
|
|
* character at a time, disable the special control keys, and disable
|
|
|
|
* the flow control characters), disable translation of carriage return
|
|
|
|
* (^M) into newline (^J) so that we can tell the difference between the
|
|
|
|
* Enter key and Ctrl-J, and disable echoing of characters as they're
|
|
|
|
* typed. Finally, disable extended input and output processing, and,
|
|
|
|
* if we're not in preserve mode, reenable interpretation of the flow
|
|
|
|
* control characters. */
|
2004-07-27 16:46:35 +00:00
|
|
|
void terminal_init(void)
|
|
|
|
{
|
2020-12-05 11:12:11 +00:00
|
|
|
raw();
|
|
|
|
nonl();
|
|
|
|
noecho();
|
|
|
|
|
|
|
|
disable_extended_io();
|
2020-01-27 15:39:34 +00:00
|
|
|
|
2020-09-08 07:15:12 +00:00
|
|
|
if (ISSET(PRESERVE))
|
|
|
|
enable_flow_control();
|
2020-12-05 10:57:08 +00:00
|
|
|
|
2020-01-27 15:39:34 +00:00
|
|
|
disable_kb_interrupt();
|
|
|
|
|
2020-01-24 16:17:34 +00:00
|
|
|
#ifndef NANO_TINY
|
2020-01-03 23:52:21 +00:00
|
|
|
/* Tell the terminal to enable bracketed pastes. */
|
2020-07-22 07:07:14 +00:00
|
|
|
printf("\x1B[?2004h");
|
2020-01-03 23:52:21 +00:00
|
|
|
fflush(stdout);
|
2020-01-24 16:17:34 +00:00
|
|
|
#endif
|
2004-07-27 16:46:35 +00:00
|
|
|
}
|
|
|
|
|
2016-08-16 08:49:55 +00:00
|
|
|
/* Ask ncurses for a keycode, or assign a default one. */
|
|
|
|
int get_keycode(const char *keyname, const int standard)
|
|
|
|
{
|
2016-11-17 16:32:28 +00:00
|
|
|
#ifdef HAVE_KEY_DEFINED
|
2017-12-29 18:27:33 +00:00
|
|
|
const char *keyvalue = tigetstr(keyname);
|
2016-08-16 08:49:55 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
if (keyvalue != 0 && keyvalue != (char *)-1 && key_defined(keyvalue))
|
|
|
|
return key_defined(keyvalue);
|
2016-08-16 08:49:55 +00:00
|
|
|
#endif
|
2018-10-30 18:01:39 +00:00
|
|
|
#ifdef DEBUG
|
2018-12-28 16:47:03 +00:00
|
|
|
if (!ISSET(RAW_SEQUENCES))
|
2018-10-30 18:01:39 +00:00
|
|
|
fprintf(stderr, "Using fallback keycode for %s\n", keyname);
|
|
|
|
#endif
|
|
|
|
return standard;
|
2016-11-17 16:32:28 +00:00
|
|
|
}
|
2016-08-16 08:49:55 +00:00
|
|
|
|
2018-05-25 15:57:04 +00:00
|
|
|
#ifdef ENABLE_LINENUMBERS
|
2020-03-25 15:49:46 +00:00
|
|
|
/* Ensure that the margin can accommodate the buffer's highest line number. */
|
2018-05-25 18:09:24 +00:00
|
|
|
void confirm_margin(void)
|
2018-05-25 15:57:04 +00:00
|
|
|
{
|
|
|
|
int needed_margin = digits(openfile->filebot->lineno) + 1;
|
|
|
|
|
|
|
|
/* When not requested or space is too tight, suppress line numbers. */
|
|
|
|
if (!ISSET(LINE_NUMBERS) || needed_margin > COLS - 4)
|
|
|
|
needed_margin = 0;
|
|
|
|
|
|
|
|
if (needed_margin != margin) {
|
2021-02-01 11:29:45 +00:00
|
|
|
bool keep_focus = (margin > 0) && focusing;
|
|
|
|
|
2018-05-25 15:57:04 +00:00
|
|
|
margin = needed_margin;
|
2020-04-25 15:19:03 +00:00
|
|
|
editwincols = COLS - margin - thebar;
|
2018-05-25 15:57:04 +00:00
|
|
|
|
|
|
|
#ifndef NANO_TINY
|
2021-04-21 14:27:36 +00:00
|
|
|
/* Ensure a proper starting column for the first screen row. */
|
2018-05-25 15:57:04 +00:00
|
|
|
ensure_firstcolumn_is_aligned();
|
2021-02-01 11:29:45 +00:00
|
|
|
focusing = keep_focus;
|
2018-05-25 15:57:04 +00:00
|
|
|
#endif
|
|
|
|
/* The margin has changed -- schedule a full refresh. */
|
|
|
|
refresh_needed = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* ENABLE_LINENUMBERS */
|
|
|
|
|
2016-04-27 12:37:31 +00:00
|
|
|
/* Say that an unbound key was struck, and if possible which one. */
|
|
|
|
void unbound_key(int code)
|
|
|
|
{
|
2020-06-03 14:45:15 +00:00
|
|
|
if (code == FOREIGN_SEQUENCE)
|
|
|
|
/* TRANSLATORS: This refers to a sequence of escape codes
|
|
|
|
* (from the keyboard) that nano does not recognize. */
|
2020-12-08 16:09:07 +00:00
|
|
|
statusline(AHEM, _("Unknown sequence"));
|
2020-06-03 14:45:15 +00:00
|
|
|
else if (code > 0x7F)
|
2020-12-08 16:09:07 +00:00
|
|
|
statusline(AHEM, _("Unbound key"));
|
2017-12-29 18:27:33 +00:00
|
|
|
else if (meta_key) {
|
2020-01-22 13:05:18 +00:00
|
|
|
#ifndef NANO_TINY
|
2020-08-04 15:11:05 +00:00
|
|
|
if (code < 0x20)
|
2020-12-08 16:09:07 +00:00
|
|
|
statusline(AHEM, _("Unbindable key: M-^%c"), code + 0x40);
|
2020-08-04 15:11:05 +00:00
|
|
|
else
|
2020-01-21 11:31:34 +00:00
|
|
|
#endif
|
|
|
|
#ifdef ENABLE_NANORC
|
2020-08-04 15:11:05 +00:00
|
|
|
if (shifted_metas && 'A' <= code && code <= 'Z')
|
2020-12-08 16:09:07 +00:00
|
|
|
statusline(AHEM, _("Unbound key: Sh-M-%c"), code);
|
2017-12-29 18:27:33 +00:00
|
|
|
else
|
2020-08-04 15:11:05 +00:00
|
|
|
#endif
|
2020-12-08 16:09:07 +00:00
|
|
|
statusline(AHEM, _("Unbound key: M-%c"), toupper(code));
|
2018-12-30 18:28:17 +00:00
|
|
|
} else if (code == ESC_CODE)
|
2020-12-08 16:09:07 +00:00
|
|
|
statusline(AHEM, _("Unbindable key: ^["));
|
2020-01-24 18:27:33 +00:00
|
|
|
else if (code < 0x20)
|
2020-12-08 16:09:07 +00:00
|
|
|
statusline(AHEM, _("Unbound key: ^%c"), code + 0x40);
|
2020-01-24 18:27:33 +00:00
|
|
|
#if defined(ENABLE_BROWSER) || defined (ENABLE_HELP)
|
|
|
|
else
|
2020-12-08 16:09:07 +00:00
|
|
|
statusline(AHEM, _("Unbound key: %c"), code);
|
2020-01-24 18:27:33 +00:00
|
|
|
#endif
|
2020-09-17 17:30:18 +00:00
|
|
|
set_blankdelay_to_one();
|
2016-04-27 12:37:31 +00:00
|
|
|
}
|
|
|
|
|
2018-01-27 18:33:03 +00:00
|
|
|
#ifdef ENABLE_MOUSE
|
|
|
|
/* Handle a mouse click on the edit window or the shortcut list. */
|
|
|
|
int do_mouse(void)
|
|
|
|
{
|
2018-01-27 18:47:00 +00:00
|
|
|
int click_row, click_col;
|
2018-01-27 19:00:14 +00:00
|
|
|
int retval = get_mouseinput(&click_row, &click_col, TRUE);
|
2018-01-27 18:33:03 +00:00
|
|
|
|
|
|
|
/* If the click is wrong or already handled, we're done. */
|
|
|
|
if (retval != 0)
|
|
|
|
return retval;
|
|
|
|
|
|
|
|
/* If the click was in the edit window, put the cursor in that spot. */
|
2018-01-27 18:47:00 +00:00
|
|
|
if (wmouse_trafo(edit, &click_row, &click_col, FALSE)) {
|
2019-03-21 16:08:52 +00:00
|
|
|
linestruct *current_save = openfile->current;
|
2018-01-27 18:47:00 +00:00
|
|
|
ssize_t row_count = click_row - openfile->current_y;
|
2018-01-27 18:33:03 +00:00
|
|
|
size_t leftedge;
|
|
|
|
#ifndef NANO_TINY
|
|
|
|
size_t current_x_save = openfile->current_x;
|
2018-01-27 18:47:00 +00:00
|
|
|
bool sameline = (click_row == openfile->current_y);
|
2018-01-27 18:33:03 +00:00
|
|
|
/* Whether the click was on the row where the cursor is. */
|
|
|
|
|
|
|
|
if (ISSET(SOFTWRAP))
|
|
|
|
leftedge = leftedge_for(xplustabs(), openfile->current);
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
leftedge = get_page_start(xplustabs());
|
|
|
|
|
2018-01-27 18:47:00 +00:00
|
|
|
/* Move current up or down to the row that was clicked on. */
|
2018-01-27 18:33:03 +00:00
|
|
|
if (row_count < 0)
|
|
|
|
go_back_chunks(-row_count, &openfile->current, &leftedge);
|
|
|
|
else
|
|
|
|
go_forward_chunks(row_count, &openfile->current, &leftedge);
|
|
|
|
|
|
|
|
openfile->current_x = actual_x(openfile->current->data,
|
2018-01-27 18:47:00 +00:00
|
|
|
actual_last_column(leftedge, click_col));
|
2018-01-27 18:33:03 +00:00
|
|
|
|
|
|
|
#ifndef NANO_TINY
|
|
|
|
/* Clicking where the cursor is toggles the mark, as does clicking
|
|
|
|
* beyond the line length with the cursor at the end of the line. */
|
2020-12-22 05:08:18 +00:00
|
|
|
if (sameline && openfile->current_x == current_x_save) {
|
2018-01-27 18:33:03 +00:00
|
|
|
do_mark();
|
2020-12-22 05:08:18 +00:00
|
|
|
if (ISSET(STATEFLAGS))
|
|
|
|
titlebar(NULL);
|
|
|
|
} else
|
2018-01-27 18:33:03 +00:00
|
|
|
#endif
|
|
|
|
/* The cursor moved; clean the cutbuffer on the next cut. */
|
2018-12-30 12:36:29 +00:00
|
|
|
keep_cutbuffer = FALSE;
|
2018-01-27 18:33:03 +00:00
|
|
|
|
|
|
|
edit_redraw(current_save, CENTERING);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* No more handling is needed. */
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
#endif /* ENABLE_MOUSE */
|
|
|
|
|
2018-03-18 12:44:57 +00:00
|
|
|
/* Return TRUE when the given function is a cursor-moving command. */
|
2018-03-18 18:17:56 +00:00
|
|
|
bool wanted_to_move(void (*func)(void))
|
2018-03-18 12:44:57 +00:00
|
|
|
{
|
|
|
|
return func == do_left || func == do_right ||
|
|
|
|
func == do_up || func == do_down ||
|
|
|
|
func == do_home || func == do_end ||
|
2020-03-11 18:43:03 +00:00
|
|
|
func == to_prev_word || func == to_next_word ||
|
2018-03-19 03:22:50 +00:00
|
|
|
#ifdef ENABLE_JUSTIFY
|
2020-03-11 18:47:21 +00:00
|
|
|
func == to_para_begin || func == to_para_end ||
|
2018-03-18 15:33:21 +00:00
|
|
|
#endif
|
2020-03-11 18:45:06 +00:00
|
|
|
func == to_prev_block || func == to_next_block ||
|
2018-03-18 12:44:57 +00:00
|
|
|
func == do_page_up || func == do_page_down ||
|
|
|
|
func == to_first_line || func == to_last_line;
|
|
|
|
}
|
|
|
|
|
2018-10-12 09:58:45 +00:00
|
|
|
/* Return TRUE when the given shortcut is admissible in view mode. */
|
2019-04-03 15:34:05 +00:00
|
|
|
bool okay_for_view(const keystruct *shortcut)
|
2018-03-20 18:56:03 +00:00
|
|
|
{
|
2019-05-08 13:17:04 +00:00
|
|
|
funcstruct *item = allfuncs;
|
2018-03-20 18:56:03 +00:00
|
|
|
|
2019-05-08 13:17:04 +00:00
|
|
|
/* Search the function of the given shortcut in the list of functions. */
|
|
|
|
while (item != NULL && item->func != shortcut->func)
|
|
|
|
item = item->next;
|
|
|
|
|
|
|
|
return (item == NULL || item->viewok);
|
2018-03-20 18:56:03 +00:00
|
|
|
}
|
|
|
|
|
2020-01-22 11:55:32 +00:00
|
|
|
#ifndef NANO_TINY
|
2020-01-16 11:44:03 +00:00
|
|
|
/* Read in all waiting input bytes and paste them into the buffer in one go. */
|
|
|
|
void suck_up_input_and_paste_it(void)
|
|
|
|
{
|
|
|
|
linestruct *was_cutbuffer = cutbuffer;
|
|
|
|
linestruct *line = make_new_node(NULL);
|
|
|
|
size_t index = 0;
|
|
|
|
|
|
|
|
line->data = copy_of("");
|
|
|
|
cutbuffer = line;
|
|
|
|
|
|
|
|
while (bracketed_paste) {
|
|
|
|
int input = get_kbinput(edit, BLIND);
|
|
|
|
|
2020-03-20 12:52:29 +00:00
|
|
|
if (input == '\r' || input == '\n') {
|
2020-01-16 11:44:03 +00:00
|
|
|
line->next = make_new_node(line);
|
|
|
|
line = line->next;
|
|
|
|
line->data = copy_of("");
|
|
|
|
index = 0;
|
2020-01-31 15:05:51 +00:00
|
|
|
} else if ((0x20 <= input && input <= 0xFF && input != DEL_CODE) ||
|
2020-03-19 13:27:57 +00:00
|
|
|
input == '\t') {
|
2020-08-30 02:57:45 +00:00
|
|
|
line->data = nrealloc(line->data, index + 2);
|
2020-01-16 11:44:03 +00:00
|
|
|
line->data[index++] = (char)input;
|
|
|
|
line->data[index] = '\0';
|
|
|
|
} else if (input != BRACKETED_PASTE_MARKER)
|
|
|
|
beep();
|
|
|
|
}
|
|
|
|
|
|
|
|
paste_text();
|
|
|
|
|
2020-03-30 14:51:34 +00:00
|
|
|
free_lines(cutbuffer);
|
2020-01-16 11:44:03 +00:00
|
|
|
cutbuffer = was_cutbuffer;
|
|
|
|
}
|
2020-01-22 11:55:32 +00:00
|
|
|
#endif
|
2020-01-16 11:44:03 +00:00
|
|
|
|
2020-04-29 10:22:02 +00:00
|
|
|
/* Insert the given short burst of bytes into the edit buffer. */
|
|
|
|
void inject(char *burst, size_t count)
|
|
|
|
{
|
|
|
|
linestruct *thisline = openfile->current;
|
|
|
|
size_t datalen = strlen(thisline->data);
|
|
|
|
#ifndef NANO_TINY
|
2020-06-06 16:57:17 +00:00
|
|
|
size_t original_row = 0;
|
2021-04-22 10:17:34 +00:00
|
|
|
size_t old_amount = 0;
|
2020-04-29 10:22:02 +00:00
|
|
|
|
|
|
|
if (ISSET(SOFTWRAP)) {
|
|
|
|
if (openfile->current_y == editwinrows - 1)
|
|
|
|
original_row = chunk_for(xplustabs(), thisline);
|
2021-04-22 10:17:34 +00:00
|
|
|
old_amount = extra_chunks_in(thisline);
|
2020-04-29 10:22:02 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Encode an embedded NUL byte as 0x0A. */
|
|
|
|
for (size_t index = 0; index < count; index++)
|
|
|
|
if (burst[index] == '\0')
|
|
|
|
burst[index] = '\n';
|
|
|
|
|
|
|
|
#ifndef NANO_TINY
|
|
|
|
/* Only add a new undo item when the current item is not an ADD or when
|
|
|
|
* the current typing is not contiguous with the previous typing. */
|
|
|
|
if (openfile->last_action != ADD ||
|
|
|
|
openfile->current_undo->tail_lineno != thisline->lineno ||
|
|
|
|
openfile->current_undo->tail_x != openfile->current_x)
|
|
|
|
add_undo(ADD, NULL);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Make room for the new bytes and copy them into the line. */
|
2020-08-30 02:57:45 +00:00
|
|
|
thisline->data = nrealloc(thisline->data, datalen + count + 1);
|
2020-04-29 10:22:02 +00:00
|
|
|
memmove(thisline->data + openfile->current_x + count,
|
|
|
|
thisline->data + openfile->current_x,
|
|
|
|
datalen - openfile->current_x + 1);
|
|
|
|
strncpy(thisline->data + openfile->current_x, burst, count);
|
|
|
|
|
|
|
|
#ifndef NANO_TINY
|
|
|
|
/* When the mark is to the right of the cursor, compensate its position. */
|
|
|
|
if (thisline == openfile->mark && openfile->current_x < openfile->mark_x)
|
|
|
|
openfile->mark_x += count;
|
|
|
|
|
|
|
|
/* When the cursor is on the top row and not on the first chunk
|
|
|
|
* of a line, adding text there might change the preceding chunk
|
|
|
|
* and thus require an adjustment of firstcolumn. */
|
|
|
|
if (thisline == openfile->edittop && openfile->firstcolumn > 0) {
|
|
|
|
ensure_firstcolumn_is_aligned();
|
|
|
|
refresh_needed = TRUE;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
/* If text was added to the magic line, create a new magic line. */
|
|
|
|
if (thisline == openfile->filebot && !ISSET(NO_NEWLINES)) {
|
|
|
|
new_magicline();
|
|
|
|
if (margin > 0)
|
|
|
|
refresh_needed = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
openfile->current_x += count;
|
|
|
|
|
|
|
|
openfile->totsize += mbstrlen(burst);
|
|
|
|
set_modified();
|
|
|
|
|
|
|
|
#ifndef NANO_TINY
|
|
|
|
update_undo(ADD);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef ENABLE_WRAPPING
|
|
|
|
/* Wrap the line when needed, and if so, schedule a refresh. */
|
|
|
|
if (ISSET(BREAK_LONG_LINES) && do_wrap())
|
|
|
|
refresh_needed = TRUE;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef NANO_TINY
|
2020-06-06 16:57:17 +00:00
|
|
|
/* When softwrapping and the number of chunks in the current line changed,
|
|
|
|
* or we were on the last row of the edit window and moved to a new chunk,
|
|
|
|
* we need a full refresh. */
|
2021-04-21 14:51:33 +00:00
|
|
|
if (ISSET(SOFTWRAP) && (extra_chunks_in(openfile->current) != old_amount ||
|
2020-06-06 16:57:17 +00:00
|
|
|
(openfile->current_y == editwinrows - 1 &&
|
2021-04-21 14:51:33 +00:00
|
|
|
chunk_for(xplustabs(), openfile->current) > original_row))) {
|
|
|
|
refresh_needed = TRUE;
|
|
|
|
focusing = FALSE;
|
2020-04-29 10:22:02 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
openfile->placewewant = xplustabs();
|
|
|
|
|
|
|
|
#ifdef ENABLE_COLOR
|
|
|
|
if (!refresh_needed)
|
|
|
|
check_the_multis(openfile->current);
|
|
|
|
#endif
|
|
|
|
if (!refresh_needed)
|
|
|
|
update_line(openfile->current, openfile->current_x);
|
|
|
|
}
|
|
|
|
|
2020-02-12 13:15:35 +00:00
|
|
|
/* Read in a keystroke, and execute its command or insert it into the buffer. */
|
|
|
|
void process_a_keystroke(void)
|
2004-12-04 17:41:52 +00:00
|
|
|
{
|
2017-12-29 18:27:33 +00:00
|
|
|
int input;
|
|
|
|
/* The keystroke we read in: a character or a shortcut. */
|
|
|
|
static char *puddle = NULL;
|
|
|
|
/* The input buffer for actual characters. */
|
|
|
|
static size_t depth = 0;
|
|
|
|
/* The length of the input buffer. */
|
2020-09-19 17:50:45 +00:00
|
|
|
#ifndef NANO_TINY
|
|
|
|
linestruct *was_mark = openfile->mark;
|
|
|
|
#endif
|
2020-09-19 10:09:50 +00:00
|
|
|
static bool give_a_hint = TRUE;
|
2019-04-03 15:34:05 +00:00
|
|
|
const keystruct *shortcut;
|
2017-12-29 18:27:33 +00:00
|
|
|
|
|
|
|
/* Read in a keystroke, and show the cursor while waiting. */
|
|
|
|
input = get_kbinput(edit, VISIBLE);
|
2017-09-18 18:34:57 +00:00
|
|
|
|
2020-12-04 10:50:23 +00:00
|
|
|
lastmessage = VACUUM;
|
2020-12-12 13:50:20 +00:00
|
|
|
hide_cursor = FALSE;
|
2020-12-04 10:50:23 +00:00
|
|
|
|
2015-05-28 13:02:29 +00:00
|
|
|
#ifndef NANO_TINY
|
2017-12-29 18:27:33 +00:00
|
|
|
if (input == KEY_WINCH)
|
2018-12-30 11:45:52 +00:00
|
|
|
return;
|
2015-05-28 13:02:29 +00:00
|
|
|
#endif
|
2017-05-01 18:45:07 +00:00
|
|
|
#ifdef ENABLE_MOUSE
|
2017-12-29 18:27:33 +00:00
|
|
|
if (input == KEY_MOUSE) {
|
2020-02-12 13:15:35 +00:00
|
|
|
/* If the user clicked on a shortcut, read in the key code that it was
|
|
|
|
* converted into. Else the click has been handled or was invalid. */
|
2017-12-29 18:27:33 +00:00
|
|
|
if (do_mouse() == 1)
|
|
|
|
input = get_kbinput(edit, BLIND);
|
|
|
|
else
|
2018-12-30 11:45:52 +00:00
|
|
|
return;
|
2017-12-29 18:27:33 +00:00
|
|
|
}
|
2004-12-04 17:41:52 +00:00
|
|
|
#endif
|
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Check for a shortcut in the main list. */
|
2018-02-24 17:20:30 +00:00
|
|
|
shortcut = get_shortcut(&input);
|
2004-12-04 17:41:52 +00:00
|
|
|
|
2020-02-12 11:05:52 +00:00
|
|
|
/* If not a command, discard anything that is not a normal character byte. */
|
2018-02-24 17:20:30 +00:00
|
|
|
if (shortcut == NULL) {
|
2020-02-12 10:46:15 +00:00
|
|
|
if (input < 0x20 || input > 0xFF || meta_key)
|
2017-12-29 18:27:33 +00:00
|
|
|
unbound_key(input);
|
2020-02-12 10:46:15 +00:00
|
|
|
else if (ISSET(VIEW_MODE))
|
2017-12-29 18:27:33 +00:00
|
|
|
print_view_warning();
|
|
|
|
else {
|
2020-08-19 06:27:08 +00:00
|
|
|
#ifndef NANO_TINY
|
2020-12-19 15:40:21 +00:00
|
|
|
if (openfile->mark && openfile->softmark) {
|
2020-08-19 06:27:08 +00:00
|
|
|
openfile->mark = NULL;
|
|
|
|
refresh_needed = TRUE;
|
|
|
|
}
|
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Store the byte, and leave room for a terminating zero. */
|
2020-08-30 02:57:45 +00:00
|
|
|
puddle = nrealloc(puddle, depth + 2);
|
2017-12-29 18:27:33 +00:00
|
|
|
puddle[depth++] = (char)input;
|
|
|
|
}
|
2004-12-04 17:41:52 +00:00
|
|
|
}
|
|
|
|
|
2020-02-12 11:05:52 +00:00
|
|
|
/* If we have a command, or if there aren't any other key codes waiting,
|
2020-02-12 15:20:20 +00:00
|
|
|
* it's time to insert the gathered bytes into the edit buffer. */
|
2020-02-12 11:09:12 +00:00
|
|
|
if ((shortcut || get_key_buffer_len() == 0) && puddle != NULL) {
|
|
|
|
puddle[depth] = '\0';
|
|
|
|
|
|
|
|
inject(puddle, depth);
|
|
|
|
|
|
|
|
free(puddle);
|
|
|
|
puddle = NULL;
|
|
|
|
depth = 0;
|
2016-08-28 19:18:34 +00:00
|
|
|
}
|
2016-08-28 19:00:13 +00:00
|
|
|
|
2019-05-02 12:05:45 +00:00
|
|
|
if (shortcut == NULL) {
|
2017-12-29 18:27:33 +00:00
|
|
|
pletion_line = NULL;
|
2019-05-02 12:05:45 +00:00
|
|
|
keep_cutbuffer = FALSE;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-05-02 12:15:34 +00:00
|
|
|
if (ISSET(VIEW_MODE) && !okay_for_view(shortcut)) {
|
|
|
|
print_view_warning();
|
|
|
|
return;
|
|
|
|
}
|
2017-12-29 18:27:33 +00:00
|
|
|
|
2020-09-19 10:09:50 +00:00
|
|
|
if (input == '\b' && give_a_hint && openfile->current_x == 0 &&
|
|
|
|
openfile->current == openfile->filetop && !ISSET(NO_HELP)) {
|
|
|
|
statusbar(_("^W = Ctrl+W M-W = Alt+W"));
|
|
|
|
give_a_hint = FALSE;
|
|
|
|
} else if (meta_key)
|
|
|
|
give_a_hint = FALSE;
|
|
|
|
|
2019-05-02 12:34:05 +00:00
|
|
|
/* When not cutting or copying text, drop the cutbuffer the next time. */
|
2019-05-03 17:51:15 +00:00
|
|
|
if (shortcut->func != cut_text) {
|
2006-04-25 02:23:28 +00:00
|
|
|
#ifndef NANO_TINY
|
2019-05-03 17:47:08 +00:00
|
|
|
if (shortcut->func != copy_text && shortcut->func != zap_text)
|
2006-04-25 02:23:28 +00:00
|
|
|
#endif
|
2019-05-02 12:34:05 +00:00
|
|
|
keep_cutbuffer = FALSE;
|
|
|
|
}
|
2004-12-04 17:41:52 +00:00
|
|
|
|
2016-12-07 12:10:40 +00:00
|
|
|
#ifdef ENABLE_WORDCOMPLETION
|
2019-05-02 12:15:34 +00:00
|
|
|
if (shortcut->func != complete_a_word)
|
|
|
|
pletion_line = NULL;
|
2016-12-07 12:10:40 +00:00
|
|
|
#endif
|
2018-02-27 10:11:02 +00:00
|
|
|
#ifdef ENABLE_NANORC
|
2019-05-02 12:15:34 +00:00
|
|
|
if (shortcut->func == (functionptrtype)implant) {
|
|
|
|
implant(shortcut->expansion);
|
|
|
|
return;
|
|
|
|
}
|
2016-01-03 17:37:05 +00:00
|
|
|
#endif
|
2016-04-24 09:28:28 +00:00
|
|
|
#ifndef NANO_TINY
|
2019-05-02 12:15:34 +00:00
|
|
|
if (shortcut->func == do_toggle_void) {
|
|
|
|
do_toggle(shortcut->toggle);
|
|
|
|
if (shortcut->toggle == CUT_FROM_CURSOR)
|
|
|
|
keep_cutbuffer = FALSE;
|
|
|
|
return;
|
|
|
|
}
|
2017-12-29 18:27:33 +00:00
|
|
|
|
2019-05-02 12:15:34 +00:00
|
|
|
linestruct *was_current = openfile->current;
|
|
|
|
size_t was_x = openfile->current_x;
|
|
|
|
|
|
|
|
/* If Shifted movement occurs, set the mark. */
|
|
|
|
if (shift_held && !openfile->mark) {
|
|
|
|
openfile->mark = openfile->current;
|
|
|
|
openfile->mark_x = openfile->current_x;
|
2020-12-19 15:40:21 +00:00
|
|
|
openfile->softmark = TRUE;
|
2019-05-02 12:15:34 +00:00
|
|
|
}
|
2017-12-29 18:27:33 +00:00
|
|
|
#endif
|
2019-05-02 12:15:34 +00:00
|
|
|
|
|
|
|
/* Execute the function of the shortcut. */
|
|
|
|
shortcut->func();
|
2018-01-20 12:01:43 +00:00
|
|
|
|
2016-04-24 09:28:28 +00:00
|
|
|
#ifndef NANO_TINY
|
2019-05-02 12:15:34 +00:00
|
|
|
/* When the marked region changes without Shift being held,
|
|
|
|
* discard a soft mark. And when the marked region covers a
|
|
|
|
* different set of lines, reset the "last line too" flag. */
|
|
|
|
if (openfile->mark) {
|
2020-12-19 15:40:21 +00:00
|
|
|
if (!shift_held && openfile->softmark &&
|
2019-05-02 12:15:34 +00:00
|
|
|
(openfile->current != was_current ||
|
|
|
|
openfile->current_x != was_x ||
|
|
|
|
wanted_to_move(shortcut->func))) {
|
|
|
|
openfile->mark = NULL;
|
|
|
|
refresh_needed = TRUE;
|
|
|
|
} else if (openfile->current != was_current)
|
|
|
|
also_the_last = FALSE;
|
|
|
|
}
|
2016-04-24 09:28:28 +00:00
|
|
|
#endif
|
2017-11-01 18:45:33 +00:00
|
|
|
#ifdef ENABLE_COLOR
|
2019-05-02 12:15:34 +00:00
|
|
|
if (!refresh_needed && !okay_for_view(shortcut))
|
|
|
|
check_the_multis(openfile->current);
|
2009-11-22 21:35:56 +00:00
|
|
|
#endif
|
2019-05-02 12:15:34 +00:00
|
|
|
if (!refresh_needed && (shortcut->func == do_delete ||
|
|
|
|
shortcut->func == do_backspace))
|
|
|
|
update_line(openfile->current, openfile->current_x);
|
2020-01-16 11:44:03 +00:00
|
|
|
|
2020-01-22 11:55:32 +00:00
|
|
|
#ifndef NANO_TINY
|
2020-01-16 11:44:03 +00:00
|
|
|
if (bracketed_paste)
|
|
|
|
suck_up_input_and_paste_it();
|
2020-09-19 17:50:45 +00:00
|
|
|
|
|
|
|
if (ISSET(STATEFLAGS) && openfile->mark != was_mark)
|
|
|
|
titlebar(NULL);
|
2020-01-22 11:55:32 +00:00
|
|
|
#endif
|
2004-12-04 17:41:52 +00:00
|
|
|
}
|
|
|
|
|
2004-08-17 05:23:38 +00:00
|
|
|
int main(int argc, char **argv)
|
2000-06-06 05:53:49 +00:00
|
|
|
{
|
2017-12-29 18:27:33 +00:00
|
|
|
int stdin_flags, optchr;
|
2019-01-27 10:10:29 +00:00
|
|
|
#ifdef ENABLE_NANORC
|
|
|
|
bool ignore_rcfiles = FALSE;
|
|
|
|
/* Whether to ignore the nanorc files. */
|
|
|
|
#endif
|
2017-11-01 19:08:55 +00:00
|
|
|
#if defined(ENABLED_WRAPORJUSTIFY) && defined(ENABLE_NANORC)
|
2017-12-29 18:27:33 +00:00
|
|
|
bool fill_used = FALSE;
|
|
|
|
/* Was the fill option used on the command line? */
|
2017-11-01 19:08:55 +00:00
|
|
|
#endif
|
2020-01-14 15:28:28 +00:00
|
|
|
#ifdef ENABLE_WRAPPING
|
2019-04-11 18:18:29 +00:00
|
|
|
int hardwrap = -2;
|
|
|
|
/* Becomes 0 when --nowrap and 1 when --breaklonglines is used. */
|
2020-01-14 15:28:28 +00:00
|
|
|
#endif
|
2018-12-11 09:42:45 +00:00
|
|
|
#ifdef ENABLE_JUSTIFY
|
|
|
|
int quoterc;
|
|
|
|
/* Whether the quoting regex was compiled successfully. */
|
2004-09-05 21:40:31 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
const struct option long_options[] = {
|
|
|
|
{"boldtext", 0, NULL, 'D'},
|
2017-05-01 18:20:34 +00:00
|
|
|
#ifdef ENABLE_MULTIBUFFER
|
2017-12-29 18:27:33 +00:00
|
|
|
{"multibuffer", 0, NULL, 'F'},
|
2002-07-19 01:08:59 +00:00
|
|
|
#endif
|
2017-05-08 17:42:44 +00:00
|
|
|
#ifdef ENABLE_NANORC
|
2017-12-29 18:27:33 +00:00
|
|
|
{"ignorercfiles", 0, NULL, 'I'},
|
2002-06-28 22:45:14 +00:00
|
|
|
#endif
|
2018-12-31 17:34:28 +00:00
|
|
|
{"rawsequences", 0, NULL, 'K'},
|
2018-01-24 08:56:03 +00:00
|
|
|
#ifdef ENABLED_WRAPORJUSTIFY
|
|
|
|
{"trimblanks", 0, NULL, 'M'},
|
|
|
|
#endif
|
2017-10-31 16:34:07 +00:00
|
|
|
#ifdef ENABLE_JUSTIFY
|
2017-12-29 18:27:33 +00:00
|
|
|
{"quotestr", 1, NULL, 'Q'},
|
2000-07-07 02:35:34 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
{"restricted", 0, NULL, 'R'},
|
|
|
|
{"quickblank", 0, NULL, 'U'},
|
|
|
|
{"version", 0, NULL, 'V'},
|
2017-11-01 18:45:33 +00:00
|
|
|
#ifdef ENABLE_COLOR
|
2017-12-29 18:27:33 +00:00
|
|
|
{"syntax", 1, NULL, 'Y'},
|
2019-01-25 13:40:30 +00:00
|
|
|
#endif
|
|
|
|
#ifdef ENABLE_WRAPPING
|
|
|
|
{"breaklonglines", 0, NULL, 'b'},
|
2001-05-21 12:56:25 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
{"constantshow", 0, NULL, 'c'},
|
|
|
|
{"rebinddelete", 0, NULL, 'd'},
|
2020-01-14 11:41:22 +00:00
|
|
|
#ifdef ENABLE_NANORC
|
|
|
|
{"rcfile", 1, NULL, 'f'},
|
|
|
|
#endif
|
2020-01-28 09:33:56 +00:00
|
|
|
#if defined(ENABLE_BROWSER) || defined(ENABLE_HELP)
|
2017-12-29 18:27:33 +00:00
|
|
|
{"showcursor", 0, NULL, 'g'},
|
2016-10-23 10:56:47 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
{"help", 0, NULL, 'h'},
|
2016-10-20 08:44:29 +00:00
|
|
|
#ifdef ENABLE_LINENUMBERS
|
2017-12-29 18:27:33 +00:00
|
|
|
{"linenumbers", 0, NULL, 'l'},
|
2016-10-20 08:44:29 +00:00
|
|
|
#endif
|
2017-05-01 18:45:07 +00:00
|
|
|
#ifdef ENABLE_MOUSE
|
2017-12-29 18:27:33 +00:00
|
|
|
{"mouse", 0, NULL, 'm'},
|
2002-12-22 16:30:00 +00:00
|
|
|
#endif
|
2017-10-29 20:08:07 +00:00
|
|
|
#ifdef ENABLE_OPERATINGDIR
|
2017-12-29 18:27:33 +00:00
|
|
|
{"operatingdir", 1, NULL, 'o'},
|
2001-09-19 03:19:43 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
{"preserve", 0, NULL, 'p'},
|
2017-10-31 16:39:30 +00:00
|
|
|
#ifdef ENABLED_WRAPORJUSTIFY
|
2017-12-29 18:27:33 +00:00
|
|
|
{"fill", 1, NULL, 'r'},
|
2002-06-28 22:45:14 +00:00
|
|
|
#endif
|
2017-10-31 18:32:42 +00:00
|
|
|
#ifdef ENABLE_SPELLER
|
2017-12-29 18:27:33 +00:00
|
|
|
{"speller", 1, NULL, 's'},
|
2001-07-11 02:08:33 +00:00
|
|
|
#endif
|
2020-04-30 15:25:48 +00:00
|
|
|
{"saveonexit", 0, NULL, 't'},
|
|
|
|
{"tempfile", 0, NULL, 't'}, /* Deprecated; remove in 2022. */
|
2017-12-29 18:27:33 +00:00
|
|
|
{"view", 0, NULL, 'v'},
|
2017-10-29 20:00:09 +00:00
|
|
|
#ifdef ENABLE_WRAPPING
|
2017-12-29 18:27:33 +00:00
|
|
|
{"nowrap", 0, NULL, 'w'},
|
2002-10-17 02:19:31 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
{"nohelp", 0, NULL, 'x'},
|
2020-03-13 14:54:24 +00:00
|
|
|
{"suspendable", 0, NULL, 'z'},
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2017-12-29 18:27:33 +00:00
|
|
|
{"smarthome", 0, NULL, 'A'},
|
|
|
|
{"backup", 0, NULL, 'B'},
|
|
|
|
{"backupdir", 1, NULL, 'C'},
|
|
|
|
{"tabstospaces", 0, NULL, 'E'},
|
|
|
|
{"locking", 0, NULL, 'G'},
|
|
|
|
{"historylog", 0, NULL, 'H'},
|
2018-12-17 18:57:30 +00:00
|
|
|
{"guidestripe", 1, NULL, 'J'},
|
2019-03-10 18:17:52 +00:00
|
|
|
{"nonewlines", 0, NULL, 'L'},
|
2017-12-29 18:27:33 +00:00
|
|
|
{"noconvert", 0, NULL, 'N'},
|
2019-12-18 16:19:04 +00:00
|
|
|
{"bookstyle", 0, NULL, 'O'},
|
2017-12-29 18:27:33 +00:00
|
|
|
{"positionlog", 0, NULL, 'P'},
|
2020-03-27 15:57:25 +00:00
|
|
|
{"softwrap", 0, NULL, 'S'},
|
2020-10-03 09:21:18 +00:00
|
|
|
{"tabsize", 1, NULL, 'T'},
|
2017-12-29 18:27:33 +00:00
|
|
|
{"wordbounds", 0, NULL, 'W'},
|
|
|
|
{"wordchars", 1, NULL, 'X'},
|
2018-10-24 09:02:08 +00:00
|
|
|
{"zap", 0, NULL, 'Z'},
|
2017-12-29 18:27:33 +00:00
|
|
|
{"atblanks", 0, NULL, 'a'},
|
2020-09-21 15:04:10 +00:00
|
|
|
{"emptyline", 0, NULL, 'e'},
|
2017-12-29 18:27:33 +00:00
|
|
|
{"autoindent", 0, NULL, 'i'},
|
2020-09-21 15:04:10 +00:00
|
|
|
{"jumpyscrolling", 0, NULL, 'j'},
|
2017-12-29 18:27:33 +00:00
|
|
|
{"cutfromcursor", 0, NULL, 'k'},
|
2020-09-21 15:04:10 +00:00
|
|
|
{"noread", 0, NULL, 'n'},
|
2020-05-26 17:07:42 +00:00
|
|
|
{"indicator", 0, NULL, 'q'},
|
2017-12-29 18:27:33 +00:00
|
|
|
{"unix", 0, NULL, 'u'},
|
2018-04-30 20:10:27 +00:00
|
|
|
{"afterends", 0, NULL, 'y'},
|
2021-01-07 13:24:27 +00:00
|
|
|
{"stateflags", 0, NULL, '%'},
|
|
|
|
{"minibar", 0, NULL, '_'},
|
2020-10-01 09:18:45 +00:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_LIBMAGIC
|
|
|
|
{"magic", 0, NULL, '!'},
|
2017-12-29 18:27:33 +00:00
|
|
|
#endif
|
|
|
|
{NULL, 0, NULL, 0}
|
|
|
|
};
|
|
|
|
|
2018-01-12 08:51:43 +00:00
|
|
|
#ifdef __linux__
|
2018-01-31 11:35:21 +00:00
|
|
|
struct vt_stat dummy;
|
|
|
|
|
2018-01-12 08:51:43 +00:00
|
|
|
/* Check whether we're running on a Linux console. */
|
2020-10-10 09:43:55 +00:00
|
|
|
on_a_vt = (ioctl(STDOUT_FILENO, VT_GETSTATE, &dummy) == 0);
|
2018-01-12 08:51:43 +00:00
|
|
|
#endif
|
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Back up the terminal settings so that they can be restored. */
|
2020-10-10 09:43:55 +00:00
|
|
|
tcgetattr(STDIN_FILENO, &original_state);
|
2017-12-29 18:27:33 +00:00
|
|
|
|
|
|
|
/* Get the state of standard input and ensure it uses blocking mode. */
|
2020-10-10 09:43:55 +00:00
|
|
|
stdin_flags = fcntl(STDIN_FILENO, F_GETFL, 0);
|
2017-12-29 18:27:33 +00:00
|
|
|
if (stdin_flags != -1)
|
2020-10-10 09:43:55 +00:00
|
|
|
fcntl(STDIN_FILENO, F_SETFL, stdin_flags & ~O_NONBLOCK);
|
2017-11-08 05:49:48 +00:00
|
|
|
|
2005-07-17 02:40:07 +00:00
|
|
|
#ifdef ENABLE_UTF8
|
2020-12-05 11:12:11 +00:00
|
|
|
/* If setting the locale is successful and it uses UTF-8, we will
|
|
|
|
* need to use the multibyte functions for text processing. */
|
|
|
|
if (setlocale(LC_ALL, "") && strcmp(nl_langinfo(CODESET), "UTF-8") == 0)
|
2017-12-29 18:27:33 +00:00
|
|
|
utf8_init();
|
2004-12-23 17:43:27 +00:00
|
|
|
#else
|
2017-12-29 18:27:33 +00:00
|
|
|
setlocale(LC_ALL, "");
|
2004-12-23 17:43:27 +00:00
|
|
|
#endif
|
|
|
|
|
2004-07-27 15:46:58 +00:00
|
|
|
#ifdef ENABLE_NLS
|
2017-12-29 18:27:33 +00:00
|
|
|
bindtextdomain(PACKAGE, LOCALEDIR);
|
|
|
|
textdomain(PACKAGE);
|
2000-06-06 05:53:49 +00:00
|
|
|
#endif
|
|
|
|
|
2021-04-15 09:43:39 +00:00
|
|
|
/* Set a sensible default, different from what Pico does. */
|
2019-01-16 18:37:10 +00:00
|
|
|
SET(NO_WRAP);
|
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* If the executable's name starts with 'r', activate restricted mode. */
|
|
|
|
if (*(tail(argv[0])) == 'r')
|
|
|
|
SET(RESTRICTED);
|
|
|
|
|
2020-10-01 09:18:45 +00:00
|
|
|
while ((optchr = getopt_long(argc, argv, "ABC:DEFGHIJ:KLMNOPQ:RST:UVWX:Y:Z"
|
2021-02-02 14:03:19 +00:00
|
|
|
"abcdef:ghijklmno:pqr:s:tuvwxyz$%_!", long_options, NULL)) != -1) {
|
2017-12-29 18:27:33 +00:00
|
|
|
switch (optchr) {
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'A':
|
|
|
|
SET(SMART_HOME);
|
|
|
|
break;
|
|
|
|
case 'B':
|
2020-05-25 16:52:09 +00:00
|
|
|
SET(MAKE_BACKUP);
|
2017-12-29 18:27:33 +00:00
|
|
|
break;
|
|
|
|
case 'C':
|
|
|
|
backup_dir = mallocstrcpy(backup_dir, optarg);
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
case 'D':
|
|
|
|
SET(BOLD_TEXT);
|
|
|
|
break;
|
2006-04-12 15:27:40 +00:00
|
|
|
#ifndef NANO_TINY
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'E':
|
|
|
|
SET(TABS_TO_SPACES);
|
|
|
|
break;
|
2001-09-22 00:42:10 +00:00
|
|
|
#endif
|
2017-05-01 18:20:34 +00:00
|
|
|
#ifdef ENABLE_MULTIBUFFER
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'F':
|
|
|
|
SET(MULTIBUFFER);
|
|
|
|
break;
|
2002-07-19 01:08:59 +00:00
|
|
|
#endif
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'G':
|
|
|
|
SET(LOCKING);
|
|
|
|
break;
|
2014-06-19 20:05:24 +00:00
|
|
|
#endif
|
2017-10-29 18:42:12 +00:00
|
|
|
#ifdef ENABLE_HISTORIES
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'H':
|
|
|
|
SET(HISTORYLOG);
|
|
|
|
break;
|
2003-09-06 21:44:37 +00:00
|
|
|
#endif
|
2017-05-08 17:42:44 +00:00
|
|
|
#ifdef ENABLE_NANORC
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'I':
|
2019-01-27 10:10:29 +00:00
|
|
|
ignore_rcfiles = TRUE;
|
2017-12-29 18:27:33 +00:00
|
|
|
break;
|
|
|
|
#endif
|
2019-03-14 18:32:10 +00:00
|
|
|
#ifndef NANO_TINY
|
2018-12-17 18:57:30 +00:00
|
|
|
case 'J':
|
|
|
|
if (!parse_num(optarg, &stripe_column) || stripe_column <= 0) {
|
2019-03-11 07:49:47 +00:00
|
|
|
fprintf(stderr, _("Guide column \"%s\" is invalid"), optarg);
|
2018-12-17 18:57:30 +00:00
|
|
|
fprintf(stderr, "\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
2019-03-14 18:32:10 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'K':
|
2018-12-28 16:47:03 +00:00
|
|
|
SET(RAW_SEQUENCES);
|
2017-12-29 18:27:33 +00:00
|
|
|
break;
|
2019-03-10 18:17:52 +00:00
|
|
|
#ifndef NANO_TINY
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'L':
|
2019-04-07 07:01:52 +00:00
|
|
|
SET(NO_NEWLINES);
|
2017-12-29 18:27:33 +00:00
|
|
|
break;
|
2019-03-10 18:17:52 +00:00
|
|
|
#endif
|
2018-01-24 08:56:03 +00:00
|
|
|
#ifdef ENABLED_WRAPORJUSTIFY
|
2018-01-23 12:44:03 +00:00
|
|
|
case 'M':
|
|
|
|
SET(TRIM_BLANKS);
|
|
|
|
break;
|
2018-01-24 08:56:03 +00:00
|
|
|
#endif
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'N':
|
|
|
|
SET(NO_CONVERT);
|
|
|
|
break;
|
2019-12-18 16:19:04 +00:00
|
|
|
case 'O':
|
|
|
|
SET(BOOKSTYLE);
|
|
|
|
break;
|
2019-03-10 18:03:43 +00:00
|
|
|
#endif
|
2017-10-29 18:42:12 +00:00
|
|
|
#ifdef ENABLE_HISTORIES
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'P':
|
2018-09-30 11:27:08 +00:00
|
|
|
SET(POSITIONLOG);
|
2017-12-29 18:27:33 +00:00
|
|
|
break;
|
2011-02-16 06:52:30 +00:00
|
|
|
#endif
|
2017-10-31 16:34:07 +00:00
|
|
|
#ifdef ENABLE_JUSTIFY
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'Q':
|
|
|
|
quotestr = mallocstrcpy(quotestr, optarg);
|
|
|
|
break;
|
2002-02-15 19:17:02 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'R':
|
|
|
|
SET(RESTRICTED);
|
|
|
|
break;
|
2020-03-27 15:57:25 +00:00
|
|
|
#ifndef NANO_TINY
|
|
|
|
case 'S':
|
|
|
|
case '$': /* Deprecated; remove in 2024. */
|
|
|
|
SET(SOFTWRAP);
|
|
|
|
break;
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'T':
|
|
|
|
if (!parse_num(optarg, &tabsize) || tabsize <= 0) {
|
|
|
|
fprintf(stderr, _("Requested tab size \"%s\" is invalid"), optarg);
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
2020-10-03 09:21:18 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'U':
|
|
|
|
SET(QUICK_BLANK);
|
|
|
|
break;
|
|
|
|
case 'V':
|
|
|
|
version();
|
|
|
|
exit(0);
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'W':
|
|
|
|
SET(WORD_BOUNDS);
|
|
|
|
break;
|
|
|
|
case 'X':
|
|
|
|
word_chars = mallocstrcpy(word_chars, optarg);
|
|
|
|
break;
|
2005-08-10 22:12:28 +00:00
|
|
|
#endif
|
2017-11-01 18:45:33 +00:00
|
|
|
#ifdef ENABLE_COLOR
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'Y':
|
|
|
|
syntaxstr = mallocstrcpy(syntaxstr, optarg);
|
|
|
|
break;
|
2017-06-28 14:57:46 +00:00
|
|
|
#endif
|
|
|
|
#ifndef NANO_TINY
|
2018-10-24 09:02:08 +00:00
|
|
|
case 'Z':
|
|
|
|
SET(LET_THEM_ZAP);
|
|
|
|
break;
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'a':
|
|
|
|
SET(AT_BLANKS);
|
|
|
|
break;
|
2019-01-25 13:40:30 +00:00
|
|
|
#endif
|
|
|
|
#ifdef ENABLE_WRAPPING
|
|
|
|
case 'b':
|
2019-04-11 18:18:29 +00:00
|
|
|
hardwrap = 1;
|
2019-01-25 13:40:30 +00:00
|
|
|
break;
|
2017-12-29 18:27:33 +00:00
|
|
|
#endif
|
|
|
|
case 'c':
|
|
|
|
SET(CONSTANT_SHOW);
|
|
|
|
break;
|
|
|
|
case 'd':
|
|
|
|
SET(REBIND_DELETE);
|
|
|
|
break;
|
2020-09-21 15:04:10 +00:00
|
|
|
#ifndef NANO_TINY
|
2019-01-25 15:31:36 +00:00
|
|
|
case 'e':
|
|
|
|
SET(EMPTY_LINE);
|
|
|
|
break;
|
2020-09-21 15:04:10 +00:00
|
|
|
#endif
|
2020-01-14 11:41:22 +00:00
|
|
|
#ifdef ENABLE_NANORC
|
|
|
|
case 'f':
|
|
|
|
custom_nanorc = mallocstrcpy(custom_nanorc, optarg);
|
|
|
|
break;
|
|
|
|
#endif
|
2020-01-28 09:33:56 +00:00
|
|
|
#if defined(ENABLE_BROWSER) || defined(ENABLE_HELP)
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'g':
|
|
|
|
SET(SHOW_CURSOR);
|
|
|
|
break;
|
2020-01-28 09:33:56 +00:00
|
|
|
#endif
|
2018-05-12 17:44:14 +00:00
|
|
|
case 'h':
|
|
|
|
usage();
|
|
|
|
exit(0);
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'i':
|
|
|
|
SET(AUTOINDENT);
|
|
|
|
break;
|
2019-01-25 14:44:52 +00:00
|
|
|
case 'j':
|
|
|
|
SET(JUMPY_SCROLLING);
|
|
|
|
break;
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'k':
|
|
|
|
SET(CUT_FROM_CURSOR);
|
|
|
|
break;
|
2000-07-12 18:14:51 +00:00
|
|
|
#endif
|
2018-05-12 17:44:14 +00:00
|
|
|
#ifdef ENABLE_LINENUMBERS
|
|
|
|
case 'l':
|
|
|
|
SET(LINE_NUMBERS);
|
|
|
|
break;
|
|
|
|
#endif
|
2017-05-01 18:45:07 +00:00
|
|
|
#ifdef ENABLE_MOUSE
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'm':
|
|
|
|
SET(USE_MOUSE);
|
|
|
|
break;
|
2002-12-22 16:30:00 +00:00
|
|
|
#endif
|
2020-09-21 15:04:10 +00:00
|
|
|
#ifndef NANO_TINY
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'n':
|
|
|
|
SET(NOREAD_MODE);
|
|
|
|
break;
|
2020-09-21 15:04:10 +00:00
|
|
|
#endif
|
2017-10-29 20:08:07 +00:00
|
|
|
#ifdef ENABLE_OPERATINGDIR
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'o':
|
|
|
|
operating_dir = mallocstrcpy(operating_dir, optarg);
|
|
|
|
break;
|
2001-09-19 03:19:43 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'p':
|
|
|
|
SET(PRESERVE);
|
|
|
|
break;
|
2020-05-26 17:07:42 +00:00
|
|
|
#ifndef NANO_TINY
|
|
|
|
case 'q':
|
|
|
|
SET(INDICATOR);
|
|
|
|
break;
|
|
|
|
#endif
|
2017-10-31 16:39:30 +00:00
|
|
|
#ifdef ENABLED_WRAPORJUSTIFY
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'r':
|
2018-10-22 23:01:23 +00:00
|
|
|
if (!parse_num(optarg, &fill)) {
|
2017-12-29 18:27:33 +00:00
|
|
|
fprintf(stderr, _("Requested fill size \"%s\" is invalid"), optarg);
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2017-11-01 19:08:55 +00:00
|
|
|
#ifdef ENABLE_NANORC
|
2017-12-29 18:27:33 +00:00
|
|
|
fill_used = TRUE;
|
2016-05-15 13:18:47 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
break;
|
2001-05-21 12:56:25 +00:00
|
|
|
#endif
|
2017-10-31 18:32:42 +00:00
|
|
|
#ifdef ENABLE_SPELLER
|
2017-12-29 18:27:33 +00:00
|
|
|
case 's':
|
|
|
|
alt_speller = mallocstrcpy(alt_speller, optarg);
|
|
|
|
break;
|
2001-01-12 07:51:05 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
case 't':
|
2020-04-30 15:25:48 +00:00
|
|
|
SET(SAVE_ON_EXIT);
|
2017-12-29 18:27:33 +00:00
|
|
|
break;
|
2015-08-09 16:31:01 +00:00
|
|
|
#ifndef NANO_TINY
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'u':
|
|
|
|
SET(MAKE_IT_UNIX);
|
|
|
|
break;
|
2015-08-09 16:31:01 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'v':
|
|
|
|
SET(VIEW_MODE);
|
|
|
|
break;
|
2017-10-29 20:00:09 +00:00
|
|
|
#ifdef ENABLE_WRAPPING
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'w':
|
2019-04-11 18:18:29 +00:00
|
|
|
hardwrap = 0;
|
2017-12-29 18:27:33 +00:00
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
case 'x':
|
|
|
|
SET(NO_HELP);
|
|
|
|
break;
|
2018-04-30 20:10:27 +00:00
|
|
|
#ifndef NANO_TINY
|
|
|
|
case 'y':
|
|
|
|
SET(AFTER_ENDS);
|
|
|
|
break;
|
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'z':
|
2020-03-13 15:17:10 +00:00
|
|
|
SET(SUSPENDABLE);
|
2017-12-29 18:27:33 +00:00
|
|
|
break;
|
2020-10-01 09:18:45 +00:00
|
|
|
#ifndef NANO_TINY
|
|
|
|
case '%':
|
|
|
|
SET(STATEFLAGS);
|
|
|
|
break;
|
2021-01-07 13:24:27 +00:00
|
|
|
case '_':
|
|
|
|
SET(MINIBAR);
|
2020-12-19 12:44:42 +00:00
|
|
|
break;
|
2020-10-01 09:18:45 +00:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_LIBMAGIC
|
|
|
|
case '!':
|
|
|
|
SET(USE_MAGIC);
|
|
|
|
break;
|
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
default:
|
|
|
|
printf(_("Type '%s -h' for a list of available options.\n"), argv[0]);
|
|
|
|
exit(1);
|
|
|
|
}
|
2000-06-06 05:53:49 +00:00
|
|
|
}
|
2017-12-29 18:27:33 +00:00
|
|
|
|
2020-06-14 10:32:42 +00:00
|
|
|
/* Enter into curses mode. Abort if this fails. */
|
|
|
|
if (initscr() == NULL)
|
|
|
|
exit(1);
|
|
|
|
|
|
|
|
#ifdef ENABLE_COLOR
|
|
|
|
/* If the terminal can do colors, tell ncurses to switch them on. */
|
|
|
|
if (has_colors())
|
|
|
|
start_color();
|
|
|
|
#endif
|
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Set up the function and shortcut lists. This needs to be done
|
|
|
|
* before reading the rcfile, to be able to rebind/unbind keys. */
|
|
|
|
shortcut_init();
|
2008-03-05 07:34:01 +00:00
|
|
|
|
2017-05-08 17:42:44 +00:00
|
|
|
#ifdef ENABLE_NANORC
|
2019-01-27 10:10:29 +00:00
|
|
|
if (!ignore_rcfiles) {
|
2019-01-27 10:17:42 +00:00
|
|
|
/* Back up the command-line options that take an argument. */
|
2017-10-31 16:39:30 +00:00
|
|
|
#ifdef ENABLED_WRAPORJUSTIFY
|
2018-10-22 23:01:23 +00:00
|
|
|
ssize_t fill_cmdline = fill;
|
2003-01-13 01:35:15 +00:00
|
|
|
#endif
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2018-09-30 08:38:27 +00:00
|
|
|
char *backup_dir_cmdline = backup_dir;
|
|
|
|
char *word_chars_cmdline = word_chars;
|
2020-10-03 09:58:43 +00:00
|
|
|
size_t stripeclm_cmdline = stripe_column;
|
2020-10-03 09:21:18 +00:00
|
|
|
ssize_t tabsize_cmdline = tabsize;
|
2004-02-28 16:24:31 +00:00
|
|
|
#endif
|
2018-09-30 08:33:43 +00:00
|
|
|
#ifdef ENABLE_OPERATINGDIR
|
2018-09-30 08:38:27 +00:00
|
|
|
char *operating_dir_cmdline = operating_dir;
|
2018-09-30 08:33:43 +00:00
|
|
|
#endif
|
2017-10-31 16:34:07 +00:00
|
|
|
#ifdef ENABLE_JUSTIFY
|
2018-09-30 08:38:27 +00:00
|
|
|
char *quotestr_cmdline = quotestr;
|
2003-01-13 01:35:15 +00:00
|
|
|
#endif
|
2017-10-31 18:32:42 +00:00
|
|
|
#ifdef ENABLE_SPELLER
|
2018-09-30 08:38:27 +00:00
|
|
|
char *alt_speller_cmdline = alt_speller;
|
2003-01-13 01:35:15 +00:00
|
|
|
#endif
|
2009-08-14 03:18:29 +00:00
|
|
|
|
2019-01-27 10:17:42 +00:00
|
|
|
/* Back up the command-line flags. */
|
|
|
|
unsigned flags_cmdline[sizeof(flags) / sizeof(flags[0])];
|
2018-09-30 08:38:27 +00:00
|
|
|
memcpy(flags_cmdline, flags, sizeof(flags_cmdline));
|
2003-01-13 01:35:15 +00:00
|
|
|
|
2019-01-27 10:17:42 +00:00
|
|
|
/* Clear the string options, to not overwrite the specified ones. */
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2017-12-29 18:27:33 +00:00
|
|
|
backup_dir = NULL;
|
|
|
|
word_chars = NULL;
|
2004-02-28 16:24:31 +00:00
|
|
|
#endif
|
2018-09-30 08:33:43 +00:00
|
|
|
#ifdef ENABLE_OPERATINGDIR
|
|
|
|
operating_dir = NULL;
|
|
|
|
#endif
|
2017-10-31 16:34:07 +00:00
|
|
|
#ifdef ENABLE_JUSTIFY
|
2017-12-29 18:27:33 +00:00
|
|
|
quotestr = NULL;
|
2003-02-05 02:39:34 +00:00
|
|
|
#endif
|
2017-10-31 18:32:42 +00:00
|
|
|
#ifdef ENABLE_SPELLER
|
2017-12-29 18:27:33 +00:00
|
|
|
alt_speller = NULL;
|
2003-02-05 02:39:34 +00:00
|
|
|
#endif
|
2018-09-30 08:38:27 +00:00
|
|
|
/* Now process the system's and the user's nanorc file, if any. */
|
2017-12-29 18:27:33 +00:00
|
|
|
do_rcfiles();
|
2003-01-13 01:35:15 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* If the backed-up command-line options have a value, restore them. */
|
2017-10-31 16:39:30 +00:00
|
|
|
#ifdef ENABLED_WRAPORJUSTIFY
|
2017-12-29 18:27:33 +00:00
|
|
|
if (fill_used)
|
2018-10-22 23:01:23 +00:00
|
|
|
fill = fill_cmdline;
|
2003-01-13 01:35:15 +00:00
|
|
|
#endif
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2018-09-30 08:38:27 +00:00
|
|
|
if (backup_dir_cmdline != NULL) {
|
2017-12-29 18:27:33 +00:00
|
|
|
free(backup_dir);
|
2018-09-30 08:38:27 +00:00
|
|
|
backup_dir = backup_dir_cmdline;
|
2017-12-29 18:27:33 +00:00
|
|
|
}
|
2018-09-30 08:38:27 +00:00
|
|
|
if (word_chars_cmdline != NULL) {
|
2017-12-29 18:27:33 +00:00
|
|
|
free(word_chars);
|
2018-09-30 08:38:27 +00:00
|
|
|
word_chars = word_chars_cmdline;
|
2017-12-29 18:27:33 +00:00
|
|
|
}
|
2020-10-03 09:58:43 +00:00
|
|
|
if (stripeclm_cmdline > 0)
|
|
|
|
stripe_column = stripeclm_cmdline;
|
2020-10-03 09:21:18 +00:00
|
|
|
if (tabsize_cmdline != -1)
|
|
|
|
tabsize = tabsize_cmdline;
|
2007-12-10 17:59:26 +00:00
|
|
|
#endif
|
2018-09-30 08:33:43 +00:00
|
|
|
#ifdef ENABLE_OPERATINGDIR
|
2018-09-30 08:38:27 +00:00
|
|
|
if (operating_dir_cmdline != NULL || ISSET(RESTRICTED)) {
|
2018-09-30 08:33:43 +00:00
|
|
|
free(operating_dir);
|
2018-09-30 08:38:27 +00:00
|
|
|
operating_dir = operating_dir_cmdline;
|
2018-09-30 08:33:43 +00:00
|
|
|
}
|
|
|
|
#endif
|
2017-10-31 16:34:07 +00:00
|
|
|
#ifdef ENABLE_JUSTIFY
|
2018-09-30 08:38:27 +00:00
|
|
|
if (quotestr_cmdline != NULL) {
|
2017-12-29 18:27:33 +00:00
|
|
|
free(quotestr);
|
2018-09-30 08:38:27 +00:00
|
|
|
quotestr = quotestr_cmdline;
|
2017-12-29 18:27:33 +00:00
|
|
|
}
|
2003-01-13 01:35:15 +00:00
|
|
|
#endif
|
2017-10-31 18:32:42 +00:00
|
|
|
#ifdef ENABLE_SPELLER
|
2018-09-30 08:38:27 +00:00
|
|
|
if (alt_speller_cmdline != NULL) {
|
2017-12-29 18:27:33 +00:00
|
|
|
free(alt_speller);
|
2018-09-30 08:38:27 +00:00
|
|
|
alt_speller = alt_speller_cmdline;
|
2017-12-29 18:27:33 +00:00
|
|
|
}
|
2021-01-11 18:15:35 +00:00
|
|
|
/* Strip leading whitespace from the speller command, if any. */
|
|
|
|
while (alt_speller && *alt_speller && isblank(*alt_speller))
|
2021-01-11 18:22:40 +00:00
|
|
|
memmove(alt_speller, alt_speller + 1, strlen(alt_speller));
|
2003-01-13 01:35:15 +00:00
|
|
|
#endif
|
2009-08-14 03:18:29 +00:00
|
|
|
|
2021-04-15 09:43:39 +00:00
|
|
|
/* If an rcfile undid the default setting, copy it to the new flag. */
|
2019-01-28 18:55:04 +00:00
|
|
|
if (!ISSET(NO_WRAP))
|
|
|
|
SET(BREAK_LONG_LINES);
|
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Simply OR the boolean flags from rcfile and command line. */
|
2019-01-27 10:17:42 +00:00
|
|
|
for (size_t i = 0; i < sizeof(flags) / sizeof(flags[0]); i++)
|
2018-09-30 08:38:27 +00:00
|
|
|
flags[i] |= flags_cmdline[i];
|
2017-12-29 18:27:33 +00:00
|
|
|
}
|
2017-05-08 17:42:44 +00:00
|
|
|
#endif /* ENABLE_NANORC */
|
2003-01-13 01:35:15 +00:00
|
|
|
|
2020-01-14 15:28:28 +00:00
|
|
|
#ifdef ENABLE_WRAPPING
|
2019-04-20 11:56:04 +00:00
|
|
|
if (hardwrap == 0)
|
|
|
|
UNSET(BREAK_LONG_LINES);
|
|
|
|
else if (hardwrap == 1)
|
|
|
|
SET(BREAK_LONG_LINES);
|
2020-01-14 15:28:28 +00:00
|
|
|
#endif
|
2019-04-20 11:56:04 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* If the user wants bold instead of reverse video for hilited text... */
|
|
|
|
if (ISSET(BOLD_TEXT))
|
|
|
|
hilite_attribute = A_BOLD;
|
2006-04-12 15:27:40 +00:00
|
|
|
|
2018-09-26 19:20:18 +00:00
|
|
|
/* When in restricted mode, disable backups, suspending, and history files,
|
|
|
|
* since they allow writing to files not specified on the command line. */
|
|
|
|
if (ISSET(RESTRICTED)) {
|
2020-05-25 16:52:09 +00:00
|
|
|
UNSET(MAKE_BACKUP);
|
2020-03-13 15:17:10 +00:00
|
|
|
UNSET(SUSPENDABLE);
|
2018-09-26 19:20:18 +00:00
|
|
|
#ifdef ENABLE_NANORC
|
|
|
|
UNSET(HISTORYLOG);
|
2018-09-30 11:27:08 +00:00
|
|
|
UNSET(POSITIONLOG);
|
2018-09-26 19:20:18 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2018-12-28 17:07:28 +00:00
|
|
|
/* When getting untranslated escape sequences, the mouse cannot be used. */
|
|
|
|
if (ISSET(RAW_SEQUENCES))
|
|
|
|
UNSET(USE_MOUSE);
|
|
|
|
|
2017-10-29 18:42:12 +00:00
|
|
|
#ifdef ENABLE_HISTORIES
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Initialize the pointers for the Search/Replace/Execute histories. */
|
|
|
|
history_init();
|
|
|
|
|
|
|
|
/* If we need history files, verify that we have a directory for them,
|
|
|
|
* and when not, cancel the options. */
|
2018-09-30 11:27:08 +00:00
|
|
|
if ((ISSET(HISTORYLOG) || ISSET(POSITIONLOG)) && !have_statedir()) {
|
2017-12-29 18:27:33 +00:00
|
|
|
UNSET(HISTORYLOG);
|
2018-09-30 11:27:08 +00:00
|
|
|
UNSET(POSITIONLOG);
|
2017-12-29 18:27:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* If the user wants history persistence, read the relevant files. */
|
|
|
|
if (ISSET(HISTORYLOG))
|
|
|
|
load_history();
|
2018-09-30 11:27:08 +00:00
|
|
|
if (ISSET(POSITIONLOG))
|
2017-12-29 18:27:33 +00:00
|
|
|
load_poshistory();
|
2017-10-29 18:42:12 +00:00
|
|
|
#endif /* ENABLE_HISTORIES */
|
2003-03-11 03:50:40 +00:00
|
|
|
|
2014-06-19 20:05:24 +00:00
|
|
|
#ifndef NANO_TINY
|
2019-01-10 19:29:04 +00:00
|
|
|
/* If a backup directory was specified and we're not in restricted mode,
|
|
|
|
* verify it is an existing folder, so backup files can be saved there. */
|
|
|
|
if (backup_dir != NULL && !ISSET(RESTRICTED))
|
2017-12-29 18:27:33 +00:00
|
|
|
init_backup_dir();
|
2014-06-19 20:05:24 +00:00
|
|
|
#endif
|
2017-10-29 20:08:07 +00:00
|
|
|
#ifdef ENABLE_OPERATINGDIR
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Set up the operating directory. This entails chdir()ing there,
|
|
|
|
* so that file reads and writes will be based there. */
|
|
|
|
if (operating_dir != NULL)
|
|
|
|
init_operating_dir();
|
2016-06-12 09:13:45 +00:00
|
|
|
#endif
|
|
|
|
|
2017-10-31 16:34:07 +00:00
|
|
|
#ifdef ENABLE_JUSTIFY
|
2018-05-24 18:43:08 +00:00
|
|
|
/* Set the default value for things that weren't specified. */
|
2017-12-29 18:27:33 +00:00
|
|
|
if (punct == NULL)
|
2019-10-13 10:24:27 +00:00
|
|
|
punct = copy_of("!.?");
|
2017-12-29 18:27:33 +00:00
|
|
|
if (brackets == NULL)
|
2019-10-13 10:24:27 +00:00
|
|
|
brackets = copy_of("\"')>]}");
|
2017-12-29 18:27:33 +00:00
|
|
|
if (quotestr == NULL)
|
2019-10-13 10:24:27 +00:00
|
|
|
quotestr = copy_of("^([ \t]*([!#%:;>|}]|/{2}))+");
|
2017-12-29 18:27:33 +00:00
|
|
|
|
2018-12-11 09:42:45 +00:00
|
|
|
/* Compile the quoting regex, and exit when it's invalid. */
|
2018-05-24 18:43:08 +00:00
|
|
|
quoterc = regcomp("ereg, quotestr, NANO_REG_EXTENDED);
|
2018-12-11 09:42:45 +00:00
|
|
|
if (quoterc != 0) {
|
2017-12-29 18:27:33 +00:00
|
|
|
size_t size = regerror(quoterc, "ereg, NULL, 0);
|
2020-08-30 02:57:45 +00:00
|
|
|
char *message = nmalloc(size);
|
2017-12-29 18:27:33 +00:00
|
|
|
|
2018-12-11 09:42:45 +00:00
|
|
|
regerror(quoterc, "ereg, message, size);
|
|
|
|
die(_("Bad quoting regex \"%s\": %s\n"), quotestr, message);
|
|
|
|
} else
|
|
|
|
free(quotestr);
|
2017-10-31 16:34:07 +00:00
|
|
|
#endif /* ENABLE_JUSTIFY */
|
2004-02-28 16:24:31 +00:00
|
|
|
|
2017-10-31 18:32:42 +00:00
|
|
|
#ifdef ENABLE_SPELLER
|
2017-12-29 18:27:33 +00:00
|
|
|
/* If we don't have an alternative spell checker after reading the
|
|
|
|
* command line and/or rcfile(s), check $SPELL for one, as Pico
|
|
|
|
* does (unless we're using restricted mode, in which case spell
|
|
|
|
* checking is disabled, since it would allow reading from or
|
|
|
|
* writing to files not specified on the command line). */
|
2018-09-30 11:11:43 +00:00
|
|
|
if (alt_speller == NULL && !ISSET(RESTRICTED)) {
|
2017-12-29 18:27:33 +00:00
|
|
|
const char *spellenv = getenv("SPELL");
|
2018-09-30 11:11:43 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
if (spellenv != NULL)
|
2019-10-13 10:24:27 +00:00
|
|
|
alt_speller = copy_of(spellenv);
|
2017-12-29 18:27:33 +00:00
|
|
|
}
|
2004-05-28 22:42:41 +00:00
|
|
|
#endif
|
|
|
|
|
2006-01-06 21:51:10 +00:00
|
|
|
#ifndef NANO_TINY
|
2017-12-29 18:27:33 +00:00
|
|
|
/* If matchbrackets wasn't specified, set its default value. */
|
|
|
|
if (matchbrackets == NULL)
|
2019-10-13 10:24:27 +00:00
|
|
|
matchbrackets = copy_of("(<[{)>]}");
|
2006-01-06 21:51:10 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* If the whitespace option wasn't specified, set its default value. */
|
|
|
|
if (whitespace == NULL) {
|
2014-03-27 11:06:16 +00:00
|
|
|
#ifdef ENABLE_UTF8
|
2017-12-29 18:27:33 +00:00
|
|
|
if (using_utf8()) {
|
|
|
|
/* A tab is shown as a Right-Pointing Double Angle Quotation Mark
|
|
|
|
* (U+00BB), and a space as a Middle Dot (U+00B7). */
|
2019-10-13 10:24:27 +00:00
|
|
|
whitespace = copy_of("\xC2\xBB\xC2\xB7");
|
2019-03-21 18:21:45 +00:00
|
|
|
whitelen[0] = 2;
|
|
|
|
whitelen[1] = 2;
|
2017-12-29 18:27:33 +00:00
|
|
|
} else
|
|
|
|
#endif
|
|
|
|
{
|
2019-10-13 10:24:27 +00:00
|
|
|
whitespace = copy_of(">.");
|
2019-03-21 18:21:45 +00:00
|
|
|
whitelen[0] = 1;
|
|
|
|
whitelen[1] = 1;
|
2017-12-29 18:27:33 +00:00
|
|
|
}
|
2014-03-16 13:19:41 +00:00
|
|
|
}
|
2014-04-05 20:28:29 +00:00
|
|
|
#endif /* !NANO_TINY */
|
2004-05-29 16:25:30 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Initialize the search string. */
|
2019-10-13 10:24:27 +00:00
|
|
|
last_search = copy_of("");
|
2017-12-29 18:27:33 +00:00
|
|
|
UNSET(BACKWARDS_SEARCH);
|
2015-04-21 18:42:11 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* If tabsize wasn't specified, set its default value. */
|
|
|
|
if (tabsize == -1)
|
|
|
|
tabsize = WIDTH_OF_TAB;
|
2002-06-13 00:40:19 +00:00
|
|
|
|
2018-01-12 09:48:13 +00:00
|
|
|
#ifdef ENABLE_COLOR
|
2020-06-14 10:32:42 +00:00
|
|
|
/* On capable terminals, use colors, otherwise just reverse or bold.*/
|
|
|
|
if (has_colors())
|
2020-04-29 10:07:31 +00:00
|
|
|
set_interface_colorpairs();
|
2020-06-14 10:32:42 +00:00
|
|
|
else
|
2018-01-12 09:48:13 +00:00
|
|
|
#endif
|
2020-04-29 10:07:31 +00:00
|
|
|
{
|
|
|
|
interface_color_pair[TITLE_BAR] = hilite_attribute;
|
|
|
|
interface_color_pair[LINE_NUMBER] = hilite_attribute;
|
|
|
|
interface_color_pair[GUIDE_STRIPE] = A_REVERSE;
|
2020-08-28 16:40:10 +00:00
|
|
|
interface_color_pair[SCROLL_BAR] = A_NORMAL;
|
2020-04-29 10:07:31 +00:00
|
|
|
interface_color_pair[SELECTED_TEXT] = hilite_attribute;
|
2021-03-03 08:39:49 +00:00
|
|
|
interface_color_pair[SPOTLIGHTED] = A_REVERSE;
|
2021-06-07 10:10:23 +00:00
|
|
|
interface_color_pair[MINI_INFOBAR] = hilite_attribute;
|
2020-12-06 14:49:35 +00:00
|
|
|
interface_color_pair[PROMPT_BAR] = hilite_attribute;
|
2020-04-29 10:07:31 +00:00
|
|
|
interface_color_pair[STATUS_BAR] = hilite_attribute;
|
|
|
|
interface_color_pair[ERROR_MESSAGE] = hilite_attribute;
|
|
|
|
interface_color_pair[KEY_COMBO] = hilite_attribute;
|
|
|
|
interface_color_pair[FUNCTION_TAG] = A_NORMAL;
|
|
|
|
}
|
2018-01-12 09:48:13 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Set up the terminal state. */
|
|
|
|
terminal_init();
|
2004-01-12 03:28:06 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Create the three subwindows, based on the current screen dimensions. */
|
|
|
|
window_init();
|
|
|
|
curs_set(0);
|
2004-02-16 20:32:40 +00:00
|
|
|
|
2020-04-25 15:19:03 +00:00
|
|
|
#ifndef NANO_TINY
|
2020-05-26 17:07:42 +00:00
|
|
|
thebar = (ISSET(INDICATOR) && LINES > 5 && COLS > 9) ? 1 : 0;
|
2020-04-25 15:19:03 +00:00
|
|
|
bardata = nrealloc(bardata, LINES * sizeof(int));
|
|
|
|
#endif
|
|
|
|
editwincols = COLS - thebar;
|
2016-10-28 08:50:06 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Set up the signal handlers. */
|
|
|
|
signal_init();
|
2000-06-06 05:53:49 +00:00
|
|
|
|
2017-05-01 18:45:07 +00:00
|
|
|
#ifdef ENABLE_MOUSE
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Initialize mouse support. */
|
|
|
|
mouse_init();
|
2002-12-22 16:30:00 +00:00
|
|
|
#endif
|
2001-11-29 02:42:27 +00:00
|
|
|
|
2018-10-16 17:22:40 +00:00
|
|
|
/* Ask ncurses for the key codes for most modified editing keys. */
|
2017-12-29 18:27:33 +00:00
|
|
|
controlleft = get_keycode("kLFT5", CONTROL_LEFT);
|
|
|
|
controlright = get_keycode("kRIT5", CONTROL_RIGHT);
|
|
|
|
controlup = get_keycode("kUP5", CONTROL_UP);
|
|
|
|
controldown = get_keycode("kDN5", CONTROL_DOWN);
|
2018-10-16 17:22:40 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
controlhome = get_keycode("kHOM5", CONTROL_HOME);
|
|
|
|
controlend = get_keycode("kEND5", CONTROL_END);
|
2018-10-05 17:09:17 +00:00
|
|
|
#ifndef NANO_TINY
|
2018-07-12 21:47:46 +00:00
|
|
|
controldelete = get_keycode("kDC5", CONTROL_DELETE);
|
2018-09-12 11:18:17 +00:00
|
|
|
controlshiftdelete = get_keycode("kDC6", CONTROL_SHIFT_DELETE);
|
2018-10-16 17:22:40 +00:00
|
|
|
|
2018-10-05 17:50:41 +00:00
|
|
|
shiftup = get_keycode("kUP", SHIFT_UP);
|
|
|
|
shiftdown = get_keycode("kDN", SHIFT_DOWN);
|
2018-10-16 17:22:40 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
shiftcontrolleft = get_keycode("kLFT6", SHIFT_CONTROL_LEFT);
|
|
|
|
shiftcontrolright = get_keycode("kRIT6", SHIFT_CONTROL_RIGHT);
|
|
|
|
shiftcontrolup = get_keycode("kUP6", SHIFT_CONTROL_UP);
|
|
|
|
shiftcontroldown = get_keycode("kDN6", SHIFT_CONTROL_DOWN);
|
2018-10-16 17:22:40 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
shiftcontrolhome = get_keycode("kHOM6", SHIFT_CONTROL_HOME);
|
|
|
|
shiftcontrolend = get_keycode("kEND6", SHIFT_CONTROL_END);
|
2018-10-16 17:22:40 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
altleft = get_keycode("kLFT3", ALT_LEFT);
|
|
|
|
altright = get_keycode("kRIT3", ALT_RIGHT);
|
|
|
|
altup = get_keycode("kUP3", ALT_UP);
|
|
|
|
altdown = get_keycode("kDN3", ALT_DOWN);
|
2018-12-04 01:45:18 +00:00
|
|
|
|
|
|
|
altpageup = get_keycode("kPRV3", ALT_PAGEUP);
|
|
|
|
altpagedown = get_keycode("kNXT3", ALT_PAGEDOWN);
|
|
|
|
altinsert = get_keycode("kIC3", ALT_INSERT);
|
2018-10-24 09:17:28 +00:00
|
|
|
altdelete = get_keycode("kDC3", ALT_DELETE);
|
2018-10-16 17:22:40 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
shiftaltleft = get_keycode("kLFT4", SHIFT_ALT_LEFT);
|
|
|
|
shiftaltright = get_keycode("kRIT4", SHIFT_ALT_RIGHT);
|
|
|
|
shiftaltup = get_keycode("kUP4", SHIFT_ALT_UP);
|
|
|
|
shiftaltdown = get_keycode("kDN4", SHIFT_ALT_DOWN);
|
2015-11-23 08:52:23 +00:00
|
|
|
#endif
|
|
|
|
|
2017-02-21 22:04:45 +00:00
|
|
|
#ifdef HAVE_SET_ESCDELAY
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Tell ncurses to pass the Esc key quickly. */
|
|
|
|
set_escdelay(50);
|
2016-07-11 12:21:38 +00:00
|
|
|
#endif
|
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Read the files mentioned on the command line into new buffers. */
|
2018-03-21 10:40:15 +00:00
|
|
|
while (optind < argc && (!openfile || read_them_all)) {
|
2017-12-29 18:27:33 +00:00
|
|
|
ssize_t givenline = 0, givencol = 0;
|
2019-08-18 10:54:28 +00:00
|
|
|
#ifndef NANO_TINY
|
2019-08-09 12:55:06 +00:00
|
|
|
char *searchstring = NULL;
|
2019-08-18 10:54:28 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
/* If there's a +LINE[,COLUMN] argument here, eat it up. */
|
|
|
|
if (optind < argc - 1 && argv[optind][0] == '+') {
|
2021-06-15 08:20:28 +00:00
|
|
|
#ifndef NANO_TINY
|
2019-08-17 21:30:43 +00:00
|
|
|
int n = 1;
|
|
|
|
|
|
|
|
while (isalpha(argv[optind][n])) {
|
|
|
|
switch (argv[optind][n++]) {
|
|
|
|
case 'c': SET(CASE_SENSITIVE); break;
|
|
|
|
case 'C': UNSET(CASE_SENSITIVE); break;
|
|
|
|
case 'r': SET(USE_REGEXP); break;
|
|
|
|
case 'R': UNSET(USE_REGEXP); break;
|
|
|
|
default:
|
|
|
|
statusline(ALERT, _("Invalid search modifier '%c'"),
|
|
|
|
argv[optind][n - 1]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (argv[optind][n] == '/' || argv[optind][n] == '?') {
|
|
|
|
if (argv[optind][n + 1]) {
|
2019-10-13 10:24:27 +00:00
|
|
|
searchstring = copy_of(&argv[optind][n + 1]);
|
2019-08-17 21:30:43 +00:00
|
|
|
if (argv[optind][n] == '?')
|
2019-08-09 12:55:06 +00:00
|
|
|
SET(BACKWARDS_SEARCH);
|
2019-08-17 21:30:43 +00:00
|
|
|
} else if (n == 1)
|
2019-08-09 12:55:06 +00:00
|
|
|
statusline(ALERT, _("Empty search string"));
|
|
|
|
optind++;
|
|
|
|
} else
|
2019-08-18 10:54:28 +00:00
|
|
|
#endif
|
2021-05-24 14:11:50 +00:00
|
|
|
/* When there is nothing after the "+", understand it as go-to-EOF,
|
|
|
|
* otherwise parse and store the given number(s).*/
|
|
|
|
if (argv[optind++][1] == '\0')
|
|
|
|
givenline = -1;
|
|
|
|
else if (!parse_line_column(&argv[optind - 1][1], &givenline, &givencol))
|
2017-12-29 18:27:33 +00:00
|
|
|
statusline(ALERT, _("Invalid line or column number"));
|
|
|
|
}
|
2017-06-18 09:12:49 +00:00
|
|
|
|
2020-09-12 09:40:08 +00:00
|
|
|
#ifndef NANO_TINY
|
2017-12-29 18:27:33 +00:00
|
|
|
/* If the filename is a dash, read from standard input; otherwise,
|
|
|
|
* open the file; skip positioning the cursor if either failed. */
|
|
|
|
if (strcmp(argv[optind], "-") == 0) {
|
2018-03-20 10:25:16 +00:00
|
|
|
optind++;
|
2017-12-29 18:27:33 +00:00
|
|
|
if (!scoop_stdin())
|
|
|
|
continue;
|
2020-09-12 09:40:08 +00:00
|
|
|
} else
|
|
|
|
#endif
|
|
|
|
if (!open_buffer(argv[optind++], TRUE))
|
2017-12-29 18:27:33 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
/* If a position was given on the command line, go there. */
|
|
|
|
if (givenline != 0 || givencol != 0)
|
|
|
|
do_gotolinecolumn(givenline, givencol, FALSE, FALSE);
|
2019-08-18 10:54:28 +00:00
|
|
|
#ifndef NANO_TINY
|
2019-08-09 12:55:06 +00:00
|
|
|
else if (searchstring != NULL) {
|
|
|
|
if (ISSET(USE_REGEXP))
|
|
|
|
regexp_init(searchstring);
|
2019-09-01 20:14:43 +00:00
|
|
|
if (!findnextstr(searchstring, FALSE, JUSTFIND, NULL,
|
|
|
|
ISSET(BACKWARDS_SEARCH), openfile->filetop, 0))
|
2019-08-09 12:55:06 +00:00
|
|
|
not_found_msg(searchstring);
|
2021-05-25 12:37:31 +00:00
|
|
|
else if (lastmessage <= REMARK)
|
2019-08-09 12:55:06 +00:00
|
|
|
wipe_statusbar();
|
2019-09-01 14:10:17 +00:00
|
|
|
openfile->placewewant = xplustabs();
|
2019-08-09 12:55:06 +00:00
|
|
|
if (ISSET(USE_REGEXP))
|
|
|
|
tidy_up_after_search();
|
|
|
|
free(last_search);
|
|
|
|
last_search = searchstring;
|
|
|
|
searchstring = NULL;
|
|
|
|
}
|
2019-08-18 10:54:28 +00:00
|
|
|
#endif
|
2017-10-29 18:42:12 +00:00
|
|
|
#ifdef ENABLE_HISTORIES
|
2018-09-30 11:27:08 +00:00
|
|
|
else if (ISSET(POSITIONLOG) && openfile->filename[0] != '\0') {
|
2017-12-29 18:27:33 +00:00
|
|
|
ssize_t savedline, savedcol;
|
|
|
|
/* If edited before, restore the last cursor position. */
|
|
|
|
if (has_old_position(argv[optind - 1], &savedline, &savedcol))
|
|
|
|
do_gotolinecolumn(savedline, savedcol, FALSE, FALSE);
|
|
|
|
}
|
2017-06-18 09:12:49 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
}
|
2004-09-05 21:40:31 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* If no filenames were given, or all of them were invalid things like
|
|
|
|
* directories, then open a blank buffer and allow editing. Otherwise,
|
|
|
|
* switch from the last opened file to the next, that is: the first. */
|
|
|
|
if (openfile == NULL) {
|
2018-03-21 10:36:00 +00:00
|
|
|
open_buffer("", TRUE);
|
2017-12-29 18:27:33 +00:00
|
|
|
UNSET(VIEW_MODE);
|
|
|
|
}
|
2017-06-18 19:37:42 +00:00
|
|
|
#ifdef ENABLE_MULTIBUFFER
|
2018-07-12 11:09:17 +00:00
|
|
|
else {
|
2017-12-29 18:27:33 +00:00
|
|
|
openfile = openfile->next;
|
2018-07-12 11:09:17 +00:00
|
|
|
if (more_than_one)
|
|
|
|
mention_name_and_linecount();
|
2018-10-12 17:57:43 +00:00
|
|
|
if (ISSET(VIEW_MODE))
|
|
|
|
SET(MULTIBUFFER);
|
2018-07-12 11:09:17 +00:00
|
|
|
}
|
2020-11-17 18:03:29 +00:00
|
|
|
#else
|
|
|
|
if (optind < argc)
|
|
|
|
die(_("Can open just one file\n"));
|
2003-01-13 01:35:15 +00:00
|
|
|
#endif
|
2000-06-06 05:53:49 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
prepare_for_display();
|
2000-07-08 14:23:32 +00:00
|
|
|
|
2018-08-04 08:53:34 +00:00
|
|
|
#ifdef ENABLE_NANORC
|
2019-10-20 12:25:22 +00:00
|
|
|
if (startup_problem != NULL)
|
|
|
|
statusline(ALERT, startup_problem);
|
2021-04-01 07:45:55 +00:00
|
|
|
|
|
|
|
#define NOTREBOUND first_sc_for(MMAIN, do_help) && \
|
|
|
|
first_sc_for(MMAIN, do_help)->keycode == 0x07
|
|
|
|
#else
|
|
|
|
#define NOTREBOUND TRUE
|
2018-08-04 08:53:34 +00:00
|
|
|
#endif
|
2017-10-28 12:18:37 +00:00
|
|
|
|
2018-05-16 15:36:14 +00:00
|
|
|
#ifdef ENABLE_HELP
|
|
|
|
if (*openfile->filename == '\0' && openfile->totsize == 0 &&
|
2021-04-01 07:45:55 +00:00
|
|
|
openfile->next == openfile && !ISSET(NO_HELP) && NOTREBOUND)
|
2018-05-16 15:36:14 +00:00
|
|
|
statusbar(_("Welcome to nano. For basic help, type Ctrl+G."));
|
|
|
|
#endif
|
|
|
|
|
2020-02-02 11:54:34 +00:00
|
|
|
we_are_running = TRUE;
|
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
while (TRUE) {
|
2016-10-21 12:31:37 +00:00
|
|
|
#ifdef ENABLE_LINENUMBERS
|
2018-05-25 18:09:24 +00:00
|
|
|
confirm_margin();
|
2020-01-23 11:32:28 +00:00
|
|
|
#endif
|
|
|
|
#ifdef __linux__
|
|
|
|
if (on_a_vt && get_key_buffer_len() == 0)
|
|
|
|
mute_modifiers = FALSE;
|
2017-02-09 16:20:04 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
if (currmenu != MMAIN)
|
2018-09-28 18:06:47 +00:00
|
|
|
bottombars(MMAIN);
|
2016-05-08 10:01:33 +00:00
|
|
|
|
2020-08-15 15:32:31 +00:00
|
|
|
#ifndef NANO_TINY
|
2021-05-03 13:47:37 +00:00
|
|
|
if (ISSET(MINIBAR) && LINES > 1 && lastmessage < REMARK)
|
2020-08-15 15:32:31 +00:00
|
|
|
minibar();
|
|
|
|
else
|
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Update the displayed current cursor position only when there
|
2020-07-03 10:39:04 +00:00
|
|
|
* is no message and no keys are waiting in the input buffer. */
|
2021-05-09 17:11:49 +00:00
|
|
|
if (ISSET(CONSTANT_SHOW) && lastmessage == VACUUM && LINES > 1 &&
|
|
|
|
get_key_buffer_len() == 0)
|
2020-07-03 07:32:25 +00:00
|
|
|
report_cursor_position();
|
|
|
|
|
|
|
|
as_an_at = TRUE;
|
2016-11-13 19:00:31 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Refresh just the cursor position or the entire edit window. */
|
|
|
|
if (!refresh_needed) {
|
|
|
|
place_the_cursor();
|
|
|
|
wnoutrefresh(edit);
|
2021-05-11 17:28:11 +00:00
|
|
|
} else if (LINES > 1 || lastmessage == VACUUM)
|
2017-12-29 18:27:33 +00:00
|
|
|
edit_refresh();
|
2016-11-12 16:59:28 +00:00
|
|
|
|
2018-04-29 10:01:02 +00:00
|
|
|
errno = 0;
|
2017-12-29 18:27:33 +00:00
|
|
|
focusing = TRUE;
|
2003-01-28 01:16:47 +00:00
|
|
|
|
2018-07-11 09:02:45 +00:00
|
|
|
/* Forget any earlier cursor position at the prompt. */
|
|
|
|
put_cursor_at_end_of_answer();
|
2016-04-17 13:24:05 +00:00
|
|
|
|
2018-12-30 11:45:52 +00:00
|
|
|
/* Read in and interpret a single keystroke. */
|
2020-02-12 13:15:35 +00:00
|
|
|
process_a_keystroke();
|
2017-12-29 18:27:33 +00:00
|
|
|
}
|
2000-06-06 05:53:49 +00:00
|
|
|
}
|