]> git.wh0rd.org Git - nano.git/commitdiff
Split nano.c up more
authorChris Allegretta <chrisa@asty.org>
Mon, 19 Jun 2000 04:22:15 +0000 (04:22 +0000)
committerChris Allegretta <chrisa@asty.org>
Mon, 19 Jun 2000 04:22:15 +0000 (04:22 +0000)
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@27 35c25a1d-7b9e-4130-9fde-d3aeb78583b8

Makefile.am
Makefile.in
files.c [new file with mode: 0644]
move.c [new file with mode: 0644]
nano.c
proto.h
search.c [new file with mode: 0644]
utils.c

index 1e5f7d5b108df210d6d32c72b5aced1f0e49cb84..1244b170c30994ed16e6ac8200c72e2e0af4bd20 100644 (file)
@@ -1,9 +1,12 @@
 bin_PROGRAMS =         nano
 nano_SOURCES = cut.c \
+               files.c \
                global.c \
+               move.c \
                nano.c \
                nano.h \
                proto.h \
+               search.c \
                utils.c \
                winio.c 
 
index 1f9429e3951ba2d9b3d9598d033ec3cff820cfe7..e7629f2902db89f605ba98190707b32f26c32908 100644 (file)
@@ -88,7 +88,7 @@ VERSION = @VERSION@
 l = @l@
 
 bin_PROGRAMS = nano
-nano_SOURCES = cut.c           global.c                nano.c          nano.h          proto.h                 utils.c                 winio.c 
+nano_SOURCES = cut.c           files.c                 global.c                move.c          nano.c          nano.h          proto.h                 search.c                utils.c                 winio.c 
 
 
 man_MANS = nano.1
@@ -112,7 +112,8 @@ DEFS = @DEFS@ -I. -I$(srcdir) -I.
 CPPFLAGS = @CPPFLAGS@
 LDFLAGS = @LDFLAGS@
 LIBS = @LIBS@
-nano_OBJECTS =  cut.o global.o nano.o utils.o winio.o
+nano_OBJECTS =  cut.o files.o global.o move.o nano.o search.o utils.o \
+winio.o
 nano_DEPENDENCIES = 
 nano_LDFLAGS = 
 CFLAGS = @CFLAGS@
@@ -398,7 +399,7 @@ distdir: $(DISTFILES)
        @for file in $(DISTFILES); do \
          d=$(srcdir); \
          if test -d $$d/$$file; then \
-           cp -pr $$/$$file $(distdir)/$$file; \
+           cp -pr $$d/$$file $(distdir)/$$file; \
          else \
            test -f $(distdir)/$$file \
            || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
