]> git.wh0rd.org Git - nano.git/commitdiff
Rocco's spelling code
authorChris Allegretta <chrisa@asty.org>
Sun, 5 Nov 2000 16:52:21 +0000 (16:52 +0000)
committerChris Allegretta <chrisa@asty.org>
Sun, 5 Nov 2000 16:52:21 +0000 (16:52 +0000)
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@266 35c25a1d-7b9e-4130-9fde-d3aeb78583b8

ChangeLog
nano.c
po/cat-id-tbl.c
po/nano.pot
proto.h
search.c

index 35d94238261994678c0a70b2b175e894ea79c11d..9c7e0c548a5a304d70d56503917a6835c99ed776 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -14,6 +14,11 @@ CVS Code -
          pointers.  New function not_found_msg in search.c for displaying
          truncated strings in satusbar when the string is not found.
          We disable this feature when using PICO_MSGS (-p).
+       - New spelling code by Rocco Corsi.  New functions
+         do_int_speller, do_alt_speller, changes to do_spell in nano.c,
+         New functions search_init_globals and do_replace_loop, changes
+         to search_init(), do_replace, findnextstr, moved last_search and
+         last_replace back to nano.c (*shrug*).
 - files.c:
   do_writeout()
        - Change strcpy to answer to mallocstrcpy.
diff --git a/nano.c b/nano.c
index c1a551959efd59023d584f59b761678a7862a6ab..7137e678de5a99bcadf469617f193e32766f8c89 100644 (file)
--- a/nano.c
+++ b/nano.c
@@ -29,6 +29,8 @@
 #include <sys/stat.h>
 #include <sys/ioctl.h>
 #include <sys/param.h>
+#include <sys/types.h>
+#include <sys/wait.h>
 #include <errno.h>
 #include <ctype.h>
 #include <locale.h>
@@ -66,6 +68,10 @@ static char *help_text_init = "";
                                /* Initial message, not including shortcuts */
 static struct sigaction act;   /* For all out fun signal handlers */
 
+char *last_search = NULL;      /* Last string we searched for */
+char *last_replace = NULL;     /* Last replacement string */
+int search_last_line;          /* Is this the last search line? */
+
 void keypad_on(int yesno)
 {
     keypad(edit, yesno);
@@ -1045,6 +1051,8 @@ void wrap_reset(void)
     UNSET(SAMELINEWRAP);
 }
 
+#ifndef NANO_SMALL
+
 /* Stuff we want to do when we exit the spell program one of its many ways */
 void exit_spell(char *tmpfilename, char *foo)
 {
@@ -1054,65 +1062,259 @@ void exit_spell(char *tmpfilename, char *foo)
        statusbar(_("Error deleting tempfile, ack!"));
     display_main_list();
 }
+#endif
 
