diff --git a/Makefile.am b/Makefile.am
index 1e5f7d5b108df210d6d32c72b5aced1f0e49cb84..1244b170c30994ed16e6ac8200c72e2e0af4bd20 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -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 
 
diff --git a/Makefile.in b/Makefile.in
index 1f9429e3951ba2d9b3d9598d033ec3cff820cfe7..e7629f2902db89f605ba98190707b32f26c32908 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -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
index 0000000000000000000000000000000000000000..03b68cbb3c703cee63fdd38f5d4d99cfeb5853c2
--- /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
index 0000000000000000000000000000000000000000..b59410866373b80e7bc8991e863735375ad62408
--- /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
--- 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
--- 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
index 0000000000000000000000000000000000000000..981cf06d88857ba9c7349bae421765e783dbcc39
--- /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
--- a/utils.c
+++ b/utils.c
@@ -26,6 +26,13 @@
 #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;
+}
+