From 8d990b5e8b9d1905b6977305d084b82e50c669c6 Mon Sep 17 00:00:00 2001 From: Chris Allegretta Date: Sat, 22 Sep 2001 22:14:25 +0000 Subject: [PATCH] - Bracket (brace, parens, etc) matching code by Ken Tyler. New functions do_find_bracket(), changes to findnextstr(), command is Meta-] (hope you dont mind since I already sold off Meta-O to the MacOS file code Ken...) git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@780 35c25a1d-7b9e-4130-9fde-d3aeb78583b8 --- ChangeLog | 4 ++ global.c | 22 ++++++---- nano.c | 21 ++++++++-- nano.h | 4 +- proto.h | 3 +- search.c | 118 +++++++++++++++++++++++++++++++++++++++++++++--------- 6 files changed, 141 insertions(+), 31 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0b0125ed..29ab8ab4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,6 +18,10 @@ CVS code - Meta-O (MacOS? OS-X? =-) - New smooth scroll code by Ken Tyler. New flag -S, --smooth, changes to page_up() and page_down(). + - Bracket (brace, parens, etc) matching code by Ken Tyler. + New functions do_find_bracket(), changes to findnextstr(), + command is Meta-] (hope you dont mind since I already sold off + Meta-O to the MacOS file code Ken...) - nano.c: main() - Added vars oldcurrent and oldcurrent_x to check whether cursor diff --git a/global.c b/global.c index 52769606..b775220b 100644 --- a/global.c +++ b/global.c @@ -170,8 +170,8 @@ void toggle_init(void) toggle_picomode_msg = _("Pico mode"); toggle_mouse_msg = _("Mouse support"); toggle_cuttoend_msg = _("Cut to end"); - toggle_backwards_msg = _("Backwards Search"); - toggle_case_msg = _("Case Sensitive Search"); + toggle_backwards_msg = _("Backwards search"); + toggle_case_msg = _("Case sensitive search"); toggle_dos_msg = _("Writing file in DOS format"); toggle_mac_msg = _("Writing file in Mac format"); toggle_smooth_msg = _("Smooth scrolling"); @@ -248,7 +248,8 @@ void shortcut_init(int unjustify) #ifndef NANO_SMALL char *nano_tofiles_msg = "", *nano_gotodir_msg = "", *nano_case_msg = - "", *nano_reverse_msg = "", *nano_regexp_msg = ""; + "", *nano_reverse_msg = "", *nano_regexp_msg = "", + *nano_bracket_msg; nano_help_msg = _("Invoke the help menu"); nano_writeout_msg = _("Write the current file to disk"); @@ -292,8 +293,9 @@ void shortcut_init(int unjustify) nano_gotodir_msg = _("Goto Directory"); nano_cancel_msg = _("Cancel the current function"); nano_append_msg = _("Append to the current file"); - nano_reverse_msg = _("Search Backwards"); - nano_regexp_msg = _("Use Regular Expressions"); + nano_reverse_msg = _("Search backwards"); + nano_regexp_msg = _("Use Regular expressions"); + nano_bracket_msg = _("Find other bracket"); #endif sc_init_one(&main_list[0], NANO_HELP_KEY, _("Get Help"), @@ -414,7 +416,11 @@ void shortcut_init(int unjustify) nano_goto_msg, NANO_ALT_G, NANO_GOTO_FKEY, 0, VIEW, do_gotoline_void); - +#if (!defined NANO_SMALL) && (defined HAVE_REGEX_H) + sc_init_one(&main_list[26], 0, _("Find Other Bracket"), + nano_bracket_msg, + NANO_BRACKET_KEY, 0, 0, VIEW, do_find_bracket); +#endif sc_init_one(&whereis_list[0], NANO_FIRSTLINE_KEY, _("First Line"), nano_firstline_msg, 0, 0, 0, VIEW, do_first_line); @@ -433,7 +439,7 @@ void shortcut_init(int unjustify) sc_init_one(&whereis_list[4], TOGGLE_CASE_KEY, _("Case Sens"), nano_case_msg, 0, 0, 0, VIEW, 0); - sc_init_one(&whereis_list[5], TOGGLE_BACKWARDS_KEY, _("Backward"), + sc_init_one(&whereis_list[5], TOGGLE_BACKWARDS_KEY, _("Direction"), nano_reverse_msg, 0, 0, 0, VIEW, 0); #ifdef HAVE_REGEX_H @@ -463,7 +469,7 @@ void shortcut_init(int unjustify) sc_init_one(&replace_list[4], TOGGLE_CASE_KEY, _("Case Sens"), nano_case_msg, 0, 0, 0, VIEW, 0); - sc_init_one(&replace_list[5], TOGGLE_BACKWARDS_KEY, _("Backward"), + sc_init_one(&replace_list[5], TOGGLE_BACKWARDS_KEY, _("Direction"), nano_reverse_msg, 0, 0, 0, VIEW, 0); #ifdef HAVE_REGEX_H diff --git a/nano.c b/nano.c index b03b900f..c59a43d7 100644 --- a/nano.c +++ b/nano.c @@ -1348,7 +1348,7 @@ int do_int_spell_fix(char *word) edit_update(fileage, TOP); /* make sure word is still mis-spelt (i.e. when multi-errors) */ - if (findnextstr(TRUE, fileage, beginx_top, prevanswer) != NULL) { + if (findnextstr(TRUE, FALSE, fileage, beginx_top, prevanswer) != NULL) { do_replace_highlight(TRUE, prevanswer); /* allow replace word to be corrected */ @@ -2266,7 +2266,10 @@ void help_init(void) /* Now add our shortcut info */ for (i = 0; i <= MAIN_LIST_LEN - 1; i++) { - sofar = snprintf(buf, BUFSIZ, "^%c ", main_list[i].val + 64); + if (main_list[i].val) + sofar = snprintf(buf, BUFSIZ, "^%c ", main_list[i].val + 64); + else + sofar = snprintf(buf, BUFSIZ, " "); if (main_list[i].misc1 > KEY_F0 && main_list[i].misc1 <= KEY_F(64)) sofar += snprintf(&buf[sofar], BUFSIZ - sofar, "(F%d) ", @@ -2274,9 +2277,12 @@ void help_init(void) else sofar += snprintf(&buf[sofar], BUFSIZ - sofar, " "); - if (main_list[i].altval > 0) + if (main_list[i].altval > 0 && main_list[i].altval < 91) sofar += snprintf(&buf[sofar], BUFSIZ - sofar, "(M-%c) ", main_list[i].altval - 32); + else if (main_list[i].altval > 0) + sofar += snprintf(&buf[sofar], BUFSIZ - sofar, "(M-%c) ", + main_list[i].altval); else sofar += snprintf(&buf[sofar], BUFSIZ - sofar, " "); @@ -2322,6 +2328,15 @@ void do_toggle(int which) char *enabled = _("enabled"); char *disabled = _("disabled"); +/* + switch (toggles[which].val) { + case TOGGLE_BACKWARDS_KEY: + case TOGGLE_CASE_KEY: + case TOGGLE_REGEXP_KEY: + return; + } +*/ + /* Even easier! */ TOGGLE(toggles[which].flag); diff --git a/nano.h b/nano.h index fa37f79a..1fbaa956 100644 --- a/nano.h +++ b/nano.h @@ -206,6 +206,7 @@ typedef struct rcoption { #define NANO_ALT_Z 'z' #define NANO_ALT_LCARAT ',' #define NANO_ALT_RCARAT '.' +#define NANO_ALT_BRACKET ']' /* Some semi-changeable keybindings; don't play with unless you're sure you know what you're doing */ @@ -263,6 +264,7 @@ know what you're doing */ #define NANO_APPEND_KEY NANO_ALT_A #define NANO_OPENPREV_KEY NANO_ALT_LCARAT #define NANO_OPENNEXT_KEY NANO_ALT_RCARAT +#define NANO_BRACKET_KEY NANO_ALT_BRACKET #define TOGGLE_CONST_KEY NANO_ALT_C #define TOGGLE_AUTOINDENT_KEY NANO_ALT_I @@ -316,7 +318,7 @@ know what you're doing */ #define WRITEFILE_LIST_LEN (3 - NO_BROWSER) #define INSERTFILE_LIST_LEN (2 - NO_BROWSER) #define BROWSER_LIST_LEN 4 -#define MAIN_LIST_LEN 26 +#define MAIN_LIST_LEN 27 #define MAIN_VISIBLE 12 #define REPLACE_LIST_2_LEN 3 #define GOTO_LIST_LEN 3 diff --git a/proto.h b/proto.h index a025c3d2..955870eb 100644 --- a/proto.h +++ b/proto.h @@ -111,6 +111,7 @@ int do_writeout(char *path, int exiting, int append); int do_gotoline(long line, int save_pos); int do_replace_loop(char *prevanswer, filestruct *begin, int *beginx, int wholewords, int *i); +int do_find_bracket(void); #ifdef ENABLE_MULTIBUFFER void do_gotopos(long line, int pos_x, int pos_y, int pos_placewewant); @@ -233,7 +234,7 @@ RETSIGTYPE main_loop (int junk); filestruct *copy_node(filestruct * src); filestruct *copy_filestruct(filestruct * src); filestruct *make_new_node(filestruct * prevnode); -filestruct *findnextstr(int quiet, filestruct * begin, +filestruct *findnextstr(int quiet, int bracket_mode, filestruct * begin, int beginx, char *needle); #ifdef ENABLE_MULTIBUFFER diff --git a/search.c b/search.c index 2f16cf5e..baf136e0 100644 --- a/search.c +++ b/search.c @@ -222,21 +222,25 @@ void not_found_msg(char *str) } } -filestruct *findnextstr(int quiet, filestruct * begin, int beginx, +int past_editbuff; /* search is now looking through lines not displayed */ + +filestruct *findnextstr(int quiet, int bracket_mode, filestruct * begin, int beginx, char *needle) { filestruct *fileptr; char *searchstr, *rev_start = NULL, *found = NULL; - int past_editbot = 0, current_x_find; + int current_x_find; fileptr = current; + past_editbuff = 0; + if (!ISSET(REVERSE_SEARCH)) { /* forward search */ current_x_find = current_x + 1; /* Are we now back to the line where the search started) */ - if ((fileptr == begin) && (current_x_find < beginx)) + if ((fileptr == begin) && (beginx >= current_x_find)) search_last_line = 1; /* Make sure we haven't passed the end of the string */ @@ -257,15 +261,17 @@ filestruct *findnextstr(int quiet, filestruct * begin, int beginx, fileptr = fileptr->next; - if (!past_editbot && (fileptr == editbot)) - past_editbot = 1; + if (!past_editbuff && (fileptr == editbot)) + past_editbuff = 1; /* EOF reached ?, wrap around once */ if (fileptr == NULL) { + if (bracket_mode) /* don't wrap if looking for bracket match */ + return NULL; fileptr = fileage; - past_editbot = 1; + past_editbuff = 1; if (!quiet) - statusbar(_("Search Wrapped")); + statusbar(_("Search Wrapped")); } /* Original start line reached */ @@ -313,13 +319,15 @@ filestruct *findnextstr(int quiet, filestruct * begin, int beginx, fileptr = fileptr->prev; -/* ? */ if (!past_editbot && (fileptr == edittop->prev)) - past_editbot = 1; +/* ? */ if (!past_editbuff && (fileptr == edittop->prev)) + past_editbuff = 1; /* SOF reached ?, wrap around once */ /* ? */ if (fileptr == NULL) { + if (bracket_mode) + return NULL; fileptr = filebot; - past_editbot = 1; + past_editbuff = 1; if (!quiet) statusbar(_("Search Wrapped")); } @@ -347,13 +355,15 @@ filestruct *findnextstr(int quiet, filestruct * begin, int beginx, current = fileptr; current_x = current_x_find; - if (past_editbot) - edit_update(fileptr, CENTER); - else - update_line(current, current_x); + if (!bracket_mode) { + if (past_editbuff) + edit_update(fileptr, CENTER); + else + update_line(current, current_x); - placewewant = xplustabs(); - reset_cursor(); + placewewant = xplustabs(); + reset_cursor(); + } return fileptr; } @@ -413,7 +423,7 @@ int do_search(void) last_search = mallocstrcpy(last_search, answer); search_last_line = 0; - findnextstr(0, current, current_x, answer); + findnextstr(FALSE, FALSE, current, current_x, answer); search_abort(); return 1; } @@ -582,7 +592,7 @@ int do_replace_loop(char *prevanswer, filestruct *begin, int *beginx, while (1) { /* Sweet optimization by Rocco here */ - fileptr = findnextstr(replaceall, begin, *beginx, prevanswer); + fileptr = findnextstr(replaceall, FALSE, begin, *beginx, prevanswer); /* No more matches. Done! */ if (!fileptr) @@ -805,3 +815,75 @@ void do_gotopos(long line, int pos_x, int pos_y, int pos_placewewant) update_line(current, pos_x); } #endif + +#if !defined(NANO_SMALL) && defined(HAVE_REGEX_H) + +int do_find_bracket(void) +{ + char ch_under_cursor, wanted_ch; + char *pos, *brackets = "([{<>}])"; + char regexp_pat[] = "[ ]"; + int offset, have_past_editbuff = 0, flagsave, current_x_save, count = 1; + filestruct *current_save; + + ch_under_cursor = current->data[current_x]; + + if ((!(pos = strchr(brackets, ch_under_cursor))) || (!((offset = pos - brackets) < 8))) { + statusbar(_("Not a bracket")); + return 1; + } + + blank_statusbar_refresh(); + + wanted_ch = *(brackets + ((strlen(brackets) - (offset + 1)))); + + current_x_save = current_x; + current_save = current; + flagsave = flags; + SET(USE_REGEXP); + +/* apparent near redundancy with regexp_pat[] here is needed, [][] works, [[]] doesn't */ + + if (offset < (strlen(brackets) / 2)) { /* on a left bracket */ + regexp_pat[1] = wanted_ch; + regexp_pat[2] = ch_under_cursor; + UNSET(REVERSE_SEARCH); + } else { /* on a right bracket */ + regexp_pat[1] = ch_under_cursor; + regexp_pat[2] = wanted_ch; + SET(REVERSE_SEARCH); + } + + regexp_init(regexp_pat); + + while (1) { + search_last_line = 0; + if (findnextstr(1, 1, current, current_x, regexp_pat)) { + have_past_editbuff |= past_editbuff; + if (current->data[current_x] == ch_under_cursor) /* found identical bracket */ + count++; + else { /* found complementary bracket */ + if (!(--count)) { + if (have_past_editbuff) + edit_update(current, CENTER); + else + update_line(current, current_x); + placewewant = xplustabs(); + reset_cursor(); + break ; + } + } + } else { /* didn't find either left or right bracket */ + statusbar(_("No matching bracket")); + current_x = current_x_save; + current = current_save; + break; + } + } + + if (ISSET(REGEXP_COMPILED)) + regexp_cleanup(); + flags = flagsave; + return 0; +} +#endif