diff --git a/files.c b/files.c
new file mode 100644 (file)
index 0000000..03b68cb
--- /dev/null
+++ b/files.c
@@ -0,0 +1,470 @@
+/**************************************************************************
+ *   files.c                                                              *
+ *                                                                        *
+ *   Copyright (C) 1999 Chris Allegretta                                  *
+ *   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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.            *
+ *                                                                        *
+ **************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "config.h"
+#include "proto.h"
+#include "nano.h"
+#ifndef NANO_SMALL
+#include <libintl.h>
+#define _(string) gettext(string)
+#else
+#define _(string) (string)
+#endif
+
+/* Load file into edit buffer - takes data from file struct */
+void load_file(void)
+{
+    current = fileage;
+    wmove(edit, current_y, current_x);
+}
+
+/* What happens when there is no file to open? aiee! */
+void new_file(void)
+{
+    fileage = nmalloc(sizeof(filestruct));
+    fileage->data = nmalloc(1);
+    strcpy(fileage->data, "");
+    fileage->prev = NULL;
+    fileage->next = NULL;
+    fileage->lineno = 1;
+    filebot = fileage;
+    edittop = fileage;
+    editbot = fileage;
+    current = fileage;
+    totlines = 1;
+    UNSET(VIEW_MODE);
+}
+
+
+int read_byte(int fd, char *filename, char *input)
+{
+    static char buf[BUFSIZ];
+    static int index = 0;
+    static int size = 0;
+
+    if (index == size) {
+       index = 0;
+       size = read(fd, buf, BUFSIZ);
+       if (size == -1) {
+           clear();
+           refresh();
+           resetty();
+           endwin();
+           perror(filename);
+       }
+       if (!size)
+           return 0;
+    }
+    *input = buf[index++];
+    return 1;
+}
+
+filestruct *read_line(char *buf, filestruct * prev, int *line1ins)
+{
+    filestruct *fileptr;
+
+    fileptr = nmalloc(sizeof(filestruct));
+    fileptr->data = nmalloc(strlen(buf) + 2);
+    strcpy(fileptr->data, buf);
+
+    if (*line1ins) {
+       /* Special case, insert with cursor on 1st line. */
+       fileptr->prev = NULL;
+       fileptr->next = fileage;
+       fileptr->lineno = 1;
+       *line1ins = 0;
+       /* If we're inserting into the first line of the file, then
+          we want to make sure that our edit buffer stays on the
+          first line (and that fileage stays up to date!) */
+       fileage = fileptr;
+       edittop = fileptr;
+    } else if (fileage == NULL) {
+       fileage = fileptr;
+       fileage->lineno = 1;
+       fileage->next = fileage->prev = NULL;
+       fileptr = filebot = fileage;
+    } else if (prev) {
+       fileptr->prev = prev;
+       fileptr->next = NULL;
+       fileptr->lineno = prev->lineno + 1;
+       prev->next = fileptr;
+    } else {
+       die(_("read_line: not on first line and prev is NULL"));
+    }
+
+    return fileptr;
+}
+
+
+int read_file(int fd, char *filename)
+{
+    long size, lines = 0, linetemp = 0;
+    char input[2];             /* buffer */
+    char *buf;
+    long i = 0, bufx = 128;
+    filestruct *fileptr = current, *tmp = NULL;
+    int line1ins = 0;
+
+    buf = nmalloc(bufx);
+
+    if (fileptr != NULL && fileptr->prev != NULL) {
+       fileptr = fileptr->prev;
+       tmp = fileptr;
+    } else if (fileptr != NULL && fileptr->prev == NULL) {
+       tmp = fileage;
+       current = fileage;
+       line1ins = 1;
+    }
+    input[1] = 0;
+    /* Read the entire file into file struct */
+    while ((size = read_byte(fd, filename, input)) > 0) {
+       linetemp = 0;
+       if (input[0] == '\n') {
+           fileptr = read_line(buf, fileptr, &line1ins);
+           lines++;
+           buf[0] = 0;
+           i = 0;
+       } else {
+           /* Now we allocate a bigger buffer 128 characters at a time.
+              If we allocate a lot of space for one line, we may indeed 
+              have to use a buffer this big later on, so we don't
+              decrease it at all.  We do free it at the end though. */
+
+           if (i >= bufx - 1) {
+               buf = nrealloc(buf, bufx + 128);
+               bufx += 128;
+           }
+           buf[i] = input[0];
+           buf[i + 1] = 0;
+           i++;
+       }
+       totsize += size;
+    }
+
+    /* Did we not get a newline but still have stuff to do? */
+    if (buf[0]) {
+       fileptr = read_line(buf, fileptr, &line1ins);
+       lines++;
+       buf[0] = 0;
+    }
+    /* Did we even GET a file? */
+    if (totsize == 0) {
+       new_file();
+       statusbar(_("Read %d lines"), lines);
+       return 1;
+    }
+    if (current != NULL) {
+       fileptr->next = current;
+       current->prev = fileptr;
+       renumber(current);
+       current_x = 0;
+       placewewant = 0;
+    } else if (fileptr->next == NULL) {
+       filebot = fileptr;
+       load_file();
+    }
+    statusbar(_("Read %d lines"), lines);
+    totlines += lines;
+
+    free(buf);
+    close(fd);
+
+    return 1;
+}
+
+/* Open the file (and decide if it exists) */
+int open_file(char *filename, int insert, int quiet)
+{
+    int fd;
+    struct stat fileinfo;
+
+    if (!strcmp(filename, "") || stat(filename, &fileinfo) == -1) {
+       if (insert) {
+           if (!quiet)
+               statusbar(_("\"%s\" not found"), filename);
+           return -1;
+       } else {
+           /* We have a new file */
+           statusbar(_("New File"));
+           new_file();
+       }
+    } else if ((fd = open(filename, O_RDONLY)) == -1) {
+       if (!quiet)
+           statusbar("%s: %s", strerror(errno), filename);
+       return -1;
+    } else {                   /* File is A-OK */
+       if (S_ISDIR(fileinfo.st_mode)) {
+           statusbar(_("File \"%s\" is a directory"), filename);
+           new_file();
+           return -1;
+       }
+       if (!quiet)
+           statusbar(_("Reading File"));
+       read_file(fd, filename);
+    }
+
+    return 1;
+}
+
+int do_insertfile(void)
+{
+    int i;
+
+    wrap_reset();
+    i = statusq(writefile_list, WRITEFILE_LIST_LEN, "",
+               _("File to insert [from ./] "));
+    if (i != -1) {
+
+#ifdef DEBUG
+       fprintf(stderr, "filename is %s", answer);
+#endif
+
+       i = open_file(answer, 1, 0);
+
+       dump_buffer(fileage);
+       set_modified();
+
+       /* Here we want to rebuild the edit window */
+       for(i = 0, editbot = edittop;
+              i <= editwinrows - 1
+           && i <= totlines
+           && editbot->next != NULL;
+           editbot = editbot->next, i++);
+
+       /* If we've gone off the bottom, recenter, otherwise just redraw */
+       if(current->lineno > editbot->lineno)
+           edit_update(current);
+       else
+           edit_refresh();
+
+       UNSET(KEEP_CUTBUFFER);
+       display_main_list();
+       return i;
+    } else {
+       statusbar(_("Cancelled"));
+       UNSET(KEEP_CUTBUFFER);
+       display_main_list();
+       return 0;
+    }
+}
+
+/*
+ * Write a file out.  If tmp is nonzero, we set the umask to 0600,
+ * we don't set the global variable filename to it's name, and don't
+ * print out how many lines we wrote on the statusbar.
+ * 
+ * Note that tmp is only set to 1 for storing temporary files internal
+ * to the editor, and is completely different from temp_opt.
+ */
+int write_file(char *name, int tmp)
+{
+    long size, lineswritten = 0;
+    char buf[PATH_MAX + 1];
+    filestruct *fileptr;
+    int fd, mask = 0;
+    struct stat st;
+
+    if (!strcmp(name, "")) {
+       statusbar(_("Cancelled"));
+       return -1;
+    }
+    titlebar();
+    fileptr = fileage;
+
+
+    /* Open the file and truncate it.  Trust the symlink. */
+    if (ISSET(FOLLOW_SYMLINKS) && !tmp) {
+       if ((fd = open(name, O_WRONLY | O_CREAT | O_TRUNC,
+                      S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH |
+                      S_IWOTH)) == -1) {
+           statusbar(_("Could not open file for writing: %s"),
+                     strerror(errno));
+           return -1;
+       }
+    }
+    /* Don't follow symlink.  Create new file. */
+    else {
+       if (strlen(name) > (PATH_MAX - 7)) {
+           statusbar(_("Could not open file: Path length exceeded."));
+           return -1;
+       }
+
+       memset(buf, 0x00, PATH_MAX + 1);
+       strcat(buf, name);
+       strcat(buf, ".XXXXXX");
+       if ((fd = mkstemp(buf)) == -1) {
+           statusbar(_("Could not open file for writing: %s"),
+                     strerror(errno));
+           return -1;
+       }
+    }
+
+
+
+    dump_buffer(fileage);
+    while (fileptr != NULL && fileptr->next != NULL) {
+       size = write(fd, fileptr->data, strlen(fileptr->data));
+       if (size == -1) {
+           statusbar(_("Could not open file for writing: %s"),
+                     strerror(errno));
+           return -1;
+       } else {
+#ifdef DEBUG
+           fprintf(stderr, _("Wrote >%s\n"), fileptr->data);
+#endif
+       }
+       write(fd, "\n", 1);
+
+       fileptr = fileptr->next;
+       lineswritten++;
+    }
+
+    if (fileptr != NULL) {
+       size = write(fd, fileptr->data, strlen(fileptr->data));
+       if (size == -1) {
+           statusbar(_("Could not open file for writing: %s"),
+                     strerror(errno));
+           return -1;
+       } else if (size > 0) {
+           size = write(fd, "\n", 1);
+           if (size == -1) {
+               statusbar(_("Could not open file for writing: %s"),
+                         strerror(errno));
+               return -1;
+           }
+       }
+    }
+
+
+    if (close(fd) == -1) {
+       statusbar(_("Could not close %s: %s"), name, strerror(errno));
+       unlink(buf);
+       return -1;
+    }
+
+    if (!ISSET(FOLLOW_SYMLINKS) || tmp) {
+       if (stat(name, &st) == -1) {
+           /* Use default umask as file permisions if file is a new file. */
+           mask = umask(0);
+           umask(mask);
+
+           if (tmp)            /* We don't want anyone reading our temporary file! */
+               mask = 0600;
+           else
+               mask = 0666 & ~mask;
+
+       } else {
+           /* Use permissions from file we are overwriting. */
+           mask = st.st_mode;
+           if (unlink(name) == -1) {
+               if (errno != ENOENT) {
+                   statusbar(_("Could not open %s for writing: %s"),
+                             name, strerror(errno));
+                   unlink(buf);
+                   return -1;
+               }
+           }
+       }
+
+       if (link(buf, name) != -1)
+           unlink(buf);
+       else if (errno != EPERM) {
+           statusbar(_("Could not open %s for writing: %s"),
+                     name, strerror(errno));
+           unlink(buf);
+           return -1;
+       } else if (rename(buf, name) == -1) {   /* Try a rename?? */
+           statusbar(_("Could not open %s for writing: %s"),
+                     name, strerror(errno));
+           unlink(buf);
+           return -1;
+       }
+       if (chmod(name, mask) == -1) {
+           statusbar(_("Could not set permissions %o on %s: %s"),
+                     mask, name, strerror(errno));
+       }
+
+    }
+    if (!tmp) {
+       strncpy(filename, name, 132);
+       statusbar(_("Wrote %d lines"), lineswritten);
+    }
+    UNSET(MODIFIED);
+    titlebar();
+    return 1;
+}
+
+int do_writeout(int exiting)
+{
+    int i = 0;
+
+    strncpy(answer, filename, 132);
+
+    if ((exiting) && (temp_opt) && (filename)) {
+       i = write_file(answer, 0);
+       display_main_list();
+       return i;
+    }
+
+    while (1) {
+       i = statusq(writefile_list, WRITEFILE_LIST_LEN, answer,
+                   _("File Name to write"));
+
+        if (i != -1) {
+
+#ifdef DEBUG
+           fprintf(stderr, _("filename is %s"), answer);
+#endif
+           if (strncmp(answer, filename, 132)) {
+               struct stat st;
+               if (!stat(answer, &st)) {
+                   i = do_yesno(0, 0, _("File exists, OVERWRITE ?"));
+
+                   if (!i || (i == -1))
+                       continue;
+                }
+            }
+           i = write_file(answer, 0);
+
+           display_main_list();
+           return i;
+        } else {
+           statusbar(_("Cancelled"));
+           display_main_list();
+           return 0;
+        }
+    }
+}
+
+int do_writeout_void(void)
+{
+    return do_writeout(0);
+}
+
diff --git a/move.c b/move.c
new file mode 100644 (file)
index 0000000..b594108
--- /dev/null
+++ b/move.c
@@ -0,0 +1,195 @@
+/**************************************************************************
+ *   move.c                                                               *
+ *                                                                        *
+ *   Copyright (C) 1999 Chris Allegretta                                  *
+ *   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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.            *
+ *                                                                        *
+ **************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "config.h"
+#include "proto.h"
+#include "nano.h"
+#ifndef NANO_SMALL
+#include <libintl.h>
+#define _(string) gettext(string)
+#else
+#define _(string) (string)
+#endif
+
+void page_down_center(void)
+{
+    if (editbot->next != NULL && editbot->next != filebot) {
+       edit_update(editbot->next);
+       center_cursor();
+    } else if (editbot != filebot) {
+       edit_update(editbot);
+       center_cursor();
+    } else {
+       while (current != filebot)
+           current = current->next;
+       edit_update(current);
+    }
+    update_cursor();
+
+}
+
+int page_down(void)
+{
+    wrap_reset();
+    current_x = 0;
+    placewewant = 0;
+
+    if (current == filebot)
+       return 0;
+
+    if (editbot != filebot) {
+       current_y = 0;
+       current = editbot;
+    } else
+       while (current != filebot) {
+           current = current->next;
+           current_y++;
+       }
+
+    edit_update_top(current);
+    update_cursor();
+    UNSET(KEEP_CUTBUFFER);
+    check_statblank();
+    return 1;
+}
+
+int do_home(void)
+{
+    current_x = 0;
+    placewewant = 0;
+    update_line(current, current_x);
+    return 1;
+}
+
+int do_end(void)
+{
+    current_x = strlen(current->data);
+    placewewant = xplustabs();
+    update_line(current, current_x);
+
+    return 1;
+}
+
+/* What happens when we want to go past the bottom of the buffer */
+int do_down(void)
+{
+    wrap_reset();
+    if (current->next != NULL) {
+       update_line(current->prev, 0);
+
+       if (placewewant > 0)
+           current_x = actual_x(current->next, placewewant);
+
+       if (current_x > strlen(current->next->data))
+           current_x = strlen(current->next->data);
+    } else {
+       UNSET(KEEP_CUTBUFFER);
+       check_statblank();
+       return 0;
+    }
+   if (current_y < editwinrows - 1 && current != editbot)
+       current_y++;
+    else
+       page_down_center();
+
+    update_cursor();
+    update_line(current->prev, 0);
+    update_line(current, current_x);
+    UNSET(KEEP_CUTBUFFER);
+    check_statblank();
+    return 1;
+}
+
+void page_up_center(void)
+{
+    if (edittop != fileage) {
+       edit_update(edittop);
+       center_cursor();
+    } else
+       current_y = 0;
+
+    update_cursor();
+
+}
+
+int do_up(void)
+{
+    wrap_reset();
+    if (current->prev != NULL) {
+       update_line(current, 0);
+
+       if (placewewant > 0)
+           current_x = actual_x(current->prev, placewewant);
+
+       if (current_x > strlen(current->prev->data))
+           current_x = strlen(current->prev->data);
+    }
+    if (current_y > 0)
+       current_y--;
+    else
+       page_up_center();
+
+    update_cursor();
+    update_line(current->next, 0);
+    update_line(current, current_x);
+    UNSET(KEEP_CUTBUFFER);
+    check_statblank();
+    return 1;
+}
+
+int do_right(void)
+{
+    if (current_x < strlen(current->data)) {
+       current_x++;
+    } else {
+       if (do_down())
+           current_x = 0;
+    }
+
+    placewewant = xplustabs();
+    update_cursor();
+    update_line(current, current_x);
+    UNSET(KEEP_CUTBUFFER);
+    check_statblank();
+    return 1;
+}
+
+int do_left(void)
+{
+    if (current_x > 0)
+       current_x--;
+    else if (current != fileage) {
+       placewewant = 0;
+       current_x = strlen(current->prev->data);
+       do_up();
+    }
+    placewewant = xplustabs();
+
+    update_cursor();
+    update_line(current, current_x);
+    UNSET(KEEP_CUTBUFFER);
+    check_statblank();
+    return 1;
+}
diff --git a/nano.c b/nano.c
index 1e374f139c15810180e2d62797bdc29b4f15dc60..1db5f689502fa0287d6826e4f6ec8cb11c9c96a8 100644 (file)
--- a/nano.c
+++ b/nano.c
@@ -63,8 +63,6 @@ char *last_replace;           /* Last replacement string */
 int temp_opt = 0;              /* Editing temp file (pico -t option) */
 int fill = 0;                  /* Fill - where to wrap lines, basically */
 static char *alt_speller;      /* Alternative spell command */
