summaryrefslogtreecommitdiff
path: root/src/nano.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nano.c')
-rw-r--r--src/nano.c801
1 files changed, 476 insertions, 325 deletions
diff --git a/src/nano.c b/src/nano.c
index e4e2222..6930425 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -1,9 +1,9 @@
-/* $Id: nano.c 4520 2010-11-12 06:23:14Z astyanax $ */
+/* $Id: nano.c 5141 2015-03-20 11:18:22Z bens $ */
/**************************************************************************
* nano.c *
* *
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
- * 2008, 2009 Free Software Foundation, Inc. *
+ * 2008, 2009, 2010, 2011, 2013, 2014 Free Software Foundation, Inc. *
* This program 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, or (at your option) *
@@ -48,7 +48,7 @@
static int oldinterval = -1;
/* Used to store the user's original mouse click interval. */
#endif
-#ifdef ENABLE_NANORC
+#ifndef DISABLE_NANORC
static bool no_rcfiles = FALSE;
/* Should we ignore all rcfiles? */
#endif
@@ -68,7 +68,7 @@ filestruct *make_new_node(filestruct *prevnode)
newnode->next = NULL;
newnode->lineno = (prevnode != NULL) ? prevnode->lineno + 1 : 1;
-#ifdef ENABLE_COLOR
+#ifndef DISABLE_COLOR
newnode->multidata = NULL;
#endif
@@ -88,7 +88,7 @@ filestruct *copy_node(const filestruct *src)
dst->next = src->next;
dst->prev = src->prev;
dst->lineno = src->lineno;
-#ifdef ENABLE_COLOR
+#ifndef DISABLE_COLOR
dst->multidata = NULL;
#endif
@@ -127,7 +127,7 @@ void delete_node(filestruct *fileptr)
if (fileptr->data != NULL)
free(fileptr->data);
-#ifdef ENABLE_COLOR
+#ifndef DISABLE_COLOR
if (fileptr->multidata)
free(fileptr->multidata);
#endif
@@ -178,7 +178,8 @@ void renumber(filestruct *fileptr)
{
ssize_t line;
- assert(fileptr != NULL);
+ if (fileptr == NULL)
+ return;
line = (fileptr->prev == NULL) ? 0 : fileptr->prev->lineno;
@@ -297,6 +298,7 @@ void move_to_filestruct(filestruct **file_top, filestruct **file_bot,
bool edittop_inside;
#ifndef NANO_TINY
bool mark_inside = FALSE;
+ bool same_line = FALSE;
#endif
assert(file_top != NULL && file_bot != NULL && top != NULL && bot != NULL);
@@ -314,7 +316,7 @@ void move_to_filestruct(filestruct **file_top, filestruct **file_bot,
openfile->fileage->lineno && openfile->edittop->lineno <=
openfile->filebot->lineno);
#ifndef NANO_TINY
- if (openfile->mark_set)
+ if (openfile->mark_set) {
mark_inside = (openfile->mark_begin->lineno >=
openfile->fileage->lineno &&
openfile->mark_begin->lineno <=
@@ -323,6 +325,8 @@ void move_to_filestruct(filestruct **file_top, filestruct **file_bot,
openfile->mark_begin_x >= top_x) &&
(openfile->mark_begin != openfile->filebot ||
openfile->mark_begin_x <= bot_x));
+ same_line = (openfile->mark_begin == openfile->fileage);
+ }
#endif
/* Get the number of characters in the text, and subtract it from
@@ -357,10 +361,12 @@ void move_to_filestruct(filestruct **file_top, filestruct **file_bot,
*file_bot = openfile->filebot;
}
+ openfile->fileage->next = NULL;
+ free_filestruct(openfile->fileage);
+
/* Renumber starting with the line after the original
* file_bot. */
- if (file_bot_save->next != NULL)
- renumber(file_bot_save->next);
+ renumber(file_bot_save->next);
}
/* Since the text has now been saved, remove it from the
@@ -369,7 +375,7 @@ void move_to_filestruct(filestruct **file_top, filestruct **file_bot,
openfile->fileage->data = mallocstrcpy(NULL, "");
openfile->filebot = openfile->fileage;
-#ifdef ENABLE_COLOR
+#ifndef DISABLE_COLOR
openfile->fileage->multidata = NULL;
#endif
@@ -382,7 +388,9 @@ void move_to_filestruct(filestruct **file_top, filestruct **file_bot,
if (mark_inside) {
openfile->mark_begin = openfile->current;
openfile->mark_begin_x = openfile->current_x;
- }
+ } else if (same_line)
+ /* Update the content of this partially cut line. */
+ openfile->mark_begin = openfile->current;
#endif
top_save = openfile->fileage;
@@ -406,10 +414,9 @@ void move_to_filestruct(filestruct **file_top, filestruct **file_bot,
new_magicline();
}
-/* Copy all the text from the filestruct beginning with file_top and
- * ending with file_bot to the current filestruct at the current cursor
- * position. */
-void copy_from_filestruct(filestruct *file_top, filestruct *file_bot)
+/* Copy all text from the given filestruct to the current filestruct
+ * at the current cursor position. */
+void copy_from_filestruct(filestruct *somebuffer)
{
filestruct *top_save;
size_t current_x_save = openfile->current_x;
@@ -418,7 +425,7 @@ void copy_from_filestruct(filestruct *file_top, filestruct *file_bot)
bool right_side_up = FALSE, single_line = FALSE;
#endif
- assert(file_top != NULL && file_bot != NULL);
+ assert(somebuffer != NULL);
#ifndef NANO_TINY
/* Keep track of whether the mark begins inside the partition and
@@ -441,9 +448,10 @@ void copy_from_filestruct(filestruct *file_top, filestruct *file_bot)
openfile->current_x, openfile->current, openfile->current_x);
edittop_inside = (openfile->edittop == openfile->fileage);
- /* Put the top and bottom of the filestruct at copies of file_top
- * and file_bot. */
- openfile->fileage = copy_filestruct(file_top);
+ /* Put the top and bottom of the current filestruct at the top and
+ * bottom of a copy of the passed buffer. */
+ free_filestruct(openfile->fileage);
+ openfile->fileage = copy_filestruct(somebuffer);
openfile->filebot = openfile->fileage;
while (openfile->filebot->next != NULL)
openfile->filebot = openfile->filebot->next;
@@ -465,7 +473,12 @@ void copy_from_filestruct(filestruct *file_top, filestruct *file_bot)
}
#ifndef NANO_TINY
else if (openfile->mark_set) {
- if (!right_side_up) {
+ if (right_side_up) {
+ if (single_line)
+ /* Get the new data, stuff was inserted on the mark line. */
+ openfile->mark_begin = openfile->fileage;
+ /* The x is okay, it did not move. */
+ } else {
if (single_line) {
openfile->mark_begin = openfile->current;
openfile->mark_begin_x -= current_x_save;
@@ -520,6 +533,7 @@ openfilestruct *make_new_opennode(void)
#ifndef NANO_TINY
newnode->current_stat = NULL;
newnode->last_action = OTHER;
+ newnode->lock_filename = NULL;
#endif
return newnode;
@@ -602,9 +616,13 @@ void finish(void)
/* Restore the old terminal settings. */
tcsetattr(0, TCSANOW, &oldterm);
-#if !defined(NANO_TINY) && defined(ENABLE_NANORC)
- if (!no_rcfiles && ISSET(HISTORYLOG))
+#ifndef DISABLE_HISTORIES
+ if (ISSET(HISTORYLOG))
save_history();
+ if (ISSET(POS_HISTORY)) {
+ update_poshistory(openfile->filename, openfile->current->lineno, xplustabs() + 1);
+ save_poshistory();
+ }
#endif
#ifdef DEBUG
@@ -642,7 +660,7 @@ void die(const char *msg, ...)
);
}
-#ifdef ENABLE_MULTIBUFFER
+#ifndef DISABLE_MULTIBUFFER
/* Save all of the other modified file buffers, if any. */
if (openfile != NULL) {
openfilestruct *tmp = openfile;
@@ -708,6 +726,8 @@ void die_save_file(const char *die_filename
int shush;
shush = chmod(retval, die_stat->st_mode);
shush = chown(retval, die_stat->st_uid, die_stat->st_gid);
+ if (shush)
+ ;
}
#endif
@@ -718,7 +738,7 @@ void die_save_file(const char *die_filename
void window_init(void)
{
/* If the screen height is too small, get out. */
- editwinrows = LINES - 5 + no_more_space() + no_help();
+ editwinrows = LINES - 5 + more_space() + no_help();
if (COLS < MIN_EDITOR_COLS || editwinrows < MIN_EDITOR_ROWS)
die(_("Window size is too small for nano...\n"));
@@ -739,10 +759,10 @@ void window_init(void)
delwin(bottomwin);
/* Set up the windows. */
- topwin = newwin(2 - no_more_space(), COLS, 0, 0);
- edit = newwin(editwinrows, COLS, 2 - no_more_space(), 0);
+ topwin = newwin(2 - more_space(), COLS, 0, 0);
+ edit = newwin(editwinrows, COLS, 2 - more_space(), 0);
bottomwin = newwin(3 - no_help(), COLS, editwinrows + (2 -
- no_more_space()), 0);
+ more_space()), 0);
/* Turn the keypad on for the windows, if necessary. */
if (!ISSET(REBIND_KEYPAD)) {
@@ -810,7 +830,7 @@ void print_opt_full(const char *shortflag
printf("\n");
}
-/* Explain how to properly use nano and its command line options. */
+/* Explain how to properly use nano and its command-line options. */
void usage(void)
{
printf(_("Usage: nano [OPTIONS] [[+LINE,COLUMN] FILE]...\n\n"));
@@ -821,8 +841,9 @@ void usage(void)
_("Option\t\tMeaning\n")
#endif
);
- print_opt("-h, -?", "--help", N_("Show this message"));
print_opt(_("+LINE,COLUMN"), "",
+ /* TRANSLATORS: The next forty or so strings are option descriptions
+ * for the --help output. Try to keep them at most 40 characters. */
N_("Start at line LINE, column COLUMN"));
#ifndef NANO_TINY
print_opt("-A", "--smarthome", N_("Enable smart home key"));
@@ -836,14 +857,18 @@ void usage(void)
print_opt("-E", "--tabstospaces",
N_("Convert typed tabs to spaces"));
#endif
-#ifdef ENABLE_MULTIBUFFER
+#ifndef DISABLE_MULTIBUFFER
print_opt("-F", "--multibuffer", N_("Enable multiple file buffers"));
#endif
-#ifdef ENABLE_NANORC
#ifndef NANO_TINY
+ print_opt("-G", "--locking",
+ N_("Use (vim-style) lock files"));
+#endif
+#ifndef DISABLE_HISTORIES
print_opt("-H", "--historylog",
N_("Log & read search/replace string history"));
#endif
+#ifndef DISABLE_NANORC
print_opt("-I", "--ignorercfiles",
N_("Don't look at nanorc files"));
#endif
@@ -856,6 +881,10 @@ void usage(void)
N_("Don't convert files from DOS/Mac format"));
#endif
print_opt("-O", "--morespace", N_("Use one more line for editing"));
+#ifndef DISABLE_HISTORIES
+ print_opt("-P", "--poslog",
+ N_("Log & read location of cursor position"));
+#endif
#ifndef DISABLE_JUSTIFY
print_opt(_("-Q <str>"), _("--quotestr=<str>"),
N_("Quoting string"));
@@ -876,13 +905,14 @@ void usage(void)
print_opt("-W", "--wordbounds",
N_("Detect word boundaries more accurately"));
#endif
-#ifdef ENABLE_COLOR
+#ifndef DISABLE_COLOR
print_opt(_("-Y <str>"), _("--syntax=<str>"),
N_("Syntax definition to use for coloring"));
#endif
print_opt("-c", "--const", N_("Constantly show cursor position"));
print_opt("-d", "--rebinddelete",
N_("Fix Backspace/Delete confusion problem"));
+ print_opt("-h", "--help", N_("Show this help text"));
#ifndef NANO_TINY
print_opt("-i", "--autoindent",
N_("Automatically indent new lines"));
@@ -893,17 +923,20 @@ void usage(void)
#ifndef DISABLE_MOUSE
print_opt("-m", "--mouse", N_("Enable the use of the mouse"));
#endif
+ print_opt("-n", "--noread", N_("Do not read the file (only write it)"));
#ifndef DISABLE_OPERATINGDIR
print_opt(_("-o <dir>"), _("--operatingdir=<dir>"),
N_("Set operating directory"));
#endif
print_opt("-p", "--preserve",
N_("Preserve XON (^Q) and XOFF (^S) keys"));
+#ifndef DISABLE_NANORC
print_opt("-q", "--quiet",
N_("Silently ignore startup issues like rc file errors"));
+#endif
#ifndef DISABLE_WRAPJUSTIFY
print_opt(_("-r <#cols>"), _("--fill=<#cols>"),
- N_("Set wrapping point at column #cols"));
+ N_("Set hard-wrapping point at column #cols"));
#endif
#ifndef DISABLE_SPELLER
print_opt(_("-s <prog>"), _("--speller=<prog>"),
@@ -911,23 +944,15 @@ void usage(void)
#endif
print_opt("-t", "--tempfile",
N_("Auto save on exit, don't prompt"));
-#ifndef NANO_TINY
- print_opt("-u", "--undo", N_("Allow generic undo [EXPERIMENTAL]"));
-#endif
-
print_opt("-v", "--view", N_("View mode (read-only)"));
#ifndef DISABLE_WRAPPING
- print_opt("-w", "--nowrap", N_("Don't wrap long lines"));
+ print_opt("-w", "--nowrap", N_("Don't hard-wrap long lines"));
#endif
print_opt("-x", "--nohelp", N_("Don't show the two help lines"));
print_opt("-z", "--suspend", N_("Enable suspension"));
+#ifndef NANO_TINY
print_opt("-$", "--softwrap", N_("Enable soft line wrapping"));
-
- /* This is a special case. */
- print_opt("-a, -b, -e,", "", NULL);
- print_opt("-f, -g, -j", "", N_("(ignored, for Pico compatibility)"));
-
- exit(0);
+#endif
}
/* Display the current version of nano, the date and time it was
@@ -935,28 +960,86 @@ void usage(void)
* it was compiled with. */
void version(void)
{
- printf(_(" GNU nano version %s (compiled %s, %s)\n"), VERSION,
- __TIME__, __DATE__);
- printf(" (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,\n");
- printf(" 2008, 2009 Free Software Foundation, Inc.\n");
+ printf(_(" GNU nano, version %s\n"), VERSION);
+ printf(" (C) 1999..2015 Free Software Foundation, Inc.\n");
printf(
_(" Email: nano@nano-editor.org Web: http://www.nano-editor.org/"));
printf(_("\n Compiled options:"));
+#ifdef NANO_TINY
+ printf(" --enable-tiny");
+#ifndef DISABLE_BROWSER
+ printf(" --enable-browser");
+#endif
+#ifndef DISABLE_COLOR
+ printf(" --enable-color");
+#endif
+#ifndef DISABLE_EXTRA
+ printf(" --enable-extra");
+#endif
+#ifndef DISABLE_HELP
+ printf(" --enable-help");
+#endif
+#ifndef DISABLE_HISTORIES
+ printf(" --enable-histories");
+#endif
+#ifndef DISABLE_JUSTIFY
+ printf(" --enable-justify");
+#endif
+#ifdef HAVE_LIBMAGIC
+ printf(" --enable-libmagic");
+#endif
+#ifndef DISABLE_MOUSE
+ printf(" --enable-mouse");
+#endif
+#ifndef DISABLE_NANORC
+ printf(" --enable-nanorc");
+#endif
+#ifndef DISABLE_MULTIBUFFER
+ printf(" --enable-multibuffer");
+#endif
+#ifndef DISABLE_OPERATINGDIR
+ printf(" --enable-operatingdir");
+#endif
+#ifndef DISABLE_SPELLER
+ printf(" --enable-speller");
+#endif
+#ifndef DISABLE_TABCOMP
+ printf(" --enable-tabcomp");
+#endif
+#ifndef DISABLE_WRAPPING
+ printf(" --enable-wrapping");
+#endif
+#else /* !NANO_TINY */
#ifdef DISABLE_BROWSER
printf(" --disable-browser");
#endif
+#ifdef DISABLE_COLOR
+ printf(" --disable-color");
+#endif
+#ifdef DISABLE_EXTRA
+ printf(" --disable-extra");
+#endif
#ifdef DISABLE_HELP
printf(" --disable-help");
#endif
+#ifdef DISABLE_HISTORIES
+ printf(" --disable-histories");
+#endif
#ifdef DISABLE_JUSTIFY
printf(" --disable-justify");
#endif
+#ifndef HAVE_LIBMAGIC
+ printf(" --disable-libmagic");
+#endif
#ifdef DISABLE_MOUSE
printf(" --disable-mouse");
#endif
-#ifndef ENABLE_NLS
- printf(" --disable-nls");
+#ifdef DISABLE_MULTIBUFFER
+ printf(" --disable-multibuffer");
+#endif
+#ifdef DISABLE_NANORC
+ printf(" --disable-nanorc");
#endif
#ifdef DISABLE_OPERATINGDIR
printf(" --disable-operatingdir");
@@ -970,29 +1053,21 @@ void version(void)
#ifdef DISABLE_WRAPPING
printf(" --disable-wrapping");
#endif
+#endif /* !NANO_TINY */
+
#ifdef DISABLE_ROOTWRAPPING
printf(" --disable-wrapping-as-root");
#endif
-#ifdef ENABLE_COLOR
- printf(" --enable-color");
-#endif
#ifdef DEBUG
printf(" --enable-debug");
#endif
-#ifdef NANO_EXTRA
- printf(" --enable-extra");
-#endif
-#ifdef ENABLE_MULTIBUFFER
- printf(" --enable-multibuffer");
-#endif
-#ifdef ENABLE_NANORC
- printf(" --enable-nanorc");
-#endif
-#ifdef NANO_TINY
- printf(" --enable-tiny");
+#ifndef ENABLE_NLS
+ printf(" --disable-nls");
#endif
#ifdef ENABLE_UTF8
printf(" --enable-utf8");
+#else
+ printf(" --disable-utf8");
#endif
#ifdef USE_SLANG
printf(" --with-slang");
@@ -1001,16 +1076,15 @@ void version(void)
}
/* Return 1 if the MORE_SPACE flag is set, and 0 otherwise. This is
- * used to calculate the relative screen position while taking this flag
- * into account, since it adds one line to the edit window. */
-int no_more_space(void)
+ * used to calculate the sizes and Y coordinates of the subwindows. */
+int more_space(void)
{
return ISSET(MORE_SPACE) ? 1 : 0;
}
/* Return 2 if the NO_HELP flag is set, and 0 otherwise. This is used
- * to calculate the relative screen position while taking this flag into
- * account, since it removes two lines from the edit window. */
+ * to calculate the sizes and Y coordinates of the subwindows, because
+ * having NO_HELP adds two lines to the edit window. */
int no_help(void)
{
return ISSET(NO_HELP) ? 2 : 0;
@@ -1024,9 +1098,10 @@ void nano_disabled_msg(void)
/* If the current file buffer has been modified, and the TEMP_FILE flag
* isn't set, ask whether or not to save the file buffer. If the
- * TEMP_FILE flag is set, save it unconditionally. Then, if more than
- * one file buffer is open, close the current file buffer and switch to
- * the next one. If only one file buffer is open, exit from nano. */
+ * TEMP_FILE flag is set and the current file has a name, save it
+ * unconditionally. Then, if more than one file buffer is open, close
+ * the current file buffer and switch to the next one. If only one file
+ * buffer is open, exit from nano. */
void do_exit(void)
{
int i;
@@ -1035,13 +1110,31 @@ void do_exit(void)
* save. */
if (!openfile->modified)
i = 0;
- /* If the TEMP_FILE flag is set, pretend the user chose to save. */
- else if (ISSET(TEMP_FILE))
+ /* If the TEMP_FILE flag is set and the current file has a name,
+ * pretend the user chose to save. */
+ else if (openfile->filename[0] != '\0' && ISSET(TEMP_FILE))
i = 1;
/* Otherwise, ask the user whether or not to save. */
- else
+ else {
+ /* If the TEMP_FILE flag is set, and the current file doesn't
+ * have a name, handle it the same way Pico does. */
+ if (ISSET(TEMP_FILE)) {
+ curs_set(0);
+
+ /* Warn that the current file has no name. */
+ statusbar(_("No file name"));
+ beep();
+
+ /* Ensure that we see the warning. */
+ doupdate();
+ napms(2000);
+
+ curs_set(1);
+ }
+
i = do_yesno_prompt(FALSE,
_("Save modified buffer (ANSWERING \"No\" WILL DESTROY CHANGES) ? "));
+ }
#ifdef DEBUG
dump_filestruct(openfile->fileage);
@@ -1050,62 +1143,68 @@ void do_exit(void)
/* If the user chose not to save, or if the user chose to save and
* the save succeeded, we're ready to exit. */
if (i == 0 || (i == 1 && do_writeout(TRUE))) {
-#ifdef ENABLE_MULTIBUFFER
+
+#ifndef NANO_TINY
+ if (ISSET(LOCKING) && openfile->lock_filename)
+ delete_lockfile(openfile->lock_filename);
+#endif
+
+#ifndef DISABLE_MULTIBUFFER
/* Exit only if there are no more open file buffers. */
- if (!close_buffer())
+ if (!close_buffer(FALSE))
#endif
finish();
/* If the user canceled, we go on. */
} else if (i != 1)
statusbar(_("Cancelled"));
- shortcut_init(FALSE);
display_main_list();
}
-
+/* Another placeholder for function mapping. */
+void do_cancel(void)
+{
+ ;
+}
static struct sigaction pager_oldaction, pager_newaction; /* Original and temporary handlers for SIGINT. */
static bool pager_sig_failed = FALSE; /* Did sigaction() fail without changing the signal handlers? */
static bool pager_input_aborted = FALSE; /* Did someone invoke the pager and abort it via ^C? */
-
/* Things which need to be run regardless of whether
- we finished the stdin pipe correctly or not */
+ * we finished the stdin pipe correctly or not. */
void finish_stdin_pager(void)
{
FILE *f;
int ttystdin;
- /* Read whatever we did get from stdin */
+ /* Read whatever we did get from stdin. */
f = fopen("/dev/stdin", "rb");
- if (f == NULL)
- nperror("fopen");
+ if (f == NULL)
+ nperror("fopen");
read_file(f, 0, "stdin", TRUE, FALSE);
ttystdin = open("/dev/tty", O_RDONLY);
if (!ttystdin)
- die(_("Couldn't reopen stdin from keyboard, sorry\n"));
+ die(_("Couldn't reopen stdin from keyboard, sorry\n"));
dup2(ttystdin,0);
close(ttystdin);
if (!pager_input_aborted)
tcgetattr(0, &oldterm);
if (!pager_sig_failed && sigaction(SIGINT, &pager_oldaction, NULL) == -1)
- nperror("sigaction");
+ nperror("sigaction");
terminal_init();
doupdate();
}
-
-/* Cancel reading from stdin like a pager */
+/* Cancel reading from stdin like a pager. */
RETSIGTYPE cancel_stdin_pager(int signal)
{
- /* Currently do nothing, just handle the intr silently */
pager_input_aborted = TRUE;
}
-/* Let nano read stdin for the first file at least */
+/* Let nano read stdin for the first file at least. */
void stdin_pager(void)
{
endwin();
@@ -1113,13 +1212,13 @@ void stdin_pager(void)
tcsetattr(0, TCSANOW, &oldterm);
fprintf(stderr, _("Reading from stdin, ^C to abort\n"));
- /* Set things up so that Ctrl-C will cancel the new process. */
- /* Enable interpretation of the special control keys so that we get
- * SIGINT when Ctrl-C is pressed. */
+ /* Enable interpretation of the special control keys so that
+ * we get SIGINT when Ctrl-C is pressed. */
#ifndef NANO_TINY
enable_signals();
#endif
+ /* Set things up so that SIGINT will cancel the new process. */
if (sigaction(SIGINT, NULL, &pager_newaction) == -1) {
pager_sig_failed = TRUE;
nperror("sigaction");
@@ -1135,8 +1234,6 @@ void stdin_pager(void)
finish_stdin_pager();
}
-
-
/* Initialize the signal handlers. */
void signal_init(void)
{
@@ -1274,7 +1371,7 @@ RETSIGTYPE handle_sigwinch(int signal)
* otherwise. However, COLS and LINES are curses global variables,
* and in some cases curses has already updated them. But not in
* all cases. Argh. */
-#ifdef REDEFINIG_MACROS_OK
+#ifdef REDEFINING_MACROS_OK
COLS = win.ws_col;
LINES = win.ws_row;
#endif
@@ -1332,11 +1429,11 @@ void allow_pending_sigwinch(bool allow)
#endif /* !NANO_TINY */
#ifndef NANO_TINY
-/* Handle the global toggle specified in which. */
+/* Handle the global toggle specified in flag. */
void do_toggle(int flag)
{
bool enabled;
- char *desc;
+ const char *desc;
TOGGLE(flag);
@@ -1354,40 +1451,43 @@ void do_toggle(int flag)
case SUSPEND:
signal_init();
break;
-#ifdef ENABLE_NANORC
+#ifndef DISABLE_NANORC
case WHITESPACE_DISPLAY:
titlebar(NULL);
edit_refresh();
break;
#endif
-#ifdef ENABLE_COLOR
+#ifndef DISABLE_COLOR
case NO_COLOR_SYNTAX:
- edit_refresh();
- break;
#endif
case SOFTWRAP:
- total_refresh();
+ edit_refresh();
break;
}
enabled = ISSET(flag);
- if (flag == NO_HELP
+ if (flag == NO_HELP
#ifndef DISABLE_WRAPPING
|| flag == NO_WRAP
#endif
-#ifdef ENABLE_COLOR
+#ifndef DISABLE_COLOR
|| flag == NO_COLOR_SYNTAX
#endif
)
enabled = !enabled;
- desc = _(flagtostr(flag));
- statusbar("%s %s", desc, enabled ? _("enabled") :
- _("disabled"));
+ desc = (char *) _(flagtostr(flag));
+ statusbar("%s %s", desc, enabled ? _("enabled") : _("disabled"));
}
#endif /* !NANO_TINY */
+/* Bleh. */
+void do_toggle_void(void)
+{
+ ;
+}
+
/* Disable extended input and output processing in our terminal
* settings. */
void disable_extended_io(void)
@@ -1489,16 +1589,10 @@ void terminal_init(void)
}
/* Read in a character, interpret it as a shortcut or toggle if
- * necessary, and return it. Set meta_key to TRUE if the character is a
- * meta sequence, set func_key to TRUE if the character is a function
- * key, set s_or_t to TRUE if the character is a shortcut or toggle
- * key, set ran_func to TRUE if we ran a function associated with a
- * shortcut key, and set finished to TRUE if we're done after running
- * or trying to run a function associated with a shortcut key. If
- * allow_funcs is FALSE, don't actually run any functions associated
+ * necessary, and return it.
+ * If allow_funcs is FALSE, don't actually run any functions associated
* with shortcut keys. */
-int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
- *ran_func, bool *finished, bool allow_funcs)
+int do_input(bool allow_funcs)
{
int input;
/* The character we read in. */
@@ -1506,36 +1600,29 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
/* The input buffer. */
static size_t kbinput_len = 0;
/* The length of the input buffer. */
- bool cut_copy = FALSE;
- /* Are we cutting or copying text? */
+ bool preserve = FALSE;
+ /* Preserve the contents of the cutbuffer? */
const sc *s;
bool have_shortcut;
- *s_or_t = FALSE;
- *ran_func = FALSE;
- *finished = FALSE;
-
/* Read in a character. */
- input = get_kbinput(edit, meta_key, func_key);
+ input = get_kbinput(edit);
#ifndef DISABLE_MOUSE
- if (allow_funcs) {
- /* If we got a mouse click and it was on a shortcut, read in the
- * shortcut character. */
- if (*func_key && input == KEY_MOUSE) {
- if (do_mouse() == 1)
- input = get_kbinput(edit, meta_key, func_key);
- else {
- *meta_key = FALSE;
- *func_key = FALSE;
- input = ERR;
- }
- }
+ if (func_key && input == KEY_MOUSE) {
+ /* We received a mouse click. */
+ if (do_mouse() == 1)
+ /* The click was on a shortcut -- read in the character
+ * that it was converted into. */
+ input = get_kbinput(edit);
+ else
+ /* The click was invalid or has been handled -- get out. */
+ return ERR;
}
#endif
/* Check for a shortcut in the main list. */
- s = get_shortcut(MMAIN, &input, meta_key, func_key);
+ s = get_shortcut(&input);
/* If we got a shortcut from the main list, or a "universal"
* edit window shortcut, set have_shortcut to TRUE. */
@@ -1544,11 +1631,11 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
/* If we got a non-high-bit control key, a meta key sequence, or a
* function key, and it's not a shortcut or toggle, throw it out. */
if (!have_shortcut) {
- if (is_ascii_cntrl_char(input) || *meta_key || *func_key) {
+ if (is_ascii_cntrl_char(input) || meta_key || func_key) {
statusbar(_("Unknown Command"));
beep();
- *meta_key = FALSE;
- *func_key = FALSE;
+ meta_key = FALSE;
+ func_key = FALSE;
input = ERR;
}
}
@@ -1575,13 +1662,11 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
* output all the characters in the input buffer if it isn't
* empty. Note that it should be empty if we're in view
* mode. */
- if (have_shortcut || get_key_buffer_len() == 0) {
+ if (have_shortcut || get_key_buffer_len() == 0) {
#ifndef DISABLE_WRAPPING
/* If we got a shortcut or toggle, and it's not the shortcut
- * for verbatim input, turn off prepending of wrapped
- * text. */
- if (have_shortcut && (!have_shortcut || s == NULL || s->scfunc !=
- DO_VERBATIM_INPUT))
+ * for verbatim input, turn off prepending of wrapped text. */
+ if (have_shortcut && s->scfunc != do_verbatim_input)
wrap_reset();
#endif
@@ -1607,63 +1692,51 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
}
if (have_shortcut) {
- switch (input) {
- /* Handle the normal edit window shortcuts, setting
- * ran_func to TRUE if we try to run their associated
- * functions and setting finished to TRUE to indicate
- * that we're done after running or trying to run their
- * associated functions. */
- default:
- /* If the function associated with this shortcut is
- * cutting or copying text, indicate this. */
- if (s->scfunc == DO_CUT_TEXT_VOID
-#ifndef NANO_TINY
- || s->scfunc == DO_COPY_TEXT || s->scfunc ==
- DO_CUT_TILL_END
-#endif
- )
- cut_copy = TRUE;
-
- if (s->scfunc != 0) {
- const subnfunc *f = sctofunc((sc *) s);
- *ran_func = TRUE;
- if (ISSET(VIEW_MODE) && f && !f->viewok)
- print_view_warning();
- else {
+ /* If the function associated with this shortcut is
+ * cutting or copying text, remember this. */
+ if (s->scfunc == do_cut_text_void
#ifndef NANO_TINY
- if (s->scfunc == DO_TOGGLE)
- do_toggle(s->toggle);
- else {
-#else
- {
+ || s->scfunc == do_copy_text || s->scfunc == do_cut_till_eof
#endif
- iso_me_harder_funcmap(s->scfunc);
-#ifdef ENABLE_COLOR
- if (f && !f->viewok && openfile->syntax != NULL
- && openfile->syntax->nmultis > 0) {
- reset_multis(openfile->current, FALSE);
- }
-#endif
- if (edit_refresh_needed) {
+ )
+ preserve = TRUE;
+
+ if (s->scfunc != 0) {
+ const subnfunc *f = sctofunc((sc *) s);
+ if (ISSET(VIEW_MODE) && f && !f->viewok)
+ print_view_warning();
+ else {
+#ifndef NANO_TINY
+ if (s->scfunc == do_toggle_void) {
+ do_toggle(s->toggle);
+ if (s->toggle != CUT_TO_END)
+ preserve = TRUE;
+ } else
+#endif
+ {
+ /* Execute the function of the shortcut. */
+ s->scfunc();
+#ifndef DISABLE_COLOR
+ if (f && !f->viewok && openfile->syntax != NULL
+ && openfile->syntax->nmultis > 0)
+ reset_multis(openfile->current, FALSE);
+#endif
+ if (edit_refresh_needed) {
#ifdef DEBUG
- fprintf(stderr, "running edit_refresh() as edit_refresh_needed is true\n");
+ fprintf(stderr, "running edit_refresh() as edit_refresh_needed is true\n");
#endif
- edit_refresh();
- edit_refresh_needed = FALSE;
- }
-
- }
+ edit_refresh();
+ edit_refresh_needed = FALSE;
}
}
- *finished = TRUE;
- break;
+ }
}
}
}
- /* If we aren't cutting or copying text, blow away the text in the
- * cutbuffer. */
- if (!cut_copy)
+ /* If we aren't cutting or copying text, and the key wasn't a toggle,
+ * blow away the text in the cutbuffer upon the next cutting action. */
+ if (!preserve)
cutbuffer_reset();
return input;
@@ -1687,32 +1760,39 @@ int do_mouse(void)
int mouse_x, mouse_y;
int retval = get_mouseinput(&mouse_x, &mouse_y, TRUE);
+ if (retval != 0)
+ /* The click is wrong or already handled. */
+ return retval;
+
/* We can click on the edit window to move the cursor. */
- if (retval == 0 && wmouse_trafo(edit, &mouse_y, &mouse_x, FALSE)) {
+ if (wmouse_trafo(edit, &mouse_y, &mouse_x, FALSE)) {
bool sameline;
/* Did they click on the line with the cursor? If they
* clicked on the cursor, we set the mark. */
filestruct *current_save = openfile->current;
+#ifndef NANO_TINY
size_t current_x_save = openfile->current_x;
+#endif
size_t pww_save = openfile->placewewant;
sameline = (mouse_y == openfile->current_y);
#ifdef DEBUG
- fprintf(stderr, "mouse_y = %d, current_y = %d\n", mouse_y, openfile->current_y);
+ fprintf(stderr, "mouse_y = %d, current_y = %ld\n", mouse_y, (long)openfile->current_y);
#endif
- if (ISSET(SOFTWRAP)) {
- int i = 0;
+#ifndef NANO_TINY
+ if (ISSET(SOFTWRAP)) {
+ size_t i = 0;
for (openfile->current = openfile->edittop;
openfile->current->next && i < mouse_y;
openfile->current = openfile->current->next, i++) {
openfile->current_y = i;
i += strlenpt(openfile->current->data) / COLS;
}
-
#ifdef DEBUG
- fprintf(stderr, "do_mouse(): moving to current_y = %d, i %d\n", openfile->current_y, i);
+ fprintf(stderr, "do_mouse(): moving to current_y = %ld, index i = %lu\n",
+ (long)openfile->current_y, (unsigned long)i);
fprintf(stderr, " openfile->current->data = \"%s\"\n", openfile->current->data);
#endif
@@ -1720,18 +1800,19 @@ int do_mouse(void)
openfile->current = openfile->current->prev;
openfile->current_x = actual_x(openfile->current->data, mouse_x + (mouse_y - openfile->current_y) * COLS);
#ifdef DEBUG
- fprintf(stderr, "do_mouse(): i > mouse_y, mouse_x = %d, current_x to = %d\n", mouse_x, openfile->current_x);
+ fprintf(stderr, "do_mouse(): i > mouse_y, mouse_x = %d, current_x to = %lu\n",
+ mouse_x, (unsigned long)openfile->current_x);
#endif
} else {
openfile->current_x = actual_x(openfile->current->data, mouse_x);
#ifdef DEBUG
- fprintf(stderr, "do_mouse(): i <= mouse_y, mouse_x = %d, setting current_x to = %d\n", mouse_x, openfile->current_x);
+ fprintf(stderr, "do_mouse(): i <= mouse_y, mouse_x = %d, setting current_x to = %lu\n",
+ mouse_x, (unsigned long)openfile->current_x);
#endif
}
-
- openfile->placewewant = xplustabs();
-
- } else {
+ } else
+#endif /* NANO_TINY */
+ {
/* Move to where the click occurred. */
for (; openfile->current_y < mouse_y && openfile->current !=
openfile->filebot; openfile->current_y++)
@@ -1742,38 +1823,42 @@ int do_mouse(void)
openfile->current_x = actual_x(openfile->current->data,
get_page_start(xplustabs()) + mouse_x);
-
- openfile->placewewant = xplustabs();
}
+ openfile->placewewant = xplustabs();
+
#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. */
if (sameline && openfile->current_x == current_x_save)
do_mark();
+ else
#endif
+ /* The cursor moved; clean the cutbuffer on the next cut. */
+ cutbuffer_reset();
edit_redraw(current_save, pww_save);
}
- return retval;
+ /* No more handling is needed. */
+ return 2;
}
#endif /* !DISABLE_MOUSE */
-#ifdef ENABLE_COLOR
+#ifndef DISABLE_COLOR
void alloc_multidata_if_needed(filestruct *fileptr)
{
if (!fileptr->multidata)
- fileptr->multidata = (short *) nmalloc(openfile->syntax->nmultis * sizeof(short));
+ fileptr->multidata = (short *)nmalloc(openfile->syntax->nmultis * sizeof(short));
}
-/* Precalculate the multi-line start and end regex info so we can speed up
- rendering (with any hope at all...) */
+/* Precalculate the multi-line start and end regex info so we can
+ * speed up rendering (with any hope at all...). */
void precalc_multicolorinfo(void)
{
#ifdef DEBUG
- fprintf(stderr, "entering precalc_multicolorinfo()\n");
+ fprintf(stderr, "Entering precalculation of multiline color info\n");
#endif
if (openfile->colorstrings != NULL && !ISSET(NO_COLOR_SYNTAX)) {
const colortype *tmpcolor = openfile->colorstrings;
@@ -1781,30 +1866,26 @@ void precalc_multicolorinfo(void)
filestruct *fileptr, *endptr;
time_t last_check = time(NULL), cur_check = 0;
- /* Let us get keypresses to see if the user is trying to
- start editing. We may want to throw up a statusbar
- message before starting this later if it takes
- too long to do this routine. For now silently
- abort if they hit a key */
- nodelay(edit, FALSE);
+ /* Let us get keypresses to see if the user is trying to start
+ * editing. Later we may want to throw up a statusbar message
+ * before starting this if it takes too long to do this routine.
+ * For now silently abort if they hit a key. */
+ nodelay(edit, TRUE);
for (; tmpcolor != NULL; tmpcolor = tmpcolor->next) {
- /* If it's not a multi-line regex, amscray */
+ /* If it's not a multi-line regex, amscray. */
if (tmpcolor->end == NULL)
continue;
#ifdef DEBUG
- fprintf(stderr, "working on color id %d\n", tmpcolor->id);
+ fprintf(stderr, "Starting work on color id %d\n", tmpcolor->id);
#endif
-
for (fileptr = openfile->fileage; fileptr != NULL; fileptr = fileptr->next) {
int startx = 0;
int nostart = 0;
-
-
#ifdef DEBUG
- fprintf(stderr, "working on lineno %lu\n", (unsigned long) fileptr->lineno);
+ fprintf(stderr, "working on lineno %ld... ", (long)fileptr->lineno);
#endif
alloc_multidata_if_needed(fileptr);
@@ -1812,84 +1893,81 @@ void precalc_multicolorinfo(void)
if ((cur_check = time(NULL)) - last_check > 1) {
last_check = cur_check;
if (wgetch(edit) != ERR)
- goto precalc_cleanup;
+ goto precalc_cleanup;
}
- while ((nostart = regexec(tmpcolor->start, &fileptr->data[startx], 1, &startmatch, 0)) == 0) {
- /* Look for end and start marking how many lines are encompassed
- whcih should speed up rendering later */
+ while ((nostart = regexec(tmpcolor->start, &fileptr->data[startx], 1, &startmatch,
+ (startx == 0) ? 0 : REG_NOTBOL)) == 0) {
+ /* Look for an end, and start marking how many lines are
+ * encompassed, which should speed up rendering later. */
startx += startmatch.rm_eo;
#ifdef DEBUG
- fprintf(stderr, "match found at pos %d...", startx);
+ fprintf(stderr, "start found at pos %lu... ", (unsigned long)startx);
#endif
- /* Look on this line first for end */
- if (regexec(tmpcolor->end, &fileptr->data[startx], 1, &endmatch, 0) == 0) {
+ /* Look first on this line for an end. */
+ if (regexec(tmpcolor->end, &fileptr->data[startx], 1, &endmatch,
+ (startx == 0) ? 0 : REG_NOTBOL) == 0) {
startx += endmatch.rm_eo;
fileptr->multidata[tmpcolor->id] |= CSTARTENDHERE;
#ifdef DEBUG
- fprintf(stderr, "end found on this line\n");
+ fprintf(stderr, "end found on this line\n");
#endif
continue;
}
- /* Nice, we didn't find the end regex on this line. Let's start looking for it */
+ /* Nice, we didn't find the end regex on this line. Let's start looking for it. */
for (endptr = fileptr->next; endptr != NULL; endptr = endptr->next) {
-
#ifdef DEBUG
- fprintf(stderr, "advancing to line %lu to find end...\n", (unsigned long) endptr->lineno);
+ fprintf(stderr, "\nadvancing to line %ld to find end... ", (long)endptr->lineno);
#endif
- /* Check for keyboard input again */
+ /* Check for keyboard input, again. */
if ((cur_check = time(NULL)) - last_check > 1) {
last_check = cur_check;
if (wgetch(edit) != ERR)
- goto precalc_cleanup;
+ goto precalc_cleanup;
}
if (regexec(tmpcolor->end, endptr->data, 1, &endmatch, 0) == 0)
- break;
+ break;
}
if (endptr == NULL) {
#ifdef DEBUG
- fprintf(stderr, "no end found, breaking out\n");
+ fprintf(stderr, "no end found, breaking out\n");
#endif
break;
}
-
#ifdef DEBUG
fprintf(stderr, "end found\n");
#endif
-
- /* We found it, we found it, la la la la la. Mark all the
- lines in between and the ends properly */
+ /* We found it, we found it, la la la la la. Mark all
+ * the lines in between and the end properly. */
fileptr->multidata[tmpcolor->id] |= CENDAFTER;
#ifdef DEBUG
- fprintf(stderr, "marking line %lu as CENDAFTER\n", (unsigned long) fileptr->lineno);
+ fprintf(stderr, "marking line %ld as CENDAFTER\n", (long)fileptr->lineno);
#endif
for (fileptr = fileptr->next; fileptr != endptr; fileptr = fileptr->next) {
alloc_multidata_if_needed(fileptr);
fileptr->multidata[tmpcolor->id] = CWHOLELINE;
#ifdef DEBUG
- fprintf(stderr, "marking intermediary line %lu as CWHOLELINE\n", (unsigned long) fileptr->lineno);
+ fprintf(stderr, "marking intermediary line %ld as CWHOLELINE\n", (long)fileptr->lineno);
#endif
}
alloc_multidata_if_needed(endptr);
+ fileptr->multidata[tmpcolor->id] |= CBEGINBEFORE;
#ifdef DEBUG
- fprintf(stderr, "marking line %lu as BEGINBEFORE\n", (unsigned long) fileptr->lineno);
+ fprintf(stderr, "marking line %ld as CBEGINBEFORE\n", (long)fileptr->lineno);
#endif
- endptr->multidata[tmpcolor->id] |= CBEGINBEFORE;
- /* We should be able to skip all the way to the line of the match.
- This may introduce more bugs but it's the Right Thing to do */
- fileptr = endptr;
+ /* Skip to the end point of the match. */
startx = endmatch.rm_eo;
#ifdef DEBUG
- fprintf(stderr, "jumping to line %lu pos %d to continue\n", (unsigned long) endptr->lineno, startx);
+ fprintf(stderr, "jumping to line %ld pos %lu to continue\n", (long)fileptr->lineno, (unsigned long)startx);
#endif
}
if (nostart && startx == 0) {
#ifdef DEBUG
- fprintf(stderr, "no start found on line %lu, continuing\n", (unsigned long) fileptr->lineno);
+ fprintf(stderr, "no match\n");
#endif
fileptr->multidata[tmpcolor->id] = CNONE;
continue;
@@ -1900,22 +1978,29 @@ void precalc_multicolorinfo(void)
precalc_cleanup:
nodelay(edit, FALSE);
}
-#endif /* ENABLE_COLOR */
+#endif /* !DISABLE_COLOR */
/* The user typed output_len multibyte characters. Add them to the edit
* buffer, filtering out all ASCII control characters if allow_cntrls is
* TRUE. */
void do_output(char *output, size_t output_len, bool allow_cntrls)
{
- size_t current_len, orig_lenpt, i = 0;
+ size_t current_len, i = 0;
+#ifndef NANO_TINY
+ size_t orig_lenpt = 0;
+#endif
+
char *char_buf = charalloc(mb_cur_max());
int char_buf_len;
assert(openfile->current != NULL && openfile->current->data != NULL);
current_len = strlen(openfile->current->data);
+
+#ifndef NANO_TINY
if (ISSET(SOFTWRAP))
orig_lenpt = strlenpt(openfile->current->data);
+#endif
while (i < output_len) {
/* If allow_cntrls is TRUE, convert nulls and newlines
@@ -1966,7 +2051,7 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
set_modified();
#ifndef NANO_TINY
- update_undo(ADD);
+ add_undo(ADD);
/* Note that current_x has not yet been incremented. */
if (openfile->mark_set && openfile->current ==
@@ -1977,14 +2062,18 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
openfile->current_x += char_buf_len;
+#ifndef NANO_TINY
+ update_undo(ADD);
+#endif
+
#ifndef DISABLE_WRAPPING
/* If we're wrapping text, we need to call edit_refresh(). */
if (!ISSET(NO_WRAP))
- if (do_wrap(openfile->current, FALSE))
+ if (do_wrap(openfile->current))
edit_refresh_needed = TRUE;
#endif
-#ifdef ENABLE_COLOR
+#ifndef DISABLE_COLOR
/* If color syntaxes are available and turned on, we need to
* call edit_refresh(). */
if (openfile->colorstrings != NULL && !ISSET(NO_COLOR_SYNTAX))
@@ -1992,18 +2081,19 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
#endif
}
- /* Well we might also need a full refresh if we've changed the
- line length to be a new multiple of COLS */
+#ifndef NANO_TINY
+ /* Well, we might also need a full refresh if we've changed the
+ * line length to be a new multiple of COLS. */
if (ISSET(SOFTWRAP) && edit_refresh_needed == FALSE)
- if (strlenpt(openfile->current->data) / COLS != orig_lenpt / COLS)
+ if (strlenpt(openfile->current->data) / COLS != orig_lenpt / COLS)
edit_refresh_needed = TRUE;
+#endif
free(char_buf);
openfile->placewewant = xplustabs();
-
-#ifdef ENABLE_COLOR
+#ifndef DISABLE_COLOR
reset_multis(openfile->current, FALSE);
#endif
if (edit_refresh_needed == TRUE) {
@@ -2016,15 +2106,13 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
int main(int argc, char **argv)
{
int optchr;
- ssize_t startline = 1;
- /* Line to try and start at. */
- ssize_t startcol = 1;
- /* Column to try and start at. */
+ ssize_t startline = 0, startcol = 0;
+ /* Target line and column when specified on the command line. */
#ifndef DISABLE_WRAPJUSTIFY
bool fill_used = FALSE;
/* Was the fill option used? */
#endif
-#ifdef ENABLE_MULTIBUFFER
+#ifndef DISABLE_MULTIBUFFER
bool old_multibuffer;
/* The old value of the multibuffer option, restored after we
* load all files on the command line. */
@@ -2033,10 +2121,10 @@ int main(int argc, char **argv)
const struct option long_options[] = {
{"help", 0, NULL, 'h'},
{"boldtext", 0, NULL, 'D'},
-#ifdef ENABLE_MULTIBUFFER
+#ifndef DISABLE_MULTIBUFFER
{"multibuffer", 0, NULL, 'F'},
#endif
-#ifdef ENABLE_NANORC
+#ifndef DISABLE_NANORC
{"ignorercfiles", 0, NULL, 'I'},
#endif
{"rebindkeypad", 0, NULL, 'K'},
@@ -2048,7 +2136,7 @@ int main(int argc, char **argv)
{"restricted", 0, NULL, 'R'},
{"tabsize", 1, NULL, 'T'},
{"version", 0, NULL, 'V'},
-#ifdef ENABLE_COLOR
+#ifndef DISABLE_COLOR
{"syntax", 1, NULL, 'Y'},
#endif
{"const", 0, NULL, 'c'},
@@ -2057,6 +2145,7 @@ int main(int argc, char **argv)
#ifndef DISABLE_MOUSE
{"mouse", 0, NULL, 'm'},
#endif
+ {"noread", 0, NULL, 'n'},
#ifndef DISABLE_OPERATINGDIR
{"operatingdir", 1, NULL, 'o'},
#endif
@@ -2080,8 +2169,10 @@ int main(int argc, char **argv)
{"backup", 0, NULL, 'B'},
{"backupdir", 1, NULL, 'C'},
{"tabstospaces", 0, NULL, 'E'},
+ {"locking", 0, NULL, 'G'},
{"historylog", 0, NULL, 'H'},
{"noconvert", 0, NULL, 'N'},
+ {"poslog", 0, NULL, 'P'},
{"smooth", 0, NULL, 'S'},
{"quickblank", 0, NULL, 'U'},
{"undo", 0, NULL, 'u'},
@@ -2117,7 +2208,7 @@ int main(int argc, char **argv)
textdomain(PACKAGE);
#endif
-#if !defined(ENABLE_NANORC) && defined(DISABLE_ROOTWRAPPING)
+#if defined(DISABLE_NANORC) && defined(DISABLE_ROOTWRAPPING)
/* If we don't have rcfile support, --disable-wrapping-as-root is
* used, and we're root, turn wrapping off. */
if (geteuid() == NANO_ROOT_UID)
@@ -2127,11 +2218,11 @@ int main(int argc, char **argv)
while ((optchr =
#ifdef HAVE_GETOPT_LONG
getopt_long(argc, argv,
- "h?ABC:DEFHIKLNOQ:RST:UVWY:abcdefgijklmo:pqr:s:tuvwxz$",
+ "ABC:DEFGHIKLNOPQ:RST:UVWY:abcdefghijklmno:pqr:s:tvwxz$",
long_options, NULL)
#else
getopt(argc, argv,
- "h?ABC:DEFHIKLNOQ:RST:UVWY:abcdefgijklmo:pqr:s:tuvwxz$")
+ "ABC:DEFGHIKLNOPQ:RST:UVWY:abcdefghijklmno:pqr:s:tvwxz$")
#endif
) != -1) {
switch (optchr) {
@@ -2162,17 +2253,22 @@ int main(int argc, char **argv)
SET(TABS_TO_SPACES);
break;
#endif
-#ifdef ENABLE_MULTIBUFFER
+#ifndef DISABLE_MULTIBUFFER
case 'F':
SET(MULTIBUFFER);
break;
#endif
-#ifdef ENABLE_NANORC
#ifndef NANO_TINY
+ case 'G':
+ SET(LOCKING);
+ break;
+#endif
+#ifndef DISABLE_HISTORIES
case 'H':
SET(HISTORYLOG);
break;
#endif
+#ifndef DISABLE_NANORC
case 'I':
no_rcfiles = TRUE;
break;
@@ -2191,6 +2287,11 @@ int main(int argc, char **argv)
case 'O':
SET(MORE_SPACE);
break;
+#ifndef DISABLE_HISTORIES
+ case 'P':
+ SET(POS_HISTORY);
+ break;
+#endif
#ifndef DISABLE_JUSTIFY
case 'Q':
quotestr = mallocstrcpy(quotestr, optarg);
@@ -2224,7 +2325,7 @@ int main(int argc, char **argv)
SET(WORD_BOUNDS);
break;
#endif
-#ifdef ENABLE_COLOR
+#ifndef DISABLE_COLOR
case 'Y':
syntaxstr = mallocstrcpy(syntaxstr, optarg);
break;
@@ -2251,6 +2352,9 @@ int main(int argc, char **argv)
SET(USE_MOUSE);
break;
#endif
+ case 'n':
+ SET(NOREAD_MODE);
+ break;
#ifndef DISABLE_OPERATINGDIR
case 'o':
operating_dir = mallocstrcpy(operating_dir, optarg);
@@ -2259,9 +2363,11 @@ int main(int argc, char **argv)
case 'p':
SET(PRESERVE);
break;
+#ifndef DISABLE_NANORC
case 'q':
SET(QUIET);
break;
+#endif
#ifndef DISABLE_WRAPJUSTIFY
case 'r':
if (!parse_num(optarg, &wrap_at)) {
@@ -2280,22 +2386,15 @@ int main(int argc, char **argv)
case 't':
SET(TEMP_FILE);
break;
-#ifndef NANO_TINY
- case 'u':
- SET(UNDOABLE);
- break;
-#endif
case 'v':
SET(VIEW_MODE);
break;
#ifndef DISABLE_WRAPPING
case 'w':
SET(NO_WRAP);
-
- /* If both --fill and --nowrap are given on the command line,
- the last option wins, */
+ /* If both --fill and --nowrap are given on the
+ * command line, the last given option wins. */
fill_used = FALSE;
-
break;
#endif
case 'x':
@@ -2309,8 +2408,12 @@ int main(int argc, char **argv)
SET(SOFTWRAP);
break;
#endif
- default:
+ case 'h':
usage();
+ exit(0);
+ default:
+ printf(_("Type '%s -h' for a list of available options.\n"), argv[0]);
+ exit(1);
}
}
@@ -2319,26 +2422,27 @@ int main(int argc, char **argv)
if (*(tail(argv[0])) == 'r')
SET(RESTRICTED);
- /* If we're using restricted mode, disable suspending, backups, and
- * reading rcfiles, since they all would allow reading from or
- * writing to files not specified on the command line. */
+ /* If we're using restricted mode, disable suspending, backups,
+ * rcfiles, and history files, since they all would allow reading
+ * from or writing to files not specified on the command line. */
if (ISSET(RESTRICTED)) {
UNSET(SUSPEND);
UNSET(BACKUP_FILE);
-#ifdef ENABLE_NANORC
+#ifndef DISABLE_NANORC
no_rcfiles = TRUE;
+ UNSET(HISTORYLOG);
+ UNSET(POS_HISTORY);
#endif
}
-
- /* Set up the shortcut lists.
- Need to do this before the rcfile */
- shortcut_init(FALSE);
+ /* 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();
/* We've read through the command line options. Now back up the flags
* and values that are set, and read the rcfile(s). If the values
* haven't changed afterward, restore the backed-up values. */
-#ifdef ENABLE_NANORC
+#ifndef DISABLE_NANORC
if (!no_rcfiles) {
#ifndef DISABLE_OPERATINGDIR
char *operating_dir_cpy = operating_dir;
@@ -2421,11 +2525,11 @@ int main(int argc, char **argv)
else if (geteuid() == NANO_ROOT_UID)
SET(NO_WRAP);
#endif
-#endif /* ENABLE_NANORC */
+#endif /* !DISABLE_NANORC */
#ifndef DISABLE_WRAPPING
/* Overwrite an rcfile "set nowrap" or --disable-wrapping-as-root
- if a --fill option was given on the command line. */
+ * if a --fill option was given on the command line. */
if (fill_used)
UNSET(NO_WRAP);
#endif
@@ -2433,16 +2537,24 @@ int main(int argc, char **argv)
/* If we're using bold text instead of reverse video text, set it up
* now. */
if (ISSET(BOLD_TEXT))
- reverse_attr = A_BOLD;
+ hilite_attribute = A_BOLD;
-#ifndef NANO_TINY
+#ifndef DISABLE_HISTORIES
/* Set up the search/replace history. */
history_init();
-#ifdef ENABLE_NANORC
- if (!no_rcfiles && ISSET(HISTORYLOG))
+ /* Verify that the home directory and ~/.nano subdir exist. */
+ if (ISSET(HISTORYLOG) || ISSET(POS_HISTORY)) {
+ get_homedir();
+ if (homedir == NULL || check_dotnano() == 0) {
+ UNSET(HISTORYLOG);
+ UNSET(POS_HISTORY);
+ }
+ }
+ if (ISSET(HISTORYLOG))
load_history();
-#endif
-#endif
+ if (ISSET(POS_HISTORY))
+ load_poshistory();
+#endif /* !DISABLE_HISTORIES */
#ifndef NANO_TINY
/* Set up the backup directory (unless we're using restricted mode,
@@ -2513,16 +2625,28 @@ int main(int argc, char **argv)
/* If matchbrackets wasn't specified, set its default value. */
if (matchbrackets == NULL)
matchbrackets = mallocstrcpy(NULL, "(<[{)>]}");
-#endif
-#if !defined(NANO_TINY) && defined(ENABLE_NANORC)
- /* If whitespace wasn't specified, set its default value. */
+#ifndef DISABLE_NANORC
+ /* If whitespace wasn't specified, set its default value. If we're
+ * using UTF-8, it's Unicode 00BB (Right-Pointing Double Angle
+ * Quotation Mark) and Unicode 00B7 (Middle Dot). Otherwise, it's
+ * ">" and ".". */
if (whitespace == NULL) {
- whitespace = mallocstrcpy(NULL, " ");
- whitespace_len[0] = 1;
- whitespace_len[1] = 1;
+#ifdef ENABLE_UTF8
+ if (using_utf8()) {
+ whitespace = mallocstrcpy(NULL, "\xC2\xBB\xC2\xB7");
+ whitespace_len[0] = 2;
+ whitespace_len[1] = 2;
+ } else
+#endif
+ {
+ whitespace = mallocstrcpy(NULL, ">.");
+ whitespace_len[0] = 1;
+ whitespace_len[1] = 1;
+ }
}
-#endif
+#endif /* !DISABLE_NANORC */
+#endif /* !NANO_TINY */
/* If tabsize wasn't specified, set its default value. */
if (tabsize == -1)
@@ -2557,6 +2681,19 @@ int main(int argc, char **argv)
mouse_init();
#endif
+#ifndef DISABLE_COLOR
+ set_colorpairs();
+#else
+ interface_color_pair[TITLE_BAR].pairnum = hilite_attribute;
+ interface_color_pair[STATUS_BAR].pairnum = hilite_attribute;
+ interface_color_pair[KEY_COMBO].pairnum = hilite_attribute;
+ interface_color_pair[FUNCTION_TAG].pairnum = A_NORMAL;
+ interface_color_pair[TITLE_BAR].bright = FALSE;
+ interface_color_pair[STATUS_BAR].bright = FALSE;
+ interface_color_pair[KEY_COMBO].bright = FALSE;
+ interface_color_pair[FUNCTION_TAG].bright = FALSE;
+#endif
+
#ifdef DEBUG
fprintf(stderr, "Main: open file\n");
#endif
@@ -2575,7 +2712,7 @@ int main(int argc, char **argv)
optind++;
}
-#ifdef ENABLE_MULTIBUFFER
+#ifndef DISABLE_MULTIBUFFER
old_multibuffer = ISSET(MULTIBUFFER);
SET(MULTIBUFFER);
@@ -2583,7 +2720,7 @@ int main(int argc, char **argv)
* new buffers. */
{
int i = optind + 1;
- ssize_t iline = 1, icol = 1;
+ ssize_t iline = 0, icol = 0;
for (; i < argc; i++) {
/* If there's a +LINE or +LINE,COLUMN flag here, it is
@@ -2595,16 +2732,25 @@ int main(int argc, char **argv)
else {
open_buffer(argv[i], FALSE);
- if (iline > 1 || icol > 1) {
+ if (iline > 0 || icol > 0) {
do_gotolinecolumn(iline, icol, FALSE, FALSE, FALSE,
FALSE);
iline = 1;
icol = 1;
}
+#ifndef DISABLE_HISTORIES
+ else {
+ /* See if we have a POS history to use if we haven't overridden it. */
+ ssize_t savedposline, savedposcol;
+ if (check_poshistory(argv[i], &savedposline, &savedposcol))
+ do_gotolinecolumn(savedposline, savedposcol, FALSE, FALSE, FALSE,
+ FALSE);
+ }
+#endif
}
}
}
-#endif
+#endif /* !DISABLE_MULTIBUFFER */
/* Read the first file on the command line into either the current
* buffer or a new buffer, depending on whether multibuffer mode is
@@ -2621,7 +2767,7 @@ int main(int argc, char **argv)
UNSET(VIEW_MODE);
}
-#ifdef ENABLE_MULTIBUFFER
+#ifndef DISABLE_MULTIBUFFER
if (!old_multibuffer)
UNSET(MULTIBUFFER);
#endif
@@ -2630,22 +2776,29 @@ int main(int argc, char **argv)
fprintf(stderr, "Main: top and bottom win\n");
#endif
-#ifdef ENABLE_COLOR
- if (openfile->syntax && openfile->syntax->nmultis > 0)
- precalc_multicolorinfo();
+#ifndef DISABLE_COLOR
+ if (openfile->syntax)
+ if (openfile->syntax->nmultis > 0)
+ precalc_multicolorinfo();
#endif
- if (startline > 1 || startcol > 1)
+ if (startline > 0 || startcol > 0)
do_gotolinecolumn(startline, startcol, FALSE, FALSE, FALSE,
FALSE);
+#ifndef DISABLE_HISTORIES
+ else {
+ /* See if we have a POS history to use if we haven't overridden it. */
+ ssize_t savedposline, savedposcol;
+ if (check_poshistory(argv[optind], &savedposline, &savedposcol))
+ do_gotolinecolumn(savedposline, savedposcol, FALSE, FALSE, FALSE, FALSE);
+ }
+#endif
display_main_list();
display_buffer();
while (TRUE) {
- bool meta_key, func_key, s_or_t, ran_func, finished;
-
/* Make sure the cursor is in the edit window. */
reset_cursor();
wnoutrefresh(edit);
@@ -2674,11 +2827,9 @@ int main(int argc, char **argv)
currmenu = MMAIN;
/* Read in and interpret characters. */
- do_input(&meta_key, &func_key, &s_or_t, &ran_func, &finished,
- TRUE);
+ do_input(TRUE);
}
/* We should never get here. */
assert(FALSE);
}
-