-/*
- * This is Chris' very ugly spell function.  Someone please make this
- * better =-)
- */
-int do_spell(void)
+#ifndef NANO_SMALL
+
+int do_int_spell_fix(char *word)
 {
-#ifdef NANO_SMALL
-    nano_small_msg();
-    return 1;
-#else
-    char *temp, *foo;
-    int i, size;
+    char *prevanswer = NULL, *save_search = NULL, *save_replace = NULL;
+    filestruct *begin, *begin_top;
+    int i = 0, beginx, beginx_top;
 
-    if ((temp = tempnam(0, "nano.")) == NULL) {
-       statusbar(_("Could not create a temporary filename: %s"),
-                 strerror(errno));
-       return 0;
+    /* save where we are */
+    begin = current;
+    beginx = current_x + 1;
+
+    /* save the current search/replace strings */
+    search_init_globals();
+    save_search = mallocstrcpy(save_search, last_search);
+    save_replace = mallocstrcpy(save_replace, last_replace);
+
+    /* set search/replace strings to mis-spelt word */
+    prevanswer = mallocstrcpy(prevanswer, word);
+    last_search = mallocstrcpy(last_search, word);
+    last_replace = mallocstrcpy(last_replace, word);
+
+    /* start from the top of file */
+    begin_top = current = fileage;
+    beginx_top = current_x = -1;
+
+    search_last_line = FALSE;
+
+    /* make sure word is still mis-spelt (i.e. when multi-errors) */
+    if (findnextstr(TRUE, begin_top, beginx_top, prevanswer) != NULL)
+    {
+       /* start from the start of this line again */
+       current = begin_top;
+       current_x = beginx_top;
+
+       search_last_line = FALSE;
+
+       /* allow replace word to be corrected */
+       i = statusq(replace_list_2, REPLACE_LIST_2_LEN, last_replace, 
+               _("Edit a replacement"));
+
+       do_replace_loop(prevanswer, begin_top, &beginx_top, TRUE, &i);
     }
-    if (write_file(temp, 1) == -1)
-       return 0;
 
-    if (alt_speller) {
-       size = strlen(temp) + strlen(alt_speller) + 2;
-       foo = nmalloc(size);
-       snprintf(foo, size, "%s %s", alt_speller, temp);
-    } else {
+    /* restore the search/replace strings */
+    last_search = mallocstrcpy(last_search, save_search);
+    last_replace = mallocstrcpy(last_replace, save_replace);
 
-       /* For now, we only try ispell because we're not capable of
-          handling the normal spell program (yet...) */
-       size = strlen(temp) + 8;
-       foo = nmalloc(size);
-       snprintf(foo, size, "ispell %s", temp);
+    /* restore where we were */
+    current = begin;
+    current_x = beginx - 1;
+
+    edit_update(current, CENTER);
+
+    if (i == -1)
+       return FALSE;
+
+    return TRUE;
+}
+#endif
+
+#ifndef NANO_SMALL
+
+/* Integrated spell checking using 'spell' program */
+int do_int_speller(void)
+{
+
+    filestruct *fileptr;
+    char read_buff[2], *read_buff_ptr;
+    char curr_word[132],  *curr_word_ptr;
+    int in_fd[2], out_fd[2];
+    int spell_status;
+    pid_t pid_spell;
+    ssize_t bytesread;
+
+    /* Input from spell pipe */
+    if (pipe(in_fd) == -1)
+       return FALSE;
+
+    /* Output to spell pipe */
+    if (pipe(out_fd) == -1) {
+
+       close(in_fd[0]);
+       close(in_fd[1]);
+
+       return FALSE;
     }
 
-    endwin();
-    if (alt_speller) {
-       if ((i = system(foo)) == -1 || i == 32512) {
-           statusbar(_("Could not invoke spell program \"%s\""),
-                     alt_speller);
-           exit_spell(temp, foo);
-           return 0;
+    if ( (pid_spell = fork()) == 0) {
+
+       /* Child continues, (i.e. future spell process) */
+
+       close(in_fd[1]);
+       close(out_fd[0]);
+
+       /* setup spell standard in */
+       if (dup2(in_fd[0], STDIN_FILENO) != STDIN_FILENO)
+       {
+           close(in_fd[0]);
+           close(out_fd[1]);
+           return FALSE;
        }
-    } else if ((i = system(foo)) == -1 || i == 32512) {        /* Why 32512? I dont know! */
-       statusbar(_("Could not invoke \"ispell\""));
-       exit_spell(temp, foo);
-       return 0;
+       close(in_fd[0]);
+
+       /* setup spell standard out */
+       if (dup2(out_fd[1], STDOUT_FILENO) != STDOUT_FILENO)
+       {
+           close(out_fd[1]);
+           return FALSE;
+       }
+       close(out_fd[1]);
+
+       /* Start spell program */
+       execlp("spell", "spell", NULL);
+
+       /* Should not be reached, if spell is available!!! */
+
+       exit(-1);
     }
-/*    initscr(); */
+
+    /* Parent continues here */
+
+    close(in_fd[0]);           /* close child's input pipe */
+    close(out_fd[1]);          /* close child's output pipe */
+
+    if (pid_spell < 0) {
+
+       /* Child process was not forked successfully */
+
+       close(in_fd[1]);        /* close parent's output pipe */
+       close(out_fd[0]);       /* close parent's input pipe */
+
+       return FALSE;
+    }
+
+    /* Send out the file content to spell program */
+
+    fileptr = fileage;
+
+    while ( fileptr != NULL )
+    {
+       write(in_fd[1], fileptr->data, strlen(fileptr->data));
+       write(in_fd[1], "\n", 1);
+       fileptr = fileptr->next;
+    }
+    close(in_fd[1]);
+
+    /* Let spell process the file */
+
+    wait(&spell_status);
+    if (spell_status != 0)
+       return FALSE;
+
+    /* Read spelling errors from spell */
+
+    curr_word_ptr = curr_word;
+
+    while ( (bytesread = read(out_fd[0], read_buff, sizeof(read_buff) - 1)) > 0)
+    {
+       read_buff[bytesread]=(char) NULL;
+       read_buff_ptr = read_buff;
+
+       while (*read_buff_ptr != (char) NULL)
+       {
+           if (*read_buff_ptr == '\n') {
+               *curr_word_ptr = (char) NULL;
+               if (do_int_spell_fix(curr_word) == FALSE)
+               {
+                    close(out_fd[0]);
+                    return TRUE;
+               }
+               curr_word_ptr = curr_word;
+           }
+           else {
+               *curr_word_ptr = *read_buff_ptr;
+               curr_word_ptr++;
+           }
+
+           read_buff_ptr++;
+       }
+    }
+    close(out_fd[0]);
+    replace_abort();
+
+    return TRUE;
+}
+#endif
+
+#ifndef NANO_SMALL
+
+/* External spell checking */
+int do_alt_speller(char *command_line, char *file_name)
+{
+    int i;
+
+    endwin();
+
+    if ( (i = system(command_line) == -1) || (i == 32512))
+       return FALSE;
+
     refresh();
 
     free_filestruct(fileage);
     global_init();
-    open_file(temp, 0, 1);
+    open_file(file_name, 0, 1);
     edit_update(fileage, CENTER);
     set_modified();
-    exit_spell(temp, foo);
-    statusbar(_("Finished checking spelling"));
-    return 1;
+
+    return TRUE;
+}
+#endif
+
+int do_spell(void)
+{
+
+#ifdef NANO_SMALL
+    nano_small_msg();
+    return (TRUE);
+#else
+    char *temp, *foo;
+    int size, spell_res;
+
+    if (alt_speller) {
+
+       if ((temp = tempnam(0, "nano.")) == NULL) {
+           statusbar(_("Could not create a temporary filename: %s"),
+               strerror(errno));
+           return 0;
+       }
+
+       if (write_file(temp, 1) == -1)
+           return 0;
+
+       size = strlen(temp) + strlen(alt_speller) + 2;
+       foo = nmalloc(size);
+       snprintf(foo, size, "%s %s", alt_speller, temp);
+
+       spell_res = do_alt_speller(foo, temp);
+
+       exit_spell(temp, foo);
+
+    } else
+       spell_res = do_int_speller();
+
+    if (spell_res)
+       statusbar(_("Finished checking spelling"));
+    else
+       statusbar(_("Spell checking failed"));
+
+    return spell_res;
+
 #endif
 }
 
index 2500810a12ca164a0dafdaf572c10b79206f8a6f..2a1e64ec405ba63ec1d6aeb4fc79c3c18663b9fa 100644 (file)
@@ -175,10 +175,10 @@ Usage: nano [option] +LINE <file>\n\
   {"current->data now = \"%s\"\n", 142},
   {"After, data = \"%s\"\n", 143},
   {"Error deleting tempfile, ack!", 144},
-  {"Could not create a temporary filename: %s", 145},
-  {"Could not invoke spell program \"%s\"", 146},
-  {"Could not invoke \"ispell\"", 147},
-  {"Finished checking spelling", 148},
+  {"Edit a replacement", 145},
+  {"Could not create a temporary filename: %s", 146},
+  {"Finished checking spelling", 147},
+  {"Spell checking failed", 148},
   {"Save modified buffer (ANSWERING \"No\" WILL DESTROY CHANGES) ? ", 149},
   {"Cannot resize top win", 150},
   {"Cannot move top win", 151},
@@ -209,10 +209,10 @@ Usage: nano [option] +LINE <file>\n\
   {"Replaced %d occurences", 176},
   {"Replaced 1 occurence", 177},
   {"Replace Cancelled", 178},
-  {"Replace with [%s]", 179},
-  {"Replace with", 180},
-  {"Replace this instance?", 181},
-  {"Replace failed: unknown subexpression!", 182},
+  {"Replace this instance?", 179},
+  {"Replace failed: unknown subexpression!", 180},
+  {"Replace with [%s]", 181},
+  {"Replace with", 182},
   {"Enter line number", 183},
   {"Aborted", 184},
   {"Come on, be reasonable", 185},
index cd70820180893441d4a8000b6546caf857b83110..914d75450bf89b983b38ec65bfa521339b28d253 100644 (file)
@@ -6,7 +6,7 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 2000-11-03 09:21-0500\n"
+"POT-Creation-Date: 2000-11-05 11:52-0500\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -32,7 +32,7 @@ msgstr ""
 msgid "Read %d lines"
 msgstr ""
 
-#: files.c:217 search.c:163
+#: files.c:217 search.c:164
 #, c-format
 msgid "\"%s\" not found"
 msgstr ""
@@ -55,7 +55,7 @@ msgstr ""
 msgid "File to insert [from ./] "
 msgstr ""
 
-#: files.c:274 files.c:298 files.c:486 nano.c:1145
+#: files.c:274 files.c:298 files.c:486 nano.c:1347
 msgid "Cancelled"
 msgstr ""
 
@@ -388,17 +388,17 @@ msgstr ""
 msgid "No Replace"
 msgstr ""
 
-#: nano.c:125
+#: nano.c:131
 msgid ""
 "\n"
 "Buffer written to 'nano.save'\n"
 msgstr ""
 
-#: nano.c:132
+#: nano.c:138
 msgid "Key illegal in VIEW mode"
 msgstr ""
 
-#: nano.c:169
+#: nano.c:175
 msgid ""
 " nano help text\n"
 "\n"
@@ -419,397 +419,395 @@ msgid ""
 "\n"
 msgstr ""
 
-#: nano.c:272
+#: nano.c:278
 msgid "free_node(): free'd a node, YAY!\n"
 msgstr ""
 
-#: nano.c:277
+#: nano.c:283
 msgid "free_node(): free'd last node.\n"
 msgstr ""
 
-#: nano.c:329
+#: nano.c:335
 msgid ""
 "Usage: nano [GNU long option] [option] +LINE <file>\n"
 "\n"
 msgstr ""
 
-#: nano.c:330
+#: nano.c:336
 msgid "Option\t\tLong option\t\tMeaning\n"
 msgstr ""
 
-#: nano.c:332
+#: nano.c:338
 msgid " -T \t\t--tabsize=[num]\t\tSet width of a tab to num\n"
 msgstr ""
 
-#: nano.c:335
+#: nano.c:341
 msgid " -R\t\t--regexp\t\tUse regular expressions for search\n"
 msgstr ""
 
-#: nano.c:339
+#: nano.c:345
 msgid " -V \t\t--version\t\tPrint version information and exit\n"
 msgstr ""
 
-#: nano.c:341
+#: nano.c:347
 msgid " -c \t\t--const\t\t\tConstantly show cursor position\n"
 msgstr ""
 
-#: nano.c:343
+#: nano.c:349
 msgid " -h \t\t--help\t\t\tShow this message\n"
 msgstr ""
 
-#: nano.c:346
+#: nano.c:352
 msgid " -k \t\t--cut\t\t\tLet ^K cut from cursor to end of line\n"
 msgstr ""
 
-#: nano.c:349
+#: nano.c:355
 msgid " -i \t\t--autoindent\t\tAutomatically indent new lines\n"
 msgstr ""
 
-#: nano.c:351
+#: nano.c:357
 msgid " -l \t\t--nofollow\t\tDon't follow symbolic links, overwrite\n"
 msgstr ""
 
-#: nano.c:354
+#: nano.c:360
 msgid " -m \t\t--mouse\t\t\tEnable mouse\n"
 msgstr ""
 
-#: nano.c:359
+#: nano.c:365
 msgid ""
 " -r [#cols] \t--fill=[#cols]\t\tSet fill cols to (wrap lines at) #cols\n"
 msgstr ""
 
-#: nano.c:361
+#: nano.c:367
 msgid " -p\t \t--pico\t\t\tMake bottom 2 lines more Pico-like\n"
 msgstr ""
 
-#: nano.c:363
+#: nano.c:369
 msgid " -s [prog] \t--speller=[prog]\tEnable alternate speller\n"
 msgstr ""
 
-#: nano.c:365
+#: nano.c:371
 msgid " -t \t\t--tempfile\t\tAuto save on exit, don't prompt\n"
 msgstr ""
 
-#: nano.c:367
+#: nano.c:373
 msgid " -v \t\t--view\t\t\tView (read only) mode\n"
 msgstr ""
 
-#: nano.c:369
+#: nano.c:375
 msgid " -w \t\t--nowrap\t\tDon't wrap long lines\n"
 msgstr ""
 
-#: nano.c:371
+#: nano.c:377
 msgid " -x \t\t--nohelp\t\tDon't show help window\n"
 msgstr ""
 
-#: nano.c:373
+#: nano.c:379
 msgid " -z \t\t--suspend\t\tEnable suspend\n"
 msgstr ""
 
-#: nano.c:375
+#: nano.c:381
 msgid " +LINE\t\t\t\t\tStart at line number LINE\n"
 msgstr ""
 
-#: nano.c:377
+#: nano.c:383
 msgid ""
 "Usage: nano [option] +LINE <file>\n"
 "\n"
 msgstr ""
 
-#: nano.c:378
+#: nano.c:384
 msgid "Option\t\tMeaning\n"
 msgstr ""
 
-#: nano.c:379
+#: nano.c:385
 msgid " -T [num]\tSet width of a tab to num\n"
 msgstr ""
 
-#: nano.c:380
+#: nano.c:386
 msgid " -R\t\tUse regular expressions for search\n"
 msgstr ""
 
-#: nano.c:381
+#: nano.c:387
 msgid " -V \t\tPrint version information and exit\n"
 msgstr ""
 
-#: nano.c:382
+#: nano.c:388
 msgid " -c \t\tConstantly show cursor position\n"
 msgstr ""
 
-#: nano.c:383
+#: nano.c:389
 msgid " -h \t\tShow this message\n"
 msgstr ""
 
-#: nano.c:385
+#: nano.c:391
 msgid " -k \t\tLet ^K cut from cursor to end of line\n"
 msgstr ""
 
-#: nano.c:387
+#: nano.c:393
 msgid " -i \t\tAutomatically indent new lines\n"
 msgstr ""
 
-#: nano.c:389
+#: nano.c:395
 msgid " -l \t\tDon't follow symbolic links, overwrite\n"
 msgstr ""
 
-#: nano.c:392
+#: nano.c:398
 msgid " -m \t\tEnable mouse\n"
 msgstr ""
 
-#: nano.c:396
+#: nano.c:402
 msgid " -r [#cols] \tSet fill cols to (wrap lines at) #cols\n"
 msgstr ""
 
-#: nano.c:397
+#: nano.c:403
 msgid " -s [prog]  \tEnable alternate speller\n"
 msgstr ""
 
-#: nano.c:398
+#: nano.c:404
 msgid " -p \t\tMake bottom 2 lines more Pico-like\n"
 msgstr ""
 
-#: nano.c:399
+#: nano.c:405
 msgid " -t \t\tAuto save on exit, don't prompt\n"
 msgstr ""
 
-#: nano.c:400
+#: nano.c:406
 msgid " -v \t\tView (read only) mode\n"
 msgstr ""
 
-#: nano.c:401
+#: nano.c:407
 msgid " -w \t\tDon't wrap long lines\n"
 msgstr ""
 
-#: nano.c:402
+#: nano.c:408
 msgid " -x \t\tDon't show help window\n"
 msgstr ""
 
-#: nano.c:403
+#: nano.c:409
 msgid " -z \t\tEnable suspend\n"
 msgstr ""
 
-#: nano.c:404
+#: nano.c:410
 msgid " +LINE\t\tStart at line number LINE\n"
 msgstr ""
 
-#: nano.c:411
+#: nano.c:417
 #, c-format
 msgid " nano version %s by Chris Allegretta (compiled %s, %s)\n"
 msgstr ""
 
-#: nano.c:414
+#: nano.c:420
 msgid " Email: nano@nano-editor.org\tWeb: http://www.nano-editor.org\n"
 msgstr ""
 
-#: nano.c:449
+#: nano.c:455
 msgid "Mark Set"
 msgstr ""
 
-#: nano.c:454
+#: nano.c:460
 msgid "Mark UNset"
 msgstr ""
 
-#: nano.c:881
+#: nano.c:887
 #, c-format
 msgid "check_wrap called with inptr->data=\"%s\"\n"
 msgstr ""
 
-#: nano.c:932
+#: nano.c:938
 #, c-format
 msgid "current->data now = \"%s\"\n"
 msgstr ""
 
-#: nano.c:985
+#: nano.c:991
 #, c-format
 msgid "After, data = \"%s\"\n"
 msgstr ""
 
-#: nano.c:1054
+#: nano.c:1062
 msgid "Error deleting tempfile, ack!"
 msgstr ""
 
-#: nano.c:1072
-#, c-format
-msgid "Could not create a temporary filename: %s"
+#: nano.c:1106
+msgid "Edit a replacement"
 msgstr ""
 
-#: nano.c:1095
+#: nano.c:1292
 #, c-format
-msgid "Could not invoke spell program \"%s\""
+msgid "Could not create a temporary filename: %s"
 msgstr ""
 
-#. Why 32512? I dont know!
-#: nano.c:1101
-msgid "Could not invoke \"ispell\""
+#: nano.c:1312
+msgid "Finished checking spelling"
 msgstr ""
 
-#: nano.c:1114
-msgid "Finished checking spelling"
+#: nano.c:1314
+msgid "Spell checking failed"
 msgstr ""
 
-#: nano.c:1132
+#: nano.c:1334
 msgid "Save modified buffer (ANSWERING \"No\" WILL DESTROY CHANGES) ? "
 msgstr ""
 
-#: nano.c:1295
+#: nano.c:1497
 msgid "Cannot resize top win"
 msgstr ""
 
-#: nano.c:1297
+#: nano.c:1499
 msgid "Cannot move top win"
 msgstr ""
 
-#: nano.c:1299
+#: nano.c:1501
 msgid "Cannot resize edit win"
 msgstr ""
 
-#: nano.c:1301
+#: nano.c:1503
 msgid "Cannot move edit win"
 msgstr ""
 
-#: nano.c:1303
+#: nano.c:1505
 msgid "Cannot resize bottom win"
 msgstr ""
 
-#: nano.c:1305
+#: nano.c:1507
 msgid "Cannot move bottom win"
 msgstr ""
 
-#: nano.c:1576
+#: nano.c:1778
 msgid "Justify Complete"
 msgstr ""
 
-#: nano.c:1644
+#: nano.c:1846
 #, c-format
 msgid "%s enable/disable"
 msgstr ""
 
-#: nano.c:1656
+#: nano.c:1858
 msgid "enabled"
 msgstr ""
 
-#: nano.c:1657
+#: nano.c:1859
 msgid "disabled"
 msgstr ""
 
-#: nano.c:1887
+#: nano.c:2089
 msgid "Main: set up windows\n"
 msgstr ""
 
-#: nano.c:1900
+#: nano.c:2102
 msgid "Main: bottom win\n"
 msgstr ""
 
-#: nano.c:1906
+#: nano.c:2108
 msgid "Main: open file\n"
 msgstr ""
 
-#: nano.c:1940
+#: nano.c:2142
 #, c-format
 msgid "I got Alt-O-%c! (%d)\n"
 msgstr ""
 
-#: nano.c:1962
+#: nano.c:2164
 #, c-format
 msgid "I got Alt-[-1-%c! (%d)\n"
 msgstr ""
 
-#: nano.c:1995
+#: nano.c:2197
 #, c-format
 msgid "I got Alt-[-2-%c! (%d)\n"
 msgstr ""
 
-#: nano.c:2043
+#: nano.c:2245
 #, c-format
 msgid "I got Alt-[-%c! (%d)\n"
 msgstr ""
 
-#: nano.c:2069
+#: nano.c:2271
 #, c-format
 msgid "I got Alt-%c! (%d)\n"
 msgstr ""
 
-#: search.c:98
+#: search.c:99
 #, c-format
 msgid "Case Sensitive Regexp Search%s%s"
 msgstr ""
 
-#: search.c:100
+#: search.c:101
 #, c-format
 msgid "Regexp Search%s%s"
 msgstr ""
 
-#: search.c:102
+#: search.c:103
 #, c-format
 msgid "Case Sensitive Search%s%s"
 msgstr ""
 
-#: search.c:104
+#: search.c:105
 #, c-format
 msgid "Search%s%s"
 msgstr ""
 
-#: search.c:107
+#: search.c:108
 msgid " (to replace)"
 msgstr ""
 
-#: search.c:120 search.c:289
+#: search.c:121 search.c:290
 msgid "Search Cancelled"
 msgstr ""
 
-#: search.c:167
+#: search.c:168
 #, c-format
 msgid "\"%s...\" not found"
 msgstr ""
 
-#: search.c:214
+#: search.c:215
 msgid "Search Wrapped"
 msgstr ""
 
-#: search.c:303
+#: search.c:304
 #, c-format
 msgid "Replaced %d occurences"
 msgstr ""
 
-#: search.c:305
+#: search.c:306
 msgid "Replaced 1 occurence"
 msgstr ""
 
-#: search.c:441 search.c:457 search.c:488
+#: search.c:443 search.c:536 search.c:552
 msgid "Replace Cancelled"
 msgstr ""
 
-#: search.c:474
-#, c-format
-msgid "Replace with [%s]"
+#: search.c:486
+msgid "Replace this instance?"
 msgstr ""
 
-#: search.c:478 search.c:482
-msgid "Replace with"
+#: search.c:494
+msgid "Replace failed: unknown subexpression!"
 msgstr ""
 
-#: search.c:519
-msgid "Replace this instance?"
+#: search.c:569
+#, c-format
+msgid "Replace with [%s]"
 msgstr ""
 
-#: search.c:527
-msgid "Replace failed: unknown subexpression!"
+#: search.c:573 search.c:577
+msgid "Replace with"
 msgstr ""
 
 #. Ask for it
-#: search.c:580
+#: search.c:612
 msgid "Enter line number"
 msgstr ""
 
-#: search.c:582
+#: search.c:614
 msgid "Aborted"
 msgstr ""
 
-#: search.c:602
+#: search.c:634
 msgid "Come on, be reasonable"
 msgstr ""
 
-#: search.c:607
+#: search.c:639
 #, c-format
 msgid "Only %d lines available, skipping to last line"
 msgstr ""
diff --git a/proto.h b/proto.h
index 6fe76aa3f1a8c561cd0a30b7365f05c7285aa014..be689f0e2cb7fccb0a0c57101bed0b78301c3ffd 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -35,11 +35,14 @@ extern int placewewant;
 extern int mark_beginx, samelinewrap;
 extern int totsize, temp_opt;
 extern int fill, flags,tabsize;
+extern int search_last_line;
 
 extern WINDOW *edit, *topwin, *bottomwin;
 extern char filename[PATH_MAX];
 extern char *answer;
 extern char *hblank, *help_text;
+extern char *last_search;
+extern char *last_replace;
 extern struct stat fileinfo;
 extern filestruct *current, *fileage, *edittop, *editbot, *filebot; 
 extern filestruct *cutbuffer, *mark_beginbuf;
@@ -77,6 +80,8 @@ int renumber_all(void);
 int open_file(char *filename, int insert, int quiet);
 int do_writeout(int exiting);
 int do_gotoline(long defline);
+int do_replace_loop(char *prevanswer, filestruct *begin, int *beginx,
+                       int wholewords, int *i);
 /* Now in move.c */
 int do_up(void);
 int do_down(void);
@@ -120,6 +125,8 @@ void new_magicline(void);
 void splice_node(filestruct *begin, filestruct *new, filestruct *end);
 void null_at(char *data, int index);
 void page_up_center(void);
+void search_init_globals(void);
+void replace_abort(void);
 
 int do_writeout_void(void), do_exit(void), do_gotoline_void(void);
 int do_insertfile(void), do_search(void), page_up(void), page_down(void);
@@ -133,3 +140,5 @@ int do_replace(void), do_help(void), do_enter_void(void);
 filestruct *copy_node(filestruct * src);
 filestruct *copy_filestruct(filestruct * src);
 filestruct *make_new_node(filestruct * prevnode);
+filestruct *findnextstr(int quiet, filestruct * begin,
+                       int beginx, char *needle);
index 501900f25045d412c5fd0ec26a905e5e5e79a7ed..9f1ddb02417c9c1e8f1ab9bad928eee6042e633f 100644 (file)
--- a/search.c
+++ b/search.c
@@ -23,6 +23,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <stdio.h>
+#include <ctype.h>
 #include "config.h"
 #include "proto.h"
 #include "nano.h"
 #define _(string) (string)
 #endif
 
-static char *last_search = NULL;       /* Last string we searched for */
-static char *last_replace = NULL;      /* Last replacement string */
-static int search_last_line;
-
-
 /* Regular expression helper functions */
 
 #ifdef HAVE_REGEX_H
@@ -55,6 +51,18 @@ void regexp_cleanup()
 }
 #endif
 
+void search_init_globals(void)
+{
+    if (last_search == NULL) {
+       last_search = nmalloc(1);
+       last_search[0] = 0;
+    }
+    if (last_replace == NULL) {
+       last_replace = nmalloc(1);
+       last_replace[0] = 0;
+    }
+}
+
 /* Set up the system variables for a search or replace.  Returns -1 on
    abort, 0 on success, and 1 on rerun calling program 
    Return -2 to run opposite program (searchg -> replace, replace -> search)
@@ -67,20 +75,13 @@ int search_init(int replacing)
     char *buf;
     char *prompt, *reprompt = "";
 
-   if (last_search == NULL) {
-       last_search = nmalloc(1);
-       last_search[0] = 0;
-   }
-   if (last_replace == NULL) {
-       last_replace = nmalloc(1);
-       last_replace[0] = 0;
-   }
+    search_init_globals();
 
-   buf = nmalloc(strlen(last_search) + 5);
-   buf[0] = 0;
+    buf = nmalloc(strlen(last_search) + 5);
+    buf[0] = 0;
 
-   /* If using Pico messages, we do things the old fashioned way... */
-   if (ISSET(PICO_MSGS)) {
+    /* If using Pico messages, we do things the old fashioned way... */
+    if (ISSET(PICO_MSGS)) {
        if (last_search[0]) {
 
            /* We use COLS / 3 here because we need to see more on the line */
@@ -428,60 +429,14 @@ char *replace_line(void)
     return copy;
 }
 
-/* Replace a string */
-int do_replace(void)
+int do_replace_loop(char *prevanswer, filestruct *begin, int *beginx,
+                       int wholewords, int *i)
 {
-    int i, replaceall = 0, numreplaced = 0, beginx;
-    filestruct *fileptr, *begin;
-    char *copy, *prevanswer = NULL, *buf = NULL;
-
-    i = search_init(1);
-    switch (i) {
-    case -1:
-       statusbar(_("Replace Cancelled"));
-       replace_abort();
-       return 0;
-    case 1:
-       do_replace();
-       return 1;
-    case -2:
-       do_search();
-       return 0;
-    case -3:
-       replace_abort();
-       return 0;
-    }
-
-    /* Again, there was a previous string but they deleted it and hit enter */
-    if (!strcmp(answer, "")) {
-       statusbar(_("Replace Cancelled"));
-       replace_abort();
-       return 0;
-    }
-
-    prevanswer = mallocstrcpy(prevanswer, answer);
-
-    if (ISSET(PICO_MSGS)) {
-       buf = nmalloc(strlen(last_replace) + 5);
-       if (strcmp(last_replace, "")) {
-           if (strlen(last_replace) > (COLS / 3)) {
-               strncpy(buf, last_replace, COLS / 3);
-               sprintf(&buf[COLS / 3 - 1], "...");
-           } else
-               sprintf(buf, "%s", last_replace);
-
-           i = statusq(replace_list_2, REPLACE_LIST_2_LEN, "",
-                       _("Replace with [%s]"), buf);
-       }
-       else
-           i = statusq(replace_list_2, REPLACE_LIST_2_LEN, "",
-                       _("Replace with"));
-    }
-    else
-       i = statusq(replace_list_2, REPLACE_LIST_2_LEN, last_replace, 
-                       _("Replace with"));
+    int replaceall = 0, numreplaced = 0;
+    filestruct *fileptr;
+    char *copy;
 
-    switch (i) {
+    switch (*i) {
     case -1:                           /* Aborted enter */
        if (strcmp(last_replace, ""))
            answer = mallocstrcpy(answer, last_replace);
@@ -492,7 +447,7 @@ int do_replace(void)
        last_replace = mallocstrcpy(last_replace, answer);
        break;
     default:
-        if (i != -2) { /* First page, last page, for example 
+        if (*i != -2) {        /* First page, last page, for example 
                                   could get here */
            do_early_abort();
            replace_abort();
@@ -500,26 +455,38 @@ int do_replace(void)
         }
     }
 
-    /* save where we are */
-    begin = current;
-    beginx = current_x + 1;
-    search_last_line = 0;
-
     while (1) {
 
        /* Sweet optimization by Rocco here */
-       fileptr = findnextstr(replaceall, begin, beginx, prevanswer);
+       fileptr = findnextstr(replaceall, begin, *beginx, prevanswer);
 
        /* No more matches.  Done! */
        if (!fileptr)
            break;
 
+       /* Make sure only wholewords are found */
+       if (wholewords)
+       {
+           /* start of line or previous character not a letter */
+           if ((current_x == 0) || (!isalpha(fileptr->data[current_x-1])))
+           {
+               /* end of line or next character not a letter */
+               if (((current_x + strlen(prevanswer)) == strlen(fileptr->data))
+                       || (!isalpha(fileptr->data[current_x + strlen(prevanswer)])))
+                   ;
+               else
+                   continue;
+           }
+           else
+               continue;
+       }
+
        /* If we're here, we've found the search string */
        if (!replaceall)
-           i = do_yesno(1, 1, _("Replace this instance?"));
+           *i = do_yesno(1, 1, _("Replace this instance?"));
 
-       if (i > 0 || replaceall) {      /* Yes, replace it!!!! */
-           if (i == 2)
+       if (*i > 0 || replaceall) {     /* Yes, replace it!!!! */
+           if (*i == 2)
                replaceall = 1;
 
            copy = replace_line();
@@ -538,21 +505,86 @@ int do_replace(void)
 
            /* Adjust the original cursor position - COULD BE IMPROVED */
            if (search_last_line) {
-               beginx += strlen(last_replace) - strlen(last_search);
+               *beginx += strlen(last_replace) - strlen(last_search);
 
                /* For strings that cross the search start/end boundary */
                /* Don't go outside of allocated memory */
-               if (beginx < 1)
-                   beginx = 1;
+               if (*beginx < 1)
+                   *beginx = 1;
            }
 
            edit_refresh();
            set_modified();
            numreplaced++;
-       } else if (i == -1)     /* Abort, else do nothing and continue loop */
+       } else if (*i == -1)    /* Abort, else do nothing and continue loop */
            break;
     }
 
+    return numreplaced;
+}
+
+/* Replace a string */
+int do_replace(void)
+{
+    int i, numreplaced, beginx;
+    filestruct *begin;
+    char *prevanswer = NULL, *buf = NULL;
+
+    i = search_init(1);
+    switch (i) {
+    case -1:
+       statusbar(_("Replace Cancelled"));
+       replace_abort();
+       return 0;
+    case 1:
+       do_replace();
+       return 1;
+    case -2:
+       do_search();
+       return 0;
+    case -3:
+       replace_abort();
+       return 0;
+    }
+
+    /* Again, there was a previous string but they deleted it and hit enter */
+    if (!strcmp(answer, "")) {
+       statusbar(_("Replace Cancelled"));
+       replace_abort();
+       return 0;
+    }
+
+    prevanswer = mallocstrcpy(prevanswer, answer);
+
+    if (ISSET(PICO_MSGS)) {
+       buf = nmalloc(strlen(last_replace) + 5);
+       if (strcmp(last_replace, "")) {
+           if (strlen(last_replace) > (COLS / 3)) {
+               strncpy(buf, last_replace, COLS / 3);
+               sprintf(&buf[COLS / 3 - 1], "...");
+           } else
+               sprintf(buf, "%s", last_replace);
+
+           i = statusq(replace_list_2, REPLACE_LIST_2_LEN, "",
+                       _("Replace with [%s]"), buf);
+       }
+       else
+           i = statusq(replace_list_2, REPLACE_LIST_2_LEN, "",
+                       _("Replace with"));
+    }
+    else
+       i = statusq(replace_list_2, REPLACE_LIST_2_LEN, last_replace, 
+                       _("Replace with"));
+
+    /* save where we are */
+    begin = current;
+    beginx = current_x + 1;
+
+    search_last_line = 0;
+
+    numreplaced = do_replace_loop(prevanswer, begin, &beginx, FALSE, &i);
+
+    /* restore where we were */
     current = begin;
     current_x = beginx - 1;
     renumber_all();