-static int editwineob = 0;     /* Last Line in edit buffer
-                                  (0 - editwineob) */
 struct termios oldterm;                /* The user's original term settings */
 static char *alt_speller;      /* Alternative spell command */
 static char *help_text_init = "";
@@ -117,29 +115,6 @@ void die(char *msg, ...)
     exit(1);                   /* We have a problem: exit w/ errorlevel(1) */
 }
 
-/* Thanks BG, many ppl have been asking for this... */
-void *nmalloc(size_t howmuch)
-{
-    void *r;
-
-    /* Panic save? */
-
-    if (!(r = malloc(howmuch)))
-       die(_("nano: malloc: out of memory!"));
-
-    return r;
-}
-
-void *nrealloc(void *ptr, size_t howmuch)
-{
-    void *r;
-
-    if (!(r = realloc(ptr, howmuch)))
-       die("nano: realloc: out of memory!");
-
-    return r;
-}
-
 void print_view_warning(void)
 {
     statusbar(_("Key illegal in VIEW mode"));
@@ -155,7 +130,6 @@ void global_init(void)
     current_x = 0;
     current_y = 0;
     editwinrows = LINES - 5 + no_help();
-    editwineob = editwinrows - 1;
     fileage = NULL;
     cutbuffer = NULL;
     current = NULL;
@@ -331,243 +305,6 @@ void align(char **strp)
     *strp = nrealloc(*strp, strlen(*strp) + 1);
 }
 
