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.
#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>
/* 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);
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)
{
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
}
{"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},
{"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},
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"
msgid "Read %d lines"
msgstr ""
-#: files.c:217 search.c:163
+#: files.c:217 search.c:164
#, c-format
msgid "\"%s\" not found"
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 ""
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"
"\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 ""
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;
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);
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);
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);
#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
}
#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)
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 */
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);
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();
}
}
- /* 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();
/* 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();