diff options
Diffstat (limited to 'src/nano.c')
-rw-r--r-- | src/nano.c | 801 |
1 files changed, 476 insertions, 325 deletions
@@ -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); } - |