-/* Load file into edit buffer - takes data from file struct */
-void load_file(void)
-{
-    current = fileage;
-    wmove(edit, current_y, current_x);
-}
-
-/* What happens when there is no file to open? aiee! */
-void new_file(void)
-{
-    fileage = nmalloc(sizeof(filestruct));
-    fileage->data = nmalloc(1);
-    strcpy(fileage->data, "");
-    fileage->prev = NULL;
-    fileage->next = NULL;
-    fileage->lineno = 1;
-    filebot = fileage;
-    edittop = fileage;
-    editbot = fileage;
-    current = fileage;
-    totlines = 1;
-    UNSET(VIEW_MODE);
-}
-
-
-int read_byte(int fd, char *filename, char *input)
-{
-    static char buf[BUFSIZ];
-    static int index = 0;
-    static int size = 0;
-
-    if (index == size) {
-       index = 0;
-       size = read(fd, buf, BUFSIZ);
-       if (size == -1) {
-           clear();
-           refresh();
-           resetty();
-           endwin();
-           perror(filename);
-       }
-       if (!size)
-           return 0;
-    }
-    *input = buf[index++];
-    return 1;
-}
-
-filestruct *read_line(char *buf, filestruct * prev, int *line1ins)
-{
-    filestruct *fileptr;
-
-    fileptr = nmalloc(sizeof(filestruct));
-    fileptr->data = nmalloc(strlen(buf) + 2);
-    strcpy(fileptr->data, buf);
-
-    if (*line1ins) {
-       /* Special case, insert with cursor on 1st line. */
-       fileptr->prev = NULL;
-       fileptr->next = fileage;
-       fileptr->lineno = 1;
-       *line1ins = 0;
-       /* If we're inserting into the first line of the file, then
-          we want to make sure that our edit buffer stays on the
-          first line (and that fileage stays up to date!) */
-       fileage = fileptr;
-       edittop = fileptr;
-    } else if (fileage == NULL) {
-       fileage = fileptr;
-       fileage->lineno = 1;
-       fileage->next = fileage->prev = NULL;
-       fileptr = filebot = fileage;
-    } else if (prev) {
-       fileptr->prev = prev;
-       fileptr->next = NULL;
-       fileptr->lineno = prev->lineno + 1;
-       prev->next = fileptr;
-    } else {
-       die(_("read_line: not on first line and prev is NULL"));
-    }
-
-    return fileptr;
-}
-
-
-int read_file(int fd, char *filename)
-{
-    long size, lines = 0, linetemp = 0;
-    char input[2];             /* buffer */
-    char *buf;
-    long i = 0, bufx = 128;
-    filestruct *fileptr = current, *tmp = NULL;
-    int line1ins = 0;
-
-    buf = nmalloc(bufx);
-
-    if (fileptr != NULL && fileptr->prev != NULL) {
-       fileptr = fileptr->prev;
-       tmp = fileptr;
-    } else if (fileptr != NULL && fileptr->prev == NULL) {
-       tmp = fileage;
-       current = fileage;
-       line1ins = 1;
-    }
-    input[1] = 0;
-    /* Read the entire file into file struct */
-    while ((size = read_byte(fd, filename, input)) > 0) {
-       linetemp = 0;
-       if (input[0] == '\n') {
-           fileptr = read_line(buf, fileptr, &line1ins);
-           lines++;
-           buf[0] = 0;
-           i = 0;
-       } else {
-           /* Now we allocate a bigger buffer 128 characters at a time.
-              If we allocate a lot of space for one line, we may indeed 
-              have to use a buffer this big later on, so we don't
-              decrease it at all.  We do free it at the end though. */
-
-           if (i >= bufx - 1) {
-               buf = nrealloc(buf, bufx + 128);
-               bufx += 128;
-           }
-           buf[i] = input[0];
-           buf[i + 1] = 0;
-           i++;
-       }
-       totsize += size;
-    }
-
-    /* Did we not get a newline but still have stuff to do? */
-    if (buf[0]) {
-       fileptr = read_line(buf, fileptr, &line1ins);
-       lines++;
-       buf[0] = 0;
-    }
-    /* Did we even GET a file? */
-    if (totsize == 0) {
-       new_file();
-       statusbar(_("Read %d lines"), lines);
-       return 1;
-    }
-    if (current != NULL) {
-       fileptr->next = current;
-       current->prev = fileptr;
-       renumber(current);
-       current_x = 0;
-       placewewant = 0;
-    } else if (fileptr->next == NULL) {
-       filebot = fileptr;
-       load_file();
-    }
-    statusbar(_("Read %d lines"), lines);
-    totlines += lines;
-
-    free(buf);
-    close(fd);
-
-    return 1;
-}
-
-/* Open the file (and decide if it exists) */
-int open_file(char *filename, int insert, int quiet)
-{
-    int fd;
-    struct stat fileinfo;
-
-    if (!strcmp(filename, "") || stat(filename, &fileinfo) == -1) {
-       if (insert) {
-           if (!quiet)
-               statusbar(_("\"%s\" not found"), filename);
-           return -1;
-       } else {
-           /* We have a new file */
-           statusbar(_("New File"));
-           new_file();
-       }
-    } else if ((fd = open(filename, O_RDONLY)) == -1) {
-       if (!quiet)
-           statusbar("%s: %s", strerror(errno), filename);
-       return -1;
-    } else {                   /* File is A-OK */
-       if (S_ISDIR(fileinfo.st_mode)) {
-           statusbar(_("File \"%s\" is a directory"), filename);
-           new_file();
-           return -1;
-       }
-       if (!quiet)
-           statusbar(_("Reading File"));
-       read_file(fd, filename);
-    }
-
-    return 1;
-}
-
-int do_insertfile(void)
-{
-    int i;
-
-    wrap_reset();
-    i = statusq(writefile_list, WRITEFILE_LIST_LEN, "",
-               _("File to insert [from ./] "));
-    if (i != -1) {
-
-#ifdef DEBUG
-       fprintf(stderr, "filename is %s", answer);
-#endif
-
-       i = open_file(answer, 1, 0);
-
-       dump_buffer(fileage);
-       set_modified();
-
-       /* Here we want to rebuild the edit window */
-       for(i = 0, editbot = edittop;
-              i <= editwinrows - 1
-           && i <= totlines
-           && editbot->next != NULL;
-           editbot = editbot->next, i++);
-
-       /* If we've gone off the bottom, recenter, otherwise just redraw */
-       if(current->lineno > editbot->lineno)
-           edit_update(current);
-       else
-           edit_refresh();
-
-       UNSET(KEEP_CUTBUFFER);
-       display_main_list();
-       return i;
-    } else {
-       statusbar(_("Cancelled"));
-       UNSET(KEEP_CUTBUFFER);
-       display_main_list();
-       return 0;
-    }
-}
-
 void usage(void)
 {
 #ifdef HAVE_GETOPT_LONG
@@ -643,65 +380,6 @@ void version(void)
     printf(_(" Email: nano@asty.org    Web: http://www.asty.org/nano\n"));
 }
 
-void page_down_center(void)
-{
-    if (editbot->next != NULL && editbot->next != filebot) {
-       edit_update(editbot->next);
-       center_cursor();
-    } else if (editbot != filebot) {
-       edit_update(editbot);
-       center_cursor();
-    } else {
-       while (current != filebot)
-           current = current->next;
-       edit_update(current);
-    }
-    update_cursor();
-
-}
-
-int page_down(void)
-{
-    wrap_reset();
-    current_x = 0;
-    placewewant = 0;
-
-    if (current == filebot)
-       return 0;
-
-    if (editbot != filebot) {
-       current_y = 0;
-       current = editbot;
-    } else
-       while (current != filebot) {
-           current = current->next;
-           current_y++;
-       }
-
-    edit_update_top(current);
-    update_cursor();
-    UNSET(KEEP_CUTBUFFER);
-    check_statblank();
-    return 1;
-}
-
-int do_home(void)
-{
-    current_x = 0;
-    placewewant = 0;
-    update_line(current, current_x);
-    return 1;
-}
-
-int do_end(void)
-{
-    current_x = strlen(current->data);
-    placewewant = xplustabs();
-    update_line(current, current_x);
-
-    return 1;
-}
-
 filestruct *make_new_node(filestruct * prevnode)
 {
     filestruct *newnode;
@@ -754,109 +432,6 @@ void nano_small_msg(void)
     statusbar("Sorry, this function not available with nano-tiny option");
 }
 
-/* What happens when we want to go past the bottom of the buffer */
-int do_down(void)
-{
-    wrap_reset();
-    if (current->next != NULL) {
-       update_line(current->prev, 0);
-
-       if (placewewant > 0)
-           current_x = actual_x(current->next, placewewant);
-
-       if (current_x > strlen(current->next->data))
-           current_x = strlen(current->next->data);
-    } else {
-       UNSET(KEEP_CUTBUFFER);
-       check_statblank();
-       return 0;
-    }
-   if (current_y < editwineob && current != editbot)
-       current_y++;
-    else
-       page_down_center();
-
-    update_cursor();
-    update_line(current->prev, 0);
-    update_line(current, current_x);
-    UNSET(KEEP_CUTBUFFER);
-    check_statblank();
-    return 1;
-}
-
-void page_up_center(void)
-{
-    if (edittop != fileage) {
-       edit_update(edittop);
-       center_cursor();
-    } else
-       current_y = 0;
-
-    update_cursor();
-
-}
-
-int do_up(void)
-{
-    wrap_reset();
-    if (current->prev != NULL) {
-       update_line(current, 0);
-
-       if (placewewant > 0)
-           current_x = actual_x(current->prev, placewewant);
-
-       if (current_x > strlen(current->prev->data))
-           current_x = strlen(current->prev->data);
-    }
-    if (current_y > 0)
-       current_y--;
-    else
-       page_up_center();
-
-    update_cursor();
-    update_line(current->next, 0);
-    update_line(current, current_x);
-    UNSET(KEEP_CUTBUFFER);
-    check_statblank();
-    return 1;
-}
-
-int do_right(void)
-{
-    if (current_x < strlen(current->data)) {
-       current_x++;
-    } else {
-       if (do_down())
-           current_x = 0;
-    }
-
-    placewewant = xplustabs();
-    update_cursor();
-    update_line(current, current_x);
-    UNSET(KEEP_CUTBUFFER);
-    check_statblank();
-    return 1;
-}
-
-int do_left(void)
-{
-    if (current_x > 0)
-       current_x--;
-    else if (current != fileage) {
-       placewewant = 0;
-       current_x = strlen(current->prev->data);
-       do_up();
-    }
-    placewewant = xplustabs();
-
-    update_cursor();
-    update_line(current, current_x);
-    UNSET(KEEP_CUTBUFFER);
-    check_statblank();
-    return 1;
-}
-
 /* The user typed a printable character; add it to the edit buffer */
 void do_char(char ch)
 {
@@ -1315,316 +890,6 @@ void do_early_abort(void)
     blank_statusbar_refresh();
 }
 
