/* $Id$ */ /************************************************************************** * global.c * * * * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 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) * * any later version. * * * * This program is distributed in the hope that it will be useful, but * * WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * * 02110-1301, USA. * * * **************************************************************************/ #include "proto.h" #include #include #include #include "assert.h" /* Global variables. */ #ifndef NANO_TINY sigjmp_buf jump_buf; /* Used to return to either main() or the unjustify routine in * do_justify() after a SIGWINCH. */ bool jump_buf_main = FALSE; /* Have we set jump_buf so that we return to main() after a * SIGWINCH? */ #endif #ifndef DISABLE_WRAPJUSTIFY ssize_t fill = 0; /* The column where we will wrap lines. */ ssize_t wrap_at = -CHARS_FROM_EOL; /* The position where we will wrap lines. fill is equal to this * if it's greater than zero, and equal to (COLS + this) if it * isn't. */ #endif char *last_search = NULL; /* The last string we searched for. */ char *last_replace = NULL; /* The last replacement string we searched for. */ unsigned flags[4] = {0, 0, 0, 0}; /* Our flag containing the states of all global options. */ WINDOW *topwin; /* The top portion of the window, where we display the version * number of nano, the name of the current file, and whether the * current file has been modified. */ WINDOW *edit; /* The middle portion of the window, i.e. the edit window, where * we display the current file we're editing. */ WINDOW *bottomwin; /* The bottom portion of the window, where we display statusbar * messages, the statusbar prompt, and a list of shortcuts. */ int editwinrows = 0; /* How many rows does the edit window take up? */ int maxrows = 0; /* How many usable lines are there (due to soft wrapping) */ filestruct *cutbuffer = NULL; /* The buffer where we store cut text. */ filestruct *cutbottom = NULL; #ifndef DISABLE_JUSTIFY filestruct *jusbuffer = NULL; /* The buffer where we store unjustified text. */ #endif partition *filepart = NULL; /* The partition where we store a portion of the current * file. */ openfilestruct *openfile = NULL; /* The list of all open file buffers. */ #ifndef NANO_TINY char *matchbrackets = NULL; /* The opening and closing brackets that can be found by bracket * searches. */ #endif #if !defined(NANO_TINY) && defined(ENABLE_NANORC) char *whitespace = NULL; /* The characters used when displaying the first characters of * tabs and spaces. */ int whitespace_len[2]; /* The length of these characters. */ #endif #ifndef DISABLE_JUSTIFY char *punct = NULL; /* The closing punctuation that can end sentences. */ char *brackets = NULL; /* The closing brackets that can follow closing punctuation and * can end sentences. */ char *quotestr = NULL; /* The quoting string. The default value is set in main(). */ #ifdef HAVE_REGEX_H regex_t quotereg; /* The compiled regular expression from the quoting string. */ int quoterc; /* Whether it was compiled successfully. */ char *quoteerr = NULL; /* The error message, if it didn't. */ #else size_t quotelen; /* The length of the quoting string in bytes. */ #endif #endif bool nodelay_mode = FALSE; /* Are we in nodelay mode (checking for a cancel wile doing something */ char *answer = NULL; /* The answer string used by the statusbar prompt. */ ssize_t tabsize = -1; /* The width of a tab in spaces. The default value is set in * main(). */ #ifndef NANO_TINY char *backup_dir = NULL; /* The directory where we store backup files. */ #endif #ifndef DISABLE_OPERATINGDIR char *operating_dir = NULL; /* The relative path to the operating directory, which we can't * move outside of. */ char *full_operating_dir = NULL; /* The full path to it. */ #endif #ifndef DISABLE_SPELLER char *alt_speller = NULL; /* The command to use for the alternate spell checker. */ #endif #ifdef ENABLE_COLOR syntaxtype *syntaxes = NULL; /* The global list of color syntaxes. */ char *syntaxstr = NULL; /* The color syntax name specified on the command line. */ #endif bool edit_refresh_needed = NULL; /* Did a command mangle enough of the buffer refresh that we should repaint the screen */ const shortcut *currshortcut; /* The current shortcut list we're using. */ int currmenu; /* The currently loaded menu */ sc *sclist = NULL; /* New shortcut key struct */ subnfunc *allfuncs = NULL; /* New struct for the function list */ #ifndef NANO_TINY filestruct *search_history = NULL; /* The search string history list. */ filestruct *searchage = NULL; /* The top of the search string history list. */ filestruct *searchbot = NULL; /* The bottom of the search string history list. */ filestruct *replace_history = NULL; /* The replace string history list. */ filestruct *replaceage = NULL; /* The top of the replace string history list. */ filestruct *replacebot = NULL; /* The bottom of the replace string history list. */ #endif /* Regular expressions. */ #ifdef HAVE_REGEX_H regex_t search_regexp; /* The compiled regular expression to use in searches. */ regmatch_t regmatches[10]; /* The match positions for parenthetical subexpressions, 10 * maximum, used in regular expression searches. */ #endif int reverse_attr = A_REVERSE; /* The curses attribute we use for reverse video. */ char *homedir = NULL; /* The user's home directory, from $HOME or /etc/passwd. */ /* Return the number of entries in the shortcut list s for a given menu. */ size_t length_of_list(int menu) { subnfunc *f; size_t i = 0; for (f = allfuncs; f != NULL; f = f->next) if ((f->menus & menu) != 0 #ifndef DISABLE_HELP && strlen(f->help) > 0 #endif ) { i++; } return i; } /* Set type of function based on the string */ function_type strtokeytype(const char *str) { if (str[0] == 'M' || str[0] == 'm') return META; else if (str[0] == '^') return CONTROL; else if (str[0] == 'F' || str[0] == 'F') return FKEY; else return RAW; } /* Add a string to the new function list strict. Does not allow updates, yet anyway */ void add_to_funcs(short func, int menus, const char *desc, const char *help, bool blank_after, bool viewok) { subnfunc *f; if (allfuncs == NULL) { allfuncs = (subnfunc *) nmalloc(sizeof(subnfunc)); f = allfuncs; } else { for (f = allfuncs; f->next != NULL; f = f->next) ; f->next = (subnfunc *)nmalloc(sizeof(subnfunc)); f = f->next; } f->next = NULL; f->scfunc = func; f->menus = menus; f->desc = desc; f->viewok = viewok; #ifndef DISABLE_HELP f->help = help; f->blank_after = blank_after; #endif #ifdef DEBUG fprintf(stderr, "Added func \"%s\"", f->desc); #endif } const sc *first_sc_for(int menu, short func) { const sc *s; const sc *metasc = NULL; for (s = sclist; s != NULL; s = s->next) { if ((s->menu & menu) && s->scfunc == func) { /* try to use a meta sequence as a last resort. Otherwise we will run into problems when we try and handle things like the arrow keys, home, etc, if for some reason the user bound them to a meta sequence first *shrug* */ if (s->type == META) { metasc = s; continue; } /* otherwise it was something else, use it */ return s; } } /* If we're here we may have found only meta sequences, if so use one */ if (metasc) return metasc; #ifdef DEBUG fprintf(stderr, "Whoops, returning null given func %ld in menu %d\n", (long) func, menu); #endif /* Otherwise... */ return NULL; } /* Add a string to the new shortcut list implementation Allows updates to existing entries in the list */ void add_to_sclist(int menu, const char *scstring, short func, int toggle, int execute) { sc *s; if (sclist == NULL) { sclist = (sc *) nmalloc(sizeof(sc)); s = sclist; s->next = NULL; } else { for (s = sclist; s->next != NULL; s = s->next) if (s->menu == menu && s->keystr == scstring) break; if (s->menu != menu || s->keystr != scstring) { /* i.e. this is not a replace... */ #ifdef DEBUG fprintf(stderr, "No match found...\n"); #endif s->next = (sc *)nmalloc(sizeof(sc)); s = s->next; s->next = NULL; } } s->type = strtokeytype(scstring); s->menu = menu; s->toggle = toggle; s->keystr = (char *) scstring; s->scfunc = func; s->execute = execute; assign_keyinfo(s); #ifdef DEBUG fprintf(stderr, "list val = %d\n", (int) s->menu); fprintf(stderr, "Hey, set sequence to %d for shortcut \"%s\"\n", s->seq, scstring); #endif } /* Return the given menu's first shortcut sequence, or the default value (2nd arg). Assumes currmenu for the menu to check*/ int sc_seq_or (short func, int defaultval) { const sc *s = first_sc_for(currmenu, func); if (s) return s->seq; /* else */ return defaultval; } /* Assign the info to the shortcut struct Assumes keystr is already assigned, naturally */ void assign_keyinfo(sc *s) { if (s->type == CONTROL) { assert(strlen(s->keystr) > 1); s->seq = s->keystr[1] - 64; } else if (s->type == META) { assert(strlen(s->keystr) > 2); s->seq = tolower((int) s->keystr[2]); } else if (s->type == FKEY) { assert(strlen(s->keystr) > 1); s->seq = KEY_F0 + atoi(&s->keystr[1]); } else /* raw */ s->seq = (int) s->keystr[0]; /* Override some keys which don't bind as nicely as we'd like */ if (s->type == CONTROL && (!strcasecmp(&s->keystr[1], "space"))) s->seq = 0; else if (s->type == META && (!strcasecmp(&s->keystr[2], "space"))) s->seq = (int) ' '; else if (s->type == RAW && (!strcasecmp(s->keystr, "kup"))) s->seq = KEY_UP; else if (s->type == RAW && (!strcasecmp(s->keystr, "kdown"))) s->seq = KEY_DOWN; else if (s->type == RAW && (!strcasecmp(s->keystr, "kleft"))) s->seq = KEY_LEFT; else if (s->type == RAW && (!strcasecmp(s->keystr, "kright"))) s->seq = KEY_RIGHT; else if (s->type == RAW && (!strcasecmp(s->keystr, "kinsert"))) s->seq = KEY_IC; else if (s->type == RAW && (!strcasecmp(s->keystr, "kdel"))) s->seq = KEY_DC; else if (s->type == RAW && (!strcasecmp(s->keystr, "kbsp"))) s->seq = KEY_BACKSPACE; else if (s->type == RAW && (!strcasecmp(s->keystr, "kenter"))) s->seq = KEY_ENTER; else if (s->type == RAW && (!strcasecmp(s->keystr, "kpup"))) s->seq = KEY_PPAGE; else if (s->type == RAW && (!strcasecmp(s->keystr, "kpdown"))) s->seq = KEY_NPAGE; #ifdef KEY_HOME else if (s->type == RAW && (!strcasecmp(s->keystr, "khome"))) s->seq = KEY_HOME; #endif #ifdef KEY_END else if (s->type == RAW && (!strcasecmp(s->keystr, "kend"))) s->seq = KEY_END; #endif } #ifdef DEBUG void print_sclist(void) { sc *s; const subnfunc *f; for (s = sclist; s->next != NULL; s = s->next) { f = sctofunc(s); if (f) fprintf(stderr, "Shortcut \"%s\", function: %s, menus %d\n", s->keystr, f->desc, f->menus); else fprintf(stderr, "Hmm, didnt find a func for \"%s\"\n", s->keystr); } } #endif /* Stuff we need to make at least static here so we can access it below */ /* TRANSLATORS: Try to keep the next five strings at most 10 characters. */ const char *cancel_msg = N_("Cancel"); const char *replace_msg = N_("Replace"); const char *no_replace_msg = N_("No Replace"); #ifndef NANO_TINY const char *case_sens_msg = N_("Case Sens"); const char *backwards_msg = N_("Backwards"); #endif #ifdef HAVE_REGEX_H const char *regexp_msg = N_("Regexp"); #endif /* Stuff we want to just stun out if we're in TINY mode */ #ifdef NANO_TINY const char *gototext_msg = ""; const char *do_para_begin_msg = ""; const char *do_para_end_msg = ""; const char *case_sens_msg = ""; const char *backwards_msg = ""; const char *do_cut_till_end = ""; const char *dos_format_msg = ""; const char *mac_format_msg = ""; const char *append_msg = ""; const char *prepend_msg = ""; const char *backup_file_msg = ""; const char *to_files_msg = ""; const char *first_file_msg = ""; const char *whereis_next_msg = ""; const char *last_file_msg = ""; const char *new_buffer_msg = ""; const char *goto_dir_msg; const char *ext_cmd_msg = ""; #else /* TRANSLATORS: Try to keep the next five strings at most 10 characters. */ const char *prev_history_msg = N_("PrevHstory"); const char *next_history_msg = N_("NextHstory"); const char *gototext_msg = N_("Go To Text"); /* TRANSLATORS: Try to keep the next three strings at most 12 characters. */ const char *whereis_next_msg = N_("WhereIs Next"); #ifndef DISABLE_BROWSER const char *first_file_msg = N_("First File"); const char *last_file_msg = N_("Last File"); /* TRANSLATORS: Try to keep the next nine strings at most 16 characters. */ const char *to_files_msg = N_("To Files"); #endif const char *dos_format_msg = N_("DOS Format"); const char *mac_format_msg = N_("Mac Format"); const char *append_msg = N_("Append"); const char *prepend_msg = N_("Prepend"); const char *backup_file_msg = N_("Backup File"); const char *ext_cmd_msg = N_("Execute Command"); #ifdef ENABLE_MULTIBUFFER const char *new_buffer_msg = N_("New Buffer"); #endif const char *goto_dir_msg = N_("Go To Dir"); #endif /* NANO_TINY */ /* Initialize all shortcut lists. If unjustify is TRUE, replace the * Uncut shortcut in the main shortcut list with UnJustify. */ void shortcut_init(bool unjustify) { /* TRANSLATORS: Try to keep the following strings at most 10 characters. */ const char *get_help_msg = N_("Get Help"); const char *exit_msg = N_("Exit"); const char *whereis_msg = N_("Where Is"); const char *prev_page_msg = N_("Prev Page"); const char *next_page_msg = N_("Next Page"); const char *first_line_msg = N_("First Line"); const char *last_line_msg = N_("Last Line"); const char *suspend_msg = N_("Suspend"); #ifndef DISABLE_JUSTIFY const char *beg_of_par_msg = N_("Beg of Par"); const char *end_of_par_msg = N_("End of Par"); const char *fulljstify_msg = N_("FullJstify"); #endif const char *refresh_msg = N_("Refresh"); #ifndef NANO_TINY const char *insert_file_msg = N_("Insert File"); #endif const char *go_to_line_msg = N_("Go To Line"); #ifndef DISABLE_JUSTIFY const char *nano_justify_msg = N_("Justify the current paragraph"); #endif #ifndef DISABLE_HELP /* TRANSLATORS: The next long series of strings are shortcut descriptions; * they are best kept shorter than 56 characters, but may be longer. */ const char *nano_cancel_msg = N_("Cancel the current function"); const char *nano_help_msg = N_("Display this help text"); const char *nano_exit_msg = #ifdef ENABLE_MULTIBUFFER N_("Close the current file buffer / Exit from nano") #else N_("Exit from nano") #endif ; const char *nano_writeout_msg = N_("Write the current file to disk"); const char *nano_insert_msg = N_("Insert another file into the current one"); const char *nano_whereis_msg = N_("Search for a string or a regular expression"); const char *nano_prevpage_msg = N_("Go to previous screen"); const char *nano_nextpage_msg = N_("Go to next screen"); const char *nano_cut_msg = N_("Cut the current line and store it in the cutbuffer"); const char *nano_uncut_msg = N_("Uncut from the cutbuffer into the current line"); const char *nano_cursorpos_msg = N_("Display the position of the cursor"); const char *nano_spell_msg = N_("Invoke the spell checker, if available"); const char *nano_replace_msg = N_("Replace a string or a regular expression"); const char *nano_gotoline_msg = N_("Go to line and column number"); #ifndef NANO_TINY const char *nano_mark_msg = N_("Mark text at the cursor position"); const char *nano_whereis_next_msg = N_("Repeat last search"); const char *nano_copy_msg = N_("Copy the current line and store it in the cutbuffer"); const char *nano_indent_msg = N_("Indent the current line"); const char *nano_unindent_msg = N_("Unindent the current line"); const char *nano_undo_msg = N_("Undo the last operation"); const char *nano_redo_msg = N_("Redo the last undone operation"); #endif const char *nano_forward_msg = N_("Go forward one character"); const char *nano_back_msg = N_("Go back one character"); #ifndef NANO_TINY const char *nano_nextword_msg = N_("Go forward one word"); const char *nano_prevword_msg = N_("Go back one word"); #endif const char *nano_prevline_msg = N_("Go to previous line"); const char *nano_nextline_msg = N_("Go to next line"); const char *nano_home_msg = N_("Go to beginning of current line"); const char *nano_end_msg = N_("Go to end of current line"); #ifndef DISABLE_JUSTIFY const char *nano_parabegin_msg = N_("Go to beginning of paragraph; then of previous paragraph"); const char *nano_paraend_msg = N_("Go just beyond end of paragraph; then of next paragraph"); #endif const char *nano_firstline_msg = N_("Go to the first line of the file"); const char *nano_lastline_msg = N_("Go to the last line of the file"); #ifndef NANO_TINY const char *nano_bracket_msg = N_("Go to the matching bracket"); const char *nano_scrollup_msg = N_("Scroll up one line without scrolling the cursor"); const char *nano_scrolldown_msg = N_("Scroll down one line without scrolling the cursor"); #endif #ifdef ENABLE_MULTIBUFFER const char *nano_prevfile_msg = N_("Switch to the previous file buffer"); const char *nano_nextfile_msg = N_("Switch to the next file buffer"); #endif const char *nano_verbatim_msg = N_("Insert the next keystroke verbatim"); const char *nano_tab_msg = N_("Insert a tab at the cursor position"); const char *nano_enter_msg = N_("Insert a newline at the cursor position"); const char *nano_delete_msg = N_("Delete the character under the cursor"); const char *nano_backspace_msg = N_("Delete the character to the left of the cursor"); #ifndef NANO_TINY const char *nano_cut_till_end_msg = N_("Cut from the cursor position to the end of the file"); #endif #ifndef DISABLE_JUSTIFY const char *nano_fulljustify_msg = N_("Justify the entire file"); #endif #ifndef NANO_TINY const char *nano_wordcount_msg = N_("Count the number of words, lines, and characters"); #endif const char *nano_refresh_msg = N_("Refresh (redraw) the current screen"); const char *nano_suspend_msg = N_("Suspend the editor (if suspend is enabled)"); #ifndef NANO_TINY const char *nano_case_msg = N_("Toggle the case sensitivity of the search"); const char *nano_reverse_msg = N_("Reverse the direction of the search"); #endif #ifdef HAVE_REGEX_H const char *nano_regexp_msg = N_("Toggle the use of regular expressions"); #endif #ifndef NANO_TINY const char *nano_prev_history_msg = N_("Recall the previous search/replace string"); const char *nano_next_history_msg = N_("Recall the next search/replace string"); #endif #ifndef DISABLE_BROWSER const char *nano_tofiles_msg = N_("Go to file browser"); #endif #ifndef NANO_TINY const char *nano_dos_msg = N_("Toggle the use of DOS format"); const char *nano_mac_msg = N_("Toggle the use of Mac format"); #endif const char *nano_append_msg = N_("Toggle appending"); const char *nano_prepend_msg = N_("Toggle prepending"); #ifndef NANO_TINY const char *nano_backup_msg = N_("Toggle backing up of the original file"); const char *nano_execute_msg = N_("Execute external command"); #endif #if !defined(NANO_TINY) && defined(ENABLE_MULTIBUFFER) const char *nano_multibuffer_msg = N_("Toggle the use of a new buffer"); #endif #ifndef DISABLE_BROWSER const char *nano_exitbrowser_msg = N_("Exit from the file browser"); const char *nano_firstfile_msg = N_("Go to the first file in the list"); const char *nano_lastfile_msg = N_("Go to the last file in the list"); const char *nano_gotodir_msg = N_("Go to directory"); #endif #endif /* !DISABLE_HELP */ #ifndef DISABLE_HELP #define IFSCHELP(help) help #else #define IFSCHELP(help) "" #endif while (allfuncs != NULL) { subnfunc *f = allfuncs; allfuncs = (allfuncs)->next; free(f); } add_to_funcs(DO_HELP_VOID, MALL, get_help_msg, IFSCHELP(nano_help_msg), FALSE, VIEW); add_to_funcs( CANCEL_MSG, (MWHEREIS|MREPLACE|MREPLACE2|MGOTOLINE|MWRITEFILE|MINSERTFILE|MEXTCMD|MSPELL|MWHEREISFILE|MGOTODIR|MYESNO), cancel_msg, IFSCHELP(nano_cancel_msg), FALSE, VIEW); add_to_funcs(DO_EXIT, MMAIN, #ifdef ENABLE_MULTIBUFFER /* TRANSLATORS: Try to keep this at most 10 characters. */ openfile != NULL && openfile != openfile->next ? N_("Close") : #endif exit_msg, IFSCHELP(nano_exit_msg), FALSE, VIEW); add_to_funcs(DO_EXIT, MHELP, exit_msg, IFSCHELP(nano_exit_msg), FALSE, VIEW); #ifndef DISABLE_BROWSER add_to_funcs(DO_EXIT, MBROWSER, exit_msg, IFSCHELP(nano_exitbrowser_msg), FALSE, VIEW); #endif /* TRANSLATORS: Try to keep this at most 10 characters. */ add_to_funcs(DO_WRITEOUT_VOID, MMAIN, N_("WriteOut"), IFSCHELP(nano_writeout_msg), FALSE, NOVIEW); #ifndef DISABLE_JUSTIFY /* TRANSLATORS: Try to keep this at most 10 characters. */ add_to_funcs(DO_JUSTIFY_VOID, MMAIN, N_("Justify"), nano_justify_msg, TRUE, NOVIEW); #endif /* We allow inserting files in view mode if multibuffers are * available, so that we can view multiple files. If we're using * restricted mode, inserting files is disabled, since it allows * reading from or writing to files not specified on the command * line. */ add_to_funcs(!ISSET(RESTRICTED) ? DO_INSERTFILE_VOID : NANO_DISABLED_MSG, /* TRANSLATORS: Try to keep this at most 10 characters. */ MMAIN, N_("Read File"), IFSCHELP(nano_insert_msg), FALSE, #ifdef ENABLE_MULTIBUFFER VIEW); #else NOVIEW); #endif add_to_funcs(DO_SEARCH, MMAIN|MBROWSER, whereis_msg, IFSCHELP(nano_whereis_msg), FALSE, VIEW); add_to_funcs(DO_PAGE_UP, MMAIN|MHELP, prev_page_msg, IFSCHELP(nano_prevpage_msg), FALSE, VIEW); add_to_funcs(DO_PAGE_DOWN, MMAIN|MHELP, next_page_msg, IFSCHELP(nano_nextpage_msg), TRUE, VIEW); /* TRANSLATORS: Try to keep this at most 10 characters. */ add_to_funcs(DO_CUT_TEXT_VOID, MMAIN, N_("Cut Text"), IFSCHELP(nano_cut_msg), FALSE, NOVIEW); if (unjustify) /* TRANSLATORS: Try to keep this at most 10 characters. */ add_to_funcs(DO_UNCUT_TEXT, MMAIN, N_("UnJustify"), "", FALSE, NOVIEW); else /* TRANSLATORS: Try to keep this at most 10 characters. */ add_to_funcs(DO_UNCUT_TEXT, MMAIN, N_("UnCut Text"), IFSCHELP(nano_uncut_msg), FALSE, NOVIEW); #ifndef NANO_TINY /* TRANSLATORS: Try to keep this at most 10 characters. */ add_to_funcs(DO_CURSORPOS_VOID, MMAIN, N_("Cur Pos"), IFSCHELP(nano_cursorpos_msg), FALSE, VIEW); #endif /* If we're using restricted mode, spell checking is disabled * because it allows reading from or writing to files not specified * on the command line. */ #ifndef DISABLE_SPELLER if (!ISSET(RESTRICTED)) /* TRANSLATORS: Try to keep this at most 10 characters. */ add_to_funcs(DO_SPELL, MMAIN, N_("To Spell"), IFSCHELP(nano_spell_msg), TRUE, NOVIEW); #endif add_to_funcs(DO_FIRST_LINE, (MMAIN|MWHEREIS|MREPLACE|MREPLACE2|MGOTOLINE), first_line_msg, IFSCHELP(nano_firstline_msg), FALSE, VIEW); add_to_funcs(DO_LAST_LINE, (MMAIN|MWHEREIS|MREPLACE|MREPLACE2|MGOTOLINE), last_line_msg, IFSCHELP(nano_lastline_msg), TRUE, VIEW); add_to_funcs(DO_GOTOLINECOLUMN_VOID, (MMAIN|MWHEREIS), go_to_line_msg, IFSCHELP(nano_gotoline_msg), FALSE, VIEW); #ifdef NANO_TINY /* TRANSLATORS: Try to keep this at most 10 characters. */ add_to_funcs(DO_CURSORPOS_VOID, MMAIN, N_("Cur Pos"), IFSCHELP(nano_cursorpos_msg), FALSE, VIEW); #endif add_to_funcs(DO_REPLACE, (MMAIN|MWHEREIS), replace_msg, IFSCHELP(nano_replace_msg), #ifndef NANO_TINY FALSE, #else TRUE, #endif NOVIEW); #ifndef NANO_TINY add_to_funcs(DO_MARK, MMAIN, N_("Mark Text"), IFSCHELP(nano_mark_msg), FALSE, VIEW); add_to_funcs(DO_RESEARCH, (MMAIN|MBROWSER), whereis_next_msg, IFSCHELP(nano_whereis_next_msg), TRUE, VIEW); add_to_funcs(DO_COPY_TEXT, MMAIN, N_("Copy Text"), IFSCHELP(nano_copy_msg), FALSE, NOVIEW); add_to_funcs(DO_INDENT_VOID, MMAIN, N_("Indent Text"), IFSCHELP(nano_indent_msg), FALSE, NOVIEW); add_to_funcs(DO_UNINDENT, MMAIN, N_("Unindent Text"), IFSCHELP(nano_unindent_msg), FALSE, NOVIEW); if (ISSET(UNDOABLE)) { add_to_funcs(DO_UNDO, MMAIN, N_("Undo"), IFSCHELP(nano_undo_msg), FALSE, NOVIEW); add_to_funcs(DO_REDO, MMAIN, N_("Redo"), IFSCHELP(nano_redo_msg), TRUE, NOVIEW); } #endif add_to_funcs(DO_PAGE_UP, MBROWSER, prev_page_msg, IFSCHELP(nano_prevpage_msg), FALSE, VIEW); add_to_funcs(DO_PAGE_DOWN, MBROWSER, next_page_msg, IFSCHELP(nano_nextpage_msg), TRUE, VIEW); add_to_funcs(DO_RIGHT, (MMAIN|MBROWSER), N_("Forward"), IFSCHELP(nano_forward_msg), FALSE, VIEW); add_to_funcs(DO_RIGHT, MALL, "", "", FALSE, VIEW); add_to_funcs(DO_LEFT, (MMAIN|MBROWSER), N_("Back"), IFSCHELP(nano_back_msg), FALSE, VIEW); add_to_funcs(DO_LEFT, MALL, "", "", FALSE, VIEW); #ifndef NANO_TINY add_to_funcs(DO_NEXT_WORD_VOID, MMAIN, N_("Next Word"), IFSCHELP(nano_nextword_msg), FALSE, VIEW); add_to_funcs(DO_PREV_WORD_VOID, MMAIN, N_("Prev Word"), IFSCHELP(nano_prevword_msg), FALSE, VIEW); #endif add_to_funcs(DO_UP_VOID, (MMAIN|MHELP|MBROWSER), N_("Prev Line"), IFSCHELP(nano_prevline_msg), FALSE, VIEW); add_to_funcs(DO_DOWN_VOID, (MMAIN|MHELP|MBROWSER), N_("Next Line"), IFSCHELP(nano_nextline_msg), TRUE, VIEW); add_to_funcs(DO_HOME, MMAIN, N_("Home"), IFSCHELP(nano_home_msg), FALSE, VIEW); add_to_funcs(DO_END, MMAIN, N_("End"), IFSCHELP(nano_end_msg), FALSE, VIEW); #ifndef DISABLE_JUSTIFY add_to_funcs(DO_PARA_BEGIN_VOID, (MMAIN|MWHEREIS), beg_of_par_msg, IFSCHELP(nano_parabegin_msg), FALSE, VIEW); add_to_funcs(DO_PARA_END_VOID, (MMAIN|MWHEREIS), end_of_par_msg, IFSCHELP(nano_paraend_msg), FALSE, VIEW); #endif #ifndef NANO_TINY add_to_funcs(DO_FIND_BRACKET, MMAIN, _("Find Other Bracket"), IFSCHELP(nano_bracket_msg), FALSE, VIEW); add_to_funcs(DO_SCROLL_UP, MMAIN, N_("Scroll Up"), IFSCHELP(nano_scrollup_msg), FALSE, VIEW); add_to_funcs(DO_SCROLL_DOWN, MMAIN, N_("Scroll Down"), IFSCHELP(nano_scrolldown_msg), FALSE, VIEW); #endif #ifdef ENABLE_MULTIBUFFER add_to_funcs(SWITCH_TO_PREV_BUFFER_VOID, MMAIN, _("Previous File"), IFSCHELP(nano_prevfile_msg), FALSE, VIEW); add_to_funcs(SWITCH_TO_NEXT_BUFFER_VOID, MMAIN, N_("Next File"), IFSCHELP(nano_nextfile_msg), TRUE, VIEW); #endif add_to_funcs(DO_VERBATIM_INPUT, MMAIN, N_("Verbatim Input"), IFSCHELP(nano_verbatim_msg), FALSE, NOVIEW); add_to_funcs(DO_VERBATIM_INPUT, MWHEREIS|MREPLACE|MREPLACE2|MEXTCMD|MSPELL, "", "", FALSE, NOVIEW); add_to_funcs(DO_TAB, MMAIN, N_("Tab"), IFSCHELP(nano_tab_msg), FALSE, NOVIEW); add_to_funcs(DO_TAB, MALL, "", "", FALSE, NOVIEW); add_to_funcs(DO_ENTER, MMAIN, N_("Enter"), IFSCHELP(nano_enter_msg), FALSE, NOVIEW); add_to_funcs(DO_ENTER, MALL, "", "", FALSE, NOVIEW); add_to_funcs(DO_DELETE, MMAIN, N_("Delete"), IFSCHELP(nano_delete_msg), FALSE, NOVIEW); add_to_funcs(DO_DELETE, MALL, "", "", FALSE, NOVIEW); add_to_funcs(DO_BACKSPACE, MMAIN, N_("Backspace"), IFSCHELP(nano_backspace_msg), #ifndef NANO_TINY FALSE, #else TRUE, #endif NOVIEW); add_to_funcs(DO_BACKSPACE, MALL, "", "", #ifndef NANO_TINY FALSE, #else TRUE, #endif NOVIEW); #ifndef NANO_TINY add_to_funcs(DO_CUT_TILL_END, MMAIN, N_("CutTillEnd"), IFSCHELP(nano_cut_till_end_msg), TRUE, NOVIEW); #endif add_to_funcs(XON_COMPLAINT, MMAIN, "", "", FALSE, VIEW); add_to_funcs(XOFF_COMPLAINT, MMAIN, "", "", FALSE, VIEW); #ifndef DISABLE_JUSTIFY add_to_funcs(DO_FULL_JUSTIFY, (MMAIN|MWHEREIS), fulljstify_msg, IFSCHELP(nano_fulljustify_msg), FALSE, NOVIEW); #endif #ifndef NANO_TINY add_to_funcs(DO_WORDLINECHAR_COUNT, MMAIN, N_("Word Count"), IFSCHELP(nano_wordcount_msg), FALSE, VIEW); #endif add_to_funcs(TOTAL_REFRESH, (MMAIN|MHELP), refresh_msg, IFSCHELP(nano_refresh_msg), FALSE, VIEW); add_to_funcs(DO_SUSPEND_VOID, MMAIN, suspend_msg, IFSCHELP(nano_suspend_msg), TRUE, VIEW); #ifndef NANO_TINY add_to_funcs( CASE_SENS_MSG, (MWHEREIS|MREPLACE|MWHEREISFILE), case_sens_msg, IFSCHELP(nano_case_msg), FALSE, VIEW); add_to_funcs( BACKWARDS_MSG, (MWHEREIS|MREPLACE|MWHEREISFILE), backwards_msg, IFSCHELP(nano_reverse_msg), FALSE, VIEW); #endif #ifdef HAVE_REGEX_H add_to_funcs( REGEXP_MSG, (MWHEREIS|MREPLACE|MWHEREISFILE), regexp_msg, IFSCHELP(nano_regexp_msg), FALSE, VIEW); #endif #ifndef NANO_TINY add_to_funcs( PREV_HISTORY_MSG, (MWHEREIS|MREPLACE|MREPLACE2|MWHEREISFILE), prev_history_msg, IFSCHELP(nano_prev_history_msg), FALSE, VIEW); add_to_funcs( NEXT_HISTORY_MSG, (MWHEREIS|MREPLACE|MREPLACE2|MWHEREISFILE), next_history_msg, IFSCHELP(nano_next_history_msg), FALSE, VIEW); #endif add_to_funcs( NO_REPLACE_MSG, MREPLACE, no_replace_msg, IFSCHELP(nano_whereis_msg), FALSE, VIEW); add_to_funcs( GOTOTEXT_MSG, MGOTOLINE, gototext_msg, IFSCHELP(nano_whereis_msg), TRUE, VIEW); #ifndef DISABLE_BROWSER if (!ISSET(RESTRICTED)) add_to_funcs( TO_FILES_MSG, (MGOTOLINE|MINSERTFILE), to_files_msg, IFSCHELP(nano_tofiles_msg), FALSE, VIEW); #endif #ifndef NANO_TINY /* If we're using restricted mode, the DOS format, Mac format, * append, prepend, and backup toggles are disabled. The first and * second are useless since inserting files is disabled, the third * and fourth are disabled because they allow writing to files not * specified on the command line, and the fifth is useless since * backups are disabled. */ if (!ISSET(RESTRICTED)) add_to_funcs( DOS_FORMAT_MSG, MWRITEFILE, dos_format_msg, IFSCHELP(nano_dos_msg), FALSE, NOVIEW); if (!ISSET(RESTRICTED)) add_to_funcs( MAC_FORMAT_MSG, MWRITEFILE, mac_format_msg, IFSCHELP(nano_mac_msg), FALSE, NOVIEW); if (!ISSET(RESTRICTED)) add_to_funcs( APPEND_MSG, MWRITEFILE, append_msg, IFSCHELP(nano_append_msg), FALSE, NOVIEW); if (!ISSET(RESTRICTED)) add_to_funcs( PREPEND_MSG, MWRITEFILE, prepend_msg, IFSCHELP(nano_prepend_msg), FALSE, NOVIEW); if (!ISSET(RESTRICTED)) add_to_funcs( BACKUP_FILE_MSG, MWRITEFILE, backup_file_msg, IFSCHELP(nano_backup_msg), FALSE, NOVIEW); #endif #ifndef NANO_TINY /* If we're using restricted mode, command execution is disabled. * It's useless since inserting files is disabled. */ if (!ISSET(RESTRICTED)) add_to_funcs( EXT_CMD_MSG, MINSERTFILE, ext_cmd_msg, IFSCHELP(nano_execute_msg), FALSE, NOVIEW); #ifdef ENABLE_MULTIBUFFER /* If we're using restricted mode, the multibuffer toggle is * disabled. It's useless since inserting files is disabled. */ if (!ISSET(RESTRICTED)) add_to_funcs( NEW_BUFFER_MSG, MINSERTFILE, new_buffer_msg, IFSCHELP(nano_multibuffer_msg), FALSE, NOVIEW); #endif add_to_funcs( INSERT_FILE_MSG, MEXTCMD, insert_file_msg, IFSCHELP(nano_insert_msg), FALSE, VIEW); #ifdef ENABLE_MULTIBUFFER add_to_funcs( NEW_BUFFER_MSG, MEXTCMD, new_buffer_msg, IFSCHELP(nano_multibuffer_msg), FALSE, NOVIEW); #endif #endif #ifndef DISABLE_HELP add_to_funcs( REFRESH_MSG, MHELP, refresh_msg, nano_refresh_msg, FALSE, VIEW); #endif #ifndef DISABLE_BROWSER add_to_funcs( FIRST_FILE_MSG, (MBROWSER|MWHEREISFILE), first_file_msg, IFSCHELP(nano_firstfile_msg), FALSE, VIEW); add_to_funcs( LAST_FILE_MSG, (MBROWSER|MWHEREISFILE), last_file_msg, IFSCHELP(nano_lastfile_msg), FALSE, VIEW); add_to_funcs( GOTO_DIR_MSG, MBROWSER, goto_dir_msg, IFSCHELP(nano_gotodir_msg), FALSE, VIEW); #endif currmenu = MMAIN; add_to_sclist(MALL, "^G", DO_HELP_VOID, 0, TRUE); add_to_sclist(MALL, "F1", DO_HELP_VOID, 0, TRUE); add_to_sclist(MMAIN|MHELP|MBROWSER, "^X", DO_EXIT, 0, TRUE); add_to_sclist(MMAIN|MHELP|MBROWSER, "F2", DO_EXIT, 0, TRUE); add_to_sclist(MMAIN, "^_", DO_GOTOLINECOLUMN_VOID, 0, TRUE); add_to_sclist(MMAIN, "F13", DO_GOTOLINECOLUMN_VOID, 0, TRUE); add_to_sclist(MMAIN, "^O", DO_WRITEOUT_VOID, 0, TRUE); add_to_sclist(MMAIN, "F3", DO_WRITEOUT_VOID, 0, TRUE); #ifndef DISABLE_JUSTIFY add_to_sclist(MMAIN, "^J", DO_JUSTIFY_VOID, 0, TRUE); add_to_sclist(MMAIN, "F4", DO_JUSTIFY_VOID, 0, TRUE); #endif add_to_sclist(MMAIN, "^R", DO_INSERTFILE_VOID, 0, TRUE); add_to_sclist(MMAIN, "F5", DO_INSERTFILE_VOID, 0, TRUE); add_to_sclist(MMAIN, "kinsert", DO_INSERTFILE_VOID, 0, TRUE); add_to_sclist(MMAIN|MBROWSER, "^W", DO_SEARCH, 0, TRUE); add_to_sclist(MMAIN|MBROWSER, "F6", DO_SEARCH, 0, TRUE); add_to_sclist(MMAIN|MBROWSER|MHELP|MWHEREISFILE, "^Y", DO_PAGE_UP, 0, TRUE); add_to_sclist(MMAIN|MBROWSER|MHELP|MWHEREISFILE, "F7", DO_PAGE_UP, 0, TRUE); add_to_sclist(MMAIN|MBROWSER|MHELP|MWHEREISFILE, "kpup", DO_PAGE_UP, 0, TRUE); add_to_sclist(MMAIN|MBROWSER|MHELP|MWHEREISFILE, "^V", DO_PAGE_DOWN, 0, TRUE); add_to_sclist(MMAIN|MBROWSER|MHELP|MWHEREISFILE, "F8", DO_PAGE_DOWN, 0, TRUE); add_to_sclist(MMAIN|MBROWSER|MHELP|MWHEREISFILE, "kpdown", DO_PAGE_DOWN, 0, TRUE); add_to_sclist(MMAIN, "^K", DO_CUT_TEXT_VOID, 0, TRUE); add_to_sclist(MMAIN, "F9", DO_CUT_TEXT_VOID, 0, TRUE); add_to_sclist(MMAIN, "^U", DO_UNCUT_TEXT, 0, TRUE); add_to_sclist(MMAIN, "F10", DO_UNCUT_TEXT, 0, TRUE); add_to_sclist(MMAIN, "^C", DO_CURSORPOS_VOID, 0, TRUE); add_to_sclist(MMAIN, "F11", DO_CURSORPOS_VOID, 0, TRUE); #ifndef DISABLE_SPELLER add_to_sclist(MMAIN, "^T", DO_SPELL, 0, TRUE); add_to_sclist(MMAIN, "F12", DO_SPELL, 0, TRUE); #endif add_to_sclist(MMAIN, "^_", DO_GOTOLINECOLUMN_VOID, 0, TRUE); add_to_sclist(MMAIN, "F13", DO_GOTOLINECOLUMN_VOID, 0, TRUE); add_to_sclist(MMAIN, "M-G", DO_GOTOLINECOLUMN_VOID, 0, TRUE); add_to_sclist(MMAIN, "^\\", DO_REPLACE, 0, TRUE); add_to_sclist(MMAIN, "F14", DO_REPLACE, 0, TRUE); add_to_sclist(MMAIN, "M-R", DO_REPLACE, 0, TRUE); add_to_sclist(MWHEREIS, "^R", DO_REPLACE, 0, FALSE); add_to_sclist(MREPLACE, "^R", NO_REPLACE_MSG, 0, FALSE); add_to_sclist(MWHEREIS, "^T", DO_GOTOLINECOLUMN_VOID, 0, FALSE); #ifndef NANO_TINY add_to_sclist(MMAIN, "^^", DO_MARK, 0, TRUE); add_to_sclist(MMAIN, "F15", DO_MARK, 0, TRUE); add_to_sclist(MMAIN, "M-A", DO_MARK, 0, TRUE); add_to_sclist(MALL, "M-W", DO_RESEARCH, 0, TRUE); add_to_sclist(MALL, "F16", DO_RESEARCH, 0, TRUE); add_to_sclist(MMAIN, "M-^", DO_COPY_TEXT, 0, TRUE); add_to_sclist(MMAIN, "M-6", DO_COPY_TEXT, 0, TRUE); add_to_sclist(MMAIN, "M-}", DO_INDENT_VOID, 0, TRUE); add_to_sclist(MMAIN, "M-{", DO_UNINDENT, 0, TRUE); if (ISSET(UNDOABLE)) { add_to_sclist(MMAIN, "M-U", DO_UNDO, 0, TRUE); add_to_sclist(MMAIN, "M-E", DO_REDO, 0, TRUE); } add_to_sclist(MALL, "^F", DO_RIGHT, 0, TRUE); add_to_sclist(MALL, "^B", DO_LEFT, 0, TRUE); add_to_sclist(MMAIN, "^Space", DO_NEXT_WORD_VOID, 0, TRUE); add_to_sclist(MMAIN, "M-Space", DO_PREV_WORD_VOID, 0, TRUE); #endif add_to_sclist(MALL, "kright", DO_RIGHT, 0, TRUE); add_to_sclist(MALL, "kleft", DO_LEFT, 0, TRUE); add_to_sclist(MMAIN, "^Q", XON_COMPLAINT, 0, TRUE); add_to_sclist(MMAIN, "^S", XOFF_COMPLAINT, 0, TRUE); add_to_sclist(MMAIN|MHELP|MBROWSER, "^P", DO_UP_VOID, 0, TRUE); add_to_sclist(MMAIN|MHELP|MBROWSER, "kup", DO_UP_VOID, 0, TRUE); add_to_sclist(MMAIN|MHELP|MBROWSER, "^N", DO_DOWN_VOID, 0, TRUE); add_to_sclist(MMAIN|MHELP|MBROWSER, "kdown", DO_DOWN_VOID, 0, TRUE); add_to_sclist(MALL, "^A", DO_HOME, 0, TRUE); add_to_sclist(MALL, "khome", DO_HOME, 0, TRUE); add_to_sclist(MALL, "^E", DO_END, 0, TRUE); add_to_sclist(MALL, "kend", DO_END, 0, TRUE); #ifndef NANO_TINY add_to_sclist(MWHEREIS|MREPLACE|MREPLACE2|MWHEREISFILE, "^P", PREV_HISTORY_MSG, 0, FALSE); add_to_sclist(MWHEREIS|MREPLACE|MREPLACE2|MWHEREISFILE, "kup", PREV_HISTORY_MSG, 0, FALSE); add_to_sclist(MWHEREIS|MREPLACE|MREPLACE2|MWHEREISFILE, "^N", NEXT_HISTORY_MSG, 0, FALSE); add_to_sclist(MWHEREIS|MREPLACE|MREPLACE2|MWHEREISFILE, "kdown", NEXT_HISTORY_MSG, 0, FALSE); #endif #ifndef DISABLE_JUSTIFY add_to_sclist(MWHEREIS|MREPLACE|MREPLACE2, "^W", DO_PARA_BEGIN_VOID, 0, TRUE); add_to_sclist(MWHEREIS|MREPLACE|MREPLACE2, "^O", DO_PARA_END_VOID, 0, TRUE); add_to_sclist(MALL, "M-(", DO_PARA_BEGIN_VOID, 0, TRUE); add_to_sclist(MALL, "M-9", DO_PARA_BEGIN_VOID, 0, TRUE); add_to_sclist(MALL, "M-)", DO_PARA_END_VOID, 0, TRUE); add_to_sclist(MALL, "M-0", DO_PARA_END_VOID, 0, TRUE); #endif add_to_sclist(MWHEREIS, "M-C", CASE_SENS_MSG, 0, FALSE); add_to_sclist(MREPLACE, "M-C", CASE_SENS_MSG, 0, FALSE); add_to_sclist(MREPLACE2, "M-C", CASE_SENS_MSG, 0, FALSE); add_to_sclist(MWHEREIS|MREPLACE|MREPLACE2, "M-B", BACKWARDS_MSG, 0, FALSE); add_to_sclist(MWHEREIS|MREPLACE|MREPLACE2, "M-R", REGEXP_MSG, 0, FALSE); add_to_sclist(MMAIN, "M-\\", DO_FIRST_LINE, 0, TRUE); add_to_sclist(MMAIN, "M-|", DO_FIRST_LINE, 0, TRUE); add_to_sclist(MMAIN, "M-/", DO_LAST_LINE, 0, TRUE); add_to_sclist(MMAIN, "M-?", DO_LAST_LINE, 0, TRUE); add_to_sclist(MWHEREIS|MREPLACE|MREPLACE2|MGOTOLINE|MHELP, "^Y", DO_FIRST_LINE, 0, TRUE); add_to_sclist(MWHEREIS|MREPLACE|MREPLACE2|MGOTOLINE|MHELP, "^V", DO_LAST_LINE, 0, TRUE); add_to_sclist(MBROWSER|MWHEREISFILE, "M-\\", FIRST_FILE_MSG, 0, TRUE); add_to_sclist(MBROWSER|MWHEREISFILE, "M-|", FIRST_FILE_MSG, 0, TRUE); add_to_sclist(MBROWSER|MWHEREISFILE, "M-/", LAST_FILE_MSG, 0, TRUE); add_to_sclist(MBROWSER|MWHEREISFILE, "M-?", LAST_FILE_MSG, 0, TRUE); #ifndef NANO_TINY add_to_sclist(MMAIN, "M-]", DO_FIND_BRACKET, 0, TRUE); add_to_sclist(MMAIN, "M--", DO_SCROLL_UP, 0, TRUE); add_to_sclist(MMAIN, "M-_", DO_SCROLL_UP, 0, TRUE); add_to_sclist(MMAIN, "M-+", DO_SCROLL_DOWN, 0, TRUE); add_to_sclist(MMAIN, "M-=", DO_SCROLL_DOWN, 0, TRUE); #endif #ifdef ENABLE_MULTIBUFFER add_to_sclist(MMAIN, "M-<", SWITCH_TO_PREV_BUFFER_VOID, 0, TRUE); add_to_sclist(MMAIN, "M-,", SWITCH_TO_PREV_BUFFER_VOID, 0, TRUE); add_to_sclist(MMAIN, "M->", SWITCH_TO_NEXT_BUFFER_VOID, 0, TRUE); add_to_sclist(MMAIN, "M-.", SWITCH_TO_NEXT_BUFFER_VOID, 0, TRUE); #endif add_to_sclist(MALL, "M-V", DO_VERBATIM_INPUT, 0, TRUE); #ifndef NANO_TINY add_to_sclist(MALL, "M-T", DO_CUT_TILL_END, 0, TRUE); #ifndef DISABLE_JUSTIFY add_to_sclist(MALL, "M-J", DO_FULL_JUSTIFY, 0, TRUE); #endif add_to_sclist(MMAIN, "M-D", DO_WORDLINECHAR_COUNT, 0, TRUE); add_to_sclist(MMAIN, "M-X", DO_TOGGLE, NO_HELP, TRUE); add_to_sclist(MMAIN, "M-C", DO_TOGGLE, CONST_UPDATE, TRUE); add_to_sclist(MMAIN, "M-O", DO_TOGGLE, MORE_SPACE, TRUE); add_to_sclist(MMAIN, "M-S", DO_TOGGLE, SMOOTH_SCROLL, TRUE); add_to_sclist(MMAIN, "M-P", DO_TOGGLE, WHITESPACE_DISPLAY, TRUE); add_to_sclist(MMAIN, "M-Y", DO_TOGGLE, NO_COLOR_SYNTAX, TRUE); add_to_sclist(MMAIN, "M-H", DO_TOGGLE, SMART_HOME, TRUE); add_to_sclist(MMAIN, "M-I", DO_TOGGLE, AUTOINDENT, TRUE); add_to_sclist(MMAIN, "M-K", DO_TOGGLE, CUT_TO_END, TRUE); add_to_sclist(MMAIN, "M-L", DO_TOGGLE, NO_WRAP, TRUE); add_to_sclist(MMAIN, "M-Q", DO_TOGGLE, TABS_TO_SPACES, TRUE); add_to_sclist(MMAIN, "M-B", DO_TOGGLE, BACKUP_FILE, TRUE); add_to_sclist(MMAIN, "M-F", DO_TOGGLE, MULTIBUFFER, TRUE); add_to_sclist(MMAIN, "M-M", DO_TOGGLE, USE_MOUSE, TRUE); add_to_sclist(MMAIN, "M-N", DO_TOGGLE, NO_CONVERT, TRUE); add_to_sclist(MMAIN, "M-Z", DO_TOGGLE, SUSPEND, TRUE); add_to_sclist(MMAIN, "M-$", DO_TOGGLE, SOFTWRAP, TRUE); #endif add_to_sclist(MGOTOLINE, "^T", GOTOTEXT_MSG, 0, FALSE); add_to_sclist(MINSERTFILE|MEXTCMD, "M-F", NEW_BUFFER_MSG, 0, FALSE); add_to_sclist((MWHEREIS|MREPLACE|MREPLACE2|MGOTOLINE|MWRITEFILE|MINSERTFILE|MEXTCMD|MSPELL|MWHEREISFILE|MGOTODIR|MYESNO), "^C", CANCEL_MSG, 0, FALSE); add_to_sclist(MHELP, "^X", DO_EXIT, 0, TRUE); add_to_sclist(MHELP, "F2", DO_EXIT, 0, TRUE); add_to_sclist(MWRITEFILE, "M-D", DOS_FORMAT_MSG, 0, FALSE); add_to_sclist(MWRITEFILE, "M-M", MAC_FORMAT_MSG, 0, FALSE); add_to_sclist(MWRITEFILE, "M-A", APPEND_MSG, 0, FALSE); add_to_sclist(MWRITEFILE, "M-P", PREPEND_MSG, 0, FALSE); add_to_sclist(MWRITEFILE, "M-B", BACKUP_FILE_MSG, 0, FALSE); add_to_sclist(MWRITEFILE, "^T", TO_FILES_MSG, 0, FALSE); add_to_sclist(MINSERTFILE, "^T", TO_FILES_MSG, 0, FALSE); add_to_sclist(MINSERTFILE, "^X", EXT_CMD_MSG, 0, FALSE); add_to_sclist(MMAIN, "^Z", DO_SUSPEND_VOID, 0, FALSE); add_to_sclist(MMAIN, "^L", TOTAL_REFRESH, 0, TRUE); add_to_sclist(MALL, "^I", DO_TAB, 0, TRUE); add_to_sclist(MALL, "^M", DO_ENTER, 0, TRUE); add_to_sclist(MALL, "kenter", DO_ENTER, 0, TRUE); add_to_sclist(MALL, "^D", DO_DELETE, 0, TRUE); add_to_sclist(MALL, "kdel", DO_DELETE, 0, TRUE); add_to_sclist(MALL, "^H", DO_BACKSPACE, 0, TRUE); add_to_sclist(MALL, "kbsp", DO_BACKSPACE, 0, TRUE); #ifdef DEBUG print_sclist(); #endif } /* Given a function alias, execute the proper function, and then me */ void iso_me_harder_funcmap(short func) { if (func == TOTAL_REFRESH) total_refresh(); else if (func == DO_HELP_VOID) do_help_void(); else if (func == DO_SEARCH) do_search(); else if (func == DO_PAGE_UP) do_page_up(); else if (func == DO_PAGE_DOWN) do_page_down(); else if (func == DO_UP_VOID) do_up_void(); else if (func == DO_LEFT) do_left(); else if (func == DO_DOWN_VOID) do_down_void(); else if (func == DO_RIGHT) do_right(); else if (func == DO_ENTER) do_enter(FALSE); else if (func == DO_EXIT) do_exit(); else if (func == DO_FIRST_LINE) do_first_line(); else if (func == DO_LAST_LINE) do_last_line(); else if (func == DO_BACKSPACE) do_backspace(); else if (func == DO_DELETE) do_delete(); else if (func == DO_TAB) do_tab(); else if (func == DO_VERBATIM_INPUT) do_verbatim_input(); #ifdef ENABLE_MULTIBUFFER else if (func == SWITCH_TO_NEXT_BUFFER_VOID) switch_to_next_buffer_void(); else if (func == SWITCH_TO_PREV_BUFFER_VOID) switch_to_prev_buffer_void(); #endif else if (func == DO_END) do_end(); else if (func == DO_HOME) do_home(); else if (func == DO_SUSPEND_VOID) do_suspend_void(); else if (func == DO_WRITEOUT_VOID) do_writeout_void(); else if (func == DO_INSERTFILE_VOID) do_insertfile_void(); else if (func == DO_CUT_TEXT_VOID) do_cut_text_void(); else if (func == DO_UNCUT_TEXT) do_uncut_text(); else if (func == DO_CURSORPOS_VOID) do_cursorpos_void(); else if (func == DO_GOTOLINECOLUMN_VOID) do_gotolinecolumn_void(); else if (func == DO_REPLACE) do_replace(); else if (func == XOFF_COMPLAINT) xoff_complaint(); else if (func == XON_COMPLAINT) xon_complaint(); else if (func == DO_CUT_TEXT) do_cut_text_void(); #ifndef NANO_TINY else if (func == DO_CUT_TILL_END) do_cut_till_end(); else if (func == DO_REDO) do_redo(); else if (func == DO_UNDO) do_undo(); else if (func == DO_WORDLINECHAR_COUNT) do_wordlinechar_count(); else if (func == DO_FIND_BRACKET) do_find_bracket(); else if (func == DO_PREV_WORD_VOID) do_prev_word_void(); #ifndef DISABLE_JUSTIFY else if (func == DO_JUSTIFY_VOID) do_justify_void(); else if (func == DO_PARA_BEGIN_VOID) do_para_begin_void(); else if (func == DO_PARA_END_VOID) do_para_end_void(); else if (func == DO_FULL_JUSTIFY) do_full_justify(); #endif else if (func == DO_MARK) do_mark(); else if (func == DO_RESEARCH) do_research(); else if (func == DO_COPY_TEXT) do_copy_text(); else if (func == DO_INDENT_VOID) do_indent_void(); else if (func == DO_UNINDENT) do_unindent(); else if (func == DO_SCROLL_UP) do_scroll_up(); else if (func == DO_SCROLL_DOWN) do_scroll_down(); else if (func == DO_NEXT_WORD_VOID) do_next_word_void(); #ifndef DISABLE_SPELLER else if (func == DO_SPELL) do_spell(); #endif else if (func == DO_NEXT_WORD) do_next_word_void(); else if (func == DO_PREV_WORD) do_prev_word_void(); #endif } /* Free the given shortcut. */ void free_shortcutage(shortcut **shortcutage) { assert(shortcutage != NULL); while (*shortcutage != NULL) { shortcut *ps = *shortcutage; *shortcutage = (*shortcutage)->next; free(ps); } } const subnfunc *sctofunc(sc *s) { subnfunc *f; for (f = allfuncs; f != NULL && s->scfunc != f->scfunc; f = f->next) ; return f; } #ifndef NANO_TINY /* Now lets come up with a single (hopefully) function to get a string for each flag */ const char *flagtostr(int flag) { switch (flag) { case NO_HELP: return N_("Help mode"); case CONST_UPDATE: return N_("Constant cursor position display"); case MORE_SPACE: return N_("Use of one more line for editing"); case SMOOTH_SCROLL: return N_("Smooth scrolling"); case WHITESPACE_DISPLAY: return N_("Whitespace display"); case NO_COLOR_SYNTAX: return N_("Color syntax highlighting"); case SMART_HOME: return N_("Smart home key"); case AUTOINDENT: return N_("Auto indent"); case CUT_TO_END: return N_("Cut to end"); case NO_WRAP: return N_("Long line wrapping"); case TABS_TO_SPACES: return N_("Conversion of typed tabs to spaces"); case BACKUP_FILE: return N_("Backup files"); case MULTIBUFFER: return N_("Multiple file buffers"); case USE_MOUSE: return N_("Mouse support"); case NO_CONVERT: return N_("No conversion from DOS/Mac format"); case SUSPEND: return N_("Suspension"); case SOFTWRAP: return N_("Soft line wrapping"); default: return "?????"; } } #endif /* NANO_TINY */ /* Interpret the string given by the rc file and return a shortcut struct, complete with proper value for execute */ sc *strtosc(int menu, char *input) { sc *s; s = (sc *)nmalloc(sizeof(sc)); s->execute = TRUE; /* overridden as needed below */ #ifndef DISABLE_HELP if (!strcasecmp(input, "help")) s->scfunc = DO_HELP_VOID; else #endif if (!strcasecmp(input, "cancel")) { s->scfunc = CANCEL_MSG; s->execute = FALSE; } else if (!strcasecmp(input, "exit")) s->scfunc = DO_EXIT; else if (!strcasecmp(input, "writeout")) s->scfunc = DO_WRITEOUT_VOID; else if (!strcasecmp(input, "insert")) s->scfunc = DO_INSERTFILE_VOID; else if (!strcasecmp(input, "whereis")) s->scfunc = DO_SEARCH; else if (!strcasecmp(input, "up")) s->scfunc = DO_UP_VOID; else if (!strcasecmp(input, "down")) s->scfunc = DO_DOWN_VOID; else if (!strcasecmp(input, "pageup") || !strcasecmp(input, "prevpage")) s->scfunc = DO_PAGE_UP; else if (!strcasecmp(input, "pagedown") || !strcasecmp(input, "nextpage")) s->scfunc = DO_PAGE_DOWN; else if (!strcasecmp(input, "cut")) s->scfunc = DO_CUT_TEXT_VOID; else if (!strcasecmp(input, "uncut")) s->scfunc = DO_UNCUT_TEXT; else if (!strcasecmp(input, "curpos") || !strcasecmp(input, "cursorpos")) s->scfunc = DO_CURSORPOS_VOID; else if (!strcasecmp(input, "firstline")) s->scfunc = DO_FIRST_LINE; else if (!strcasecmp(input, "lastline")) s->scfunc = DO_LAST_LINE; else if (!strcasecmp(input, "gotoline")) s->scfunc = DO_GOTOLINECOLUMN_VOID; else if (!strcasecmp(input, "replace")) s->scfunc = DO_REPLACE; #ifndef DISABLE_JUSTIFY else if (!strcasecmp(input, "justify")) s->scfunc = DO_JUSTIFY_VOID; else if (!strcasecmp(input, "beginpara")) s->scfunc = DO_PARA_BEGIN_VOID; else if (!strcasecmp(input, "endpara")) s->scfunc = DO_PARA_END_VOID; else if (!strcasecmp(input, "fulljustify")) s->scfunc = DO_FULL_JUSTIFY; #endif #ifndef NANO_TINY else if (!strcasecmp(input, "mark")) s->scfunc = DO_MARK; else if (!strcasecmp(input, "searchagain") || !strcasecmp(input, "research")) s->scfunc = DO_RESEARCH; else if (!strcasecmp(input, "copytext")) s->scfunc = DO_COPY_TEXT; else if (!strcasecmp(input, "indent")) s->scfunc = DO_INDENT_VOID; else if (!strcasecmp(input, "unindent")) s->scfunc = DO_UNINDENT; else if (!strcasecmp(input, "scrollup")) s->scfunc = DO_SCROLL_UP; else if (!strcasecmp(input, "scrolldown")) s->scfunc = DO_SCROLL_DOWN; else if (!strcasecmp(input, "nextword")) s->scfunc = DO_NEXT_WORD_VOID; else if (!strcasecmp(input, "suspend")) s->scfunc = DO_SUSPEND_VOID; else if (!strcasecmp(input, "prevword")) s->scfunc = DO_PREV_WORD_VOID; else if (!strcasecmp(input, "findbracket")) s->scfunc = DO_FIND_BRACKET; else if (!strcasecmp(input, "wordcount")) s->scfunc = DO_WORDLINECHAR_COUNT; else if (!strcasecmp(input, "undo")) s->scfunc = DO_UNDO; else if (!strcasecmp(input, "redo")) s->scfunc = DO_REDO; else if (!strcasecmp(input, "prevhistory")) { s->scfunc = PREV_HISTORY_MSG; s->execute = FALSE; } else if (!strcasecmp(input, "nexthistory")) { s->scfunc = NEXT_HISTORY_MSG; s->execute = FALSE; } else if (!strcasecmp(input, "nohelp") || !strcasecmp(input, "nohelp")) { s->scfunc = DO_TOGGLE; s->execute = FALSE; s->toggle = NO_HELP; } else if (!strcasecmp(input, "constupdate")) { s->scfunc = DO_TOGGLE; s->execute = FALSE; s->toggle = CONST_UPDATE; } else if (!strcasecmp(input, "morespace")) { s->scfunc = DO_TOGGLE; s->execute = FALSE; s->toggle = MORE_SPACE; } else if (!strcasecmp(input, "smoothscroll")) { s->scfunc = DO_TOGGLE; s->execute = FALSE; s->toggle = SMOOTH_SCROLL; } else if (!strcasecmp(input, "whitespacedisplay")) { s->scfunc = DO_TOGGLE; s->execute = FALSE; s->toggle = WHITESPACE_DISPLAY; } else if (!strcasecmp(input, "nosyntax")) { s->scfunc = DO_TOGGLE; s->execute = FALSE; s->toggle = NO_COLOR_SYNTAX; } else if (!strcasecmp(input, "smarthome")) { s->scfunc = DO_TOGGLE; s->execute = FALSE; s->toggle = SMART_HOME; } else if (!strcasecmp(input, "autoindent")) { s->scfunc = DO_TOGGLE; s->execute = FALSE; s->toggle = AUTOINDENT; } else if (!strcasecmp(input, "cuttoend")) { s->scfunc = DO_TOGGLE; s->execute = FALSE; s->toggle = CUT_TO_END; } else if (!strcasecmp(input, "nowrap")) { s->scfunc = DO_TOGGLE; s->execute = FALSE; s->toggle = NO_WRAP; } else if (!strcasecmp(input, "tabstospaces")) { s->scfunc = DO_TOGGLE; s->execute = FALSE; s->toggle = TABS_TO_SPACES; } else if (!strcasecmp(input, "backupfile")) { s->scfunc = DO_TOGGLE; s->execute = FALSE; s->toggle = BACKUP_FILE; } else if (!strcasecmp(input, "mutlibuffer")) { s->scfunc = DO_TOGGLE; s->execute = FALSE; s->toggle = MULTIBUFFER; } else if (!strcasecmp(input, "mouse")) { s->scfunc = DO_TOGGLE; s->execute = FALSE; s->toggle = USE_MOUSE; } else if (!strcasecmp(input, "noconvert")) { s->scfunc = DO_TOGGLE; s->execute = FALSE; s->toggle = NO_CONVERT; } else if (!strcasecmp(input, "suspendenable")) { s->scfunc = DO_TOGGLE; s->execute = FALSE; s->toggle = SUSPEND; } #endif /* NANO_TINY */ else if (!strcasecmp(input, "right") || !strcasecmp(input, "forward")) s->scfunc = DO_RIGHT; else if (!strcasecmp(input, "left") || !strcasecmp(input, "back")) s->scfunc = DO_LEFT; else if (!strcasecmp(input, "up") || !strcasecmp(input, "prevline")) s->scfunc = DO_UP_VOID; else if (!strcasecmp(input, "down") || !strcasecmp(input, "nextline")) s->scfunc = DO_DOWN_VOID; else if (!strcasecmp(input, "home")) s->scfunc = DO_HOME; else if (!strcasecmp(input, "end")) s->scfunc = DO_END; #ifdef ENABLE_MULTIBUFFER else if (!strcasecmp(input, "prevbuf")) s->scfunc = SWITCH_TO_PREV_BUFFER_VOID; else if (!strcasecmp(input, "nextbuf")) s->scfunc = SWITCH_TO_NEXT_BUFFER_VOID; #endif else if (!strcasecmp(input, "verbatim")) s->scfunc = DO_VERBATIM_INPUT; else if (!strcasecmp(input, "tab")) s->scfunc = DO_TAB; else if (!strcasecmp(input, "enter")) s->scfunc = DO_ENTER; else if (!strcasecmp(input, "delete")) s->scfunc = DO_DELETE; else if (!strcasecmp(input, "backspace")) s->scfunc = DO_BACKSPACE; else if (!strcasecmp(input, "refresh")) s->scfunc = TOTAL_REFRESH; else if (!strcasecmp(input, "casesens")) { s->scfunc = CASE_SENS_MSG; s->execute = FALSE; } else if (!strcasecmp(input, "regexp") || !strcasecmp(input, "regex")) { s->scfunc = REGEXP_MSG; s->execute = FALSE; } else if (!strcasecmp(input, "dontreplace")) { s->scfunc = NO_REPLACE_MSG; s->execute = FALSE; } else if (!strcasecmp(input, "gototext")) { s->scfunc = GOTOTEXT_MSG; s->execute = FALSE; } else if (!strcasecmp(input, "browser") || !strcasecmp(input, "tofiles")) { s->scfunc = TO_FILES_MSG; s->execute = FALSE; } else if (!strcasecmp(input, "dosformat")) { s->scfunc = DOS_FORMAT_MSG; s->execute = FALSE; } else if (!strcasecmp(input, "macformat")) { s->scfunc = MAC_FORMAT_MSG; s->execute = FALSE; } else if (!strcasecmp(input, "append")) { s->scfunc = APPEND_MSG; s->execute = FALSE; } else if (!strcasecmp(input, "prepend")) { s->scfunc = PREPEND_MSG; s->execute = FALSE; } else if (!strcasecmp(input, "backup")) { s->scfunc = BACKUP_FILE_MSG; s->execute = FALSE; #ifdef ENABLE_MULTIBUFFER } else if (!strcasecmp(input, "newbuffer")) { s->scfunc = NEW_BUFFER_MSG; s->execute = FALSE; #endif } else if (!strcasecmp(input, "firstfile")) { s->scfunc = FIRST_FILE_MSG; s->execute = FALSE; } else if (!strcasecmp(input, "lastfile")) { s->scfunc = LAST_FILE_MSG; s->execute = FALSE; } else { free(s); return NULL; } return s; } #ifdef ENABLE_NANORC /* Same thing as abnove but for the menu */ int strtomenu(char *input) { if (!strcasecmp(input, "all")) return MALL; else if (!strcasecmp(input, "main")) return MMAIN; else if (!strcasecmp(input, "search")) return MWHEREIS; else if (!strcasecmp(input, "replace")) return MREPLACE; else if (!strcasecmp(input, "replace2") || !strcasecmp(input, "replacewith")) return MREPLACE2; else if (!strcasecmp(input, "gotoline")) return MGOTOLINE; else if (!strcasecmp(input, "writeout")) return MWRITEFILE; else if (!strcasecmp(input, "insert")) return MINSERTFILE; else if (!strcasecmp(input, "externalcmd") || !strcasecmp(input, "extcmd")) return MEXTCMD; else if (!strcasecmp(input, "help")) return MHELP; else if (!strcasecmp(input, "spell")) return MSPELL; else if (!strcasecmp(input, "browser")) return MBROWSER; else if (!strcasecmp(input, "whereisfile")) return MWHEREISFILE; else if (!strcasecmp(input, "gotodir")) return MGOTODIR; return -1; } #endif #ifdef DEBUG /* This function is used to gracefully return all the memory we've used. * It should be called just before calling exit(). Practically, the * only effect is to cause a segmentation fault if the various data * structures got bolloxed earlier. Thus, we don't bother having this * function unless debugging is turned on. */ void thanks_for_all_the_fish(void) { delwin(topwin); delwin(edit); delwin(bottomwin); #ifndef DISABLE_JUSTIFY if (quotestr != NULL) free(quotestr); #ifdef HAVE_REGEX_H regfree("ereg); if (quoteerr != NULL) free(quoteerr); #endif #endif #ifndef NANO_TINY if (backup_dir != NULL) free(backup_dir); #endif #ifndef DISABLE_OPERATINGDIR if (operating_dir != NULL) free(operating_dir); if (full_operating_dir != NULL) free(full_operating_dir); #endif if (last_search != NULL) free(last_search); if (last_replace != NULL) free(last_replace); #ifndef DISABLE_SPELLER if (alt_speller != NULL) free(alt_speller); #endif if (answer != NULL) free(answer); if (cutbuffer != NULL) free_filestruct(cutbuffer); #ifndef DISABLE_JUSTIFY if (jusbuffer != NULL) free_filestruct(jusbuffer); #endif #ifdef DEBUG /* Free the memory associated with each open file buffer. */ if (openfile != NULL) free_openfilestruct(openfile); #endif #ifdef ENABLE_COLOR if (syntaxstr != NULL) free(syntaxstr); while (syntaxes != NULL) { syntaxtype *bill = syntaxes; free(syntaxes->desc); while (syntaxes->extensions != NULL) { exttype *bob = syntaxes->extensions; syntaxes->extensions = bob->next; free(bob->ext_regex); if (bob->ext != NULL) { regfree(bob->ext); free(bob->ext); } free(bob); } while (syntaxes->color != NULL) { colortype *bob = syntaxes->color; syntaxes->color = bob->next; free(bob->start_regex); if (bob->start != NULL) { regfree(bob->start); free(bob->start); } if (bob->end_regex != NULL) free(bob->end_regex); if (bob->end != NULL) { regfree(bob->end); free(bob->end); } free(bob); } syntaxes = syntaxes->next; free(bill); } #endif /* ENABLE_COLOR */ #ifndef NANO_TINY /* Free the search and replace history lists. */ if (searchage != NULL) free_filestruct(searchage); if (replaceage != NULL) free_filestruct(replaceage); #endif #ifdef ENABLE_NANORC if (homedir != NULL) free(homedir); #endif } #endif /* DEBUG */