-/* 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)
-
-   replacing = 1 if we call from do_replace, 0 if called from do_search func.
-*/
-int search_init(int replacing)
-{
-    int i;
-    char buf[135];
-
-    if (last_search[0]) {
-       sprintf(buf, " [%s]", last_search);
-    } else {
-       buf[0] = '\0';
-    }
-
-    i = statusq(replacing ? replace_list : whereis_list,
-               replacing ? REPLACE_LIST_LEN : WHEREIS_LIST_LEN, "",
-               ISSET(CASE_SENSITIVE) ? _("Case Sensitive Search%s") :
-               _("Search%s"), buf);
-
-    /* Cancel any search, or just return with no previous search */
-    if ((i == -1) || (i < 0 && !last_search[0])) {
-       statusbar(_("Search Cancelled"));
-       reset_cursor();
-       return -1;
-    } else if (i == -2) {      /* Same string */
-       strncpy(answer, last_search, 132);
-    } else if (i == 0) {       /* They entered something new */
-       strncpy(last_search, answer, 132);
-
-       /* Blow away last_replace because they entered a new search
-          string....uh, right? =) */
-       last_replace[0] = '\0';
-    } else if (i == NANO_CASE_KEY) {   /* They want it case sensitive */
-       if (ISSET(CASE_SENSITIVE))
-           UNSET(CASE_SENSITIVE);
-       else
-           SET(CASE_SENSITIVE);
-
-       return 1;
-    } else if (i == NANO_OTHERSEARCH_KEY) {
-       return -2;              /* Call the opposite search function */
-    } else {                   /* First line key, etc. */
-       do_early_abort();
-       return -3;
-    }
-
-    return 0;
-}
-
-filestruct *findnextstr(int quiet, filestruct * begin, char *needle)
-{
-    filestruct *fileptr;
-    char *searchstr, *found = NULL, *tmp;
-
-    fileptr = current;
-
-    searchstr = &current->data[current_x + 1];
-    /* Look for searchstr until EOF */
-    while (fileptr != NULL &&
-          (found = strstrwrapper(searchstr, needle)) == NULL) {
-       fileptr = fileptr->next;
-
-       if (fileptr == begin)
-           return NULL;
-
-       if (fileptr != NULL)
-           searchstr = fileptr->data;
-    }
-
-    /* If we're not at EOF, we found an instance */
-    if (fileptr != NULL) {
-       current = fileptr;
-       current_x = 0;
-       for (tmp = fileptr->data; tmp != found; tmp++)
-           current_x++;
-
-       edit_update(current);
-       reset_cursor();
-    } else {                   /* We're at EOF, go back to the top, once */
-
-       fileptr = fileage;
-
-       while (fileptr != current && fileptr != begin &&
-              (found = strstrwrapper(fileptr->data, needle)) == NULL)
-           fileptr = fileptr->next;
-
-       if (fileptr == begin) {
-           if (!quiet)
-               statusbar(_("\"%s\" not found"), needle);
-
-           return NULL;
-       }
-       if (fileptr != current) {       /* We found something */
-           current = fileptr;
-           current_x = 0;
-           for (tmp = fileptr->data; tmp != found; tmp++)
-               current_x++;
-
-           edit_update(current);
-           reset_cursor();
-
-           if (!quiet)
-               statusbar(_("Search Wrapped"));
-       } else {                /* Nada */
-
-           if (!quiet)
-               statusbar(_("\"%s\" not found"), needle);
-           return NULL;
-       }
-    }
-
-    return fileptr;
-}
-
-void search_abort(void)
-{
-    UNSET(KEEP_CUTBUFFER);
-    display_main_list();
-    wrefresh(bottomwin);
-}
-
-/* Search for a string */
-int do_search(void)
-{
-    int i;
-    filestruct *fileptr = current;
-
-    wrap_reset();
-    if ((i = search_init(0)) == -1) {
-       current = fileptr;
-       search_abort();
-       return 0;
-    } else if (i == -3) {
-       search_abort();
-       return 0;
-    } else if (i == -2) {
-       search_abort();
-       do_replace();
-       return 0;
-    } else if (i == 1) {
-       do_search();
-       search_abort();
-       return 1;
-    }
-    findnextstr(0, current, answer);
-    search_abort();
-    return 1;
-}
-
-void print_replaced(int num)
-{
-    if (num > 1)
-       statusbar(_("Replaced %d occurences"), num);
-    else if (num == 1)
-       statusbar(_("Replaced 1 occurence"));
-}
-
-void replace_abort(void)
-{
-    UNSET(KEEP_CUTBUFFER);
-    display_main_list();
-    reset_cursor();
-}
-
-/* Search for a string */
-int do_replace(void)
-{
-    int i, replaceall = 0, numreplaced = 0, beginx;
-    filestruct *fileptr, *begin;
-    char *tmp, *copy, prevanswer[132] = "";
-
-    if ((i = search_init(1)) == -1) {
-       statusbar(_("Replace Cancelled"));
-       replace_abort();
-       return 0;
-    } else if (i == 1) {
-       do_replace();
-       return 1;
-    } else if (i == -2) {
-       replace_abort();
-       do_search();
-       return 0;
-    } else if (i == -3) {
-       replace_abort();
-       return 0;
-    }
-    strncpy(prevanswer, answer, 132);
-
-    if (strcmp(last_replace, "")) {    /* There's a previous replace str */
-       i = statusq(replace_list, REPLACE_LIST_LEN, "",
-                   _("Replace with [%s]"), last_replace);
-
-       if (i == -1) {          /* Aborted enter */
-           strncpy(answer, last_replace, 132);
-           statusbar(_("Replace Cancelled"));
-           replace_abort();
-           return 0;
-       } else if (i == 0)      /* They actually entered something */
-           strncpy(last_replace, answer, 132);
-       else if (i == NANO_CASE_KEY) {  /* They asked for case sensitivity */
-           if (ISSET(CASE_SENSITIVE))
-               UNSET(CASE_SENSITIVE);
-           else
-               SET(CASE_SENSITIVE);
-
-           do_replace();
-           return 0;
-       } else {                /* First page, last page, for example could get here */
-
-           do_early_abort();
-           replace_abort();
-           return 0;
-       }
-    } else {                   /* last_search is empty */
-
-       i = statusq(replace_list, REPLACE_LIST_LEN, "", _("Replace with"));
-       if (i == -1) {
-           statusbar(_("Replace Cancelled"));
-           reset_cursor();
-           replace_abort();
-           return 0;
-       } else if (i == 0)      /* They entered something new */
-           strncpy(last_replace, answer, 132);
-       else if (i == NANO_CASE_KEY) {  /* They want it case sensitive */
-           if (ISSET(CASE_SENSITIVE))
-               UNSET(CASE_SENSITIVE);
-           else
-               SET(CASE_SENSITIVE);
-
-           do_replace();
-           return 1;
-       } else {                /* First line key, etc. */
-
-           do_early_abort();
-           replace_abort();
-           return 0;
-       }
-    }
-
-    /* save where we are */
-    begin = current;
-    beginx = current_x;
-
-    while (1) {
-
-       if (replaceall)
-           fileptr = findnextstr(1, begin, prevanswer);
-       else
-           fileptr = findnextstr(0, begin, prevanswer);
-
-       /* No more matches.  Done! */
-       if (!fileptr)
-           break;
-
-       /* If we're here, we've found the search string */
-       if (!replaceall)
-           i = do_yesno(1, 1, _("Replace this instance?"));
-
-       if (i > 0 || replaceall) {      /* Yes, replace it!!!! */
-           if (i == 2)
-               replaceall = 1;
-
-           /* Create buffer */
-           copy = nmalloc(strlen(current->data) - strlen(last_search) +
-                          strlen(last_replace) + 1);
-
-           /* Head of Original Line */
-           strncpy(copy, current->data, current_x);
-           copy[current_x] = 0;
-
-           /* Replacement Text */
-           strcat(copy, last_replace);
-
-           /* The tail of the original line */
-           /*  This may expose other bugs, because it no longer
-              goes through each character on the string
-              and tests for string goodness.  But because
-              we can assume the invariant that current->data
-              is less than current_x + strlen(last_search) long,   
-              this should be safe.  Or it will expose bugs ;-) */
-           tmp = current->data + current_x + strlen(last_search);
-           strcat(copy, tmp);
-
-           /* Cleanup */
-           free(current->data);
-           current->data = copy;
-
-           /* Stop bug where we replace a substring of the replacement text */
-           current_x += strlen(last_replace);
-
-           edit_refresh();
-           set_modified();
-           numreplaced++;
-       } else if (i == -1)     /* Abort, else do nothing and continue loop */
-           break;
-    }
-
-    current = begin;
-    current_x = beginx;
-    renumber_all();
-    edit_update(current);
-    print_replaced(numreplaced);
-    replace_abort();
-    return 1;
-}
-
-
 int page_up(void)
 {
     wrap_reset();
@@ -1759,276 +1024,18 @@ int do_delete(void)
     return 1;
 }
 
-void goto_abort(void)
-{
-    UNSET(KEEP_CUTBUFFER);
-    display_main_list();
-}
-
-int do_gotoline(long defline)
-{
-    long line, i = 1, j = 0;
-    filestruct *fileptr;
-
-    if (defline > 0)           /* We already know what line we want to go to */
-       line = defline;
-    else {                     /* Ask for it */
-
-       j = statusq(goto_list, GOTO_LIST_LEN, "", _("Enter line number"));
-       if (j == -1) {
-           statusbar(_("Aborted"));
-           goto_abort();
-           return 0;
-       } else if (j != 0) {
-           do_early_abort();
-           goto_abort();
-           return 0;
-       }
-       if (!strcmp(answer, "$")) {
-           current = filebot;
-           current_x = 0;
-           edit_update(current);
-           goto_abort();
-           return 1;
-       }
-       line = atoi(answer);
-    }
-
-    /* Bounds check */
-    if (line <= 0) {
-       statusbar(_("Come on, be reasonable"));
-       goto_abort();
-       return 0;
-    }
-    if (line > totlines) {
-       statusbar(_("Only %d lines available, skipping to last line"),
-                 filebot->lineno);
-       current = filebot;
-       current_x = 0;
-       edit_update(current);
-    } else {
-       for (fileptr = fileage; fileptr != NULL && i < line; i++)
-           fileptr = fileptr->next;
-
-       current = fileptr;
-       current_x = 0;
-       edit_update(current);
-    }
-
-    goto_abort();
-    return 1;
-}
-
-int do_gotoline_void(void)
-{
-    return do_gotoline(0);
-}
-
 void wrap_reset(void)
 {
     UNSET(SAMELINEWRAP);
 }
 
-/*
- * Write a file out.  If tmp is nonzero, we set the umask to 0600,
- * we don't set the global variable filename to it's name, and don't
- * print out how many lines we wrote on the statusbar.
- * 
- * Note that tmp is only set to 1 for storing temporary files internal
- * to the editor, and is completely different from temp_opt.
- */
-int write_file(char *name, int tmp)
-{
-    long size, lineswritten = 0;
-    char buf[PATH_MAX + 1];
-    filestruct *fileptr;
-    int fd, mask = 0;
-    struct stat st;
-
-    if (!strcmp(name, "")) {
-       statusbar(_("Cancelled"));
-       return -1;
-    }
-    titlebar();
-    fileptr = fileage;
-
-
-    /* Open the file and truncate it.  Trust the symlink. */
-    if (ISSET(FOLLOW_SYMLINKS) && !tmp) {
-       if ((fd = open(name, O_WRONLY | O_CREAT | O_TRUNC,
-                      S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH |
-                      S_IWOTH)) == -1) {
-           statusbar(_("Could not open file for writing: %s"),
-                     strerror(errno));
-           return -1;
-       }
-    }
-    /* Don't follow symlink.  Create new file. */
-    else {
-       if (strlen(name) > (PATH_MAX - 7)) {
-           statusbar(_("Could not open file: Path length exceeded."));
-           return -1;
-       }
-
-       memset(buf, 0x00, PATH_MAX + 1);
-       strcat(buf, name);
-       strcat(buf, ".XXXXXX");
-       if ((fd = mkstemp(buf)) == -1) {
-           statusbar(_("Could not open file for writing: %s"),
-                     strerror(errno));
-           return -1;
-       }
-    }
-
-
-
-    dump_buffer(fileage);
-    while (fileptr != NULL && fileptr->next != NULL) {
-       size = write(fd, fileptr->data, strlen(fileptr->data));
-       if (size == -1) {
-           statusbar(_("Could not open file for writing: %s"),
-                     strerror(errno));
-           return -1;
-       } else {
-#ifdef DEBUG
-           fprintf(stderr, _("Wrote >%s\n"), fileptr->data);
-#endif
-       }
-       write(fd, "\n", 1);
-
-       fileptr = fileptr->next;
-       lineswritten++;
-    }
-
-    if (fileptr != NULL) {
-       size = write(fd, fileptr->data, strlen(fileptr->data));
-       if (size == -1) {
-           statusbar(_("Could not open file for writing: %s"),
-                     strerror(errno));
-           return -1;
-       } else if (size > 0) {
-           size = write(fd, "\n", 1);
-           if (size == -1) {
-               statusbar(_("Could not open file for writing: %s"),
-                         strerror(errno));
-               return -1;
-           }
-       }
-    }
-
-
-    if (close(fd) == -1) {
-       statusbar(_("Could not close %s: %s"), name, strerror(errno));
-       unlink(buf);
-       return -1;
-    }
-
-    if (!ISSET(FOLLOW_SYMLINKS) || tmp) {
-       if (stat(name, &st) == -1) {
-           /* Use default umask as file permisions if file is a new file. */
-           mask = umask(0);
-           umask(mask);
-
-           if (tmp)            /* We don't want anyone reading our temporary file! */
-               mask = 0600;
-           else
-               mask = 0666 & ~mask;
-
-       } else {
-           /* Use permissions from file we are overwriting. */
-           mask = st.st_mode;
-           if (unlink(name) == -1) {
-               if (errno != ENOENT) {
-                   statusbar(_("Could not open %s for writing: %s"),
-                             name, strerror(errno));
-                   unlink(buf);
-                   return -1;
-               }
-           }
-       }
-
-       if (link(buf, name) != -1)
-           unlink(buf);
-       else if (errno != EPERM) {
-           statusbar(_("Could not open %s for writing: %s"),
-                     name, strerror(errno));
-           unlink(buf);
-           return -1;
-       } else if (rename(buf, name) == -1) {   /* Try a rename?? */
-           statusbar(_("Could not open %s for writing: %s"),
-                     name, strerror(errno));
-           unlink(buf);
-           return -1;
-       }
-       if (chmod(name, mask) == -1) {
-           statusbar(_("Could not set permissions %o on %s: %s"),
-                     mask, name, strerror(errno));
-       }
-
-    }
-    if (!tmp) {
-       strncpy(filename, name, 132);
-       statusbar(_("Wrote %d lines"), lineswritten);
-    }
-    UNSET(MODIFIED);
-    titlebar();
-    return 1;
-}
-
-int do_writeout(int exiting)
-{
-    int i = 0;
-
-    strncpy(answer, filename, 132);
-
-    if ((exiting) && (temp_opt) && (filename)) {
-       i = write_file(answer, 0);
-       display_main_list();
-       return i;
-    }
-
-    while (1) {
-       i = statusq(writefile_list, WRITEFILE_LIST_LEN, answer,
-                   _("File Name to write"));
-
-        if (i != -1) {
-
-#ifdef DEBUG
-           fprintf(stderr, _("filename is %s"), answer);
-#endif
-           if (strncmp(answer, filename, 132)) {
-               struct stat st;
-               if (!stat(answer, &st)) {
-                   i = do_yesno(0, 0, _("File exists, OVERWRITE ?"));
-
-                   if (!i || (i == -1))
-                       continue;
-                }
-            }
-           i = write_file(answer, 0);
-
-           display_main_list();
-           return i;
-        } else {
-           statusbar(_("Cancelled"));
-           display_main_list();
-           return 0;
-        }
-    }
-}
-
-int do_writeout_void(void)
-{
-    return do_writeout(0);
-}
-
 /* Stuff we want to do when we exit the spell program one of its many ways */
 void exit_spell(char *tmpfilename, char *foo)
 {
     free(foo);
-
     if (remove(tmpfilename) == -1)
-       statusbar(_("Error deleting tempfile, ack!"));
+        statusbar(_("Error deleting tempfile, ack!"));
 }
 
 /*
@@ -2258,7 +1265,6 @@ void handle_sigwinch(int s)
     center_x = COLS / 2;
     center_y = LINES / 2;
     editwinrows = LINES - 5 + no_help();
-    editwineob = editwinrows - 1;
     fill = COLS - 8;
 
     free(hblank);
@@ -2288,11 +1294,11 @@ void handle_sigwinch(int s)
 
     editbot = edittop;
 
-    for (i = 0; (i <= editwineob) && (editbot->next != NULL)
+    for (i = 0; (i <= editwinrows - 1) && (editbot->next != NULL)
         && (editbot->next != filebot); i++)
        editbot = editbot->next;
 
-    if (current_y > editwineob) {
+    if (current_y > editwinrows - 1) {
        edit_update(editbot);
     }
     erase();
@@ -2472,14 +1478,14 @@ int do_justify(void)
     current_x = 0;
     placewewant = 0;
 
-    if ((current_y < 0) || (current_y >= editwineob) || (initial_y <= 0)) {
+    if ((current_y < 0) || (current_y >= editwinrows - 1) || (initial_y <= 0)) {
        edit_update(current);
        center_cursor();
     } else {
        int i = 0;
 
        editbot = edittop;
-       for (i = 0; (i <= editwineob) && (editbot->next != NULL)
+       for (i = 0; (i <= editwinrows - 1) && (editbot->next != NULL)
             && (editbot->next != filebot); i++)
            editbot = editbot->next;
        edit_refresh();
diff --git a/proto.h b/proto.h
index 40f3c29d2b53079fba77f68547b46ba153da4e62..6d86025cef65860a214d40d4ca99503990295fb0 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -58,6 +58,16 @@ int write_file(char *name, int tmpfile);
 int do_cut_text(void);
 int do_uncut_text(void);
 int no_help(void);
+int renumber_all(void);
+int open_file(char *filename, int insert, int quiet);
+int do_writeout(int exiting);
+int do_gotoline(long defline);
+/* Now in move.c */
+int do_up(void);
+int do_down(void);
+int do_left(void);
+int do_right(void);
+
 
 void shortcut_init(void);
 void lowercase(char *src);
@@ -86,6 +96,12 @@ void *nmalloc (size_t howmuch);
 void wrap_reset(void);
 void display_main_list(void);
 void nano_small_msg(void);
+void do_early_abort(void);
+void *nmalloc(size_t howmuch);
+void *nrealloc(void *ptr, size_t howmuch);
+void die(char *msg, ...);
+void new_file(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);
diff --git a/search.c b/search.c
new file mode 100644 (file)
index 0000000..981cf06
--- /dev/null
+++ b/search.c
@@ -0,0 +1,408 @@
+/**************************************************************************
+ *   search.c                                                             *
+ *                                                                        *
+ *   Copyright (C) 2000 Chris Allegretta                                  *
+ *   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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.            *
+ *                                                                        *
+ **************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "config.h"
+#include "proto.h"
+#include "nano.h"
+#ifndef NANO_SMALL
+#include <libintl.h>
+#define _(string) gettext(string)
+#else
+#define _(string) (string)
+#endif
+
+/* 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)
+
+   replacing = 1 if we call from do_replace, 0 if called from do_search func.
+*/
+int search_init(int replacing)
+{
+    int i;
+    char buf[135];
+
+    if (last_search[0]) {
+       sprintf(buf, " [%s]", last_search);
+    } else {
+       buf[0] = '\0';
+    }
+
+    i = statusq(replacing ? replace_list : whereis_list,
+               replacing ? REPLACE_LIST_LEN : WHEREIS_LIST_LEN, "",
+               ISSET(CASE_SENSITIVE) ? _("Case Sensitive Search%s") :
+               _("Search%s"), buf);
+
+    /* Cancel any search, or just return with no previous search */
+    if ((i == -1) || (i < 0 && !last_search[0])) {
+       statusbar(_("Search Cancelled"));
+       reset_cursor();
+       return -1;
+    } else if (i == -2) {      /* Same string */
+       strncpy(answer, last_search, 132);
+    } else if (i == 0) {       /* They entered something new */
+       strncpy(last_search, answer, 132);
+
+       /* Blow away last_replace because they entered a new search
+          string....uh, right? =) */
+       last_replace[0] = '\0';
+    } else if (i == NANO_CASE_KEY) {   /* They want it case sensitive */
+       if (ISSET(CASE_SENSITIVE))
+           UNSET(CASE_SENSITIVE);
+       else
+           SET(CASE_SENSITIVE);
+
+       return 1;
+    } else if (i == NANO_OTHERSEARCH_KEY) {
+       return -2;              /* Call the opposite search function */
+    } else {                   /* First line key, etc. */
+       do_early_abort();
+       return -3;
+    }
+
+    return 0;
+}
+
+filestruct *findnextstr(int quiet, filestruct * begin, char *needle)
+{
+    filestruct *fileptr;
+    char *searchstr, *found = NULL, *tmp;
+
+    fileptr = current;
+
+    searchstr = &current->data[current_x + 1];
+    /* Look for searchstr until EOF */
+    while (fileptr != NULL &&
+          (found = strstrwrapper(searchstr, needle)) == NULL) {
+       fileptr = fileptr->next;
+
+       if (fileptr == begin)
+           return NULL;
+
+       if (fileptr != NULL)
+           searchstr = fileptr->data;
+    }
+
+    /* If we're not at EOF, we found an instance */
+    if (fileptr != NULL) {
+       current = fileptr;
+       current_x = 0;
+       for (tmp = fileptr->data; tmp != found; tmp++)
+           current_x++;
+
+       edit_update(current);
+       reset_cursor();
+    } else {                   /* We're at EOF, go back to the top, once */
+
+       fileptr = fileage;
+
+       while (fileptr != current && fileptr != begin &&
+              (found = strstrwrapper(fileptr->data, needle)) == NULL)
+           fileptr = fileptr->next;
+
+       if (fileptr == begin) {
+           if (!quiet)
+               statusbar(_("\"%s\" not found"), needle);
+
+           return NULL;
+       }
+       if (fileptr != current) {       /* We found something */
+           current = fileptr;
+           current_x = 0;
+           for (tmp = fileptr->data; tmp != found; tmp++)
+               current_x++;
+
+           edit_update(current);
+           reset_cursor();
+
+           if (!quiet)
+               statusbar(_("Search Wrapped"));
+       } else {                /* Nada */
+
+           if (!quiet)
+               statusbar(_("\"%s\" not found"), needle);
+           return NULL;
+       }
+    }
+
+    return fileptr;
+}
+
+void search_abort(void)
+{
+    UNSET(KEEP_CUTBUFFER);
+    display_main_list();
+    wrefresh(bottomwin);
+}
+
+/* Search for a string */
+int do_search(void)
+{
+    int i;
+    filestruct *fileptr = current;
+
+    wrap_reset();
+    if ((i = search_init(0)) == -1) {
+       current = fileptr;
+       search_abort();
+       return 0;
+    } else if (i == -3) {
+       search_abort();
+       return 0;
+    } else if (i == -2) {
+       search_abort();
+       do_replace();
+       return 0;
+    } else if (i == 1) {
+       do_search();
+       search_abort();
+       return 1;
+    }
+    findnextstr(0, current, answer);
+    search_abort();
+    return 1;
+}
+
+void print_replaced(int num)
+{
+    if (num > 1)
+       statusbar(_("Replaced %d occurences"), num);
+    else if (num == 1)
+       statusbar(_("Replaced 1 occurence"));
+}
+
+void replace_abort(void)
+{
+    UNSET(KEEP_CUTBUFFER);
+    display_main_list();
+    reset_cursor();
+}
+
+/* Search for a string */
+int do_replace(void)
+{
+    int i, replaceall = 0, numreplaced = 0, beginx;
+    filestruct *fileptr, *begin;
+    char *tmp, *copy, prevanswer[132] = "";
+
+    if ((i = search_init(1)) == -1) {
+       statusbar(_("Replace Cancelled"));
+       replace_abort();
+       return 0;
+    } else if (i == 1) {
+       do_replace();
+       return 1;
+    } else if (i == -2) {
+       replace_abort();
+       do_search();
+       return 0;
+    } else if (i == -3) {
+       replace_abort();
+       return 0;
+    }
+    strncpy(prevanswer, answer, 132);
+
+    if (strcmp(last_replace, "")) {    /* There's a previous replace str */
+       i = statusq(replace_list, REPLACE_LIST_LEN, "",
+                   _("Replace with [%s]"), last_replace);
+
+       if (i == -1) {          /* Aborted enter */
+           strncpy(answer, last_replace, 132);
+           statusbar(_("Replace Cancelled"));
+           replace_abort();
+           return 0;
+       } else if (i == 0)      /* They actually entered something */
+           strncpy(last_replace, answer, 132);
+       else if (i == NANO_CASE_KEY) {  /* They asked for case sensitivity */
+           if (ISSET(CASE_SENSITIVE))
+               UNSET(CASE_SENSITIVE);
+           else
+               SET(CASE_SENSITIVE);
+
+           do_replace();
+           return 0;
+       } else {                /* First page, last page, for example could get here */
+
+           do_early_abort();
+           replace_abort();
+           return 0;
+       }
+    } else {                   /* last_search is empty */
+
+       i = statusq(replace_list, REPLACE_LIST_LEN, "", _("Replace with"));
+       if (i == -1) {
+           statusbar(_("Replace Cancelled"));
+           reset_cursor();
+           replace_abort();
+           return 0;
+       } else if (i == 0)      /* They entered something new */
+           strncpy(last_replace, answer, 132);
+       else if (i == NANO_CASE_KEY) {  /* They want it case sensitive */
+           if (ISSET(CASE_SENSITIVE))
+               UNSET(CASE_SENSITIVE);
+           else
+               SET(CASE_SENSITIVE);
+
+           do_replace();
+           return 1;
+       } else {                /* First line key, etc. */
+
+           do_early_abort();
+           replace_abort();
+           return 0;
+       }
+    }
+
+    /* save where we are */
+    begin = current;
+    beginx = current_x;
+
+    while (1) {
+
+       if (replaceall)
+           fileptr = findnextstr(1, begin, prevanswer);
+       else
+           fileptr = findnextstr(0, begin, prevanswer);
+
+       /* No more matches.  Done! */
+       if (!fileptr)
+           break;
+
+       /* If we're here, we've found the search string */
+       if (!replaceall)
+           i = do_yesno(1, 1, _("Replace this instance?"));
+
+       if (i > 0 || replaceall) {      /* Yes, replace it!!!! */
+           if (i == 2)
+               replaceall = 1;
+
+           /* Create buffer */
+           copy = nmalloc(strlen(current->data) - strlen(last_search) +
+                          strlen(last_replace) + 1);
+
+           /* Head of Original Line */
+           strncpy(copy, current->data, current_x);
+           copy[current_x] = 0;
+
+           /* Replacement Text */
+           strcat(copy, last_replace);
+
+           /* The tail of the original line */
+           /*  This may expose other bugs, because it no longer
+              goes through each character on the string
+              and tests for string goodness.  But because
+              we can assume the invariant that current->data
+              is less than current_x + strlen(last_search) long,   
+              this should be safe.  Or it will expose bugs ;-) */
+           tmp = current->data + current_x + strlen(last_search);
+           strcat(copy, tmp);
+
+           /* Cleanup */
+           free(current->data);
+           current->data = copy;
+
+           /* Stop bug where we replace a substring of the replacement text */
+           current_x += strlen(last_replace);
+
+           edit_refresh();
+           set_modified();
+           numreplaced++;
+       } else if (i == -1)     /* Abort, else do nothing and continue loop */
+           break;
+    }
+
+    current = begin;
+    current_x = beginx;
+    renumber_all();
+    edit_update(current);
+    print_replaced(numreplaced);
+    replace_abort();
+    return 1;
+}
+
+void goto_abort(void)
+{
+    UNSET(KEEP_CUTBUFFER);
+    display_main_list();
+}
+
+int do_gotoline(long defline)
+{
+    long line, i = 1, j = 0;
+    filestruct *fileptr;
+
+    if (defline > 0)           /* We already know what line we want to go to */
+       line = defline;
+    else {                     /* Ask for it */
+
+       j = statusq(goto_list, GOTO_LIST_LEN, "", _("Enter line number"));
+       if (j == -1) {
+           statusbar(_("Aborted"));
+           goto_abort();
+           return 0;
+       } else if (j != 0) {
+           do_early_abort();
+           goto_abort();
+           return 0;
+       }
+       if (!strcmp(answer, "$")) {
+           current = filebot;
+           current_x = 0;
+           edit_update(current);
+           goto_abort();
+           return 1;
+       }
+       line = atoi(answer);
+    }
+
+    /* Bounds check */
+    if (line <= 0) {
+       statusbar(_("Come on, be reasonable"));
+       goto_abort();
+       return 0;
+    }
+    if (line > totlines) {
+       statusbar(_("Only %d lines available, skipping to last line"),
+                 filebot->lineno);
+       current = filebot;
+       current_x = 0;
+       edit_update(current);
+    } else {
+       for (fileptr = fileage; fileptr != NULL && i < line; i++)
+           fileptr = fileptr->next;
+
+       current = fileptr;
+       current_x = 0;
+       edit_update(current);
+    }
+
+    goto_abort();
+    return 1;
+}
+
+int do_gotoline_void(void)
+{
+    return do_gotoline(0);
+}
+
diff --git a/utils.c b/utils.c
index fa44d80b96d0e25ecde6cbcf227d30c2ae08ce64..6649b4a228e2702c2d2c73f7c18e8042aa23026b 100644 (file)
--- a/utils.c
+++ b/utils.c
 #include "nano.h"
 #include "proto.h"
 
+#ifndef NANO_SMALL 
+#include <libintl.h>
+#define _(string) gettext(string)
+#else
+#define _(string) (string)
+#endif
+
 /* Lower case a string - must be null terminated */
 void lowercase(char *src)
 {
@@ -79,3 +86,27 @@ char *strstrwrapper(char *haystack, char *needle)
     else
        return strcasestr(haystack, needle);
 }
+
+/* Thanks BG, many ppl have been asking for this... */
+void *nmalloc(size_t howmuch)
+{   
+    void *r;
+    /* Panic save? */
+
+    if (!(r = malloc(howmuch)))
+       die(_("nano: malloc: out of memory!"));
+
+    return r;
+}
+void *nrealloc(void *ptr, size_t howmuch)
+{   
+    void *r;
+    
+    if (!(r = realloc(ptr, howmuch)))
+       die("nano: realloc: out of memory!");  
+
+    return r;
+}
+